New submission from Vlad <vladandje...@gmail.com>: When dealing with a new connection, SocketServer.BaseRequestHandler.__init__ first calls the request handler (self.handle below) and then calls cleanup code which closes the connection (self.finish below).
class BaseRequestHandler: def __init__(self, request, client_address, server): < ... snip ... > try: self.handle() finally: self.finish() The issue arises when a client disconnects suddenly during the self.handle() call. The handler may attempt to write data to the disconnected socket. This will cause an exception (which is correct), but somehow data will still be added to the connection's buffer and self.wfile.closed will be False! As a result, BaseRequestHandler.finish() will attempt to flush the connection's buffer and this will raise another exception which can't be handled without modifying the library code. ---------------------------------------- Exception happened during processing of request from ('127.0.0.1', 62718) Traceback (most recent call last): File "C:\Python27\lib\SocketServer.py", line 284, in _handle_request_noblock self.process_request(request, client_address) File "C:\Python27\lib\SocketServer.py", line 310, in process_request self.finish_request(request, client_address) File "C:\Python27\lib\SocketServer.py", line 323, in finish_request self.RequestHandlerClass(request, client_address, self) File "C:\Python27\lib\SocketServer.py", line 641, in __init__ self.finish() File "C:\Python27\lib\SocketServer.py", line 694, in finish self.wfile.flush() File "C:\Python27\lib\socket.py", line 303, in flush self._sock.sendall(view[write_offset:write_offset+buffer_size]) error: [Errno 10053] An established connection was aborted by the software in your host machine ---------------------------------------- I've provided a toy server below, you can reproduce the issue by submitting a request to it with curl and then immediately killing curl: curl -d "test" http://127.0.0.1:8000/ Toy server code: =========================== import BaseHTTPServer import SocketServer import time class ThreadedHTTPServer(BaseHTTPServer.HTTPServer): pass class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): def do_POST(self): try: length = int(self.headers["Content-Length"]) request = self.rfile.read(length) print "Sleeping. Kill the 'curl' command now." time.sleep(10) print "Woke up. You should see a stack trace from the problematic exception below." print "Received POST: " + request self.send_response(200) # <------- This somehow adds to the connection's buffer! self.end_headers() except Exception as e: print "Exception: " + str(e) # <----- This exception is expected httpd = ThreadedHTTPServer(("127.0.0.1", 8000), RequestHandler) httpd.serve_forever() httpd.server_close() ---------- components: Library (Lib) messages: 158240 nosy: vdjeric priority: normal severity: normal status: open title: SocketServer doesn't handle client disconnects properly versions: Python 2.7 _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue14574> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com