← Back to team overview

touch-packages team mailing list archive

[Bug 1214848] Re: SocketServer doesn't handle client disconnects properly.

 

fixed in 14.04 LTS and later releases

** Changed in: python2.7 (Ubuntu)
       Status: Triaged => Fix Released

-- 
You received this bug notification because you are a member of Ubuntu
Touch seeded packages, which is subscribed to python2.7 in Ubuntu.
https://bugs.launchpad.net/bugs/1214848

Title:
  SocketServer doesn't handle client disconnects properly.

Status in Python:
  Fix Released
Status in python2.7 package in Ubuntu:
  Fix Released

Bug description:
  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()

To manage notifications about this bug go to:
https://bugs.launchpad.net/python/+bug/1214848/+subscriptions