Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b507cba

Browse files
committed
asyncio: Fix SSLProtocol.eof_received()
Wake-up the waiter if it is not done yet.
1 parent a89f5f0 commit b507cba

2 files changed

Lines changed: 33 additions & 11 deletions

File tree

Lib/asyncio/sslproto.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,10 @@ def eof_received(self):
489489
try:
490490
if self._loop.get_debug():
491491
logger.debug("%r received EOF", self)
492+
493+
if self._waiter is not None and not self._waiter.done():
494+
self._waiter.set_exception(ConnectionResetError())
495+
492496
if not self._in_handshake:
493497
keep_open = self._app_protocol.eof_received()
494498
if keep_open:

Lib/test/test_asyncio/test_sslproto.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,36 @@
1212
from asyncio import test_utils
1313

1414

15+
@unittest.skipIf(ssl is None, 'No ssl module')
1516
class SslProtoHandshakeTests(test_utils.TestCase):
1617

1718
def setUp(self):
1819
self.loop = asyncio.new_event_loop()
1920
self.set_event_loop(self.loop)
2021

21-
@unittest.skipIf(ssl is None, 'No ssl module')
22+
def ssl_protocol(self, waiter=None):
23+
sslcontext = test_utils.dummy_ssl_context()
24+
app_proto = asyncio.Protocol()
25+
return sslproto.SSLProtocol(self.loop, app_proto, sslcontext, waiter)
26+
27+
def connection_made(self, ssl_proto, do_handshake=None):
28+
transport = mock.Mock()
29+
sslpipe = mock.Mock()
30+
sslpipe.shutdown.return_value = b''
31+
if do_handshake:
32+
sslpipe.do_handshake.side_effect = do_handshake
33+
else:
34+
def mock_handshake(callback):
35+
return []
36+
sslpipe.do_handshake.side_effect = mock_handshake
37+
with mock.patch('asyncio.sslproto._SSLPipe', return_value=sslpipe):
38+
ssl_proto.connection_made(transport)
39+
2240
def test_cancel_handshake(self):
2341
# Python issue #23197: cancelling an handshake must not raise an
2442
# exception or log an error, even if the handshake failed
25-
sslcontext = test_utils.dummy_ssl_context()
26-
app_proto = asyncio.Protocol()
2743
waiter = asyncio.Future(loop=self.loop)
28-
ssl_proto = sslproto.SSLProtocol(self.loop, app_proto, sslcontext,
29-
waiter)
44+
ssl_proto = self.ssl_protocol(waiter)
3045
handshake_fut = asyncio.Future(loop=self.loop)
3146

3247
def do_handshake(callback):
@@ -36,19 +51,22 @@ def do_handshake(callback):
3651
return []
3752

3853
waiter.cancel()
39-
transport = mock.Mock()
40-
sslpipe = mock.Mock()
41-
sslpipe.shutdown.return_value = b''
42-
sslpipe.do_handshake.side_effect = do_handshake
43-
with mock.patch('asyncio.sslproto._SSLPipe', return_value=sslpipe):
44-
ssl_proto.connection_made(transport)
54+
self.connection_made(ssl_proto, do_handshake)
4555

4656
with test_utils.disable_logger():
4757
self.loop.run_until_complete(handshake_fut)
4858

4959
# Close the transport
5060
ssl_proto._app_transport.close()
5161

62+
def test_eof_received_waiter(self):
63+
waiter = asyncio.Future(loop=self.loop)
64+
ssl_proto = self.ssl_protocol(waiter)
65+
self.connection_made(ssl_proto)
66+
ssl_proto.eof_received()
67+
test_utils.run_briefly(self.loop)
68+
self.assertIsInstance(waiter.exception(), ConnectionResetError)
69+
5270

5371
if __name__ == '__main__':
5472
unittest.main()

0 commit comments

Comments
 (0)