]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Backport Python 3.2 fix for issue #12065, and add another test for SSLSocket.connect_...
authorAntoine Pitrou <solipsis@pitrou.net>
Fri, 28 Dec 2012 18:03:43 +0000 (19:03 +0100)
committerAntoine Pitrou <solipsis@pitrou.net>
Fri, 28 Dec 2012 18:03:43 +0000 (19:03 +0100)
Lib/ssl.py
Lib/test/test_ssl.py
Misc/NEWS

index 1951a620d961ae51f6a5f414dbea280a0f51d008..88296358a0242e6fce3eb37f9f03c75cb72e8bee 100644 (file)
@@ -313,17 +313,19 @@ class SSLSocket(socket):
                                     self.cert_reqs, self.ssl_version,
                                     self.ca_certs, self.ciphers)
         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
+                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
index 58da942f4923d3e473da1717d12d13d60057749d..9f5138719e89fc87dad390173453eeed673e97e4 100644 (file)
@@ -280,6 +280,34 @@ class NetworkedTests(unittest.TestCase):
             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 test_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_ex_error(self):
+        with test_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)
+            try:
+                self.assertEqual(errno.ECONNREFUSED,
+                                 s.connect_ex(("svn.python.org", 444)))
+            finally:
+                s.close()
+
     @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
     def test_makefile_close(self):
         # Issue #5238: creating a file-like object with makefile() shouldn't
index b718641a95a1acb9f50c9c76fb2598ba4f01036a..f087f415d6a3ca3d024fd3ab02e54eac8c60bdef 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -175,6 +175,9 @@ 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).
+
 - Issue #16504: IDLE now catches SyntaxErrors raised by tokenizer. Patch by
   Roger Serwy.