Skip to content

Commit

Permalink
Errors from socket.connect() should be treated the same way as async …
Browse files Browse the repository at this point in the history
…failures.

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.
  • Loading branch information
bdarnell committed Oct 4, 2011
1 parent 4b346bd commit 420ad08
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
13 changes: 11 additions & 2 deletions tornado/iostream.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,18 @@ def connect(self, address, callback=None):
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)

Expand Down
6 changes: 5 additions & 1 deletion tornado/test/simple_httpclient_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,15 @@ def test_request_timeout(self):
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]")
Expand Down

0 comments on commit 420ad08

Please sign in to comment.