tower_http/decompression/request/
mod.rs1pub(super) mod future;
2pub(super) mod layer;
3pub(super) mod service;
4
5#[cfg(test)]
6mod tests {
7 use super::service::RequestDecompression;
8 use crate::decompression::DecompressionBody;
9 use crate::test_helpers::Body;
10 use flate2::{write::GzEncoder, Compression};
11 use http::{header, Request, Response, StatusCode};
12 use http_body_util::BodyExt;
13 use std::{convert::Infallible, io::Write};
14 use tower::{service_fn, Service, ServiceExt};
15
16 #[tokio::test]
17 async fn decompress_accepted_encoding() {
18 let req = request_gzip();
19 let mut svc = RequestDecompression::new(service_fn(assert_request_is_decompressed));
20 let _ = svc.ready().await.unwrap().call(req).await.unwrap();
21 }
22
23 #[tokio::test]
24 async fn support_unencoded_body() {
25 let req = Request::builder().body(Body::from("Hello?")).unwrap();
26 let mut svc = RequestDecompression::new(service_fn(assert_request_is_decompressed));
27 let _ = svc.ready().await.unwrap().call(req).await.unwrap();
28 }
29
30 #[tokio::test]
31 async fn unaccepted_content_encoding_returns_unsupported_media_type() {
32 let req = request_gzip();
33 let mut svc = RequestDecompression::new(service_fn(should_not_be_called)).gzip(false);
34 let res = svc.ready().await.unwrap().call(req).await.unwrap();
35 assert_eq!(StatusCode::UNSUPPORTED_MEDIA_TYPE, res.status());
36 }
37
38 #[tokio::test]
39 async fn pass_through_unsupported_encoding_when_enabled() {
40 let req = request_gzip();
41 let mut svc = RequestDecompression::new(service_fn(assert_request_is_passed_through))
42 .pass_through_unaccepted(true)
43 .gzip(false);
44 let _ = svc.ready().await.unwrap().call(req).await.unwrap();
45 }
46
47 async fn assert_request_is_decompressed(
48 req: Request<DecompressionBody<Body>>,
49 ) -> Result<Response<Body>, Infallible> {
50 let (parts, mut body) = req.into_parts();
51 let body = read_body(&mut body).await;
52
53 assert_eq!(body, b"Hello?");
54 assert!(!parts.headers.contains_key(header::CONTENT_ENCODING));
55
56 Ok(Response::new(Body::from("Hello, World!")))
57 }
58
59 async fn assert_request_is_passed_through(
60 req: Request<DecompressionBody<Body>>,
61 ) -> Result<Response<Body>, Infallible> {
62 let (parts, mut body) = req.into_parts();
63 let body = read_body(&mut body).await;
64
65 assert_ne!(body, b"Hello?");
66 assert!(parts.headers.contains_key(header::CONTENT_ENCODING));
67
68 Ok(Response::new(Body::empty()))
69 }
70
71 async fn should_not_be_called(
72 _: Request<DecompressionBody<Body>>,
73 ) -> Result<Response<Body>, Infallible> {
74 panic!("Inner service should not be called");
75 }
76
77 fn request_gzip() -> Request<Body> {
78 let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
79 encoder.write_all(b"Hello?").unwrap();
80 let body = encoder.finish().unwrap();
81 Request::builder()
82 .header(header::CONTENT_ENCODING, "gzip")
83 .body(Body::from(body))
84 .unwrap()
85 }
86
87 async fn read_body(body: &mut DecompressionBody<Body>) -> Vec<u8> {
88 body.collect().await.unwrap().to_bytes().to_vec()
89 }
90}