summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Somerville <matthew-github@dracos.co.uk>2014-08-03 00:50:55 +0100
committerTim Graham <timograham@gmail.com>2014-11-28 10:51:15 -0500
commit9253042d53d61b23b3f727a00c41e8089be73836 (patch)
tree1963f8d07eaa6aa9375c9beabae845657b68f973
parent9e80c5f457340126adcae375d6de5ee64d6075b9 (diff)
Fixed #4444 - Made runserver suppress 'broken pipe' errors
One handler in WSGIServer, to catch the error when raised from SocketServer.BaseServer's finish_request, and one in WSGIRequestHandler (by creating a subclass of ServerHandler), to catch the error when raised in wsgiref.handlers.BaseHandler's finish_response.
-rw-r--r--django/core/servers/basehttp.py38
1 files changed, 38 insertions, 0 deletions
diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py
index 9ba9ede43a..5af226f31f 100644
--- a/django/core/servers/basehttp.py
+++ b/django/core/servers/basehttp.py
@@ -60,6 +60,11 @@ def get_internal_wsgi_application():
sys.exc_info()[2])
+def is_broken_pipe_error():
+ exc_type, exc_value = sys.exc_info()[:2]
+ return issubclass(exc_type, socket.error) and exc_value.args[0] == 32
+
+
class WSGIServer(simple_server.WSGIServer, object):
"""BaseHTTPServer that implements the Python WSGI protocol"""
@@ -75,6 +80,19 @@ class WSGIServer(simple_server.WSGIServer, object):
super(WSGIServer, self).server_bind()
self.setup_environ()
+ def handle_error(self, request, client_address):
+ if is_broken_pipe_error():
+ sys.stderr.write("- Broken pipe from %s\n" % (client_address,))
+ else:
+ super(WSGIServer, self).handle_error(request, client_address)
+
+
+class ServerHandler(simple_server.ServerHandler):
+ def handle_error(self):
+ # Ignore broken pipe errors, otherwise pass on
+ if not is_broken_pipe_error():
+ super(ServerHandler, self).handle_error()
+
class WSGIRequestHandler(simple_server.WSGIRequestHandler, object):
@@ -134,6 +152,26 @@ class WSGIRequestHandler(simple_server.WSGIRequestHandler, object):
return env
+ def handle(self):
+ """Copy of WSGIRequestHandler, but with different ServerHandler"""
+
+ self.raw_requestline = self.rfile.readline(65537)
+ if len(self.raw_requestline) > 65536:
+ self.requestline = ''
+ self.request_version = ''
+ self.command = ''
+ self.send_error(414)
+ return
+
+ if not self.parse_request(): # An error code has been sent, just exit
+ return
+
+ handler = ServerHandler(
+ self.rfile, self.wfile, self.get_stderr(), self.get_environ()
+ )
+ handler.request_handler = self # backpointer for logging
+ handler.run(self.server.get_app())
+
def run(addr, port, wsgi_handler, ipv6=False, threading=False):
server_address = (addr, port)