#1291 http.server's send_error takes an optional explain argument

This commit is contained in:
Senthil Kumaran 2013-03-15 07:53:21 -07:00
parent 12bb353d43
commit 2688644eef
4 changed files with 33 additions and 10 deletions

View file

@ -170,15 +170,19 @@ of which this module provides three different variants:
.. versionadded:: 3.2
.. method:: send_error(code, message=None)
.. method:: send_error(code, message=None, explain=None)
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.
specifies the HTTP error code, with *message* as optional, more specific
text, usually referring to short message response. The *explain*
argument can be used to send a detailed information about the error in
response content body. A 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.
explain argument was added.
.. method:: send_response(code, message=None)

View file

@ -401,12 +401,17 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler):
while not self.close_connection:
self.handle_one_request()
def send_error(self, code, message=None):
def send_error(self, code, message=None, explain=None):
"""Send and log an error reply.
Arguments are the error code, and a detailed message.
The detailed message defaults to the short entry matching the
response code.
Arguments are
* code: an HTTP error code
3 digits
* message: a simple optional 1 line reason phrase.
*( HTAB / SP / VCHAR / %x80-FF )
defaults to short entry matching the response code
* explain: a detailed message defaults to the long entry
matching the response code.
This sends an error response (so it must be called before any
output has been generated), logs the error, and finally sends
@ -420,11 +425,12 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler):
shortmsg, longmsg = '???', '???'
if message is None:
message = shortmsg
if explain is None:
explain = longmsg
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})
{'code': code, 'message': _quote_html(message), 'explain': _quote_html(explain)})
body = content.encode('UTF-8', 'replace')
self.send_response(code, message)
self.send_header("Content-Type", self.error_content_type)

View file

@ -95,6 +95,10 @@ class BaseHTTPServerTestCase(BaseTestCase):
def do_NOTFOUND(self):
self.send_error(404)
def do_EXPLAINERROR(self):
self.send_error(999, "Short Message",
"This is a long \n explaination")
def do_CUSTOM(self):
self.send_response(999)
self.send_header('Content-Type', 'text/html')
@ -206,6 +210,12 @@ class BaseHTTPServerTestCase(BaseTestCase):
res = self.con.getresponse()
self.assertEqual(res.status, 999)
def test_return_explain_error(self):
self.con.request('EXPLAINERROR', '/')
res = self.con.getresponse()
self.assertEqual(res.status, 999)
self.assertTrue(int(res.getheader('Content-Length')))
def test_latin1_header(self):
self.con.request('LATINONEHEADER', '/', headers={
'X-Special-Incoming': 'Ärger mit Unicode'

View file

@ -280,6 +280,9 @@ Core and Builtins
Library
-------
- Issue #12921: http.server's send_error takes an explain argument to send more
information in response. Patch contributed by Karl.
- Issue #17414: Add timeit, repeat, and default_timer to timeit.__all__.
- Issue #1285086: Get rid of the refcounting hack and speed up