11use 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
611fn 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]
3287fn 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}
0 commit comments