[Python-checkins] r88666 - in python/branches/release27-maint: Lib/ssl.py Lib/test/test_ssl.py Misc/NEWS
antoine.pitrou
python-checkins at python.org
Sun Feb 27 00:35:27 CET 2011
Author: antoine.pitrou
Date: Sun Feb 27 00:35:27 2011
New Revision: 88666
Log:
Merged revisions 88664 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k
........
r88664 | antoine.pitrou | 2011-02-27 00:24:06 +0100 (dim., 27 févr. 2011) | 4 lines
Issue #11326: Add the missing connect_ex() implementation for SSL sockets,
and make it work for non-blocking connects.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/ssl.py
python/branches/release27-maint/Lib/test/test_ssl.py
python/branches/release27-maint/Misc/NEWS
Modified: python/branches/release27-maint/Lib/ssl.py
==============================================================================
--- python/branches/release27-maint/Lib/ssl.py (original)
+++ python/branches/release27-maint/Lib/ssl.py Sun Feb 27 00:35:27 2011
@@ -110,9 +110,11 @@
if e.errno != errno.ENOTCONN:
raise
# no, no connection yet
+ self._connected = False
self._sslobj = None
else:
# yes, create the SSL object
+ self._connected = True
self._sslobj = _ssl.sslwrap(self._sock, server_side,
keyfile, certfile,
cert_reqs, ssl_version, ca_certs,
@@ -282,21 +284,36 @@
self._sslobj.do_handshake()
- def connect(self, addr):
-
- """Connects to remote ADDR, and then wraps the connection in
- an SSL channel."""
-
+ def _real_connect(self, addr, return_errno):
# Here we assume that the socket is client-side, and not
# connected at the time of the call. We connect it, then wrap it.
- if self._sslobj:
+ if self._connected:
raise ValueError("attempt to connect already-connected SSLSocket!")
- socket.connect(self, addr)
self._sslobj = _ssl.sslwrap(self._sock, False, self.keyfile, self.certfile,
self.cert_reqs, self.ssl_version,
self.ca_certs, self.ciphers)
- if self.do_handshake_on_connect:
- self.do_handshake()
+ 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
+ else:
+ self._sslobj = None
+ raise e
+ self._connected = True
+ return 0
+
+ def connect(self, addr):
+ """Connects to remote ADDR, and then wraps the connection in
+ an SSL channel."""
+ self._real_connect(addr, False)
+
+ def connect_ex(self, addr):
+ """Connects to remote ADDR, and then wraps the connection in
+ an SSL channel."""
+ return self._real_connect(addr, True)
def accept(self):
Modified: python/branches/release27-maint/Lib/test/test_ssl.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_ssl.py (original)
+++ python/branches/release27-maint/Lib/test/test_ssl.py Sun Feb 27 00:35:27 2011
@@ -225,6 +225,49 @@
finally:
s.close()
+ def test_connect_ex(self):
+ # Issue #11326: check connect_ex() implementation
+ 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(0, s.connect_ex(("svn.python.org", 443)))
+ self.assertTrue(s.getpeercert())
+ finally:
+ s.close()
+
+ def test_non_blocking_connect_ex(self):
+ # Issue #11326: non-blocking connect_ex() should allow handshake
+ # to proceed after the socket gets ready.
+ 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.setblocking(False)
+ rc = s.connect_ex(('svn.python.org', 443))
+ self.assertIn(rc, (0, errno.EINPROGRESS))
+ # Wait for connect to finish
+ select.select([], [s], [], 5.0)
+ # Non-blocking handshake
+ while True:
+ try:
+ s.do_handshake()
+ break
+ except ssl.SSLError as err:
+ if err.args[0] == ssl.SSL_ERROR_WANT_READ:
+ select.select([s], [], [], 5.0)
+ elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
+ select.select([], [s], [], 5.0)
+ else:
+ raise
+ # SSL established
+ self.assertTrue(s.getpeercert())
+ 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
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Sun Feb 27 00:35:27 2011
@@ -37,6 +37,9 @@
Library
-------
+- Issue #11326: Add the missing connect_ex() implementation for SSL sockets,
+ and make it work for non-blocking connects.
+
- Issue #10956: Buffered I/O classes retry reading or writing after a signal
has arrived and the handler returned successfully.
More information about the Python-checkins
mailing list