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

Skip to content

Commit 51eb1c6

Browse files
authored
bpo-29970: Make ssh_handshake_timeout None by default (#4939)
* Make ssh_handshake_timeout None by default. * Raise ValueError if ssl_handshake_timeout is used without ssl. * Raise ValueError if ssl_handshake_timeout is not positive.
1 parent a7a751d commit 51eb1c6

10 files changed

Lines changed: 108 additions & 21 deletions

File tree

Doc/library/asyncio-eventloop.rst

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ Tasks
261261
Creating connections
262262
--------------------
263263

264-
.. coroutinemethod:: AbstractEventLoop.create_connection(protocol_factory, host=None, port=None, \*, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None, ssl_handshake_timeout=10.0)
264+
.. coroutinemethod:: AbstractEventLoop.create_connection(protocol_factory, host=None, port=None, \*, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None, ssl_handshake_timeout=None)
265265

266266
Create a streaming transport connection to a given Internet *host* and
267267
*port*: socket family :py:data:`~socket.AF_INET` or
@@ -327,6 +327,7 @@ Creating connections
327327

328328
* *ssl_handshake_timeout* is (for an SSL connection) the time in seconds
329329
to wait for the SSL handshake to complete before aborting the connection.
330+
``10.0`` seconds if ``None`` (default).
330331

331332
.. versionadded:: 3.7
332333

@@ -393,7 +394,7 @@ Creating connections
393394
:ref:`UDP echo server protocol <asyncio-udp-echo-server-protocol>` examples.
394395

395396

396-
.. coroutinemethod:: AbstractEventLoop.create_unix_connection(protocol_factory, path=None, \*, ssl=None, sock=None, server_hostname=None, ssl_handshake_timeout=10.0)
397+
.. coroutinemethod:: AbstractEventLoop.create_unix_connection(protocol_factory, path=None, \*, ssl=None, sock=None, server_hostname=None, ssl_handshake_timeout=None)
397398

398399
Create UNIX connection: socket family :py:data:`~socket.AF_UNIX`, socket
399400
type :py:data:`~socket.SOCK_STREAM`. The :py:data:`~socket.AF_UNIX` socket
@@ -423,7 +424,7 @@ Creating connections
423424
Creating listening connections
424425
------------------------------
425426

426-
.. coroutinemethod:: AbstractEventLoop.create_server(protocol_factory, host=None, port=None, \*, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None, ssl_handshake_timeout=10.0)
427+
.. coroutinemethod:: AbstractEventLoop.create_server(protocol_factory, host=None, port=None, \*, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None, ssl_handshake_timeout=None)
427428

428429
Create a TCP server (socket type :data:`~socket.SOCK_STREAM`) bound to
429430
*host* and *port*.
@@ -469,6 +470,7 @@ Creating listening connections
469470

470471
* *ssl_handshake_timeout* is (for an SSL server) the time in seconds to wait
471472
for the SSL handshake to complete before aborting the connection.
473+
``10.0`` seconds if ``None`` (default).
472474

473475
.. versionadded:: 3.7
474476

@@ -488,7 +490,7 @@ Creating listening connections
488490
The *host* parameter can now be a sequence of strings.
489491

490492

491-
.. coroutinemethod:: AbstractEventLoop.create_unix_server(protocol_factory, path=None, \*, sock=None, backlog=100, ssl=None, ssl_handshake_timeout=10.0)
493+
.. coroutinemethod:: AbstractEventLoop.create_unix_server(protocol_factory, path=None, \*, sock=None, backlog=100, ssl=None, ssl_handshake_timeout=None)
492494

493495
Similar to :meth:`AbstractEventLoop.create_server`, but specific to the
494496
socket family :py:data:`~socket.AF_UNIX`.
@@ -507,7 +509,7 @@ Creating listening connections
507509

508510
The *path* parameter can now be a :class:`~pathlib.Path` object.
509511

510-
.. coroutinemethod:: BaseEventLoop.connect_accepted_socket(protocol_factory, sock, \*, ssl=None, ssl_handshake_timeout=10.0)
512+
.. coroutinemethod:: BaseEventLoop.connect_accepted_socket(protocol_factory, sock, \*, ssl=None, ssl_handshake_timeout=None)
511513

512514
Handle an accepted connection.
513515

@@ -524,6 +526,7 @@ Creating listening connections
524526

525527
* *ssl_handshake_timeout* is (for an SSL connection) the time in seconds to
526528
wait for the SSL handshake to complete before aborting the connection.
529+
``10.0`` seconds if ``None`` (default).
527530

528531
When completed it returns a ``(transport, protocol)`` pair.
529532

Lib/asyncio/base_events.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import warnings
3030
import weakref
3131

32-
from . import constants
3332
from . import coroutines
3433
from . import events
3534
from . import futures
@@ -280,7 +279,7 @@ def _make_ssl_transport(
280279
self, rawsock, protocol, sslcontext, waiter=None,
281280
*, server_side=False, server_hostname=None,
282281
extra=None, server=None,
283-
ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
282+
ssl_handshake_timeout=None):
284283
"""Create SSL transport."""
285284
raise NotImplementedError
286285

@@ -643,7 +642,7 @@ async def create_connection(
643642
*, ssl=None, family=0,
644643
proto=0, flags=0, sock=None,
645644
local_addr=None, server_hostname=None,
646-
ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
645+
ssl_handshake_timeout=None):
647646
"""Connect to a TCP server.
648647
649648
Create a streaming transport connection to a given Internet host and
@@ -674,6 +673,10 @@ async def create_connection(
674673
'when using ssl without a host')
675674
server_hostname = host
676675

676+
if ssl_handshake_timeout is not None and not ssl:
677+
raise ValueError(
678+
'ssl_handshake_timeout is only meaningful with ssl')
679+
677680
if host is not None or port is not None:
678681
if sock is not None:
679682
raise ValueError(
@@ -769,7 +772,7 @@ async def create_connection(
769772
async def _create_connection_transport(
770773
self, sock, protocol_factory, ssl,
771774
server_hostname, server_side=False,
772-
ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
775+
ssl_handshake_timeout=None):
773776

774777
sock.setblocking(False)
775778

@@ -948,7 +951,7 @@ async def create_server(
948951
ssl=None,
949952
reuse_address=None,
950953
reuse_port=None,
951-
ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
954+
ssl_handshake_timeout=None):
952955
"""Create a TCP server.
953956
954957
The host parameter can be a string, in that case the TCP server is
@@ -966,6 +969,11 @@ async def create_server(
966969
"""
967970
if isinstance(ssl, bool):
968971
raise TypeError('ssl argument must be an SSLContext or None')
972+
973+
if ssl_handshake_timeout is not None and ssl is None:
974+
raise ValueError(
975+
'ssl_handshake_timeout is only meaningful with ssl')
976+
969977
if host is not None or port is not None:
970978
if sock is not None:
971979
raise ValueError(
@@ -1046,7 +1054,7 @@ async def create_server(
10461054
async def connect_accepted_socket(
10471055
self, protocol_factory, sock,
10481056
*, ssl=None,
1049-
ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
1057+
ssl_handshake_timeout=None):
10501058
"""Handle an accepted connection.
10511059
10521060
This is used by servers that accept connections outside of
@@ -1058,6 +1066,10 @@ async def connect_accepted_socket(
10581066
if sock.type != socket.SOCK_STREAM:
10591067
raise ValueError(f'A Stream Socket was expected, got {sock!r}')
10601068

1069+
if ssl_handshake_timeout is not None and not ssl:
1070+
raise ValueError(
1071+
'ssl_handshake_timeout is only meaningful with ssl')
1072+
10611073
transport, protocol = await self._create_connection_transport(
10621074
sock, protocol_factory, ssl, '', server_side=True,
10631075
ssl_handshake_timeout=ssl_handshake_timeout)

Lib/asyncio/events.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import sys
1818
import threading
1919

20-
from . import constants
2120
from . import format_helpers
2221

2322

@@ -255,15 +254,15 @@ async def create_connection(
255254
*, ssl=None, family=0, proto=0,
256255
flags=0, sock=None, local_addr=None,
257256
server_hostname=None,
258-
ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
257+
ssl_handshake_timeout=None):
259258
raise NotImplementedError
260259

261260
async def create_server(
262261
self, protocol_factory, host=None, port=None,
263262
*, family=socket.AF_UNSPEC,
264263
flags=socket.AI_PASSIVE, sock=None, backlog=100,
265264
ssl=None, reuse_address=None, reuse_port=None,
266-
ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
265+
ssl_handshake_timeout=None):
267266
"""A coroutine which creates a TCP server bound to host and port.
268267
269268
The return value is a Server object which can be used to stop
@@ -310,13 +309,13 @@ async def create_unix_connection(
310309
self, protocol_factory, path=None, *,
311310
ssl=None, sock=None,
312311
server_hostname=None,
313-
ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
312+
ssl_handshake_timeout=None):
314313
raise NotImplementedError
315314

316315
async def create_unix_server(
317316
self, protocol_factory, path=None, *,
318317
sock=None, backlog=100, ssl=None,
319-
ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
318+
ssl_handshake_timeout=None):
320319
"""A coroutine which creates a UNIX Domain Socket server.
321320
322321
The return value is a Server object, which can be used to stop

Lib/asyncio/proactor_events.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ def _make_ssl_transport(
393393
self, rawsock, protocol, sslcontext, waiter=None,
394394
*, server_side=False, server_hostname=None,
395395
extra=None, server=None,
396-
ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
396+
ssl_handshake_timeout=None):
397397
ssl_protocol = sslproto.SSLProtocol(
398398
self, protocol, sslcontext, waiter,
399399
server_side, server_hostname,
@@ -491,7 +491,7 @@ def _write_to_self(self):
491491

492492
def _start_serving(self, protocol_factory, sock,
493493
sslcontext=None, server=None, backlog=100,
494-
ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
494+
ssl_handshake_timeout=None):
495495

496496
def loop(f=None):
497497
try:

Lib/asyncio/sslproto.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,10 +402,17 @@ class SSLProtocol(protocols.Protocol):
402402
def __init__(self, loop, app_protocol, sslcontext, waiter,
403403
server_side=False, server_hostname=None,
404404
call_connection_made=True,
405-
ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
405+
ssl_handshake_timeout=None):
406406
if ssl is None:
407407
raise RuntimeError('stdlib ssl module not available')
408408

409+
if ssl_handshake_timeout is None:
410+
ssl_handshake_timeout = constants.SSL_HANDSHAKE_TIMEOUT
411+
elif ssl_handshake_timeout <= 0:
412+
raise ValueError(
413+
f"ssl_handshake_timeout should be a positive number, "
414+
f"got {ssl_handshake_timeout}")
415+
409416
if not sslcontext:
410417
sslcontext = _create_transport_context(
411418
server_side, server_hostname)

Lib/asyncio/unix_events.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ async def create_unix_connection(
196196
self, protocol_factory, path=None, *,
197197
ssl=None, sock=None,
198198
server_hostname=None,
199-
ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
199+
ssl_handshake_timeout=None):
200200
assert server_hostname is None or isinstance(server_hostname, str)
201201
if ssl:
202202
if server_hostname is None:
@@ -205,6 +205,9 @@ async def create_unix_connection(
205205
else:
206206
if server_hostname is not None:
207207
raise ValueError('server_hostname is only meaningful with ssl')
208+
if ssl_handshake_timeout is not None:
209+
raise ValueError(
210+
'ssl_handshake_timeout is only meaningful with ssl')
208211

209212
if path is not None:
210213
if sock is not None:
@@ -237,10 +240,14 @@ async def create_unix_connection(
237240
async def create_unix_server(
238241
self, protocol_factory, path=None, *,
239242
sock=None, backlog=100, ssl=None,
240-
ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
243+
ssl_handshake_timeout=None):
241244
if isinstance(ssl, bool):
242245
raise TypeError('ssl argument must be an SSLContext or None')
243246

247+
if ssl_handshake_timeout is not None and not ssl:
248+
raise ValueError(
249+
'ssl_handshake_timeout is only meaningful with ssl')
250+
244251
if path is not None:
245252
if sock is not None:
246253
raise ValueError(

Lib/test/test_asyncio/test_base_events.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,14 @@ def test_create_server_wrong_sock(self):
10531053
'A Stream Socket was expected'):
10541054
self.loop.run_until_complete(coro)
10551055

1056+
def test_create_server_ssl_timeout_for_plain_socket(self):
1057+
coro = self.loop.create_server(
1058+
MyProto, 'example.com', 80, ssl_handshake_timeout=1)
1059+
with self.assertRaisesRegex(
1060+
ValueError,
1061+
'ssl_handshake_timeout is only meaningful with ssl'):
1062+
self.loop.run_until_complete(coro)
1063+
10561064
@unittest.skipUnless(hasattr(socket, 'SOCK_NONBLOCK'),
10571065
'no socket.SOCK_NONBLOCK (linux only)')
10581066
def test_create_server_stream_bittype(self):
@@ -1362,6 +1370,14 @@ def test_create_connection_ssl_server_hostname_errors(self):
13621370
self.addCleanup(sock.close)
13631371
self.assertRaises(ValueError, self.loop.run_until_complete, coro)
13641372

1373+
def test_create_connection_ssl_timeout_for_plain_socket(self):
1374+
coro = self.loop.create_connection(
1375+
MyProto, 'example.com', 80, ssl_handshake_timeout=1)
1376+
with self.assertRaisesRegex(
1377+
ValueError,
1378+
'ssl_handshake_timeout is only meaningful with ssl'):
1379+
self.loop.run_until_complete(coro)
1380+
13651381
def test_create_server_empty_host(self):
13661382
# if host is empty string use None instead
13671383
host = object()

Lib/test/test_asyncio/test_events.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,16 @@ def test_ssl_connect_accepted_socket(self):
852852

853853
self.test_connect_accepted_socket(server_context, client_context)
854854

855+
def test_connect_accepted_socket_ssl_timeout_for_plain_socket(self):
856+
sock = socket.socket()
857+
self.addCleanup(sock.close)
858+
coro = self.loop.connect_accepted_socket(
859+
MyProto, sock, ssl_handshake_timeout=1)
860+
with self.assertRaisesRegex(
861+
ValueError,
862+
'ssl_handshake_timeout is only meaningful with ssl'):
863+
self.loop.run_until_complete(coro)
864+
855865
@mock.patch('asyncio.base_events.socket')
856866
def create_server_multiple_hosts(self, family, hosts, mock_sock):
857867
@asyncio.coroutine

Lib/test/test_asyncio/test_sslproto.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,22 @@ def test_handshake_timeout(self):
7575
self.loop.run_until_complete(tasks.sleep(0.2, loop=self.loop))
7676
self.assertTrue(transport.abort.called)
7777

78+
def test_handshake_timeout_zero(self):
79+
sslcontext = test_utils.dummy_ssl_context()
80+
app_proto = mock.Mock()
81+
waiter = mock.Mock()
82+
with self.assertRaisesRegex(ValueError, 'a positive number'):
83+
sslproto.SSLProtocol(self.loop, app_proto, sslcontext, waiter,
84+
ssl_handshake_timeout=0)
85+
86+
def test_handshake_timeout_negative(self):
87+
sslcontext = test_utils.dummy_ssl_context()
88+
app_proto = mock.Mock()
89+
waiter = mock.Mock()
90+
with self.assertRaisesRegex(ValueError, 'a positive number'):
91+
sslproto.SSLProtocol(self.loop, app_proto, sslcontext, waiter,
92+
ssl_handshake_timeout=-10)
93+
7894
def test_eof_received_waiter(self):
7995
waiter = asyncio.Future(loop=self.loop)
8096
ssl_proto = self.ssl_protocol(waiter)

Lib/test/test_asyncio/test_unix_events.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,14 @@ def test_create_unix_server_path_stream_bittype(self):
327327
finally:
328328
os.unlink(fn)
329329

330+
def test_create_unix_server_ssl_timeout_with_plain_sock(self):
331+
coro = self.loop.create_unix_server(lambda: None, path='spam',
332+
ssl_handshake_timeout=1)
333+
with self.assertRaisesRegex(
334+
ValueError,
335+
'ssl_handshake_timeout is only meaningful with ssl'):
336+
self.loop.run_until_complete(coro)
337+
330338
def test_create_unix_connection_path_inetsock(self):
331339
sock = socket.socket()
332340
with sock:
@@ -383,6 +391,15 @@ def test_create_unix_connection_ssl_noserverhost(self):
383391

384392
self.loop.run_until_complete(coro)
385393

394+
def test_create_unix_connection_ssl_timeout_with_plain_sock(self):
395+
coro = self.loop.create_unix_connection(lambda: None, path='spam',
396+
ssl_handshake_timeout=1)
397+
with self.assertRaisesRegex(
398+
ValueError,
399+
'ssl_handshake_timeout is only meaningful with ssl'):
400+
self.loop.run_until_complete(coro)
401+
402+
386403

387404
class UnixReadPipeTransportTests(test_utils.TestCase):
388405

0 commit comments

Comments
 (0)