From: Pierce Lopez Date: Tue, 26 Dec 2017 03:11:26 +0000 (-0500) Subject: http: read final crlf of chunked requests X-Git-Tag: v5.0.0~26^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F2225%2Fhead;p=thirdparty%2Ftornado.git http: read final crlf of chunked requests otherwise a subsequent request on the same connection will fail to be parsed thanks to @eeelin for the bug report --- diff --git a/tornado/http1connection.py b/tornado/http1connection.py index de8d8bf38..331386a15 100644 --- a/tornado/http1connection.py +++ b/tornado/http1connection.py @@ -599,6 +599,9 @@ class HTTP1Connection(httputil.HTTPConnection): chunk_len = yield self.stream.read_until(b"\r\n", max_bytes=64) chunk_len = int(chunk_len.strip(), 16) if chunk_len == 0: + crlf = yield self.stream.read_bytes(2) + if crlf != b'\r\n': + raise HTTPInputError("improperly terminated chunked request") return total_size += chunk_len if total_size > self._max_body_size: diff --git a/tornado/test/httpserver_test.py b/tornado/test/httpserver_test.py index 1b1286022..3b0524940 100644 --- a/tornado/test/httpserver_test.py +++ b/tornado/test/httpserver_test.py @@ -808,9 +808,12 @@ class KeepAliveTest(AsyncHTTPTestCase): def test_keepalive_chunked(self): self.http_version = b'HTTP/1.0' self.connect() - self.stream.write(b'POST / HTTP/1.0\r\nConnection: keep-alive\r\n' + self.stream.write(b'POST / HTTP/1.0\r\n' + b'Connection: keep-alive\r\n' b'Transfer-Encoding: chunked\r\n' - b'\r\n0\r\n') + b'\r\n' + b'0\r\n' + b'\r\n') self.read_response() self.assertEqual(self.headers['Connection'], 'Keep-Alive') self.stream.write(b'GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n') diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py index 7e3ac7c25..46390e0d1 100644 --- a/tornado/test/web_test.py +++ b/tornado/test/web_test.py @@ -2138,7 +2138,7 @@ class StreamingRequestBodyTest(WebTestCase): stream.write(b"4\r\nqwer\r\n") data = yield self.data self.assertEquals(data, b"qwer") - stream.write(b"0\r\n") + stream.write(b"0\r\n\r\n") yield self.finished data = yield gen.Task(stream.read_until_close) # This would ideally use an HTTP1Connection to read the response.