@@ -322,7 +322,7 @@ def test_chunking_request_without_content(self):
322322 self .assertFalse ("transfer-encoding" in headers )
323323
324324 def test_chunking_request_with_content (self ):
325- control_line = b"20; \r \n " # 20 hex = 32 dec
325+ control_line = b"20\r \n " # 20 hex = 32 dec
326326 s = b"This string has 32 characters.\r \n "
327327 expected = s * 12
328328 header = b"GET / HTTP/1.1\r \n Transfer-Encoding: chunked\r \n \r \n "
@@ -341,7 +341,7 @@ def test_chunking_request_with_content(self):
341341 self .assertFalse ("transfer-encoding" in headers )
342342
343343 def test_broken_chunked_encoding (self ):
344- control_line = b"20; \r \n " # 20 hex = 32 dec
344+ control_line = b"20\r \n " # 20 hex = 32 dec
345345 s = b"This string has 32 characters.\r \n "
346346 to_send = b"GET / HTTP/1.1\r \n Transfer-Encoding: chunked\r \n \r \n "
347347 to_send += control_line + s + b"\r \n "
@@ -364,8 +364,52 @@ def test_broken_chunked_encoding(self):
364364 self .send_check_error (to_send )
365365 self .assertRaises (ConnectionClosed , read_http , fp )
366366
367+ def test_broken_chunked_encoding_invalid_hex (self ):
368+ control_line = b"0x20\r \n " # 20 hex = 32 dec
369+ s = b"This string has 32 characters.\r \n "
370+ to_send = b"GET / HTTP/1.1\r \n Transfer-Encoding: chunked\r \n \r \n "
371+ to_send += control_line + s + b"\r \n "
372+ self .connect ()
373+ self .sock .send (to_send )
374+ with self .sock .makefile ("rb" , 0 ) as fp :
375+ line , headers , response_body = read_http (fp )
376+ self .assertline (line , "400" , "Bad Request" , "HTTP/1.1" )
377+ cl = int (headers ["content-length" ])
378+ self .assertEqual (cl , len (response_body ))
379+ self .assertIn (b"Invalid chunk size" , response_body )
380+ self .assertEqual (
381+ sorted (headers .keys ()),
382+ ["connection" , "content-length" , "content-type" , "date" , "server" ],
383+ )
384+ self .assertEqual (headers ["content-type" ], "text/plain" )
385+ # connection has been closed
386+ self .send_check_error (to_send )
387+ self .assertRaises (ConnectionClosed , read_http , fp )
388+
389+ def test_broken_chunked_encoding_invalid_extension (self ):
390+ control_line = b"20;invalid=\r \n " # 20 hex = 32 dec
391+ s = b"This string has 32 characters.\r \n "
392+ to_send = b"GET / HTTP/1.1\r \n Transfer-Encoding: chunked\r \n \r \n "
393+ to_send += control_line + s + b"\r \n "
394+ self .connect ()
395+ self .sock .send (to_send )
396+ with self .sock .makefile ("rb" , 0 ) as fp :
397+ line , headers , response_body = read_http (fp )
398+ self .assertline (line , "400" , "Bad Request" , "HTTP/1.1" )
399+ cl = int (headers ["content-length" ])
400+ self .assertEqual (cl , len (response_body ))
401+ self .assertIn (b"Invalid chunk extension" , response_body )
402+ self .assertEqual (
403+ sorted (headers .keys ()),
404+ ["connection" , "content-length" , "content-type" , "date" , "server" ],
405+ )
406+ self .assertEqual (headers ["content-type" ], "text/plain" )
407+ # connection has been closed
408+ self .send_check_error (to_send )
409+ self .assertRaises (ConnectionClosed , read_http , fp )
410+
367411 def test_broken_chunked_encoding_missing_chunk_end (self ):
368- control_line = b"20; \r \n " # 20 hex = 32 dec
412+ control_line = b"20\r \n " # 20 hex = 32 dec
369413 s = b"This string has 32 characters.\r \n "
370414 to_send = b"GET / HTTP/1.1\r \n Transfer-Encoding: chunked\r \n \r \n "
371415 to_send += control_line + s
0 commit comments