diff options
-rw-r--r-- | Doc/library/http.server.rst | 3 | ||||
-rw-r--r-- | Lib/http/server.py | 4 | ||||
-rw-r--r-- | Lib/test/test_httpservers.py | 12 | ||||
-rw-r--r-- | Misc/NEWS | 3 |
4 files changed, 21 insertions, 1 deletions
diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst index cbad3ed..0577d5e 100644 --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -177,6 +177,9 @@ of which this module provides three different variants: complete set of headers is sent, followed by text composed using the :attr:`error_message_format` class variable. + .. versionchanged:: 3.4 + The error response includes a Content-Length header. + .. method:: send_response(code, message=None) Adds a response header to the headers buffer and logs the accepted diff --git a/Lib/http/server.py b/Lib/http/server.py index c4ac703..7167142 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -425,12 +425,14 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler): # using _quote_html to prevent Cross Site Scripting attacks (see bug #1100201) content = (self.error_message_format % {'code': code, 'message': _quote_html(message), 'explain': explain}) + body = content.encode('UTF-8', 'replace') self.send_response(code, message) self.send_header("Content-Type", self.error_content_type) self.send_header('Connection', 'close') + self.send_header('Content-Length', int(len(body))) self.end_headers() if self.command != 'HEAD' and code >= 200 and code not in (204, 304): - self.wfile.write(content.encode('UTF-8', 'replace')) + self.wfile.write(body) def send_response(self, code, message=None): """Add the response header to the headers buffer and log the diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index 75133c9..64640f5 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -92,6 +92,9 @@ class BaseHTTPServerTestCase(BaseTestCase): def do_KEYERROR(self): self.send_error(999) + def do_NOTFOUND(self): + self.send_error(404) + def do_CUSTOM(self): self.send_response(999) self.send_header('Content-Type', 'text/html') @@ -211,6 +214,15 @@ class BaseHTTPServerTestCase(BaseTestCase): self.assertEqual(res.getheader('X-Special'), 'Dängerous Mind') self.assertEqual(res.read(), 'Ärger mit Unicode'.encode('utf-8')) + def test_error_content_length(self): + # Issue #16088: standard error responses should have a content-length + self.con.request('NOTFOUND', '/') + res = self.con.getresponse() + self.assertEqual(res.status, 404) + data = res.read() + import pdb; pdb.set_trace() + self.assertEqual(int(res.getheader('Content-Length')), len(data)) + class SimpleHTTPServerTestCase(BaseTestCase): class request_handler(NoLogRequestHandler, SimpleHTTPRequestHandler): @@ -45,6 +45,9 @@ Core and Builtins Library ------- +- Issue #16088: BaseHTTPRequestHandler's send_error method includes a + Content-Length header in it's response now. Patch by Antoine Pitrou. + - Issue #16114: The subprocess module no longer provides a misleading error message stating that args[0] did not exist when either the cwd or executable keyword arguments specified a path that did not exist. |