Skip to content

Commit 21828b2

Browse files
committed
feat(decompression): support HTTP responses containing multiple ZSTD frames
1 parent eeda42e commit 21828b2

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

tower-http/src/decompression/body.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ where
397397
type Output = ZstdDecoder<Self::Input>;
398398

399399
fn apply(input: Self::Input, _quality: CompressionLevel) -> Self::Output {
400-
let decoder = ZstdDecoder::new(input);
400+
let mut decoder = ZstdDecoder::new(input);
401401
decoder.multiple_members(true);
402402
decoder
403403
}

tower-http/src/decompression/mod.rs

+34
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,24 @@ mod tests {
168168
assert_eq!(decompressed_data, "Hello, World!");
169169
}
170170

171+
#[tokio::test]
172+
async fn decompress_multi_zstd() {
173+
let mut client = Decompression::new(service_fn(handle_multi_zstd));
174+
175+
let req = Request::builder()
176+
.header("accept-encoding", "zstd")
177+
.body(Body::empty())
178+
.unwrap();
179+
let res = client.ready().await.unwrap().call(req).await.unwrap();
180+
181+
// read the body, it will be decompressed automatically
182+
let body = res.into_body();
183+
let decompressed_data =
184+
String::from_utf8(body.collect().await.unwrap().to_bytes().to_vec()).unwrap();
185+
186+
assert_eq!(decompressed_data, "Hello, World!");
187+
}
188+
171189
async fn handle_multi_gz(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
172190
let mut buf = Vec::new();
173191
let mut enc1 = GzEncoder::new(&mut buf, Default::default());
@@ -184,6 +202,22 @@ mod tests {
184202
Ok(res)
185203
}
186204

205+
async fn handle_multi_zstd(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
206+
let mut buf = Vec::new();
207+
let mut enc1 = zstd::Encoder::new(&mut buf, Default::default()).unwrap();
208+
enc1.write_all(b"Hello, ").unwrap();
209+
enc1.finish().unwrap();
210+
211+
let mut enc2 = zstd::Encoder::new(&mut buf, Default::default()).unwrap();
212+
enc2.write_all(b"World!").unwrap();
213+
enc2.finish().unwrap();
214+
215+
let mut res = Response::new(Body::from(buf));
216+
res.headers_mut()
217+
.insert("content-encoding", "zstd".parse().unwrap());
218+
Ok(res)
219+
}
220+
187221
#[allow(dead_code)]
188222
async fn is_compatible_with_hyper() {
189223
let client =

0 commit comments

Comments
 (0)