diff options
author | Georg Brandl <georg@python.org> | 2006-03-31 18:01:16 (GMT) |
---|---|---|
committer | Georg Brandl <georg@python.org> | 2006-03-31 18:01:16 (GMT) |
commit | 43f08a85e4b86acf6e4313a51cec4df0cc586da7 (patch) | |
tree | f1e9812632d468fa2340e1db157b70926117be42 | |
parent | dd2245f2309da358b4c0b56d6a3a411888052f26 (diff) | |
download | cpython-43f08a85e4b86acf6e4313a51cec4df0cc586da7.zip cpython-43f08a85e4b86acf6e4313a51cec4df0cc586da7.tar.gz cpython-43f08a85e4b86acf6e4313a51cec4df0cc586da7.tar.bz2 |
Patch #1380952: fix SSL objects timing out on consecutive read()s
-rw-r--r-- | Lib/test/test_socket_ssl.py | 14 | ||||
-rw-r--r-- | Misc/NEWS | 2 | ||||
-rw-r--r-- | Modules/_ssl.c | 23 |
3 files changed, 31 insertions, 8 deletions
diff --git a/Lib/test/test_socket_ssl.py b/Lib/test/test_socket_ssl.py index 98680b9..91a8212 100644 --- a/Lib/test/test_socket_ssl.py +++ b/Lib/test/test_socket_ssl.py @@ -26,6 +26,19 @@ def test_basic(): 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 threading @@ -74,6 +87,7 @@ def test_main(): raise test_support.TestSkipped("socket module has no ssl support") test_rude_shutdown() test_basic() + test_timeout() if __name__ == "__main__": test_main() @@ -303,6 +303,8 @@ Core and builtins Extension Modules ----------------- +- Patch #1380952: fix SSL objects timing out on consecutive read()s + - Patch #1309579: wait3 and wait4 were added to the posix module. - Patch #1231053: The audioop module now supports encoding/decoding of alaw. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 5f541f5..0c085a8 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -474,15 +474,22 @@ static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args) if (!(buf = PyString_FromStringAndSize((char *) 0, len))) return NULL; + + /* first check if there are bytes ready to be read */ + Py_BEGIN_ALLOW_THREADS + count = SSL_pending(self->ssl); + Py_END_ALLOW_THREADS - sockstate = check_socket_and_wait_for_timeout(self->Socket, 0); - if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySSLErrorObject, "The read operation timed out"); - Py_DECREF(buf); - return NULL; - } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select()."); - return NULL; + if (!count) { + sockstate = check_socket_and_wait_for_timeout(self->Socket, 0); + if (sockstate == SOCKET_HAS_TIMED_OUT) { + PyErr_SetString(PySSLErrorObject, "The read operation timed out"); + Py_DECREF(buf); + return NULL; + } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { + PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select()."); + return NULL; + } } do { err = 0; |