[Python-checkins] r79918 - in python/trunk: Lib/test/test_ftplib.py Modules/_ssl.c
antoine.pitrou
python-checkins at python.org
Sat Apr 10 00:41:32 CEST 2010
Author: antoine.pitrou
Date: Sat Apr 10 00:41:31 2010
New Revision: 79918
Log:
Revert r79915 (temporary commit to check for buildbots -> the fix was successful)
Modified:
python/trunk/Lib/test/test_ftplib.py
python/trunk/Modules/_ssl.c
Modified: python/trunk/Lib/test/test_ftplib.py
==============================================================================
--- python/trunk/Lib/test/test_ftplib.py (original)
+++ python/trunk/Lib/test/test_ftplib.py Sat Apr 10 00:41:31 2010
@@ -29,7 +29,6 @@
class DummyDTPHandler(asynchat.async_chat):
- dtp_conn_closed = False
def __init__(self, conn, baseclass):
asynchat.async_chat.__init__(self, conn)
@@ -40,13 +39,8 @@
self.baseclass.last_received_data += self.recv(1024)
def handle_close(self):
- # XXX: this method can be called many times in a row for a single
- # connection, including in clear-text (non-TLS) mode.
- # (behaviour witnessed with test_data_connection)
- if not self.dtp_conn_closed:
- self.baseclass.push('226 transfer complete')
- self.close()
- self.dtp_conn_closed = True
+ self.baseclass.push('226 transfer complete')
+ self.close()
class DummyFTPHandler(asynchat.async_chat):
@@ -259,7 +253,6 @@
"""An asyncore.dispatcher subclass supporting TLS/SSL."""
_ssl_accepting = False
- _ssl_closing = False
def secure_connection(self):
self.socket = ssl.wrap_socket(self.socket, suppress_ragged_eofs=False,
@@ -284,36 +277,15 @@
else:
self._ssl_accepting = False
- def _do_ssl_shutdown(self):
- self._ssl_closing = True
- try:
- self.socket = self.socket.unwrap()
- except ssl.SSLError, err:
- if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
- ssl.SSL_ERROR_WANT_WRITE):
- return
- except socket.error, err:
- # Any "socket error" corresponds to a SSL_ERROR_SYSCALL return
- # from OpenSSL's SSL_shutdown(), corresponding to a
- # closed socket condition. See also:
- # http://www.mail-archive.com/openssl-users@openssl.org/msg60710.html
- pass
- self._ssl_closing = False
- super(SSLConnection, self).close()
-
def handle_read_event(self):
if self._ssl_accepting:
self._do_ssl_handshake()
- elif self._ssl_closing:
- self._do_ssl_shutdown()
else:
super(SSLConnection, self).handle_read_event()
def handle_write_event(self):
if self._ssl_accepting:
self._do_ssl_handshake()
- elif self._ssl_closing:
- self._do_ssl_shutdown()
else:
super(SSLConnection, self).handle_write_event()
@@ -343,9 +315,12 @@
raise
def close(self):
- if (isinstance(self.socket, ssl.SSLSocket) and
- self.socket._sslobj is not None):
- self._do_ssl_shutdown()
+ try:
+ if isinstance(self.socket, ssl.SSLSocket):
+ if self.socket._sslobj is not None:
+ self.socket.unwrap()
+ finally:
+ super(SSLConnection, self).close()
class DummyTLS_DTPHandler(SSLConnection, DummyDTPHandler):
@@ -622,21 +597,21 @@
sock = self.client.transfercmd('list')
self.assertNotIsInstance(sock, ssl.SSLSocket)
sock.close()
- self.assertEqual(self.client.voidresp(), "226 transfer complete")
+ self.client.voidresp()
# secured, after PROT P
self.client.prot_p()
sock = self.client.transfercmd('list')
self.assertIsInstance(sock, ssl.SSLSocket)
sock.close()
- self.assertEqual(self.client.voidresp(), "226 transfer complete")
+ self.client.voidresp()
# PROT C is issued, the connection must be in cleartext again
self.client.prot_c()
sock = self.client.transfercmd('list')
self.assertNotIsInstance(sock, ssl.SSLSocket)
sock.close()
- self.assertEqual(self.client.voidresp(), "226 transfer complete")
+ self.client.voidresp()
def test_login(self):
# login() is supposed to implicitly secure the control connection
Modified: python/trunk/Modules/_ssl.c
==============================================================================
--- python/trunk/Modules/_ssl.c (original)
+++ python/trunk/Modules/_ssl.c Sat Apr 10 00:41:31 2010
@@ -1347,7 +1347,7 @@
static PyObject *PySSL_SSLshutdown(PySSLObject *self)
{
- int err, ssl_err, sockstate;
+ int err;
/* Guard against closed socket */
if (self->Socket->sock_fd < 0) {
@@ -1356,42 +1356,13 @@
return NULL;
}
- while (1) {
- PySSL_BEGIN_ALLOW_THREADS
+ PySSL_BEGIN_ALLOW_THREADS
+ err = SSL_shutdown(self->ssl);
+ if (err == 0) {
+ /* we need to call it again to finish the shutdown */
err = SSL_shutdown(self->ssl);
- if (err == 0) {
- /* we need to call it again to finish the shutdown */
- err = SSL_shutdown(self->ssl);
- }
- PySSL_END_ALLOW_THREADS
- if (err >= 0)
- break;
- /* Possibly retry shutdown until timeout or failure */
- ssl_err = SSL_get_error(self->ssl, err);
- if (ssl_err == SSL_ERROR_WANT_READ)
- sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
- else if (ssl_err == SSL_ERROR_WANT_WRITE)
- sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
- else
- break;
- if (sockstate == SOCKET_HAS_TIMED_OUT) {
- if (ssl_err == SSL_ERROR_WANT_READ)
- PyErr_SetString(PySSLErrorObject,
- "The read operation timed out");
- else
- PyErr_SetString(PySSLErrorObject,
- "The write operation timed out");
- return NULL;
- }
- else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
- PyErr_SetString(PySSLErrorObject,
- "Underlying socket too large for select().");
- return NULL;
- }
- else if (sockstate != SOCKET_OPERATION_OK)
- /* Retain the SSL error code */
- break;
}
+ PySSL_END_ALLOW_THREADS
if (err < 0)
return PySSL_SetError(self, err, __FILE__, __LINE__);
More information about the Python-checkins
mailing list