]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Check for Content-Length and Transfer-Encoding
authorszweep <szweep@gmail.com>
Fri, 23 Oct 2015 14:24:35 +0000 (10:24 -0400)
committerszweep <szweep@gmail.com>
Fri, 23 Oct 2015 14:24:35 +0000 (10:24 -0400)
If an HTTP response contains both Content-Length and
Transfer-Encoding headers, flag this as an error as
per RFC 7230, Section 3.3.3#3. Also added a unit test
to validate the code.

tornado/http1connection.py
tornado/test/simple_httpclient_test.py

index c9eb2ad4cb7cd68e5ae327dd93fe300dfe0d3e84..1c577063b0036b2010439a110c922d197bd04344 100644 (file)
@@ -515,6 +515,12 @@ class HTTP1Connection(httputil.HTTPConnection):
 
     def _read_body(self, code, headers, delegate):
         if "Content-Length" in headers:
+            if "Transfer-Encoding" in headers:
+                # Response cannot contain both Content-Length and
+                # Transfer-Encoding headers.
+                # http://tools.ietf.org/html/rfc7230#section-3.3.3
+                raise httputil.HTTPInputError(
+                    "Response with both Transfer-Encoding and Content-Length")
             if "," in headers["Content-Length"]:
                 # Proxies sometimes cause Content-Length headers to get
                 # duplicated.  If all the values are identical then we can
index b6687a2982d8fab158021b6ba7334655a28b30ab..90394ec2f12cf9eeaa291031a88433f15e418967 100644 (file)
@@ -735,3 +735,22 @@ class MaxBufferSizeTest(AsyncHTTPTestCase):
         response = self.fetch('/large')
         response.rethrow()
         self.assertEqual(response.body, b'a' * 1024 * 100)
+
+
+class ChunkedWithContentLengthTest(AsyncHTTPTestCase):
+    def get_app(self):
+
+        class ChunkedWithContentLength(RequestHandler):
+            def get(self):
+                # Add an invalid Transfer-Encoding to the response
+                self.set_header('Transfer-Encoding', 'chunked')
+                self.write("Hello world")
+
+        return Application([('/chunkwithcl', ChunkedWithContentLength)])
+
+    def test_chunked_with_content_length(self):
+        # Make sure the invalid headers are detected
+        with ExpectLog(gen_log, ("Malformed HTTP message from None: Response "
+                       "with both Transfer-Encoding and Content-Length")):
+            response = self.fetch('/chunkwithcl')
+        self.assertEqual(response.code, 599)