summaryrefslogtreecommitdiffstats
path: root/Modules/_ssl.c
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2011-10-27 21:56:55 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2011-10-27 21:56:55 (GMT)
commit41032a69c12c1d4939daa84c98b2726f00380a9e (patch)
tree97607f9001b060955a87ff6789b51027f031cbc9 /Modules/_ssl.c
parentb5cab85dc79913b6825ecdbbd6b085529ee2dc91 (diff)
downloadcpython-41032a69c12c1d4939daa84c98b2726f00380a9e.zip
cpython-41032a69c12c1d4939daa84c98b2726f00380a9e.tar.gz
cpython-41032a69c12c1d4939daa84c98b2726f00380a9e.tar.bz2
Issue #11183: Add finer-grained exceptions to the ssl module, so that
you don't have to inspect the exception's attributes in the common case.
Diffstat (limited to 'Modules/_ssl.c')
-rw-r--r--Modules/_ssl.c60
1 files changed, 57 insertions, 3 deletions
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index 2998605..dcde4ff 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -99,6 +99,11 @@ static PySocketModule_APIObject PySocketModule;
/* SSL error object */
static PyObject *PySSLErrorObject;
+static PyObject *PySSLZeroReturnErrorObject;
+static PyObject *PySSLWantReadErrorObject;
+static PyObject *PySSLWantWriteErrorObject;
+static PyObject *PySSLSyscallErrorObject;
+static PyObject *PySSLEOFErrorObject;
#ifdef WITH_THREAD
@@ -191,6 +196,7 @@ static PyObject *
PySSL_SetError(PySSLSocket *obj, int ret, char *filename, int lineno)
{
PyObject *v;
+ PyObject *type = PySSLErrorObject;
char buf[2048];
char *errstr;
int err;
@@ -203,15 +209,18 @@ PySSL_SetError(PySSLSocket *obj, int ret, char *filename, int lineno)
switch (err) {
case SSL_ERROR_ZERO_RETURN:
- errstr = "TLS/SSL connection has been closed";
+ errstr = "TLS/SSL connection has been closed (EOF)";
+ type = PySSLZeroReturnErrorObject;
p = PY_SSL_ERROR_ZERO_RETURN;
break;
case SSL_ERROR_WANT_READ:
errstr = "The operation did not complete (read)";
+ type = PySSLWantReadErrorObject;
p = PY_SSL_ERROR_WANT_READ;
break;
case SSL_ERROR_WANT_WRITE:
p = PY_SSL_ERROR_WANT_WRITE;
+ type = PySSLWantWriteErrorObject;
errstr = "The operation did not complete (write)";
break;
case SSL_ERROR_WANT_X509_LOOKUP:
@@ -230,6 +239,7 @@ PySSL_SetError(PySSLSocket *obj, int ret, char *filename, int lineno)
= (PySocketSockObject *) PyWeakref_GetObject(obj->Socket);
if (ret == 0 || (((PyObject *)s) == Py_None)) {
p = PY_SSL_ERROR_EOF;
+ type = PySSLEOFErrorObject;
errstr = "EOF occurred in violation of protocol";
} else if (ret == -1) {
/* underlying BIO reported an I/O error */
@@ -240,6 +250,7 @@ PySSL_SetError(PySSLSocket *obj, int ret, char *filename, int lineno)
return v;
} else { /* possible? */
p = PY_SSL_ERROR_SYSCALL;
+ type = PySSLSyscallErrorObject;
errstr = "Some I/O error occurred";
}
} else {
@@ -272,7 +283,7 @@ PySSL_SetError(PySSLSocket *obj, int ret, char *filename, int lineno)
ERR_clear_error();
v = Py_BuildValue("(is)", p, buf);
if (v != NULL) {
- PyErr_SetObject(PySSLErrorObject, v);
+ PyErr_SetObject(type, v);
Py_DECREF(v);
}
return NULL;
@@ -2300,6 +2311,23 @@ parse_openssl_version(unsigned long libver,
PyDoc_STRVAR(SSLError_doc,
"An error occurred in the SSL implementation.");
+PyDoc_STRVAR(SSLZeroReturnError_doc,
+"SSL/TLS session closed cleanly.");
+
+PyDoc_STRVAR(SSLWantReadError_doc,
+"Non-blocking SSL socket needs to read more data\n"
+"before the requested operation can be completed.");
+
+PyDoc_STRVAR(SSLWantWriteError_doc,
+"Non-blocking SSL socket needs to write more data\n"
+"before the requested operation can be completed.");
+
+PyDoc_STRVAR(SSLSyscallError_doc,
+"System error when attempting SSL operation.");
+
+PyDoc_STRVAR(SSLEOFError_doc,
+"SSL/TLS connection terminated abruptly.");
+
PyMODINIT_FUNC
PyInit__ssl(void)
@@ -2343,7 +2371,33 @@ PyInit__ssl(void)
NULL);
if (PySSLErrorObject == NULL)
return NULL;
- if (PyDict_SetItemString(d, "SSLError", PySSLErrorObject) != 0)
+ PySSLZeroReturnErrorObject = PyErr_NewExceptionWithDoc(
+ "ssl.SSLZeroReturnError", SSLZeroReturnError_doc,
+ PySSLErrorObject, NULL);
+ PySSLWantReadErrorObject = PyErr_NewExceptionWithDoc(
+ "ssl.SSLWantReadError", SSLWantReadError_doc,
+ PySSLErrorObject, NULL);
+ PySSLWantWriteErrorObject = PyErr_NewExceptionWithDoc(
+ "ssl.SSLWantWriteError", SSLWantWriteError_doc,
+ PySSLErrorObject, NULL);
+ PySSLSyscallErrorObject = PyErr_NewExceptionWithDoc(
+ "ssl.SSLSyscallError", SSLSyscallError_doc,
+ PySSLErrorObject, NULL);
+ PySSLEOFErrorObject = PyErr_NewExceptionWithDoc(
+ "ssl.SSLEOFError", SSLEOFError_doc,
+ PySSLErrorObject, NULL);
+ if (PySSLZeroReturnErrorObject == NULL
+ || PySSLWantReadErrorObject == NULL
+ || PySSLWantWriteErrorObject == NULL
+ || PySSLSyscallErrorObject == NULL
+ || PySSLEOFErrorObject == NULL)
+ return NULL;
+ if (PyDict_SetItemString(d, "SSLError", PySSLErrorObject) != 0
+ || PyDict_SetItemString(d, "SSLZeroReturnError", PySSLZeroReturnErrorObject) != 0
+ || PyDict_SetItemString(d, "SSLWantReadError", PySSLWantReadErrorObject) != 0
+ || PyDict_SetItemString(d, "SSLWantWriteError", PySSLWantWriteErrorObject) != 0
+ || PyDict_SetItemString(d, "SSLSyscallError", PySSLSyscallErrorObject) != 0
+ || PyDict_SetItemString(d, "SSLEOFError", PySSLEOFErrorObject) != 0)
return NULL;
if (PyDict_SetItemString(d, "_SSLContext",
(PyObject *)&PySSLContext_Type) != 0)