summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/http.server.rst3
-rw-r--r--Lib/http/server.py4
-rw-r--r--Lib/test/test_httpservers.py12
-rw-r--r--Misc/NEWS3
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):
diff --git a/Misc/NEWS b/Misc/NEWS
index 0215e2d..63c62b9 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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.