From: Ben Darnell Date: Mon, 29 Nov 2010 22:08:01 +0000 (-0800) Subject: Log malformed HTTP requests more gracefully. X-Git-Tag: v1.2.0~63 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6151498dba7d55d602cbf0360df8f29b712c33a1;p=thirdparty%2Ftornado.git Log malformed HTTP requests more gracefully. Malformed requests are now logged as a single INFO line (which includes the IP address) instead of a verbose but uninformative stack trace. --- diff --git a/tornado/httpserver.py b/tornado/httpserver.py index a0f2e5071..2018d279f 100644 --- a/tornado/httpserver.py +++ b/tornado/httpserver.py @@ -267,6 +267,9 @@ class HTTPServer(object): except: logging.error("Error in connection callback", exc_info=True) +class _BadRequestException(Exception): + """Exception class for malformed HTTP requests.""" + pass class HTTPConnection(object): """Handles a connection to an HTTP client, executing HTTP requests. @@ -323,28 +326,37 @@ class HTTPConnection(object): self.stream.read_until("\r\n\r\n", self._header_callback) def _on_headers(self, data): - eol = data.find("\r\n") - start_line = data[:eol] - method, uri, version = start_line.split(" ") - if not version.startswith("HTTP/"): - raise Exception("Malformed HTTP version in HTTP Request-Line") - headers = httputil.HTTPHeaders.parse(data[eol:]) - self._request = HTTPRequest( - connection=self, method=method, uri=uri, version=version, - headers=headers, remote_ip=self.address[0]) - - content_length = headers.get("Content-Length") - if content_length: - content_length = int(content_length) - if content_length > self.stream.max_buffer_size: - raise Exception("Content-Length too long") - if headers.get("Expect") == "100-continue": - self.stream.write("HTTP/1.1 100 (Continue)\r\n\r\n") - self.stream.read_bytes(content_length, self._on_request_body) + try: + eol = data.find("\r\n") + start_line = data[:eol] + try: + method, uri, version = start_line.split(" ") + except ValueError: + 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:]) + self._request = HTTPRequest( + connection=self, method=method, uri=uri, version=version, + headers=headers, remote_ip=self.address[0]) + + content_length = headers.get("Content-Length") + if content_length: + content_length = int(content_length) + if content_length > self.stream.max_buffer_size: + raise _BadRequestException("Content-Length too long") + if headers.get("Expect") == "100-continue": + self.stream.write("HTTP/1.1 100 (Continue)\r\n\r\n") + self.stream.read_bytes(content_length, self._on_request_body) + return + + self.request_callback(self._request) + except _BadRequestException, e: + logging.info("Malformed HTTP request from %s: %s", + self.address[0], e) + self.stream.close() return - self.request_callback(self._request) - def _on_request_body(self, data): self._request.body = data content_type = self._request.headers.get("Content-Type", "")