[Python-checkins] cpython (2.7): Issue #25738: Don’t send message body for 205 Reset Content
martin.panter
python-checkins at python.org
Wed Jun 8 05:50:49 EDT 2016
https://hg.python.org/cpython/rev/b1041ddb1391
changeset: 101787:b1041ddb1391
branch: 2.7
parent: 101784:b86e259271b3
user: Martin Panter <vadmium+py at gmail.com>
date: Wed Jun 08 07:16:14 2016 +0000
summary:
Issue #25738: Don’t send message body for 205 Reset Content
Patch by Susumu Koshiba.
files:
Doc/library/basehttpserver.rst | 5 ++-
Lib/BaseHTTPServer.py | 21 +++++++++--
Lib/test/test_httpservers.py | 38 ++++++++++++++++++++++
Misc/ACKS | 1 +
Misc/NEWS | 5 ++
5 files changed, 64 insertions(+), 6 deletions(-)
diff --git a/Doc/library/basehttpserver.rst b/Doc/library/basehttpserver.rst
--- a/Doc/library/basehttpserver.rst
+++ b/Doc/library/basehttpserver.rst
@@ -197,7 +197,10 @@
Sends and logs a complete error reply to the client. The numeric *code*
specifies the HTTP error code, with *message* as optional, more specific text. A
complete set of headers is sent, followed by text composed using the
- :attr:`error_message_format` class variable.
+ :attr:`error_message_format` class variable. The body will be empty
+ if the method is HEAD or the response code is one of the following:
+ ``1xx``, ``204 No Content``, ``205 Reset Content``,
+ ``304 Not Modified``.
.. method:: send_response(code[, message])
diff --git a/Lib/BaseHTTPServer.py b/Lib/BaseHTTPServer.py
--- a/Lib/BaseHTTPServer.py
+++ b/Lib/BaseHTTPServer.py
@@ -362,14 +362,25 @@
message = short
explain = long
self.log_error("code %d, message %s", code, message)
- # 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})
self.send_response(code, message)
- self.send_header("Content-Type", self.error_content_type)
self.send_header('Connection', 'close')
+
+ # Message body is omitted for cases described in:
+ # - RFC7230: 3.3. 1xx, 204(No Content), 304(Not Modified)
+ # - RFC7231: 6.3.6. 205(Reset Content)
+ content = None
+ if code >= 200 and code not in (204, 205, 304):
+ # HTML encode to prevent Cross Site Scripting attacks
+ # (see bug #1100201)
+ content = (self.error_message_format % {
+ 'code': code,
+ 'message': _quote_html(message),
+ 'explain': explain
+ })
+ self.send_header("Content-Type", self.error_content_type)
self.end_headers()
- if self.command != 'HEAD' and code >= 200 and code not in (204, 304):
+
+ if self.command != 'HEAD' and content:
self.wfile.write(content)
error_message_format = DEFAULT_ERROR_MESSAGE
diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py
--- a/Lib/test/test_httpservers.py
+++ b/Lib/test/test_httpservers.py
@@ -178,6 +178,12 @@
self.send_header('Connection', 'close')
self.end_headers()
+ def do_SEND_ERROR(self):
+ self.send_error(int(self.path[1:]))
+
+ def do_HEAD(self):
+ self.send_error(int(self.path[1:]))
+
def setUp(self):
BaseTestCase.setUp(self)
self.con = httplib.HTTPConnection('localhost', self.PORT)
@@ -276,6 +282,38 @@
res = self.con.getresponse()
self.assertEqual(res.status, 999)
+ def test_send_error(self):
+ allow_transfer_encoding_codes = (205, 304)
+ for code in (101, 102, 204, 205, 304):
+ self.con.request('SEND_ERROR', '/{}'.format(code))
+ res = self.con.getresponse()
+ self.assertEqual(code, res.status)
+ self.assertEqual(None, res.getheader('Content-Length'))
+ self.assertEqual(None, res.getheader('Content-Type'))
+ if code not in allow_transfer_encoding_codes:
+ self.assertEqual(None, res.getheader('Transfer-Encoding'))
+
+ data = res.read()
+ self.assertEqual(b'', data)
+
+ def test_head_via_send_error(self):
+ allow_transfer_encoding_codes = (205, 304)
+ for code in (101, 200, 204, 205, 304):
+ self.con.request('HEAD', '/{}'.format(code))
+ res = self.con.getresponse()
+ self.assertEqual(code, res.status)
+ if code == 200:
+ self.assertEqual(None, res.getheader('Content-Length'))
+ self.assertIn('text/html', res.getheader('Content-Type'))
+ else:
+ self.assertEqual(None, res.getheader('Content-Length'))
+ self.assertEqual(None, res.getheader('Content-Type'))
+ if code not in allow_transfer_encoding_codes:
+ self.assertEqual(None, res.getheader('Transfer-Encoding'))
+
+ data = res.read()
+ self.assertEqual(b'', data)
+
class SimpleHTTPServerTestCase(BaseTestCase):
class request_handler(NoLogRequestHandler, SimpleHTTPRequestHandler):
diff --git a/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -741,6 +741,7 @@
Марк Коренберг
Vlad Korolev
Anna Koroliuk
+Susumu Koshiba
Joseph Koshy
Daniel Kozan
Jerzy Kozera
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -92,6 +92,11 @@
Library
-------
+- Issue #25738: Stop BaseHTTPServer.BaseHTTPRequestHandler.send_error() from
+ sending a message body for 205 Reset Content. Also, don't send the
+ Content-Type header field in responses that don't have a body. Based on
+ patch by Susumu Koshiba.
+
- Issue #21313: Fix the "platform" module to tolerate when sys.version
contains truncated build information.
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list