diff -r 5667f43f71cd Doc/library/ssl.rst --- a/Doc/library/ssl.rst Wed Apr 07 10:24:44 2010 +0200 +++ b/Doc/library/ssl.rst Wed Apr 07 13:41:57 2010 +0200 @@ -354,6 +354,15 @@ the other side of the connection, rather than the original socket instance (which may not function properly after the unwrap). +.. method:: SSLSocket.get_mode() + + Return the mode. + +.. method:: SSLSocket.set_mode(mode) + + Add the mode set via bitmask in mode. Options already set before are not + cleared. Return the new mode. + .. index:: single: certificates .. index:: single: X509 certificate diff -r 5667f43f71cd Lib/ssl.py --- a/Lib/ssl.py Wed Apr 07 10:24:44 2010 +0200 +++ b/Lib/ssl.py Wed Apr 07 13:41:57 2010 +0200 @@ -64,6 +64,7 @@ from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED from _ssl import PROTOCOL_SSLv2, PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1 from _ssl import RAND_status, RAND_egd, RAND_add +from _ssl import SSL_MODE_ENABLE_PARTIAL_WRITE, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER from _ssl import \ SSL_ERROR_ZERO_RETURN, \ SSL_ERROR_WANT_READ, \ @@ -322,6 +323,17 @@ self._makefile_refs += 1 return _fileobject(self, mode, bufsize) + def get_mode(self): + if self._sslobj: + return self._sslobj.get_mode() + else: + return 0 + + def set_mode(self, mode): + if self._sslobj: + return self._sslobj.set_mode(mode) + else: + return 0 def wrap_socket(sock, keyfile=None, certfile=None, diff -r 5667f43f71cd Lib/test/test_ssl.py --- a/Lib/test/test_ssl.py Wed Apr 07 10:24:44 2010 +0200 +++ b/Lib/test/test_ssl.py Wed Apr 07 13:41:57 2010 +0200 @@ -79,6 +79,18 @@ ssl.CERT_OPTIONAL ssl.CERT_REQUIRED + def testMode(self): + ssl.SSL_MODE_ENABLE_PARTIAL_WRITE + ssl.SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER + if not test_support.is_resource_enabled('network'): + return + s = ssl.wrap_socket(socket.socket(socket.AF_INET)) + s.connect(("svn.python.org", 443)) + mode = ssl.SSL_MODE_ENABLE_PARTIAL_WRITE + self.assertFalse(s.get_mode() & mode) + self.assertTrue(s.set_mode(mode) & mode) + self.assertTrue(s.get_mode() & mode) + def testRAND(self): v = ssl.RAND_status() if test_support.verbose: diff -r 5667f43f71cd Modules/_ssl.c --- a/Modules/_ssl.c Wed Apr 07 10:24:44 2010 +0200 +++ b/Modules/_ssl.c Wed Apr 07 13:41:57 2010 +0200 @@ -1376,6 +1376,36 @@ Does the SSL shutdown handshake with the remote end, and returns\n\ the underlying socket object."); +static PyObject *PySSL_SSLget_mode(PySSLObject *self) +{ + long mode = SSL_get_mode(self->ssl); + + return PyInt_FromLong(mode); +} + +PyDoc_STRVAR(PySSL_SSLget_mode_doc, +"get_mode() -> mode\n\ +\n\ +Return the mode."); + +static PyObject *PySSL_SSLset_mode(PySSLObject *self, PyObject *args) +{ + int mode = 0; + long new_mode = 0; + + if (!PyArg_ParseTuple(args, "|i:mode", &mode)) + return NULL; + + new_mode = SSL_set_mode(self->ssl, mode); + return PyInt_FromLong(new_mode); +} + +PyDoc_STRVAR(PySSL_SSLset_mode_doc, +"set_mode(mode) -> mode\n\ +\n\ +Add the mode set via bitmask in mode. Options already set before are not cleared.\n\ +Return the new mode."); + static PyMethodDef PySSLMethods[] = { {"do_handshake", (PyCFunction)PySSL_SSLdo_handshake, METH_NOARGS}, {"write", (PyCFunction)PySSL_SSLwrite, METH_VARARGS, @@ -1390,7 +1420,11 @@ PySSL_peercert_doc}, {"cipher", (PyCFunction)PySSL_cipher, METH_NOARGS}, {"shutdown", (PyCFunction)PySSL_SSLshutdown, METH_NOARGS, - PySSL_SSLshutdown_doc}, + PySSL_SSLshutdown_doc}, + {"get_mode", (PyCFunction)PySSL_SSLget_mode, METH_NOARGS, + PySSL_SSLget_mode_doc}, + {"set_mode", (PyCFunction)PySSL_SSLset_mode, METH_VARARGS, + PySSL_SSLset_mode_doc}, {NULL, NULL} }; @@ -1647,6 +1681,12 @@ PyModule_AddIntConstant(m, "PROTOCOL_TLSv1", PY_SSL_VERSION_TLS1); + /* modes */ + PyModule_AddIntConstant(m, "SSL_MODE_ENABLE_PARTIAL_WRITE", + SSL_MODE_ENABLE_PARTIAL_WRITE); + PyModule_AddIntConstant(m, "SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER", + SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); + /* OpenSSL version */ /* SSLeay() gives us the version of the library linked against, which could be different from the headers version.