[Python-checkins] python/dist/src/Modules _ssl.c,1.9,1.10
gvanrossum@users.sourceforge.net
gvanrossum@users.sourceforge.net
Fri, 31 Jan 2003 10:13:21 -0800
Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1:/tmp/cvs-serv5789
Modified Files:
_ssl.c
Log Message:
SF patch 676472 by Geoff Talvola, reviewed by Ben Laurie.
Geoff writes:
This is yet another patch to _ssl.c that sets the
underlying BIO to non-blocking if the socket being
wrapped is non-blocking. It also correctly loops when
SSL_connect, SSL_write, or SSL_read indicates that it
needs to read or write more bytes.
This seems to fix bug #673797 which was not fixed by my
previous patch.
Index: _ssl.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_ssl.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** _ssl.c 27 Jan 2003 22:19:21 -0000 1.9
--- _ssl.c 31 Jan 2003 18:13:18 -0000 1.10
***************
*** 169,172 ****
--- 169,174 ----
char *errstr = NULL;
int ret;
+ int err;
+ int timedout;
self = PyObject_New(PySSLObject, &PySSL_Type); /* Create new object */
***************
*** 221,232 ****
Py_END_ALLOW_THREADS
SSL_set_fd(self->ssl, Sock->sock_fd); /* Set the socket for SSL */
Py_BEGIN_ALLOW_THREADS
SSL_set_connect_state(self->ssl);
!
/* Actually negotiate SSL connection */
/* XXX If SSL_connect() returns 0, it's also a failure. */
! ret = SSL_connect(self->ssl);
! Py_END_ALLOW_THREADS
if (ret <= 0) {
PySSL_SetError(self, ret);
--- 223,258 ----
Py_END_ALLOW_THREADS
SSL_set_fd(self->ssl, Sock->sock_fd); /* Set the socket for SSL */
+
+ /* If the socket is is non-blocking mode or timeout mode, set the BIO
+ * to non-blocking mode (blocking is the default)
+ */
+ if (Sock->sock_timeout >= 0.0) {
+ /* Set both the read and write BIO's to non-blocking mode */
+ BIO_set_nbio(SSL_get_rbio(self->ssl), 1);
+ BIO_set_nbio(SSL_get_wbio(self->ssl), 1);
+ }
+
Py_BEGIN_ALLOW_THREADS
SSL_set_connect_state(self->ssl);
! Py_END_ALLOW_THREADS
/* Actually negotiate SSL connection */
/* XXX If SSL_connect() returns 0, it's also a failure. */
! timedout = 0;
! do {
! Py_BEGIN_ALLOW_THREADS
! ret = SSL_connect(self->ssl);
! err = SSL_get_error(self->ssl, ret);
! Py_END_ALLOW_THREADS
! if (err == SSL_ERROR_WANT_READ) {
! timedout = wait_for_timeout(Sock, 0);
! } else if (err == SSL_ERROR_WANT_WRITE) {
! timedout = wait_for_timeout(Sock, 1);
! }
! if (timedout) {
! PyErr_SetString(PySSLErrorObject, "The connect operation timed out");
! return NULL;
! }
! } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
if (ret <= 0) {
PySSL_SetError(self, ret);
***************
*** 329,336 ****
--- 355,364 ----
/* See if the socket is ready */
+ Py_BEGIN_ALLOW_THREADS
if (writing)
rc = select(s->sock_fd+1, NULL, &fds, NULL, &tv);
else
rc = select(s->sock_fd+1, &fds, NULL, NULL, &tv);
+ Py_END_ALLOW_THREADS
/* Return 1 on timeout, 0 otherwise */
***************
*** 343,360 ****
int len;
int timedout;
if (!PyArg_ParseTuple(args, "s#:write", &data, &len))
return NULL;
- Py_BEGIN_ALLOW_THREADS
timedout = wait_for_timeout(self->Socket, 1);
- Py_END_ALLOW_THREADS
if (timedout) {
PyErr_SetString(PySSLErrorObject, "The write operation timed out");
return NULL;
}
! Py_BEGIN_ALLOW_THREADS
! len = SSL_write(self->ssl, data, len);
! Py_END_ALLOW_THREADS
if (len > 0)
return PyInt_FromLong(len);
--- 371,400 ----
int len;
int timedout;
+ int err;
if (!PyArg_ParseTuple(args, "s#:write", &data, &len))
return NULL;
timedout = wait_for_timeout(self->Socket, 1);
if (timedout) {
PyErr_SetString(PySSLErrorObject, "The write operation timed out");
return NULL;
}
! do {
! err = 0;
! Py_BEGIN_ALLOW_THREADS
! len = SSL_write(self->ssl, data, len);
! err = SSL_get_error(self->ssl, len);
! Py_END_ALLOW_THREADS
! if (err == SSL_ERROR_WANT_READ) {
! timedout = wait_for_timeout(self->Socket, 0);
! } else if (err == SSL_ERROR_WANT_WRITE) {
! timedout = wait_for_timeout(self->Socket, 1);
! }
! if (timedout) {
! PyErr_SetString(PySSLErrorObject, "The write operation timed out");
! return NULL;
! }
! } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
if (len > 0)
return PyInt_FromLong(len);
***************
*** 375,378 ****
--- 415,419 ----
int len = 1024;
int timedout;
+ int err;
if (!PyArg_ParseTuple(args, "|i:read", &len))
***************
*** 382,395 ****
return NULL;
- Py_BEGIN_ALLOW_THREADS
timedout = wait_for_timeout(self->Socket, 0);
- Py_END_ALLOW_THREADS
if (timedout) {
PyErr_SetString(PySSLErrorObject, "The read operation timed out");
return NULL;
}
! Py_BEGIN_ALLOW_THREADS
! count = SSL_read(self->ssl, PyString_AsString(buf), len);
! Py_END_ALLOW_THREADS
if (count <= 0) {
Py_DECREF(buf);
--- 423,447 ----
return NULL;
timedout = wait_for_timeout(self->Socket, 0);
if (timedout) {
PyErr_SetString(PySSLErrorObject, "The read operation timed out");
return NULL;
}
! do {
! err = 0;
! Py_BEGIN_ALLOW_THREADS
! count = SSL_read(self->ssl, PyString_AsString(buf), len);
! err = SSL_get_error(self->ssl, count);
! Py_END_ALLOW_THREADS
! if (err == SSL_ERROR_WANT_READ) {
! timedout = wait_for_timeout(self->Socket, 0);
! } else if (err == SSL_ERROR_WANT_WRITE) {
! timedout = wait_for_timeout(self->Socket, 1);
! }
! if (timedout) {
! PyErr_SetString(PySSLErrorObject, "The read operation timed out");
! return NULL;
! }
! } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
if (count <= 0) {
Py_DECREF(buf);