]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Errors from socket.connect() should be treated the same way as async failures.
authorBen Darnell <ben@bendarnell.com>
Tue, 4 Oct 2011 05:28:33 +0000 (22:28 -0700)
committerBen Darnell <ben@bendarnell.com>
Tue, 4 Oct 2011 05:28:33 +0000 (22:28 -0700)
On freebsd non-blocking connect() may return certain errors (such as
ECONNREFUSED from localhost) immediately instead of returning EINPROGRESS
and then giving the error later.

Also improve the test for ipv6 compatibility, since freebsd returns a different
error than other platforms when ipv6 is not available.

tornado/iostream.py
tornado/test/simple_httpclient_test.py

index 0027a82bf24dec38b13f9d3df7ac996d6c37c073..6c9e61c9c24af9206dd368c21ca5f775dff85c38 100644 (file)
@@ -119,9 +119,18 @@ class IOStream(object):
         try:
             self.socket.connect(address)
         except socket.error, e:
-            # In non-blocking mode connect() always raises an exception
+            # In non-blocking mode we expect connect() to raise an
+            # exception with EINPROGRESS or EWOULDBLOCK.
+            #
+            # On freebsd, other errors such as ECONNREFUSED may be
+            # returned immediately when attempting to connect to
+            # localhost, so handle them the same way as an error
+            # reported later in _handle_connect.
             if e.args[0] not in (errno.EINPROGRESS, errno.EWOULDBLOCK):
-                raise
+                logging.warning("Connect error on fd %d: %s",
+                                self.socket.fileno(), e)
+                self.close()
+                return
         self._connect_callback = stack_context.wrap(callback)
         self._add_io_state(self.io_loop.WRITE)
 
index f6d7235ae5b562079f199cb30ae5b3199cbaa6c4..cc23d620c5962b1d2e302e464d4a7747d21bcdc0 100644 (file)
@@ -141,11 +141,15 @@ class SimpleHTTPClientTestCase(AsyncHTTPTestCase, LogTrapTestCase):
         self.assertEqual(str(response.error), "HTTP 599: Timeout")
 
     def test_ipv6(self):
+        if not socket.has_ipv6:
+            # python compiled without ipv6 support, so skip this test
+            return
         try:
             self.http_server.listen(self.get_http_port(), address='::1')
         except socket.gaierror, e:
             if e.errno == socket.EAI_ADDRFAMILY:
-                # ipv6 is not configured on this system, so skip this test
+                # python supports ipv6, but it's not configured on the network
+                # interface, so skip this test.
                 return
             raise
         url = self.get_url("/hello").replace("localhost", "[::1]")