Skip to content

Commit

Permalink
Add test for zstd window size
Browse files Browse the repository at this point in the history
Also bump the version of the zstd dev dependency.
  • Loading branch information
AlyoshaVasilieva committed May 26, 2024
1 parent a9575c0 commit 6e504c3
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
2 changes: 1 addition & 1 deletion tower-http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ tokio = { version = "1", features = ["full"] }
tower = { version = "0.4.10", features = ["buffer", "util", "retry", "make", "timeout"] }
tracing-subscriber = "0.3"
uuid = { version = "1.0", features = ["v4"] }
zstd = "0.12"
zstd = "0.13"

[features]
default = []
Expand Down
37 changes: 37 additions & 0 deletions tower-http/src/compression/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,41 @@ mod tests {

Ok(())
}

/// Test ensuring that zstd compression will not exceed an 8MiB window size; browsers do not
/// accept responses using 16MiB+ window sizes.
#[tokio::test]
async fn zstd_is_web_safe() -> Result<(), crate::BoxError> {
async fn zeroes(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
Ok(Response::new(Body::from(vec![0u8; 18_874_368])))
}
// zstd will (I believe) lower its window size if a larger one isn't beneficial and
// it knows the size of the input; use an 18MiB body to ensure it would want a
// >=16MiB window (though it might not be able to see the input size here).

let zstd_layer = CompressionLayer::new()
.quality(CompressionLevel::Best)
.no_br()
.no_deflate()
.no_gzip();

let mut service = ServiceBuilder::new().layer(zstd_layer).service_fn(zeroes);

let request = Request::builder()
.header(ACCEPT_ENCODING, "zstd")
.body(Body::empty())?;

let response = service.ready().await?.call(request).await?;

assert_eq!(response.headers()["content-encoding"], "zstd");

let body = response.into_body();
let bytes = body.collect().await?.to_bytes();
let mut dec = zstd::Decoder::new(&*bytes)?;
dec.window_log_max(23)?; // Limit window size accepted by decoder to 2 ^ 23 bytes (8MiB)

std::io::copy(&mut dec, &mut std::io::sink())?;

Ok(())
}
}

0 comments on commit 6e504c3

Please sign in to comment.