@@ -222,12 +222,23 @@ fn request_body_len(request: &Request) -> Result<usize, ParseError> {
222222 // the Transfer-Encoding overrides the Content-Length
223223 if request
224224 . headers_with_name ( "Transfer-Encoding" )
225- . next ( )
226- . is_some ( )
225+ . any ( |h| {
226+ std:: str:: from_utf8 ( h. value . 0 . as_bytes ( ) )
227+ . unwrap_or ( "" )
228+ . split ( ',' )
229+ . any ( |v| v. trim ( ) != "identity" )
230+ } )
227231 {
228- Err ( ParseError (
229- "Transfer-Encoding not supported yet" . to_string ( ) ,
230- ) )
232+ let bad_values = request
233+ . headers_with_name ( "Transfer-Encoding" )
234+ . map ( |h| std:: str:: from_utf8 ( h. value . 0 . as_bytes ( ) ) . unwrap_or ( "" ) )
235+ . collect :: < Vec < _ > > ( )
236+ . join ( ", " ) ;
237+
238+ Err ( ParseError ( format ! (
239+ "Transfer-Encoding other than identity not supported yet: {:?}" ,
240+ bad_values
241+ ) ) )
231242 } else if let Some ( h) = request. headers_with_name ( "Content-Length" ) . next ( ) {
232243 // If a valid Content-Length header field is present without Transfer-Encoding, its decimal value
233244 // defines the expected message body length in octets.
@@ -258,12 +269,23 @@ fn response_body_len(response: &Response) -> Result<usize, ParseError> {
258269
259270 if response
260271 . headers_with_name ( "Transfer-Encoding" )
261- . next ( )
262- . is_some ( )
272+ . any ( |h| {
273+ std:: str:: from_utf8 ( h. value . 0 . as_bytes ( ) )
274+ . unwrap_or ( "" )
275+ . split ( ',' )
276+ . any ( |v| v. trim ( ) != "identity" )
277+ } )
263278 {
264- Err ( ParseError (
265- "Transfer-Encoding not supported yet" . to_string ( ) ,
266- ) )
279+ let bad_values = response
280+ . headers_with_name ( "Transfer-Encoding" )
281+ . map ( |h| std:: str:: from_utf8 ( h. value . 0 . as_bytes ( ) ) . unwrap_or ( "" ) )
282+ . collect :: < Vec < _ > > ( )
283+ . join ( ", " ) ;
284+
285+ Err ( ParseError ( format ! (
286+ "Transfer-Encoding other than identity not supported yet: {:?}" ,
287+ bad_values
288+ ) ) )
267289 } else if let Some ( h) = response. headers_with_name ( "Content-Length" ) . next ( ) {
268290 // If a valid Content-Length header field is present without Transfer-Encoding, its decimal value
269291 // defines the expected message body length in octets.
@@ -363,6 +385,46 @@ mod tests {
363385 Content-Length: 14\r \n \r \n \
364386 {\" foo\" : \" bar\" }";
365387
388+ const TEST_REQUEST_TRANSFER_ENCODING_IDENTITY : & [ u8 ] = b"\
389+ POST / HTTP/1.1\r \n \
390+ Transfer-Encoding: identity\r \n \
391+ Content-Length: 12\r \n \r \n \
392+ Hello World!";
393+
394+ const TEST_RESPONSE_TRANSFER_ENCODING_IDENTITY : & [ u8 ] = b"\
395+ HTTP/1.1 200 OK\r \n \
396+ Transfer-Encoding: identity\r \n \
397+ Content-Length: 12\r \n \r \n \
398+ Hello World!";
399+
400+ const TEST_REQUEST_TRANSFER_ENCODING_CHUNKED : & [ u8 ] = b"\
401+ POST / HTTP/1.1\r \n \
402+ Transfer-Encoding: chunked\r \n \r \n \
403+ a\r \n \
404+ Hello World!\r \n \
405+ 0\r \n \r \n ";
406+
407+ const TEST_RESPONSE_TRANSFER_ENCODING_CHUNKED : & [ u8 ] = b"\
408+ HTTP/1.1 200 OK\r \n \
409+ Transfer-Encoding: chunked\r \n \r \n \
410+ a\r \n \
411+ Hello World!\r \n \
412+ 0\r \n \r \n ";
413+
414+ const TEST_REQUEST_TRANSFER_ENCODING_MULTIPLE : & [ u8 ] = b"\
415+ POST / HTTP/1.1\r \n \
416+ Transfer-Encoding: chunked, identity\r \n \r \n \
417+ a\r \n \
418+ Hello World!\r \n \
419+ 0\r \n \r \n ";
420+
421+ const TEST_RESPONSE_TRANSFER_ENCODING_MULTIPLE : & [ u8 ] = b"\
422+ HTTP/1.1 200 OK\r \n \
423+ Transfer-Encoding: chunked, identity\r \n \r \n \
424+ a\r \n \
425+ Hello World!\r \n \
426+ 0\r \n \r \n ";
427+
366428 #[ test]
367429 fn test_parse_request ( ) {
368430 let req = parse_request ( TEST_REQUEST ) . unwrap ( ) ;
@@ -496,4 +558,44 @@ mod tests {
496558
497559 assert_eq ! ( value. span( ) , "{\" foo\" : \" bar\" }" ) ;
498560 }
561+
562+ #[ test]
563+ fn test_parse_request_transfer_encoding_identity ( ) {
564+ let req = parse_request ( TEST_REQUEST_TRANSFER_ENCODING_IDENTITY ) . unwrap ( ) ;
565+ assert_eq ! ( req. body. unwrap( ) . span( ) , b"Hello World!" . as_slice( ) ) ;
566+ }
567+
568+ #[ test]
569+ fn test_parse_response_transfer_encoding_identity ( ) {
570+ let res = parse_response ( TEST_RESPONSE_TRANSFER_ENCODING_IDENTITY ) . unwrap ( ) ;
571+ assert_eq ! ( res. body. unwrap( ) . span( ) , b"Hello World!" . as_slice( ) ) ;
572+ }
573+
574+ #[ test]
575+ fn test_parse_request_transfer_encoding_chunked ( ) {
576+ let err = parse_request ( TEST_REQUEST_TRANSFER_ENCODING_CHUNKED ) . unwrap_err ( ) ;
577+ assert ! ( matches!( err, ParseError ( _) ) ) ;
578+ assert ! ( err. to_string( ) . contains( "Transfer-Encoding other than identity not supported yet" ) ) ;
579+ }
580+
581+ #[ test]
582+ fn test_parse_response_transfer_encoding_chunked ( ) {
583+ let err = parse_response ( TEST_RESPONSE_TRANSFER_ENCODING_CHUNKED ) . unwrap_err ( ) ;
584+ assert ! ( matches!( err, ParseError ( _) ) ) ;
585+ assert ! ( err. to_string( ) . contains( "Transfer-Encoding other than identity not supported yet" ) ) ;
586+ }
587+
588+ #[ test]
589+ fn test_parse_request_transfer_encoding_multiple ( ) {
590+ let err = parse_request ( TEST_REQUEST_TRANSFER_ENCODING_MULTIPLE ) . unwrap_err ( ) ;
591+ assert ! ( matches!( err, ParseError ( _) ) ) ;
592+ assert ! ( err. to_string( ) . contains( "Transfer-Encoding other than identity not supported yet" ) ) ;
593+ }
594+
595+ #[ test]
596+ fn test_parse_response_transfer_encoding_multiple ( ) {
597+ let err = parse_response ( TEST_RESPONSE_TRANSFER_ENCODING_MULTIPLE ) . unwrap_err ( ) ;
598+ assert ! ( matches!( err, ParseError ( _) ) ) ;
599+ assert ! ( err. to_string( ) . contains( "Transfer-Encoding other than identity not supported yet" ) ) ;
600+ }
499601}
0 commit comments