]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Fix handling of closed connections with epoll. This fixes a problem with
authorBen Darnell <ben@bendarnell.com>
Sun, 15 May 2011 03:52:42 +0000 (20:52 -0700)
committerBen Darnell <ben@bendarnell.com>
Sun, 15 May 2011 03:52:42 +0000 (20:52 -0700)
simple_httpclient and servers that close the connection after sending the
response.

tornado/iostream.py
tornado/test/iostream_test.py

index c75e89237f04b51a9a9fec394f597649f8bd97f2..812d5f6dcf5f763d236e0590ebfdb3c203207a42 100644 (file)
@@ -209,7 +209,10 @@ class IOStream(object):
             if not self.socket:
                 return
             if events & self.io_loop.ERROR:
-                self.close()
+                # We may have queued up a user callback in _handle_read or
+                # _handle_write, so don't close the IOStream until those
+                # callbacks have had a chance to run.
+                self.io_loop.add_callback(self.close)
                 return
             state = self.io_loop.ERROR
             if self.reading():
index 835e19b749db287314ea9e4f40a15f7388545587..f7d462da72ce2cee1bc623a5b33bafa4c0ddfc8f 100644 (file)
@@ -47,3 +47,12 @@ class TestIOStream(AsyncHTTPTestCase, LogTrapTestCase):
         self.wait()
         self.assertFalse(self.connect_called)
 
+    def test_connection_closed(self):
+        # When a server sends a response and then closes the connection,
+        # the client must be allowed to read the data before the IOStream
+        # closes itself.  Epoll reports closed connections with a separate
+        # EPOLLRDHUP event delivered at the same time as the read event,
+        # while kqueue reports them as a second read/write event with an EOF
+        # flag.
+        response = self.fetch("/", headers={"Connection": "close"})
+        response.rethrow()