Permalink
Browse files

Handle malformed headers more gracefully.

Closes #699.
  • Loading branch information...
1 parent 75a2946 commit 8ca13ef006b9d223d9e63d416318a2d11fe17754 @bdarnell bdarnell committed Apr 14, 2013
Showing with 39 additions and 5 deletions.
  1. +5 −1 tornado/httpserver.py
  2. +34 −4 tornado/test/httpserver_test.py
View
@@ -294,7 +294,11 @@ def _on_headers(self, data):
raise _BadRequestException("Malformed HTTP request line")
if not version.startswith("HTTP/"):
raise _BadRequestException("Malformed HTTP version in HTTP Request-Line")
- headers = httputil.HTTPHeaders.parse(data[eol:])
+ try:
+ headers = httputil.HTTPHeaders.parse(data[eol:])
+ except ValueError:
+ # Probably from split() if there was no ':' in the line
+ raise _BadRequestException("Malformed HTTP headers")
# HTTPRequest wants an IP, not a full socket address
if self.address_family in (socket.AF_INET, socket.AF_INET6):
@@ -341,14 +341,44 @@ def test_double_slash(self):
self.assertEqual(200, response.code)
self.assertEqual(json_decode(response.body), {})
- def test_empty_request(self):
- stream = IOStream(socket.socket(), io_loop=self.io_loop)
- stream.connect(('localhost', self.get_http_port()), self.stop)
+
+class HTTPServerRawTest(AsyncHTTPTestCase):
+ def get_app(self):
+ return Application([
+ ('/echo', EchoHandler),
+ ])
+
+ def setUp(self):
+ super(HTTPServerRawTest, self).setUp()
+ self.stream = IOStream(socket.socket())
+ self.stream.connect(('localhost', self.get_http_port()), self.stop)
self.wait()
- stream.close()
+
+ def tearDown(self):
+ self.stream.close()
+ super(HTTPServerRawTest, self).tearDown()
+
+ def test_empty_request(self):
+ self.stream.close()
self.io_loop.add_timeout(datetime.timedelta(seconds=0.001), self.stop)
self.wait()
+ def test_malformed_first_line(self):
+ with ExpectLog(gen_log, '.*Malformed HTTP request line'):
+ self.stream.write(b'asdf\r\n\r\n')
+ # TODO: need an async version of ExpectLog so we don't need
+ # hard-coded timeouts here.
+ self.io_loop.add_timeout(datetime.timedelta(seconds=0.01),
+ self.stop)
+ self.wait()
+
+ def test_malformed_headers(self):
+ with ExpectLog(gen_log, '.*Malformed HTTP headers'):
+ self.stream.write(b'GET / HTTP/1.0\r\nasdf\r\n\r\n')
+ self.io_loop.add_timeout(datetime.timedelta(seconds=0.01),
+ self.stop)
+ self.wait()
+
class XHeaderTest(HandlerBaseTestCase):
class Handler(RequestHandler):

0 comments on commit 8ca13ef

Please sign in to comment.