]> granicus.if.org Git - python/commitdiff
Forward port of patch # 500311: Work around for buggy https servers.
authorMartin v. Löwis <martin@v.loewis.de>
Sat, 20 Apr 2002 07:47:40 +0000 (07:47 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Sat, 20 Apr 2002 07:47:40 +0000 (07:47 +0000)
Fixes #494762.

Lib/httplib.py
Misc/ACKS
Modules/_ssl.c

index 2faf3189fad3c5c9213a5b8471d04b460e0a9d4c..9d018590640232e27bfd5bd695283d1cc75586ad 100644 (file)
@@ -633,7 +633,8 @@ class FakeSocket:
                 if (err[0] == socket.SSL_ERROR_WANT_READ
                     or err[0] == socket.SSL_ERROR_WANT_WRITE):
                     continue
-                if err[0] == socket.SSL_ERROR_ZERO_RETURN:
+                if (err[0] == socket.SSL_ERROR_ZERO_RETURN
+                    or err[0] == socket.SSL_ERROR_EOF):
                     break
                 raise
             except socket.error, err:
index 2cafde88ba8220ee822007578c451cd697aa31da..12605fccd7a9219aae72cc6ad0488ad3c9f51f76 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -38,6 +38,7 @@ Reimer Behrends
 Thomas Bellman
 Juan M. Bello Rivas
 Andy Bensky
+Michel Van den Bergh
 Eric Beser
 Stephen Bevan
 Ron Bickers
index 17ca3b027a9dd7d08d81cd5417086eb6b8610b22..f5ab2b6e01534b8cca7709499df30f3b4a3260cd 100644 (file)
@@ -8,6 +8,20 @@
 */
 
 #include "Python.h"
+enum py_ssl_error {
+       /* these mirror ssl.h */
+       PY_SSL_ERROR_NONE,                 
+       PY_SSL_ERROR_SSL,                   
+       PY_SSL_ERROR_WANT_READ,             
+       PY_SSL_ERROR_WANT_WRITE,            
+       PY_SSL_ERROR_WANT_X509_LOOKUP,      
+       PY_SSL_ERROR_SYSCALL,     /* look at error stack/return value/errno */
+       PY_SSL_ERROR_ZERO_RETURN,           
+       PY_SSL_ERROR_WANT_CONNECT,
+       /* start of non ssl.h errorcodes */ 
+       PY_SSL_ERROR_EOF,         /* special case of SSL_ERROR_SYSCALL */
+       PY_SSL_ERROR_INVALID_ERROR_CODE
+};
 
 /* Include symbols from _socket module */
 #include "socketmodule.h"
@@ -64,53 +78,79 @@ PySSL_SetError(PySSLObject *obj, int ret)
        PyObject *v, *n, *s;
        char *errstr;
        int err;
+       enum py_ssl_error p;
 
        assert(ret <= 0);
     
        err = SSL_get_error(obj->ssl, ret);
-       n = PyInt_FromLong(err);
-       if (n == NULL)
-               return NULL;
-       v = PyTuple_New(2);
-       if (v == NULL) {
-               Py_DECREF(n);
-               return NULL;
-       }
 
-       switch (SSL_get_error(obj->ssl, ret)) {
+       switch (err) {
        case SSL_ERROR_ZERO_RETURN:
                errstr = "TLS/SSL connection has been closed";
+               p=PY_SSL_ERROR_ZERO_RETURN;
                break;
        case SSL_ERROR_WANT_READ:
                errstr = "The operation did not complete (read)";
+               p=PY_SSL_ERROR_WANT_READ;
                break;
        case SSL_ERROR_WANT_WRITE:
+               p=PY_SSL_ERROR_WANT_WRITE;
                errstr = "The operation did not complete (write)";
                break;
        case SSL_ERROR_WANT_X509_LOOKUP:
+               p=PY_SSL_ERROR_WANT_X509_LOOKUP;
                errstr = "The operation did not complete (X509 lookup)";
                break;
+       case SSL_ERROR_WANT_CONNECT:
+               p=PY_SSL_ERROR_WANT_CONNECT;
+               errstr = "The operation did not complete (connect)";
+               break;
        case SSL_ERROR_SYSCALL:
-       case SSL_ERROR_SSL:
        {
                unsigned long e = ERR_get_error();
-               if (e == 0) {
-                       /* an EOF was observed that violates the protocol */
-                       errstr = "EOF occurred in violation of protocol";
-               } else if (e == -1) {
-                       /* the underlying BIO reported an I/O error */
-                       Py_DECREF(v);
-                       Py_DECREF(n);
-                       return obj->Socket->errorhandler();
+               if(e==0){
+                       if(ret==0){
+                               p=PY_SSL_ERROR_EOF;
+                               errstr = "EOF occurred in violation of protocol";
+                       }else if(ret==-1){
+                               /* the underlying BIO reported an I/O error */
+                               return obj->Socket->errorhandler();
+                       }else{  /* possible? */
+                               p=PY_SSL_ERROR_SYSCALL;
+                               errstr = "Some I/O error occurred";
+                       }
                } else {
+                       p=PY_SSL_ERROR_SYSCALL;
+                       /* XXX Protected by global interpreter lock */
+                       errstr = ERR_error_string(e, NULL);
+               }
+               break;
+       }   
+       case SSL_ERROR_SSL:
+       {
+               unsigned long e = ERR_get_error();
+               p=PY_SSL_ERROR_SSL;
+               if (e !=0) {
                        /* XXX Protected by global interpreter lock */
                        errstr = ERR_error_string(e, NULL);
+               } else { /* possible? */
+                       errstr="A failure in the SSL library occurred";
                }
                break;
        }
        default:
+               p=PY_SSL_ERROR_INVALID_ERROR_CODE;
                errstr = "Invalid error code";
        }
+       n = PyInt_FromLong((long) p);
+       if (n == NULL)
+               return NULL;
+       v = PyTuple_New(2);
+       if (v == NULL) {
+               Py_DECREF(n);
+               return NULL;
+       }
+
        s = PyString_FromString(errstr);
        if (s == NULL) {
                Py_DECREF(v);
@@ -447,15 +487,23 @@ init_ssl(void)
                                 (PyObject *)&PySSL_Type) != 0)
                return;
        PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN",
-                               SSL_ERROR_ZERO_RETURN);
+                               PY_SSL_ERROR_ZERO_RETURN);
        PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ",
-                               SSL_ERROR_WANT_READ);
+                               PY_SSL_ERROR_WANT_READ);
        PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE",
-                               SSL_ERROR_WANT_WRITE);
+                               PY_SSL_ERROR_WANT_WRITE);
        PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP",
-                               SSL_ERROR_WANT_X509_LOOKUP);
+                               PY_SSL_ERROR_WANT_X509_LOOKUP);
        PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL",
-                               SSL_ERROR_SYSCALL);
+                               PY_SSL_ERROR_SYSCALL);
        PyModule_AddIntConstant(m, "SSL_ERROR_SSL",
-                               SSL_ERROR_SSL);
+                               PY_SSL_ERROR_SSL);
+       PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT",
+                               PY_SSL_ERROR_WANT_CONNECT);
+       /* non ssl.h errorcodes */
+       PyModule_AddIntConstant(m, "SSL_ERROR_EOF",
+                               PY_SSL_ERROR_EOF);
+       PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE",
+                               PY_SSL_ERROR_INVALID_ERROR_CODE);
+
 }