Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e42e129

Browse files
committed
Issue #25738: Don’t send message body for 205 Reset Content
Patch by Susumu Koshiba.
1 parent 4e50553 commit e42e129

5 files changed

Lines changed: 73 additions & 11 deletions

File tree

Doc/library/http.server.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,9 @@ of which this module provides three different variants:
191191
a complete set of headers, as the response body. The :attr:`responses`
192192
attribute holds the default values for *message* and *explain* that
193193
will be used if no value is provided; for unknown codes the default value
194-
for both is the string ``???``.
194+
for both is the string ``???``. The body will be empty if the method is
195+
HEAD or the response code is one of the following: ``1xx``,
196+
``204 No Content``, ``205 Reset Content``, ``304 Not Modified``.
195197

196198
.. versionchanged:: 3.4
197199
The error response includes a Content-Length header.

Lib/http/server.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -450,20 +450,30 @@ def send_error(self, code, message=None, explain=None):
450450
if explain is None:
451451
explain = longmsg
452452
self.log_error("code %d, message %s", code, message)
453-
# using _quote_html to prevent Cross Site Scripting attacks (see bug #1100201)
454-
content = (self.error_message_format %
455-
{'code': code, 'message': _quote_html(message), 'explain': _quote_html(explain)})
456-
body = content.encode('UTF-8', 'replace')
457453
self.send_response(code, message)
458-
self.send_header("Content-Type", self.error_content_type)
459454
self.send_header('Connection', 'close')
460-
self.send_header('Content-Length', int(len(body)))
455+
456+
# Message body is omitted for cases described in:
457+
# - RFC7230: 3.3. 1xx, 204(No Content), 304(Not Modified)
458+
# - RFC7231: 6.3.6. 205(Reset Content)
459+
body = None
460+
if (code >= 200 and
461+
code not in (HTTPStatus.NO_CONTENT,
462+
HTTPStatus.RESET_CONTENT,
463+
HTTPStatus.NOT_MODIFIED)):
464+
# HTML encode to prevent Cross Site Scripting attacks
465+
# (see bug #1100201)
466+
content = (self.error_message_format % {
467+
'code': code,
468+
'message': _quote_html(message),
469+
'explain': _quote_html(explain)
470+
})
471+
body = content.encode('UTF-8', 'replace')
472+
self.send_header("Content-Type", self.error_content_type)
473+
self.send_header('Content-Length', int(len(body)))
461474
self.end_headers()
462475

463-
if (self.command != 'HEAD' and
464-
code >= 200 and
465-
code not in (
466-
HTTPStatus.NO_CONTENT, HTTPStatus.NOT_MODIFIED)):
476+
if self.command != 'HEAD' and body:
467477
self.wfile.write(body)
468478

469479
def send_response(self, code, message=None):

Lib/test/test_httpservers.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ def do_LATINONEHEADER(self):
115115
body = self.headers['x-special-incoming'].encode('utf-8')
116116
self.wfile.write(body)
117117

118+
def do_SEND_ERROR(self):
119+
self.send_error(int(self.path[1:]))
120+
121+
def do_HEAD(self):
122+
self.send_error(int(self.path[1:]))
123+
118124
def setUp(self):
119125
BaseTestCase.setUp(self)
120126
self.con = http.client.HTTPConnection(self.HOST, self.PORT)
@@ -236,6 +242,44 @@ def test_error_content_length(self):
236242
data = res.read()
237243
self.assertEqual(int(res.getheader('Content-Length')), len(data))
238244

245+
def test_send_error(self):
246+
allow_transfer_encoding_codes = (HTTPStatus.NOT_MODIFIED,
247+
HTTPStatus.RESET_CONTENT)
248+
for code in (HTTPStatus.NO_CONTENT, HTTPStatus.NOT_MODIFIED,
249+
HTTPStatus.PROCESSING, HTTPStatus.RESET_CONTENT,
250+
HTTPStatus.SWITCHING_PROTOCOLS):
251+
self.con.request('SEND_ERROR', '/{}'.format(code))
252+
res = self.con.getresponse()
253+
self.assertEqual(code, res.status)
254+
self.assertEqual(None, res.getheader('Content-Length'))
255+
self.assertEqual(None, res.getheader('Content-Type'))
256+
if code not in allow_transfer_encoding_codes:
257+
self.assertEqual(None, res.getheader('Transfer-Encoding'))
258+
259+
data = res.read()
260+
self.assertEqual(b'', data)
261+
262+
def test_head_via_send_error(self):
263+
allow_transfer_encoding_codes = (HTTPStatus.NOT_MODIFIED,
264+
HTTPStatus.RESET_CONTENT)
265+
for code in (HTTPStatus.OK, HTTPStatus.NO_CONTENT,
266+
HTTPStatus.NOT_MODIFIED, HTTPStatus.RESET_CONTENT,
267+
HTTPStatus.SWITCHING_PROTOCOLS):
268+
self.con.request('HEAD', '/{}'.format(code))
269+
res = self.con.getresponse()
270+
self.assertEqual(code, res.status)
271+
if code == HTTPStatus.OK:
272+
self.assertTrue(int(res.getheader('Content-Length')) > 0)
273+
self.assertIn('text/html', res.getheader('Content-Type'))
274+
else:
275+
self.assertEqual(None, res.getheader('Content-Length'))
276+
self.assertEqual(None, res.getheader('Content-Type'))
277+
if code not in allow_transfer_encoding_codes:
278+
self.assertEqual(None, res.getheader('Transfer-Encoding'))
279+
280+
data = res.read()
281+
self.assertEqual(b'', data)
282+
239283

240284
class RequestHandlerLoggingTestCase(BaseTestCase):
241285
class request_handler(BaseHTTPRequestHandler):

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,7 @@ Arkady Koplyarov
781781
Peter A. Koren
782782
Марк Коренберг
783783
Vlad Korolev
784+
Susumu Koshiba
784785
Joseph Koshy
785786
Daniel Kozan
786787
Jerzy Kozera

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ Core and Builtins
131131
Library
132132
-------
133133

134+
- Issue #25738: Stop http.server.BaseHTTPRequestHandler.send_error() from
135+
sending a message body for 205 Reset Content. Also, don't send Content
136+
header fields in responses that don't have a body. Patch by Susumu
137+
Koshiba.
138+
134139
- Issue #21313: Fix the "platform" module to tolerate when sys.version
135140
contains truncated build information.
136141

0 commit comments

Comments
 (0)