1 mod support;
2 use std::io::Read;
3 use support::*;
4 
5 #[tokio::test]
brotli_response()6 async fn brotli_response() {
7     brotli_case(10_000, 4096).await;
8 }
9 
10 #[tokio::test]
brotli_single_byte_chunks()11 async fn brotli_single_byte_chunks() {
12     brotli_case(10, 1).await;
13 }
14 
15 #[tokio::test]
test_brotli_empty_body()16 async fn test_brotli_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", "br")
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://{}/brotli", 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("br"));
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 
brotli_case(response_size: usize, chunk_size: usize)88 async fn brotli_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 
96     let mut encoder = brotli_crate::CompressorReader::new(content.as_bytes(), 4096, 5, 20);
97     let mut brotlied_content = Vec::new();
98     encoder.read_to_end(&mut brotlied_content).unwrap();
99 
100     let mut response = format!(
101         "\
102          HTTP/1.1 200 OK\r\n\
103          Server: test-accept\r\n\
104          Content-Encoding: br\r\n\
105          Content-Length: {}\r\n\
106          \r\n",
107         &brotlied_content.len()
108     )
109     .into_bytes();
110     response.extend(&brotlied_content);
111 
112     let server = server::http(move |req| {
113         assert!(req.headers()["accept-encoding"]
114             .to_str()
115             .unwrap()
116             .contains("br"));
117 
118         let brotlied = brotlied_content.clone();
119         async move {
120             let len = brotlied.len();
121             let stream =
122                 futures_util::stream::unfold((brotlied, 0), move |(brotlied, pos)| async move {
123                     let chunk = brotlied.chunks(chunk_size).nth(pos)?.to_vec();
124 
125                     Some((chunk, (brotlied, pos + 1)))
126                 });
127 
128             let body = hyper::Body::wrap_stream(stream.map(Ok::<_, std::convert::Infallible>));
129 
130             http::Response::builder()
131                 .header("content-encoding", "br")
132                 .header("content-length", len)
133                 .body(body)
134                 .unwrap()
135         }
136     });
137 
138     let client = reqwest::Client::new();
139 
140     let res = client
141         .get(&format!("http://{}/brotli", server.addr()))
142         .send()
143         .await
144         .expect("response");
145 
146     let body = res.text().await.expect("text");
147     assert_eq!(body, content);
148 }
149