@@ -52,13 +52,38 @@ impl BodyHeader {
5252 self . transfer_type = Some ( transfer_type) ;
5353 }
5454 }
55+
56+ fn has_single_te_encoding ( & self , encoding : & ContentEncoding ) -> bool {
57+ self . transfer_encoding . as_ref ( ) . is_some_and ( |einfo_vec| {
58+ einfo_vec. len ( ) == 1
59+ && einfo_vec[ 0 ] . encodings ( ) . len ( ) == 1
60+ && & einfo_vec[ 0 ] . encodings ( ) [ 0 ] == encoding
61+ } )
62+ }
63+
64+ pub fn is_chunked_te_only ( & self ) -> bool {
65+ self . has_single_te_encoding ( & ContentEncoding :: Chunked )
66+ }
67+
68+ pub fn is_identity_te_only ( & self ) -> bool {
69+ self . has_single_te_encoding ( & ContentEncoding :: Identity )
70+ }
71+
72+ pub fn is_identity_ce_only ( & self ) -> bool {
73+ self . content_encoding . as_ref ( ) . is_some_and ( |einfo_vec| {
74+ einfo_vec. len ( ) == 1
75+ && einfo_vec[ 0 ] . encodings ( ) . len ( ) == 1
76+ && einfo_vec[ 0 ] . encodings ( ) [ 0 ] == ContentEncoding :: Identity
77+ } )
78+ }
5579}
5680
5781#[ cfg( test) ]
5882mod tests {
5983
6084 use super :: * ;
6185
86+ // sanitize
6287 #[ test]
6388 fn test_bodyheader_sanitize_all ( ) {
6489 let body = BodyHeader {
@@ -83,8 +108,9 @@ mod tests {
83108 assert ! ( body. sanitize( ) . is_none( ) ) ;
84109 }
85110
111+ // content type
86112 #[ test]
87- fn test_bodyheader_contenttype ( ) {
113+ fn test_bodyheader_content_type ( ) {
88114 let body = BodyHeader {
89115 content_type : Some ( ContentType :: Application ) ,
90116 ..Default :: default ( )
@@ -93,8 +119,140 @@ mod tests {
93119 }
94120
95121 #[ test]
96- fn test_bodyheader_contenttype_default ( ) {
122+ fn test_bodyheader_content_type_default ( ) {
97123 let body = BodyHeader :: default ( ) ;
98124 assert_eq ! ( body. content_type( ) , ContentType :: Unknown ) ;
99125 }
126+
127+ // chunked te position
128+ #[ test]
129+ fn test_bodyheader_chunked_te_position_none ( ) {
130+ let body = BodyHeader :: default ( ) ;
131+ assert_eq ! ( body. chunked_te_position( ) , None ) ;
132+ }
133+
134+ #[ test]
135+ fn test_bodyheader_chunked_te_position_single ( ) {
136+ let body = BodyHeader {
137+ transfer_encoding : Some ( vec ! [ EncodingInfo :: new(
138+ 0 ,
139+ vec![ ContentEncoding :: Chunked ] ,
140+ ) ] ) ,
141+ ..Default :: default ( )
142+ } ;
143+ assert_eq ! ( body. chunked_te_position( ) , Some ( ( 0 , 0 ) ) ) ;
144+ }
145+
146+ #[ test]
147+ fn test_bodyheader_chunked_te_position_multi ( ) {
148+ let body = BodyHeader {
149+ transfer_encoding : Some ( vec ! [
150+ EncodingInfo :: new( 0 , vec![ ContentEncoding :: Brotli ] ) ,
151+ EncodingInfo :: new( 1 , vec![ ContentEncoding :: Identity ] ) ,
152+ EncodingInfo :: new( 1 , vec![ ContentEncoding :: Gzip ] ) ,
153+ EncodingInfo :: new( 1 , vec![ ContentEncoding :: Chunked ] ) ,
154+ ] ) ,
155+ ..Default :: default ( )
156+ } ;
157+ assert_eq ! ( body. chunked_te_position( ) , Some ( ( 3 , 0 ) ) ) ;
158+ }
159+
160+ // is_chunked_te_only
161+ #[ test]
162+ fn test_bodyheader_is_chunked_te_only_true ( ) {
163+ let body = BodyHeader {
164+ transfer_encoding : Some ( vec ! [ EncodingInfo :: new(
165+ 0 ,
166+ vec![ ContentEncoding :: Chunked ] ,
167+ ) ] ) ,
168+ ..Default :: default ( )
169+ } ;
170+ assert ! ( body. is_chunked_te_only( ) ) ;
171+ }
172+
173+ #[ test]
174+ fn test_bodyheader_is_chunked_te_only_none_false ( ) {
175+ let body = BodyHeader :: default ( ) ;
176+ assert ! ( !body. is_chunked_te_only( ) ) ;
177+ }
178+
179+ #[ test]
180+ fn test_bodyheader_is_chunked_te_only_multi_false ( ) {
181+ let body = BodyHeader {
182+ transfer_encoding : Some ( vec ! [
183+ EncodingInfo :: new( 0 , vec![ ContentEncoding :: Brotli ] ) ,
184+ EncodingInfo :: new( 1 , vec![ ContentEncoding :: Identity ] ) ,
185+ EncodingInfo :: new( 1 , vec![ ContentEncoding :: Gzip ] ) ,
186+ EncodingInfo :: new( 1 , vec![ ContentEncoding :: Chunked ] ) ,
187+ ] ) ,
188+ ..Default :: default ( )
189+ } ;
190+ assert ! ( !body. is_chunked_te_only( ) ) ;
191+ }
192+
193+ // is_identity_te_only
194+ #[ test]
195+ fn test_bodyheader_is_identity_te_only_true ( ) {
196+ let body = BodyHeader {
197+ transfer_encoding : Some ( vec ! [ EncodingInfo :: new(
198+ 0 ,
199+ vec![ ContentEncoding :: Identity ] ,
200+ ) ] ) ,
201+ ..Default :: default ( )
202+ } ;
203+ assert ! ( body. is_identity_te_only( ) ) ;
204+ }
205+
206+ #[ test]
207+ fn test_bodyheader_is_identity_te_only_none_false ( ) {
208+ let body = BodyHeader :: default ( ) ;
209+ assert ! ( !body. is_identity_te_only( ) ) ;
210+ }
211+
212+ #[ test]
213+ fn test_bodyheader_is_identity_te_only_multi_false ( ) {
214+ let body = BodyHeader {
215+ transfer_encoding : Some ( vec ! [
216+ EncodingInfo :: new( 0 , vec![ ContentEncoding :: Brotli ] ) ,
217+ EncodingInfo :: new( 1 , vec![ ContentEncoding :: Identity ] ) ,
218+ EncodingInfo :: new( 1 , vec![ ContentEncoding :: Gzip ] ) ,
219+ EncodingInfo :: new( 1 , vec![ ContentEncoding :: Chunked ] ) ,
220+ ] ) ,
221+ ..Default :: default ( )
222+ } ;
223+ assert ! ( !body. is_identity_te_only( ) ) ;
224+ }
225+
226+ // is_identity_ce_only
227+ #[ test]
228+ fn test_bodyheader_is_identity_ce_only_true ( ) {
229+ let body = BodyHeader {
230+ content_encoding : Some ( vec ! [ EncodingInfo :: new(
231+ 0 ,
232+ vec![ ContentEncoding :: Identity ] ,
233+ ) ] ) ,
234+ ..Default :: default ( )
235+ } ;
236+ assert ! ( body. is_identity_ce_only( ) ) ;
237+ }
238+
239+ #[ test]
240+ fn test_bodyheader_is_identity_ce_only_none_false ( ) {
241+ let body = BodyHeader :: default ( ) ;
242+ assert ! ( !body. is_identity_ce_only( ) ) ;
243+ }
244+
245+ #[ test]
246+ fn test_bodyheader_is_identity_ce_only_multi_false ( ) {
247+ let body = BodyHeader {
248+ content_encoding : Some ( vec ! [
249+ EncodingInfo :: new( 0 , vec![ ContentEncoding :: Brotli ] ) ,
250+ EncodingInfo :: new( 1 , vec![ ContentEncoding :: Identity ] ) ,
251+ EncodingInfo :: new( 1 , vec![ ContentEncoding :: Gzip ] ) ,
252+ EncodingInfo :: new( 1 , vec![ ContentEncoding :: Chunked ] ) ,
253+ ] ) ,
254+ ..Default :: default ( )
255+ } ;
256+ assert ! ( !body. is_identity_ce_only( ) ) ;
257+ }
100258}
0 commit comments