diff -r 1d72402c1c91 Lib/http/server.py --- a/Lib/http/server.py Tue Mar 15 13:33:28 2016 +1300 +++ b/Lib/http/server.py Fri Mar 18 12:05:16 2016 +0800 @@ -137,7 +137,7 @@ def server_bind(self): """Override server_bind to store the server name.""" socketserver.TCPServer.server_bind(self) - host, port = self.socket.getsockname()[:2] + host, port = self.server_address[:2] self.server_name = socket.getfqdn(host) self.server_port = port @@ -283,12 +283,9 @@ words = requestline.split() if len(words) == 3: command, path, version = words - if version[:5] != 'HTTP/': - self.send_error( - HTTPStatus.BAD_REQUEST, - "Bad request version (%r)" % version) - return False try: + if version[:5] != 'HTTP/': + raise ValueError base_version_number = version.split('/', 1)[1] version_number = base_version_number.split(".") # RFC 2145 section 3.1 says there can be only one "." and @@ -310,7 +307,7 @@ if version_number >= (2, 0): self.send_error( HTTPStatus.HTTP_VERSION_NOT_SUPPORTED, - "Invalid HTTP Version (%s)" % base_version_number) + "Invalid HTTP version (%s)" % base_version_number) return False elif len(words) == 2: command, path = words @@ -338,6 +335,12 @@ HTTPStatus.BAD_REQUEST, "Line too long") return False + except http.client.HTTPException: + self.send_error( + HTTPStatus.BAD_REQUEST, + "Too many headers" + ) + return False conntype = self.headers.get('Connection', "") if conntype.lower() == 'close': @@ -475,17 +478,17 @@ def send_response_only(self, code, message=None): """Send the response header only.""" - if message is None: - if code in self.responses: - message = self.responses[code][0] - else: - message = '' if self.request_version != 'HTTP/0.9': + if message is None: + if code in self.responses: + message = self.responses[code][0] + else: + message = '' if not hasattr(self, '_headers_buffer'): self._headers_buffer = [] - self._headers_buffer.append(("%s %d %s\r\n" % - (self.protocol_version, code, message)).encode( - 'latin-1', 'strict')) + self._headers_buffer.append( + ("%s %d %s\r\n" % (self.protocol_version, code, message)) + .encode('latin-1', 'strict')) def send_header(self, keyword, value): """Send a MIME header to the headers buffer.""" diff -r 1d72402c1c91 Lib/test/test_httpservers.py --- a/Lib/test/test_httpservers.py Tue Mar 15 13:33:28 2016 +1300 +++ b/Lib/test/test_httpservers.py Fri Mar 18 12:05:16 2016 +0800 @@ -859,6 +859,14 @@ self.assertFalse(self.handler.get_called) self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1') + def test_too_many_headers(self): + headers = ['header%d: test\r\n' for i in range(101)] + result = self.send_typical_request( + b'GET / HTTP/1.1\r\n' + ''.join(headers).encode('utf-8') + b'\r\n') + self.assertEqual(result[0], b'HTTP/1.1 400 Too many headers\r\n') + self.assertFalse(self.handler.get_called) + self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1') + def test_close_connection(self): # handle_one_request() should be repeatedly called until # it sets close_connection