Skip to content

Commit e9492b3

Browse files
committed
test(decompression-plz): added tests for chunked and compressed encodings
1 parent 03627df commit e9492b3

File tree

11 files changed

+237
-130
lines changed

11 files changed

+237
-130
lines changed

decompression-plz/tests/test_cases/both_te_ce.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ fn test_both_te_ce() {
2828
state = state.try_next().unwrap();
2929
assert!(matches!(state, DecodeState::UpdateContentLength(_)));
3030
state = state.try_next().unwrap();
31-
assert!(matches!(state, DecodeState::End));
31+
assert!(state.is_ended());
3232

3333
let result = tm.into_bytes();
3434
let verify = "Host: example.com\r\n\
Lines changed: 154 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
use super::*;
2-
use body_plz::{
3-
reader::chunked_reader::ChunkReaderState, variants::chunked::ChunkType,
4-
};
2+
use body_plz::variants::chunked::ChunkType;
3+
use decompression_plz::chunked::{chunked_to_raw, partial_chunked_to_raw};
4+
use tests_utils::all_compressed_data;
55

6+
const HEADERS: &str = "Host: example.com\r\n\
7+
Content-Type: text/html; charset=utf-8\r\n\
8+
Transfer-Encoding: chunked\r\n\r\n";
9+
10+
// converter
611
fn build_chunked_body_large() -> Body {
712
/*
813
7\r\n\
@@ -16,41 +21,176 @@ fn build_chunked_body_large() -> Body {
1621
*/
1722

1823
let chunk_vec = vec![
19-
ChunkType::Size("7".into()),
24+
ChunkType::Size("7\r\n".into()),
2025
ChunkType::Chunk("Mozilla\r\n".into()),
21-
ChunkType::Size("9".into()),
26+
ChunkType::Size("9\r\n".into()),
2227
ChunkType::Chunk("Developer\r\n".into()),
23-
ChunkType::Size("7".into()),
28+
ChunkType::Size("7\r\n".into()),
2429
ChunkType::Chunk("Network\r\n".into()),
2530
ChunkType::LastChunk("0\r\n".into()),
2631
ChunkType::EndCRLF("\r\n".into()),
2732
];
2833
Body::Chunked(chunk_vec)
2934
}
3035

36+
#[test]
37+
fn test_chunked_to_raw() {
38+
let body = build_chunked_body_large();
39+
let mut buf = BytesMut::new();
40+
41+
let mut tm = TestMessage::build(HEADERS.into(), body, None);
42+
chunked_to_raw(&mut tm, &mut buf);
43+
let verify = "Host: example.com\r\n\
44+
Content-Type: text/html; charset=utf-8\r\n\
45+
Transfer-Encoding: chunked\r\n\r\n\
46+
MozillaDeveloperNetwork";
47+
assert_eq!(tm.into_bytes(), verify);
48+
}
49+
50+
#[test]
51+
fn test_chunked_to_raw_with_trailer() {
52+
let mut body = build_chunked_body_large();
53+
let trailer_headers = "Header: Val\r\n\
54+
Another: Val\r\n\r\n";
55+
let trailer_chunk =
56+
ChunkType::Trailers(HeaderMap::from(BytesMut::from(trailer_headers)));
57+
body.push_chunk(trailer_chunk);
58+
let mut tm = TestMessage::build(HEADERS.into(), body, None);
59+
let mut buf = BytesMut::new();
60+
chunked_to_raw(&mut tm, &mut buf);
61+
let verify = "Host: example.com\r\n\
62+
Content-Type: text/html; charset=utf-8\r\n\
63+
Transfer-Encoding: chunked\r\n\
64+
Header: Val\r\n\
65+
Another: Val\r\n\r\n\
66+
MozillaDeveloperNetwork";
67+
assert_eq!(tm.into_bytes(), verify);
68+
}
69+
70+
#[test]
71+
fn test_partial_chunked_to_raw() {
72+
let chunks = build_chunked_body_large().into_chunks();
73+
let body = partial_chunked_to_raw(chunks);
74+
assert!(body.is_some());
75+
let verify = "7\r\n\
76+
Mozilla\r\n\
77+
9\r\n\
78+
Developer\r\n\
79+
7\r\n\
80+
Network\r\n\
81+
0\r\n\r\n";
82+
assert_eq!(body.unwrap(), verify);
83+
}
84+
85+
// state
3186
#[test]
3287
fn test_chunked_body_large() {
33-
let headers = "Host: example.com\r\n\
34-
Content-Type: text/html; charset=utf-8\r\n\
35-
Transfer-Encoding: chunked\r\n\r\n";
3688
let mut tm =
37-
TestMessage::build(headers.into(), build_chunked_body_large(), None);
89+
TestMessage::build(HEADERS.into(), build_chunked_body_large(), None);
90+
let mut buf = BytesMut::new();
91+
let mut state = DecodeState::init(&mut tm, &mut buf);
92+
state = state.try_next().unwrap();
93+
assert!(matches!(state, DecodeState::TransferEncoding(..)));
94+
state = state.try_next().unwrap();
95+
assert!(matches!(state, DecodeState::UpdateContentLength(_)));
96+
state = state.try_next().unwrap();
97+
assert!(state.is_ended());
98+
let verify = "Host: example.com\r\n\
99+
Content-Type: text/html; charset=utf-8\r\n\
100+
Content-Length: 23\r\n\r\n\
101+
MozillaDeveloperNetwork";
102+
let result = tm.into_bytes();
103+
assert_eq!(result, verify);
104+
}
38105

106+
fn build_all_compressed_chunk_body() -> Body {
107+
let body = all_compressed_data(); // len 53
108+
let mut chunk_vec = vec![
109+
ChunkType::Size("10\r\n".into()),
110+
ChunkType::Chunk(body[0..10].into()),
111+
ChunkType::Size("10\r\n".into()),
112+
ChunkType::Chunk(body[10..20].into()),
113+
ChunkType::Size("10\r\n".into()),
114+
ChunkType::Chunk(body[20..30].into()),
115+
ChunkType::Size("10\r\n".into()),
116+
ChunkType::Chunk(body[30..40].into()),
117+
ChunkType::Size("10\r\n".into()),
118+
ChunkType::Chunk(body[40..50].into()),
119+
ChunkType::Size("3\r\n".into()),
120+
ChunkType::Chunk(body[50..].into()),
121+
ChunkType::EndCRLF("\r\n".into()),
122+
];
123+
124+
for chunk in chunk_vec.iter_mut() {
125+
if let ChunkType::Chunk(chunk) = chunk {
126+
chunk.extend_from_slice("\r\n".as_bytes());
127+
}
128+
}
129+
Body::Chunked(chunk_vec)
130+
}
131+
132+
#[test]
133+
fn test_chunked_with_compression() {
134+
let headers = "Host: example.com\r\n\
135+
Content-Type: text/html; charset=utf-8\r\n\
136+
Transfer-Encoding: br, deflate, identity, gzip, zstd, chunked\r\n\
137+
\r\n";
39138
let mut buf = BytesMut::new();
139+
140+
let mut tm = TestMessage::build(
141+
headers.into(),
142+
build_all_compressed_chunk_body(),
143+
None,
144+
);
40145
let mut state = DecodeState::init(&mut tm, &mut buf);
41146
state = state.try_next().unwrap();
42147
assert!(matches!(state, DecodeState::TransferEncoding(..)));
43148

44149
state = state.try_next().unwrap();
45-
assert!(matches!(state, DecodeState::UpdateContentLength(_)));
150+
assert!(matches!(state, DecodeState::UpdateContentLength(..)));
46151

47152
state = state.try_next().unwrap();
48-
assert!(matches!(state, DecodeState::End));
153+
assert!(state.is_ended());
49154

50155
let verify = "Host: example.com\r\n\
51156
Content-Type: text/html; charset=utf-8\r\n\
52-
Content-Length: 23\r\n\r\n\
53-
MozillaDeveloperNetwork";
157+
Content-Length: 11\r\n\r\n\
158+
hello world";
159+
let result = tm.into_bytes();
160+
assert_eq!(result, verify);
161+
}
162+
163+
#[test]
164+
fn test_chunked_with_ce_compression() {
165+
let headers = "Host: example.com\r\n\
166+
Content-Type: text/html; charset=utf-8\r\n\
167+
Transfer-Encoding: chunked\r\n\
168+
Content-Encoding: br, deflate, identity, gzip, zstd\r\n\
169+
\r\n";
170+
let mut buf = BytesMut::new();
171+
172+
let mut tm = TestMessage::build(
173+
headers.into(),
174+
build_all_compressed_chunk_body(),
175+
None,
176+
);
177+
let mut state = DecodeState::init(&mut tm, &mut buf);
178+
state = state.try_next().unwrap();
179+
assert!(matches!(state, DecodeState::TransferEncoding(..)));
180+
181+
state = state.try_next().unwrap();
182+
assert!(matches!(state, DecodeState::ContentEncoding(..)));
183+
184+
state = state.try_next().unwrap();
185+
assert!(matches!(state, DecodeState::UpdateContentLength(..)));
186+
187+
state = state.try_next().unwrap();
188+
assert!(state.is_ended());
189+
190+
let verify = "Host: example.com\r\n\
191+
Content-Type: text/html; charset=utf-8\r\n\
192+
Content-Length: 11\r\n\r\n\
193+
hello world";
54194
let result = tm.into_bytes();
55195
assert_eq!(result, verify);
56196
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
1+
use header_plz::const_headers::{CONTENT_ENCODING, TRANSFER_ENCODING};
2+
13
use super::*;
24
pub mod both_te_ce;
35
pub mod chunked;
6+
pub mod extra;
47
pub mod multi_compression;
58
pub mod no_encodings;
9+
pub mod partial;
610
pub mod single_compression;
11+
12+
fn encoding_state(
13+
header: &str,
14+
) -> impl FnOnce(&DecodeState<TestMessage>) -> bool {
15+
if header == TRANSFER_ENCODING {
16+
|s: &DecodeState<TestMessage>| {
17+
matches!(s, DecodeState::TransferEncoding(_, _))
18+
}
19+
} else if header == CONTENT_ENCODING {
20+
|s: &DecodeState<TestMessage>| {
21+
matches!(s, DecodeState::ContentEncoding(_, _))
22+
}
23+
} else {
24+
panic!("Unknown header");
25+
}
26+
}

decompression-plz/tests/test_cases/multi_compression/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
use header_plz::body_headers::content_encoding::ContentEncoding;
21
use tests_utils::{ALL_COMPRESSIONS, all_compressed_data};
32

43
use super::*;
54
mod multi_header;
65
mod single_header;
76

87
fn assert_case_multi_compression(
9-
f: fn(&DecodeState<TestMessage>) -> bool,
108
mut tm: TestMessage,
9+
header: &str,
1110
verify: &str,
1211
) {
1312
let mut buf = BytesMut::new();
1413
let mut state = DecodeState::init(&mut tm, &mut buf);
1514
state = state.try_next().unwrap();
16-
assert!((f)(&state));
15+
let encoding_state = encoding_state(header);
16+
assert!((encoding_state)(&state));
1717
state = state.try_next().unwrap();
1818
assert!(matches!(state, DecodeState::UpdateContentLength(_)));
1919
state = state.try_next().unwrap();
20-
assert!(matches!(state, DecodeState::End));
20+
assert!(state.is_ended());
2121

2222
let result = tm.into_bytes();
2323
assert_eq!(result, verify);

decompression-plz/tests/test_cases/multi_compression/multi_header.rs

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@ use header_plz::const_headers::{CONTENT_ENCODING, TRANSFER_ENCODING};
22

33
use super::*;
44

5+
const VERIFY: &str = "Host: example.com\r\n\
6+
Content-Type: text/html; charset=utf-8\r\n\
7+
random: random\r\n\
8+
another-random: random\r\n\
9+
test-header: test-header\r\n\
10+
Content-Length: 11\r\n\r\n\
11+
hello world";
12+
513
fn build_test_message_all_encodings_multi_header(
614
header_name: &str,
715
) -> TestMessage {
@@ -26,37 +34,22 @@ fn build_test_message_all_encodings_multi_header(
2634
body.len()
2735
);
2836

29-
let mut tm = TestMessage::build(
37+
TestMessage::build(
3038
headers.as_bytes().into(),
3139
Body::Raw(body.as_slice().into()),
3240
None,
33-
);
34-
tm
41+
)
3542
}
3643

37-
const VERIFY: &str = "Host: example.com\r\n\
38-
Content-Type: text/html; charset=utf-8\r\n\
39-
random: random\r\n\
40-
another-random: random\r\n\
41-
test-header: test-header\r\n\
42-
Content-Length: 11\r\n\r\n\
43-
hello world";
44-
4544
#[test]
4645
fn assert_decode_state_ce_all_multi_header() {
4746
let tm = build_test_message_all_encodings_multi_header(CONTENT_ENCODING);
4847

49-
let f = move |s: &DecodeState<TestMessage>| {
50-
matches!(s, DecodeState::ContentEncoding(_, _))
51-
};
52-
assert_case_multi_compression(f, tm, VERIFY);
48+
assert_case_multi_compression(tm, CONTENT_ENCODING, VERIFY);
5349
}
5450

5551
#[test]
5652
fn assert_decode_state_te_all_multi_header() {
5753
let tm = build_test_message_all_encodings_multi_header(TRANSFER_ENCODING);
58-
let f = move |s: &DecodeState<TestMessage>| {
59-
matches!(s, DecodeState::TransferEncoding(_, _))
60-
};
61-
assert_case_multi_compression(f, tm, VERIFY);
54+
assert_case_multi_compression(tm, TRANSFER_ENCODING, VERIFY);
6255
}

decompression-plz/tests/test_cases/multi_compression/single_header.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@ fn build_test_message_all_encodings_single_header(
1616
body.len()
1717
);
1818

19-
let mut tm = TestMessage::build(
19+
TestMessage::build(
2020
headers.as_bytes().into(),
2121
Body::Raw(body.as_slice().into()),
2222
None,
23-
);
24-
tm
23+
)
2524
}
2625

2726
const VERIFY: &str = "Host: example.com\r\n\
@@ -32,18 +31,11 @@ const VERIFY: &str = "Host: example.com\r\n\
3231
#[test]
3332
fn assert_decode_state_ce_all_single_header() {
3433
let tm = build_test_message_all_encodings_single_header(CONTENT_ENCODING);
35-
36-
let f = move |s: &DecodeState<TestMessage>| {
37-
matches!(s, DecodeState::ContentEncoding(_, _))
38-
};
39-
assert_case_multi_compression(f, tm, VERIFY);
34+
assert_case_multi_compression(tm, CONTENT_ENCODING, VERIFY);
4035
}
4136

4237
#[test]
4338
fn assert_decode_state_te_all_single_header() {
4439
let tm = build_test_message_all_encodings_single_header(TRANSFER_ENCODING);
45-
let f = move |s: &DecodeState<TestMessage>| {
46-
matches!(s, DecodeState::TransferEncoding(_, _))
47-
};
48-
assert_case_multi_compression(f, tm, VERIFY);
40+
assert_case_multi_compression(tm, TRANSFER_ENCODING, VERIFY);
4941
}

decompression-plz/tests/test_cases/no_encodings.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn test_decode_init_no_enc() {
1414
let mut buf = BytesMut::new();
1515
let mut state = DecodeState::init(&mut tm, &mut buf);
1616
state = state.try_next().unwrap();
17-
assert!(matches!(state, DecodeState::End));
17+
assert!(state.is_ended());
1818
let result = tm.into_bytes();
1919
let verify = "Host: example.com\r\n\
2020
Content-Type: text/html; charset=utf-8\r\n\
@@ -39,7 +39,7 @@ fn test_decode_init_no_enc_extra_body() {
3939
state = state.try_next().unwrap();
4040
assert!(matches!(state, DecodeState::UpdateContentLength(_)));
4141
state = state.try_next().unwrap();
42-
assert!(matches!(state, DecodeState::End));
42+
assert!(state.is_ended());
4343
let result = tm.into_bytes();
4444
let verify = "Host: example.com\r\n\
4545
Content-Type: text/html; charset=utf-8\r\n\
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

0 commit comments

Comments
 (0)