diff -r ec373d762213 Lib/ftplib.py --- a/Lib/ftplib.py Sat Oct 03 07:37:22 2015 +0000 +++ b/Lib/ftplib.py Sat Oct 03 13:30:22 2015 +0200 @@ -710,7 +710,8 @@ conn, size = FTP.ntransfercmd(self, cmd, rest) if self._prot_p: conn = self.context.wrap_socket(conn, - server_hostname=self.host) + server_hostname=self.host, + established_socket=self.sock) return conn, size def retrbinary(self, cmd, callback, blocksize=8192, rest=None): diff -r ec373d762213 Lib/ssl.py --- a/Lib/ssl.py Sat Oct 03 07:37:22 2015 +0000 +++ b/Lib/ssl.py Sat Oct 03 13:30:22 2015 +0200 @@ -344,12 +344,13 @@ def wrap_socket(self, sock, server_side=False, do_handshake_on_connect=True, suppress_ragged_eofs=True, - server_hostname=None): + server_hostname=None, + established_socket=None): return SSLSocket(sock=sock, server_side=server_side, do_handshake_on_connect=do_handshake_on_connect, suppress_ragged_eofs=suppress_ragged_eofs, server_hostname=server_hostname, - _context=self) + _context=self, _established_socket=established_socket) def set_npn_protocols(self, npn_protocols): protos = bytearray() @@ -501,7 +502,7 @@ family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None, suppress_ragged_eofs=True, npn_protocols=None, ciphers=None, server_hostname=None, - _context=None): + _context=None, _established_socket=None): self._makefile_refs = 0 if _context: @@ -571,6 +572,11 @@ try: self._sslobj = self._context._wrap_socket(self._sock, server_side, server_hostname, ssl_sock=self) + + # reuse session + if _established_socket: + self._sslobj.reuse_session(_established_socket._sslobj) + if do_handshake_on_connect: timeout = self.gettimeout() if timeout == 0.0: diff -r ec373d762213 Modules/_ssl.c --- a/Modules/_ssl.c Sat Oct 03 07:37:22 2015 +0000 +++ b/Modules/_ssl.c Sat Oct 03 13:30:22 2015 +0200 @@ -1407,6 +1407,13 @@ return PyUnicode_FromString(version); } +static PyObject * +PySSL_reuse_session(PySSLSocket *self, PySSLSocket *src) +{ + SSL_set_session(self->ssl, SSL_get_session(src->ssl)); + Py_RETURN_NONE; +} + #ifdef OPENSSL_NPN_NEGOTIATED static PyObject *PySSL_selected_npn_protocol(PySSLSocket *self) { const unsigned char *out; @@ -1924,6 +1931,7 @@ PySSL_peercert_doc}, {"cipher", (PyCFunction)PySSL_cipher, METH_NOARGS}, {"version", (PyCFunction)PySSL_version, METH_NOARGS}, + {"reuse_session", (PyCFunction)PySSL_reuse_session, METH_O}, #ifdef OPENSSL_NPN_NEGOTIATED {"selected_npn_protocol", (PyCFunction)PySSL_selected_npn_protocol, METH_NOARGS}, #endif