Forward port of patch # 500311: Work around for buggy https servers.
Fixes #494762.
diff --git a/Lib/httplib.py b/Lib/httplib.py
index 2faf318..9d01859 100644
--- a/Lib/httplib.py
+++ b/Lib/httplib.py
@@ -633,7 +633,8 @@
                 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:
diff --git a/Misc/ACKS b/Misc/ACKS
index 2cafde8..12605fc 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -38,6 +38,7 @@
 Thomas Bellman
 Juan M. Bello Rivas
 Andy Bensky
+Michel Van den Bergh
 Eric Beser
 Stephen Bevan
 Ron Bickers
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index 17ca3b0..f5ab2b6 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -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,11 +78,71 @@
 	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);
+
+	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:
+	{
+		unsigned long e = ERR_get_error();
+		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);
@@ -77,40 +151,6 @@
 		return NULL;
 	}
 
-	switch (SSL_get_error(obj->ssl, ret)) {
-	case SSL_ERROR_ZERO_RETURN:
-		errstr = "TLS/SSL connection has been closed";
-		break;
-	case SSL_ERROR_WANT_READ:
-		errstr = "The operation did not complete (read)";
-		break;
-	case SSL_ERROR_WANT_WRITE:
-		errstr = "The operation did not complete (write)";
-		break;
-	case SSL_ERROR_WANT_X509_LOOKUP:
-		errstr = "The operation did not complete (X509 lookup)";
-		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();
-		} else {
-			/* XXX Protected by global interpreter lock */
-			errstr = ERR_error_string(e, NULL);
-		}
-		break;
-	}
-	default:
-		errstr = "Invalid error code";
-	}
 	s = PyString_FromString(errstr);
 	if (s == NULL) {
 		Py_DECREF(v);
@@ -447,15 +487,23 @@
 				 (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);
+
 }