1 mod support;
2 use std::io::Write;
3 use support::*;
4
5 #[tokio::test]
deflate_response()6 async fn deflate_response() {
7 deflate_case(10_000, 4096).await;
8 }
9
10 #[tokio::test]
deflate_single_byte_chunks()11 async fn deflate_single_byte_chunks() {
12 deflate_case(10, 1).await;
13 }
14
15 #[tokio::test]
test_deflate_empty_body()16 async fn test_deflate_empty_body() {
17 let server = server::http(move |req| async move {
18 assert_eq!(req.method(), "HEAD");
19
20 http::Response::builder()
21 .header("content-encoding", "deflate")
22 .header("content-length", 100)
23 .body(Default::default())
24 .unwrap()
25 });
26
27 let client = reqwest::Client::new();
28 let res = client
29 .head(&format!("http://{}/deflate", server.addr()))
30 .send()
31 .await
32 .unwrap();
33
34 let body = res.text().await.unwrap();
35
36 assert_eq!(body, "");
37 }
38
39 #[tokio::test]
test_accept_header_is_not_changed_if_set()40 async fn test_accept_header_is_not_changed_if_set() {
41 let server = server::http(move |req| async move {
42 assert_eq!(req.headers()["accept"], "application/json");
43 assert!(req.headers()["accept-encoding"]
44 .to_str()
45 .unwrap()
46 .contains("deflate"));
47 http::Response::default()
48 });
49
50 let client = reqwest::Client::new();
51
52 let res = client
53 .get(&format!("http://{}/accept", server.addr()))
54 .header(
55 reqwest::header::ACCEPT,
56 reqwest::header::HeaderValue::from_static("application/json"),
57 )
58 .send()
59 .await
60 .unwrap();
61
62 assert_eq!(res.status(), reqwest::StatusCode::OK);
63 }
64
65 #[tokio::test]
test_accept_encoding_header_is_not_changed_if_set()66 async fn test_accept_encoding_header_is_not_changed_if_set() {
67 let server = server::http(move |req| async move {
68 assert_eq!(req.headers()["accept"], "*/*");
69 assert_eq!(req.headers()["accept-encoding"], "identity");
70 http::Response::default()
71 });
72
73 let client = reqwest::Client::new();
74
75 let res = client
76 .get(&format!("http://{}/accept-encoding", server.addr()))
77 .header(
78 reqwest::header::ACCEPT_ENCODING,
79 reqwest::header::HeaderValue::from_static("identity"),
80 )
81 .send()
82 .await
83 .unwrap();
84
85 assert_eq!(res.status(), reqwest::StatusCode::OK);
86 }
87
deflate_case(response_size: usize, chunk_size: usize)88 async fn deflate_case(response_size: usize, chunk_size: usize) {
89 use futures_util::stream::StreamExt;
90
91 let content: String = (0..response_size)
92 .into_iter()
93 .map(|i| format!("test {}", i))
94 .collect();
95 let mut encoder = libflate::zlib::Encoder::new(Vec::new()).unwrap();
96 match encoder.write(content.as_bytes()) {
97 Ok(n) => assert!(n > 0, "Failed to write to encoder."),
98 _ => panic!("Failed to deflate encode string."),
99 };
100
101 let deflated_content = encoder.finish().into_result().unwrap();
102
103 let mut response = format!(
104 "\
105 HTTP/1.1 200 OK\r\n\
106 Server: test-accept\r\n\
107 Content-Encoding: deflate\r\n\
108 Content-Length: {}\r\n\
109 \r\n",
110 &deflated_content.len()
111 )
112 .into_bytes();
113 response.extend(&deflated_content);
114
115 let server = server::http(move |req| {
116 assert!(req.headers()["accept-encoding"]
117 .to_str()
118 .unwrap()
119 .contains("deflate"));
120
121 let deflated = deflated_content.clone();
122 async move {
123 let len = deflated.len();
124 let stream =
125 futures_util::stream::unfold((deflated, 0), move |(deflated, pos)| async move {
126 let chunk = deflated.chunks(chunk_size).nth(pos)?.to_vec();
127
128 Some((chunk, (deflated, pos + 1)))
129 });
130
131 let body = hyper::Body::wrap_stream(stream.map(Ok::<_, std::convert::Infallible>));
132
133 http::Response::builder()
134 .header("content-encoding", "deflate")
135 .header("content-length", len)
136 .body(body)
137 .unwrap()
138 }
139 });
140
141 let client = reqwest::Client::new();
142
143 let res = client
144 .get(&format!("http://{}/deflate", server.addr()))
145 .send()
146 .await
147 .expect("response");
148
149 let body = res.text().await.expect("text");
150 assert_eq!(body, content);
151 }
152