[Python-checkins] cpython (merge 3.2 -> default): Issue #12065: connect_ex() on an SSL socket now returns the original errno

antoine.pitrou python-checkins at python.org
Wed May 18 18:52:35 CEST 2011


http://hg.python.org/cpython/rev/162ed9841f14
changeset:   70188:162ed9841f14
parent:      70186:ebe93fec1558
parent:      70187:019d8ccdf03b
user:        Antoine Pitrou <solipsis at pitrou.net>
date:        Wed May 18 18:52:20 2011 +0200
summary:
  Issue #12065: connect_ex() on an SSL socket now returns the original errno
when the socket's timeout expires (it used to return None).

files:
  Lib/ssl.py           |  24 +++++++++++++-----------
  Lib/test/test_ssl.py |  17 +++++++++++++++++
  Misc/NEWS            |   3 +++
  3 files changed, 33 insertions(+), 11 deletions(-)


diff --git a/Lib/ssl.py b/Lib/ssl.py
--- a/Lib/ssl.py
+++ b/Lib/ssl.py
@@ -443,7 +443,7 @@
         finally:
             self.settimeout(timeout)
 
-    def _real_connect(self, addr, return_errno):
+    def _real_connect(self, addr, connect_ex):
         if self.server_side:
             raise ValueError("can't connect in server-side mode")
         # Here we assume that the socket is client-side, and not
@@ -452,17 +452,19 @@
             raise ValueError("attempt to connect already-connected SSLSocket!")
         self._sslobj = self.context._wrap_socket(self, False, self.server_hostname)
         try:
-            socket.connect(self, addr)
-            if self.do_handshake_on_connect:
-                self.do_handshake()
-        except socket_error as e:
-            if return_errno:
-                return e.errno
+            if connect_ex:
+                rc = socket.connect_ex(self, addr)
             else:
-                self._sslobj = None
-                raise e
-        self._connected = True
-        return 0
+                rc = None
+                socket.connect(self, addr)
+            if not rc:
+                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):
         """Connects to remote ADDR, and then wraps the connection in
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -519,6 +519,23 @@
             finally:
                 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):
         with support.transient_internet("svn.python.org"):
             # Same as test_connect, but with a separately created context
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -153,6 +153,9 @@
 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).
+
 - Issue #8809: The SMTP_SSL constructor and SMTP.starttls() now support
   passing a ``context`` argument pointing to an ssl.SSLContext instance.
   Patch by Kasun Herath.

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list