Issue #12065: connect_ex() on an SSL socket now returns the original errno

when the socket's timeout expires (it used to return None).
This commit is contained in:
Antoine Pitrou 2011-05-18 18:51:06 +02:00
parent 3349bca46d
commit b4410dbea6
3 changed files with 45 additions and 11 deletions

View File

@ -442,7 +442,7 @@ class SSLSocket(socket):
finally: finally:
self.settimeout(timeout) self.settimeout(timeout)
def _real_connect(self, addr, return_errno): def _real_connect(self, addr, connect_ex):
if self.server_side: if self.server_side:
raise ValueError("can't connect in server-side mode") raise ValueError("can't connect in server-side mode")
# Here we assume that the socket is client-side, and not # Here we assume that the socket is client-side, and not
@ -451,17 +451,19 @@ class SSLSocket(socket):
raise ValueError("attempt to connect already-connected SSLSocket!") raise ValueError("attempt to connect already-connected SSLSocket!")
self._sslobj = self.context._wrap_socket(self, False, self.server_hostname) self._sslobj = self.context._wrap_socket(self, False, self.server_hostname)
try: try:
socket.connect(self, addr) if connect_ex:
if self.do_handshake_on_connect: rc = socket.connect_ex(self, addr)
self.do_handshake()
except socket_error as e:
if return_errno:
return e.errno
else: else:
self._sslobj = None rc = None
raise e socket.connect(self, addr)
self._connected = True if not rc:
return 0 if self.do_handshake_on_connect:
self.do_handshake()
self._connected = True
return rc
except socket_error:
self._sslobj = None
raise
def connect(self, addr): def connect(self, addr):
"""Connects to remote ADDR, and then wraps the connection in """Connects to remote ADDR, and then wraps the connection in

View File

@ -519,6 +519,23 @@ class NetworkedTests(unittest.TestCase):
finally: finally:
s.close() s.close()
def test_timeout_connect_ex(self):
# Issue #12065: on a timeout, connect_ex() should return the original
# errno (mimicking the behaviour of non-SSL sockets).
with support.transient_internet("svn.python.org"):
s = ssl.wrap_socket(socket.socket(socket.AF_INET),
cert_reqs=ssl.CERT_REQUIRED,
ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
do_handshake_on_connect=False)
try:
s.settimeout(0.0000001)
rc = s.connect_ex(('svn.python.org', 443))
if rc == 0:
self.skipTest("svn.python.org responded too quickly")
self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
finally:
s.close()
def test_connect_with_context(self): def test_connect_with_context(self):
with support.transient_internet("svn.python.org"): with support.transient_internet("svn.python.org"):
# Same as test_connect, but with a separately created context # Same as test_connect, but with a separately created context

View File

@ -2,6 +2,21 @@
Python News Python News
+++++++++++ +++++++++++
What's New in Python 3.2.2?
===========================
*Release date: XX-XXX-2011*
Core and Builtins
-----------------
Library
-------
- Issue #12065: connect_ex() on an SSL socket now returns the original errno
when the socket's timeout expires (it used to return None).
What's New in Python 3.2.1 release candidate 1? What's New in Python 3.2.1 release candidate 1?
=============================================== ===============================================