]> granicus.if.org Git - python/commitdiff
Closing transport during handshake process leaks socket (#480) (#2044)
authorYury Selivanov <yury@magic.io>
Fri, 9 Jun 2017 22:33:31 +0000 (18:33 -0400)
committerGitHub <noreply@github.com>
Fri, 9 Jun 2017 22:33:31 +0000 (18:33 -0400)
Lib/asyncio/sslproto.py
Lib/test/test_asyncio/test_sslproto.py
Misc/NEWS

index ab7ff0bf93d076ad93524357990332b603c2724a..6e9ce2968a0826fb386b10c6dc3c3a6a71f7bb03 100644 (file)
@@ -551,8 +551,11 @@ class SSLProtocol(protocols.Protocol):
     def _start_shutdown(self):
         if self._in_shutdown:
             return
-        self._in_shutdown = True
-        self._write_appdata(b'')
+        if self._in_handshake:
+            self._abort()
+        else:
+            self._in_shutdown = True
+            self._write_appdata(b'')
 
     def _write_appdata(self, data):
         self._write_backlog.append((data, 0))
index f1771c5561afea819c3fdc6590efbc1d1d84d3fb..bcd236ea2632ed728a91a4b485b68ed7c5535f14 100644 (file)
@@ -42,6 +42,7 @@ class SslProtoHandshakeTests(test_utils.TestCase):
             sslpipe.do_handshake.side_effect = mock_handshake
         with mock.patch('asyncio.sslproto._SSLPipe', return_value=sslpipe):
             ssl_proto.connection_made(transport)
+        return transport
 
     def test_cancel_handshake(self):
         # Python issue #23197: cancelling a handshake must not raise an
@@ -95,6 +96,20 @@ class SslProtoHandshakeTests(test_utils.TestCase):
         test_utils.run_briefly(self.loop)
         self.assertIsInstance(waiter.exception(), ConnectionAbortedError)
 
+    def test_close_during_handshake(self):
+        # bpo-29743 Closing transport during handshake process leaks socket
+        waiter = asyncio.Future(loop=self.loop)
+        ssl_proto = self.ssl_protocol(waiter)
+
+        def do_handshake(callback):
+            return []
+
+        transport = self.connection_made(ssl_proto)
+        test_utils.run_briefly(self.loop)
+
+        ssl_proto._app_transport.close()
+        self.assertTrue(transport.abort.called)
+
     def test_get_extra_info_on_closed_connection(self):
         waiter = asyncio.Future(loop=self.loop)
         ssl_proto = self.ssl_protocol(waiter)
index 0342c71cd65a131bcfb6578b151fab6871c01470..7bd46d5578750ecac9383587b9c808d289a34c5e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -49,6 +49,9 @@ Core and Builtins
 Library
 -------
 
+- bpo-29743: Closing transport during handshake process leaks open socket.
+  Patch by Nikolay Kim
+
 - bpo-27585: Fix waiter cancellation in asyncio.Lock.
   Patch by Mathieu Sornay.