From: Ben Darnell Date: Sun, 11 Jan 2015 18:29:57 +0000 (-0500) Subject: Fix regression in support for both CRLF and bare LF in headers. X-Git-Tag: v4.1.0b1~38 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a0569678bbaff68e0df64a539059eb175f7de6cc;p=thirdparty%2Ftornado.git Fix regression in support for both CRLF and bare LF in headers. Closes #1297. --- diff --git a/tornado/http1connection.py b/tornado/http1connection.py index 90895cc94..1ff9b8335 100644 --- a/tornado/http1connection.py +++ b/tornado/http1connection.py @@ -491,8 +491,9 @@ class HTTP1Connection(httputil.HTTPConnection): # we SHOULD ignore at least one empty line before the request. # http://tools.ietf.org/html/rfc7230#section-3.5 data = native_str(data.decode('latin1')).lstrip("\r\n") - eol = data.find("\r\n") - start_line = data[:eol] + # RFC 7230 section allows for both CRLF and bare LF. + eol = data.find("\n") + start_line = data[:eol].rstrip("\r") try: headers = httputil.HTTPHeaders.parse(data[eol:]) except ValueError: diff --git a/tornado/test/httpserver_test.py b/tornado/test/httpserver_test.py index 156a027bb..49a099659 100644 --- a/tornado/test/httpserver_test.py +++ b/tornado/test/httpserver_test.py @@ -195,14 +195,14 @@ class HTTPConnectionTest(AsyncHTTPTestCase): def get_app(self): return Application(self.get_handlers()) - def raw_fetch(self, headers, body): + def raw_fetch(self, headers, body, newline=b"\r\n"): with closing(IOStream(socket.socket())) as stream: stream.connect(('127.0.0.1', self.get_http_port()), self.stop) self.wait() stream.write( - b"\r\n".join(headers + - [utf8("Content-Length: %d\r\n" % len(body))]) + - b"\r\n" + body) + newline.join(headers + + [utf8("Content-Length: %d" % len(body))]) + + newline + newline + body) read_stream_body(stream, self.stop) headers, body = self.wait() return body @@ -232,6 +232,13 @@ class HTTPConnectionTest(AsyncHTTPTestCase): self.assertEqual(u("\u00f3"), data["filename"]) self.assertEqual(u("\u00fa"), data["filebody"]) + def test_newlines(self): + # We support both CRLF and bare LF as line separators. + for newline in (b"\r\n", b"\n"): + response = self.raw_fetch([b"GET /hello HTTP/1.0"], b"", + newline=newline) + self.assertEqual(response, b'Hello world') + def test_100_continue(self): # Run through a 100-continue interaction by hand: # When given Expect: 100-continue, we get a 100 response after the