Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6af3e2d

Browse files
committed
Forward port of patch # 500311: Work around for buggy https servers.
Fixes #494762.
1 parent 954aed8 commit 6af3e2d

3 files changed

Lines changed: 75 additions & 25 deletions

File tree

Lib/httplib.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,8 @@ def makefile(self, mode, bufsize=None):
633633
if (err[0] == socket.SSL_ERROR_WANT_READ
634634
or err[0] == socket.SSL_ERROR_WANT_WRITE):
635635
continue
636-
if err[0] == socket.SSL_ERROR_ZERO_RETURN:
636+
if (err[0] == socket.SSL_ERROR_ZERO_RETURN
637+
or err[0] == socket.SSL_ERROR_EOF):
637638
break
638639
raise
639640
except socket.error, err:

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Reimer Behrends
3838
Thomas Bellman
3939
Juan M. Bello Rivas
4040
Andy Bensky
41+
Michel Van den Bergh
4142
Eric Beser
4243
Stephen Bevan
4344
Ron Bickers

Modules/_ssl.c

Lines changed: 72 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,20 @@
88
*/
99

1010
#include "Python.h"
11+
enum py_ssl_error {
12+
/* these mirror ssl.h */
13+
PY_SSL_ERROR_NONE,
14+
PY_SSL_ERROR_SSL,
15+
PY_SSL_ERROR_WANT_READ,
16+
PY_SSL_ERROR_WANT_WRITE,
17+
PY_SSL_ERROR_WANT_X509_LOOKUP,
18+
PY_SSL_ERROR_SYSCALL, /* look at error stack/return value/errno */
19+
PY_SSL_ERROR_ZERO_RETURN,
20+
PY_SSL_ERROR_WANT_CONNECT,
21+
/* start of non ssl.h errorcodes */
22+
PY_SSL_ERROR_EOF, /* special case of SSL_ERROR_SYSCALL */
23+
PY_SSL_ERROR_INVALID_ERROR_CODE
24+
};
1125

1226
/* Include symbols from _socket module */
1327
#include "socketmodule.h"
@@ -64,53 +78,79 @@ PySSL_SetError(PySSLObject *obj, int ret)
6478
PyObject *v, *n, *s;
6579
char *errstr;
6680
int err;
81+
enum py_ssl_error p;
6782

6883
assert(ret <= 0);
6984

7085
err = SSL_get_error(obj->ssl, ret);
71-
n = PyInt_FromLong(err);
72-
if (n == NULL)
73-
return NULL;
74-
v = PyTuple_New(2);
75-
if (v == NULL) {
76-
Py_DECREF(n);
77-
return NULL;
78-
}
7986

80-
switch (SSL_get_error(obj->ssl, ret)) {
87+
switch (err) {
8188
case SSL_ERROR_ZERO_RETURN:
8289
errstr = "TLS/SSL connection has been closed";
90+
p=PY_SSL_ERROR_ZERO_RETURN;
8391
break;
8492
case SSL_ERROR_WANT_READ:
8593
errstr = "The operation did not complete (read)";
94+
p=PY_SSL_ERROR_WANT_READ;
8695
break;
8796
case SSL_ERROR_WANT_WRITE:
97+
p=PY_SSL_ERROR_WANT_WRITE;
8898
errstr = "The operation did not complete (write)";
8999
break;
90100
case SSL_ERROR_WANT_X509_LOOKUP:
101+
p=PY_SSL_ERROR_WANT_X509_LOOKUP;
91102
errstr = "The operation did not complete (X509 lookup)";
92103
break;
104+
case SSL_ERROR_WANT_CONNECT:
105+
p=PY_SSL_ERROR_WANT_CONNECT;
106+
errstr = "The operation did not complete (connect)";
107+
break;
93108
case SSL_ERROR_SYSCALL:
94-
case SSL_ERROR_SSL:
95109
{
96110
unsigned long e = ERR_get_error();
97-
if (e == 0) {
98-
/* an EOF was observed that violates the protocol */
99-
errstr = "EOF occurred in violation of protocol";
100-
} else if (e == -1) {
101-
/* the underlying BIO reported an I/O error */
102-
Py_DECREF(v);
103-
Py_DECREF(n);
104-
return obj->Socket->errorhandler();
111+
if(e==0){
112+
if(ret==0){
113+
p=PY_SSL_ERROR_EOF;
114+
errstr = "EOF occurred in violation of protocol";
115+
}else if(ret==-1){
116+
/* the underlying BIO reported an I/O error */
117+
return obj->Socket->errorhandler();
118+
}else{ /* possible? */
119+
p=PY_SSL_ERROR_SYSCALL;
120+
errstr = "Some I/O error occurred";
121+
}
105122
} else {
123+
p=PY_SSL_ERROR_SYSCALL;
124+
/* XXX Protected by global interpreter lock */
125+
errstr = ERR_error_string(e, NULL);
126+
}
127+
break;
128+
}
129+
case SSL_ERROR_SSL:
130+
{
131+
unsigned long e = ERR_get_error();
132+
p=PY_SSL_ERROR_SSL;
133+
if (e !=0) {
106134
/* XXX Protected by global interpreter lock */
107135
errstr = ERR_error_string(e, NULL);
136+
} else { /* possible? */
137+
errstr="A failure in the SSL library occurred";
108138
}
109139
break;
110140
}
111141
default:
142+
p=PY_SSL_ERROR_INVALID_ERROR_CODE;
112143
errstr = "Invalid error code";
113144
}
145+
n = PyInt_FromLong((long) p);
146+
if (n == NULL)
147+
return NULL;
148+
v = PyTuple_New(2);
149+
if (v == NULL) {
150+
Py_DECREF(n);
151+
return NULL;
152+
}
153+
114154
s = PyString_FromString(errstr);
115155
if (s == NULL) {
116156
Py_DECREF(v);
@@ -447,15 +487,23 @@ init_ssl(void)
447487
(PyObject *)&PySSL_Type) != 0)
448488
return;
449489
PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN",
450-
SSL_ERROR_ZERO_RETURN);
490+
PY_SSL_ERROR_ZERO_RETURN);
451491
PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ",
452-
SSL_ERROR_WANT_READ);
492+
PY_SSL_ERROR_WANT_READ);
453493
PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE",
454-
SSL_ERROR_WANT_WRITE);
494+
PY_SSL_ERROR_WANT_WRITE);
455495
PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP",
456-
SSL_ERROR_WANT_X509_LOOKUP);
496+
PY_SSL_ERROR_WANT_X509_LOOKUP);
457497
PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL",
458-
SSL_ERROR_SYSCALL);
498+
PY_SSL_ERROR_SYSCALL);
459499
PyModule_AddIntConstant(m, "SSL_ERROR_SSL",
460-
SSL_ERROR_SSL);
500+
PY_SSL_ERROR_SSL);
501+
PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT",
502+
PY_SSL_ERROR_WANT_CONNECT);
503+
/* non ssl.h errorcodes */
504+
PyModule_AddIntConstant(m, "SSL_ERROR_EOF",
505+
PY_SSL_ERROR_EOF);
506+
PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE",
507+
PY_SSL_ERROR_INVALID_ERROR_CODE);
508+
461509
}

0 commit comments

Comments
 (0)