mirror of
https://github.com/lexmount/moli.git
synced 2026-09-24 00:01:27 +00:00
refactor(compression): share the Brotli backend with curl
Replace brotli2 with brotlic so stream codecs and curl use the same brotlic-sys 0.2.2 dependency. Remove the separate brotli-sys dependency and preserve compression quality 5 and streaming finish handling. Validation: cargo fmt --all; cargo clippy --workspace --all-targets --all-features -- -D warnings. Tests were skipped as requested.
This commit is contained in:
Generated
+5
-16
@@ -382,23 +382,12 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "brotli-sys"
|
||||
version = "0.3.2"
|
||||
name = "brotlic"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd"
|
||||
checksum = "f552f56f302af0006c32b50bfa2bdb4696fd6ba33c3ab9f6225fefdb1efdc680"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "brotli2"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e"
|
||||
dependencies = [
|
||||
"brotli-sys",
|
||||
"libc",
|
||||
"brotlic-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2877,7 +2866,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"app_units",
|
||||
"base64 0.22.1",
|
||||
"brotli2",
|
||||
"brotlic",
|
||||
"crossbeam-channel",
|
||||
"cssparser",
|
||||
"curl",
|
||||
|
||||
@@ -18,7 +18,7 @@ wpt-extensions = []
|
||||
anyhow = "1.0.100"
|
||||
app_units = "0.7.8"
|
||||
base64 = "0.22"
|
||||
brotli2 = "0.3.2"
|
||||
brotlic = "0.8.2"
|
||||
crossbeam-channel = "0.5.15"
|
||||
cssparser = "0.37"
|
||||
data-url = "0.3.2"
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
//! Streaming codecs, independent of V8 and the Streams lifecycle.
|
||||
//! One decoder accepts exactly one stream/member, including any checksum.
|
||||
|
||||
use brotli2::{
|
||||
CompressParams,
|
||||
raw::{
|
||||
CoStatus, Compress as BrotliCompress, CompressOp, DeStatus, Decompress as BrotliDecompress,
|
||||
},
|
||||
use brotlic::{
|
||||
BrotliDecoder, BrotliEncoder, BrotliEncoderOptions, Quality, decode::DecoderInfo,
|
||||
encode::BrotliOperation,
|
||||
};
|
||||
use flate2::{Compress, Compression, Decompress, FlushCompress, FlushDecompress, Status};
|
||||
|
||||
@@ -30,8 +28,8 @@ impl Format {
|
||||
}
|
||||
|
||||
enum Engine {
|
||||
BrotliCompress(BrotliCompress),
|
||||
BrotliDecompress(BrotliDecompress),
|
||||
BrotliCompress(BrotliEncoder),
|
||||
BrotliDecompress(BrotliDecoder),
|
||||
Compress(Compress),
|
||||
Decompress(Decompress),
|
||||
}
|
||||
@@ -44,12 +42,14 @@ pub(super) struct Codec {
|
||||
impl Codec {
|
||||
pub(super) fn new(format: Format, decompress: bool) -> Self {
|
||||
let engine = match (format, decompress) {
|
||||
(Format::Brotli, true) => Engine::BrotliDecompress(BrotliDecompress::new()),
|
||||
(Format::Brotli, true) => Engine::BrotliDecompress(BrotliDecoder::new()),
|
||||
(Format::Brotli, false) => {
|
||||
let mut encoder = BrotliCompress::new();
|
||||
// Moderate quality for interactive streaming; retain the
|
||||
// standard window size and generic compression mode.
|
||||
encoder.set_params(CompressParams::new().quality(5));
|
||||
let encoder = BrotliEncoderOptions::new()
|
||||
.quality(Quality::new(5).expect("Brotli quality 5 must be valid"))
|
||||
.build()
|
||||
.expect("fixed Brotli encoder parameters must be valid");
|
||||
Engine::BrotliCompress(encoder)
|
||||
}
|
||||
(Format::Gzip, true) => Engine::Decompress(Decompress::new_gzip(15)),
|
||||
@@ -92,40 +92,28 @@ impl Codec {
|
||||
let mut output = vec![0; 16 * 1024];
|
||||
let (status, consumed, produced) = match &mut self.engine {
|
||||
Engine::BrotliCompress(engine) => {
|
||||
let (before_in, before_out) = (input.len(), output.len());
|
||||
let mut remaining_in = input;
|
||||
let mut remaining_out = output.as_mut_slice();
|
||||
let status = engine
|
||||
.compress(
|
||||
if finish {
|
||||
CompressOp::Finish
|
||||
} else {
|
||||
CompressOp::Process
|
||||
},
|
||||
&mut remaining_in,
|
||||
&mut remaining_out,
|
||||
)
|
||||
// Process completion is not the end of the stream.
|
||||
.map(|status| finish && status == CoStatus::Finished)
|
||||
.map_err(|_| "Compression failed");
|
||||
let operation = if finish {
|
||||
BrotliOperation::Finish
|
||||
} else {
|
||||
BrotliOperation::Process
|
||||
};
|
||||
let Ok(result) = engine.compress(input, &mut output, operation) else {
|
||||
return (chunks, Err("Compression failed"));
|
||||
};
|
||||
(
|
||||
status,
|
||||
before_in - remaining_in.len(),
|
||||
before_out - remaining_out.len(),
|
||||
Ok(engine.is_finished()),
|
||||
result.bytes_read,
|
||||
result.bytes_written,
|
||||
)
|
||||
}
|
||||
Engine::BrotliDecompress(engine) => {
|
||||
let (before_in, before_out) = (input.len(), output.len());
|
||||
let mut remaining_in = input;
|
||||
let mut remaining_out = output.as_mut_slice();
|
||||
let status = engine
|
||||
.decompress(&mut remaining_in, &mut remaining_out)
|
||||
.map(|status| status == DeStatus::Finished)
|
||||
.map_err(|_| "The compressed data was not valid");
|
||||
let Ok(result) = engine.decompress(input, &mut output) else {
|
||||
return (chunks, Err("The compressed data was not valid"));
|
||||
};
|
||||
(
|
||||
status,
|
||||
before_in - remaining_in.len(),
|
||||
before_out - remaining_out.len(),
|
||||
Ok(result.info == DecoderInfo::Finished),
|
||||
result.bytes_read,
|
||||
result.bytes_written,
|
||||
)
|
||||
}
|
||||
Engine::Compress(engine) => {
|
||||
|
||||
Reference in New Issue
Block a user