]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Close the IOStream when the remote connection is closed.
authorBen Darnell <ben@bendarnell.com>
Mon, 27 Sep 2010 19:46:20 +0000 (12:46 -0700)
committerBen Darnell <ben@bendarnell.com>
Mon, 27 Sep 2010 19:46:20 +0000 (12:46 -0700)
This was a regression introduced by http://github.com/facebook/tornado/commit/f6f7f83719a48083f3e5ed999e19c0ec67de9b9b

Closes #143.

tornado/iostream.py
tornado/test/web_test.py

index 3e76af12f3da1ea9b504bb3b1e622c5dfa30975a..361955487bbc2b9c08e6b8e851fcd3c369fe6978 100644 (file)
@@ -214,6 +214,9 @@ class IOStream(object):
                 return None
             else:
                 raise
+        if not chunk:
+            self.close()
+            return None
         return chunk
 
     def _read_to_buffer(self):
@@ -358,4 +361,7 @@ class SSLIOStream(IOStream):
                 return None
             else:
                 raise
+        if not chunk:
+            self.close()
+            return None
         return chunk
index 7f4a975d0c4d0070145fa011f0cfcb50f2ecf313..181ffe5aca53c7f1bdd0eb58d879145c15dc6821 100644 (file)
@@ -1,8 +1,11 @@
+from tornado.iostream import IOStream
 from tornado.testing import LogTrapTestCase, AsyncHTTPTestCase
-from tornado.web import RequestHandler, _O, authenticated, Application
+from tornado.web import RequestHandler, _O, authenticated, Application, asynchronous
 
 import logging
 import re
+import socket
+import tornado.ioloop
 
 class CookieTestRequestHandler(RequestHandler):
     # stub out enough methods to make the secure_cookie functions work
@@ -79,3 +82,38 @@ class AuthRedirectTest(AsyncHTTPTestCase, LogTrapTestCase):
         self.assertTrue(re.match(
             'http://example.com/login\?next=http%3A%2F%2Flocalhost%3A[0-9]+%2Fabsolute',
             response.headers['Location']), response.headers['Location'])
+
+
+class ConnectionCloseHandler(RequestHandler):
+    def initialize(self, test):
+        self.test = test
+
+    @asynchronous
+    def get(self):
+        self.test.on_handler_waiting()
+
+    def on_connection_close(self):
+        self.test.on_connection_close()
+
+class ConnectionCloseTest(AsyncHTTPTestCase, LogTrapTestCase):
+    def get_app(self):
+        return Application([('/', ConnectionCloseHandler, dict(test=self))])
+
+    def test_connection_close(self):
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
+        s.connect(("localhost", self.get_http_port()))
+        self.stream = IOStream(s, io_loop=self.io_loop)
+        self.stream.write("GET / HTTP/1.0\r\n\r\n")
+        self.wait()
+
+    def on_handler_waiting(self):
+        logging.info('handler waiting')
+        self.stream.close()
+
+    def on_connection_close(self):
+        logging.info('connection closed')
+        self.stop()
+
+if tornado.ioloop._poll is tornado.ioloop._Select:
+    # select-based ioloop does not detect closed connections promptly
+    del ConnectionCloseTest