SOURCES: python-ssl-nonblocking.patch (NEW) Fix SSL sockets when s...
arekm
arekm at pld-linux.org
Wed Dec 14 23:40:06 CET 2005
Author: arekm Date: Wed Dec 14 22:40:06 2005 GMT
Module: SOURCES Tag: HEAD
---- Log message:
Fix SSL sockets when settimeout(X.X) was used (was hanging on read()).
---- Files affected:
SOURCES:
python-ssl-nonblocking.patch (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/python-ssl-nonblocking.patch
diff -u /dev/null SOURCES/python-ssl-nonblocking.patch:1.1
--- /dev/null Wed Dec 14 23:40:06 2005
+++ SOURCES/python-ssl-nonblocking.patch Wed Dec 14 23:40:01 2005
@@ -0,0 +1,124 @@
+--- Python.org/Lib/test/test_socket_ssl.py.org 2005-12-14 23:04:19.000000000 +0100
++++ Python/Lib/test/test_socket_ssl.py 2005-12-14 23:06:07.000000000 +0100
+@@ -27,6 +27,19 @@
+ buf = f.read()
+ f.close()
+
++def test_timeout():
++ test_support.requires('network')
++
++ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
++ s.settimeout(30.0)
++ # connect to service which issues an welcome banner (without need to write anything)
++ s.connect(("gmail.org", 995))
++ ss = socket.ssl(s)
++ # read part of return welcome banner twice,# read part of return welcome banner twice
++ ss.read(1)
++ ss.read(1)
++ s.close()
++
+ def test_rude_shutdown():
+ try:
+ import thread
+@@ -63,6 +76,7 @@
+ raise test_support.TestSkipped("socket module has no ssl support")
+ test_rude_shutdown()
+ test_basic()
++ test_timeout()
+
+ if __name__ == "__main__":
+ test_main()
+--- Python.org/Modules/_ssl.c 2004-08-04 16:59:00.000000000 +0200
++++ Python/Modules/_ssl.c 2005-12-14 23:36:18.000000000 +0100
+@@ -65,6 +65,7 @@
+ static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args);
+ static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args);
+ static int check_socket_and_wait_for_timeout(PySocketSockObject *s,
++ SSL *ssl,
+ int writing);
+
+ #define PySSLObject_Check(v) ((v)->ob_type == &PySSL_Type)
+@@ -260,9 +261,9 @@
+ goto fail;
+ }
+ if (err == SSL_ERROR_WANT_READ) {
+- sockstate = check_socket_and_wait_for_timeout(Sock, 0);
++ sockstate = check_socket_and_wait_for_timeout(Sock, NULL, 0);
+ } else if (err == SSL_ERROR_WANT_WRITE) {
+- sockstate = check_socket_and_wait_for_timeout(Sock, 1);
++ sockstate = check_socket_and_wait_for_timeout(Sock, NULL, 1);
+ } else {
+ sockstate = SOCKET_OPERATION_OK;
+ }
+@@ -356,11 +357,11 @@
+ */
+
+ static int
+-check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing)
++check_socket_and_wait_for_timeout(PySocketSockObject *s, SSL *ssl, int writing)
+ {
+ fd_set fds;
+ struct timeval tv;
+- int rc;
++ int pending, rc;
+
+ /* Nothing to do unless we're in timeout mode (not non-blocking) */
+ if (s->sock_timeout < 0.0)
+@@ -372,6 +373,15 @@
+ if (s->sock_fd < 0)
+ return SOCKET_HAS_BEEN_CLOSED;
+
++ /* There is data to be read from SSL layer (even if there is no data on socket!) */
++ if (!writing && ssl) {
++ Py_BEGIN_ALLOW_THREADS
++ pending = SSL_pending(ssl);
++ Py_END_ALLOW_THREADS
++ if (pending)
++ return SOCKET_OPERATION_OK;
++ }
++
+ /* Construct the arguments to select */
+ tv.tv_sec = (int)s->sock_timeout;
+ tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);
+@@ -402,7 +412,7 @@
+ if (!PyArg_ParseTuple(args, "s#:write", &data, &count))
+ return NULL;
+
+- sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
++ sockstate = check_socket_and_wait_for_timeout(self->Socket, NULL, 1);
+ if (sockstate == SOCKET_HAS_TIMED_OUT) {
+ PyErr_SetString(PySSLErrorObject, "The write operation timed out");
+ return NULL;
+@@ -420,9 +430,9 @@
+ return NULL;
+ }
+ if (err == SSL_ERROR_WANT_READ) {
+- sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
++ sockstate = check_socket_and_wait_for_timeout(self->Socket, NULL, 0);
+ } else if (err == SSL_ERROR_WANT_WRITE) {
+- sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
++ sockstate = check_socket_and_wait_for_timeout(self->Socket, NULL, 1);
+ } else {
+ sockstate = SOCKET_OPERATION_OK;
+ }
+@@ -462,7 +472,7 @@
+ if (!(buf = PyString_FromStringAndSize((char *) 0, len)))
+ return NULL;
+
+- sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
++ sockstate = check_socket_and_wait_for_timeout(self->Socket, self->ssl, 0);
+ if (sockstate == SOCKET_HAS_TIMED_OUT) {
+ PyErr_SetString(PySSLErrorObject, "The read operation timed out");
+ Py_DECREF(buf);
+@@ -479,9 +489,9 @@
+ return NULL;
+ }
+ if (err == SSL_ERROR_WANT_READ) {
+- sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
++ sockstate = check_socket_and_wait_for_timeout(self->Socket, NULL, 0);
+ } else if (err == SSL_ERROR_WANT_WRITE) {
+- sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
++ sockstate = check_socket_and_wait_for_timeout(self->Socket, NULL, 1);
+ } else {
+ sockstate = SOCKET_OPERATION_OK;
+ }
================================================================
More information about the pld-cvs-commit
mailing list