diff options
| author | Matthew Somerville <matthew-github@dracos.co.uk> | 2014-08-03 00:50:55 +0100 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2014-11-28 10:51:15 -0500 |
| commit | 9253042d53d61b23b3f727a00c41e8089be73836 (patch) | |
| tree | 1963f8d07eaa6aa9375c9beabae845657b68f973 | |
| parent | 9e80c5f457340126adcae375d6de5ee64d6075b9 (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.py | 38 |
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) |
