]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Patch #1380952: fix SSL objects timing out on consecutive read()s
authorGeorg Brandl <georg@python.org>
Fri, 31 Mar 2006 18:01:24 +0000 (18:01 +0000)
committerGeorg Brandl <georg@python.org>
Fri, 31 Mar 2006 18:01:24 +0000 (18:01 +0000)
 (backport from rev. 43491)

Lib/test/test_socket_ssl.py
Misc/NEWS
Modules/_ssl.c

index bcdb705b617546f86b58f8f028aacdde17ae5cbe..e72004e65ebe960afccf36f589fb14c07c020a39 100644 (file)
@@ -27,6 +27,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 thread
@@ -63,6 +76,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()
index 748aca6a47ee9b36922818bb02106d804bba2300..eb3062f358bc2efe364422b7cc2b041bb2f51f00 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -25,6 +25,8 @@ Core and builtins
 Extension Modules
 -----------------
 
+- Patch #1380952: fix SSL objects timing out on consecutive read()s
+
 - Ubuntu bug #29289: Fixed a bug that the gb18030 codec raises
   RuntimeError on encoding surrogate pair area on UCS4 build.
 
index a1c0512523b8eacbe8b1f8e08b20af535cedcba0..df36fe2de37c8ca2a7fb8cfdd0a0670addb11581 100644 (file)
@@ -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;