* 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.
Creating connections
--------------------
-.. 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)
+.. 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)
Create a streaming transport connection to a given Internet *host* and
*port*: socket family :py:data:`~socket.AF_INET` or
* *ssl_handshake_timeout* is (for an SSL connection) the time in seconds
to wait for the SSL handshake to complete before aborting the connection.
+ ``10.0`` seconds if ``None`` (default).
.. versionadded:: 3.7
:ref:`UDP echo server protocol <asyncio-udp-echo-server-protocol>` examples.
-.. coroutinemethod:: AbstractEventLoop.create_unix_connection(protocol_factory, path=None, \*, ssl=None, sock=None, server_hostname=None, ssl_handshake_timeout=10.0)
+.. coroutinemethod:: AbstractEventLoop.create_unix_connection(protocol_factory, path=None, \*, ssl=None, sock=None, server_hostname=None, ssl_handshake_timeout=None)
Create UNIX connection: socket family :py:data:`~socket.AF_UNIX`, socket
type :py:data:`~socket.SOCK_STREAM`. The :py:data:`~socket.AF_UNIX` socket
Creating listening connections
------------------------------
-.. 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)
+.. 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)
Create a TCP server (socket type :data:`~socket.SOCK_STREAM`) bound to
*host* and *port*.
* *ssl_handshake_timeout* is (for an SSL server) the time in seconds to wait
for the SSL handshake to complete before aborting the connection.
+ ``10.0`` seconds if ``None`` (default).
.. versionadded:: 3.7
The *host* parameter can now be a sequence of strings.
-.. coroutinemethod:: AbstractEventLoop.create_unix_server(protocol_factory, path=None, \*, sock=None, backlog=100, ssl=None, ssl_handshake_timeout=10.0)
+.. coroutinemethod:: AbstractEventLoop.create_unix_server(protocol_factory, path=None, \*, sock=None, backlog=100, ssl=None, ssl_handshake_timeout=None)
Similar to :meth:`AbstractEventLoop.create_server`, but specific to the
socket family :py:data:`~socket.AF_UNIX`.
The *path* parameter can now be a :class:`~pathlib.Path` object.
-.. coroutinemethod:: BaseEventLoop.connect_accepted_socket(protocol_factory, sock, \*, ssl=None, ssl_handshake_timeout=10.0)
+.. coroutinemethod:: BaseEventLoop.connect_accepted_socket(protocol_factory, sock, \*, ssl=None, ssl_handshake_timeout=None)
Handle an accepted connection.
* *ssl_handshake_timeout* is (for an SSL connection) the time in seconds to
wait for the SSL handshake to complete before aborting the connection.
+ ``10.0`` seconds if ``None`` (default).
When completed it returns a ``(transport, protocol)`` pair.
import warnings
import weakref
-from . import constants
from . import coroutines
from . import events
from . import futures
self, rawsock, protocol, sslcontext, waiter=None,
*, server_side=False, server_hostname=None,
extra=None, server=None,
- ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
+ ssl_handshake_timeout=None):
"""Create SSL transport."""
raise NotImplementedError
*, ssl=None, family=0,
proto=0, flags=0, sock=None,
local_addr=None, server_hostname=None,
- ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
+ ssl_handshake_timeout=None):
"""Connect to a TCP server.
Create a streaming transport connection to a given Internet host and
'when using ssl without a host')
server_hostname = host
+ if ssl_handshake_timeout is not None and not ssl:
+ raise ValueError(
+ 'ssl_handshake_timeout is only meaningful with ssl')
+
if host is not None or port is not None:
if sock is not None:
raise ValueError(
async def _create_connection_transport(
self, sock, protocol_factory, ssl,
server_hostname, server_side=False,
- ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
+ ssl_handshake_timeout=None):
sock.setblocking(False)
ssl=None,
reuse_address=None,
reuse_port=None,
- ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
+ ssl_handshake_timeout=None):
"""Create a TCP server.
The host parameter can be a string, in that case the TCP server is
"""
if isinstance(ssl, bool):
raise TypeError('ssl argument must be an SSLContext or None')
+
+ if ssl_handshake_timeout is not None and ssl is None:
+ raise ValueError(
+ 'ssl_handshake_timeout is only meaningful with ssl')
+
if host is not None or port is not None:
if sock is not None:
raise ValueError(
async def connect_accepted_socket(
self, protocol_factory, sock,
*, ssl=None,
- ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
+ ssl_handshake_timeout=None):
"""Handle an accepted connection.
This is used by servers that accept connections outside of
if sock.type != socket.SOCK_STREAM:
raise ValueError(f'A Stream Socket was expected, got {sock!r}')
+ if ssl_handshake_timeout is not None and not ssl:
+ raise ValueError(
+ 'ssl_handshake_timeout is only meaningful with ssl')
+
transport, protocol = await self._create_connection_transport(
sock, protocol_factory, ssl, '', server_side=True,
ssl_handshake_timeout=ssl_handshake_timeout)
import sys
import threading
-from . import constants
from . import format_helpers
*, ssl=None, family=0, proto=0,
flags=0, sock=None, local_addr=None,
server_hostname=None,
- ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
+ ssl_handshake_timeout=None):
raise NotImplementedError
async def create_server(
*, family=socket.AF_UNSPEC,
flags=socket.AI_PASSIVE, sock=None, backlog=100,
ssl=None, reuse_address=None, reuse_port=None,
- ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
+ ssl_handshake_timeout=None):
"""A coroutine which creates a TCP server bound to host and port.
The return value is a Server object which can be used to stop
self, protocol_factory, path=None, *,
ssl=None, sock=None,
server_hostname=None,
- ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
+ ssl_handshake_timeout=None):
raise NotImplementedError
async def create_unix_server(
self, protocol_factory, path=None, *,
sock=None, backlog=100, ssl=None,
- ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
+ ssl_handshake_timeout=None):
"""A coroutine which creates a UNIX Domain Socket server.
The return value is a Server object, which can be used to stop
self, rawsock, protocol, sslcontext, waiter=None,
*, server_side=False, server_hostname=None,
extra=None, server=None,
- ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
+ ssl_handshake_timeout=None):
ssl_protocol = sslproto.SSLProtocol(
self, protocol, sslcontext, waiter,
server_side, server_hostname,
def _start_serving(self, protocol_factory, sock,
sslcontext=None, server=None, backlog=100,
- ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
+ ssl_handshake_timeout=None):
def loop(f=None):
try:
def __init__(self, loop, app_protocol, sslcontext, waiter,
server_side=False, server_hostname=None,
call_connection_made=True,
- ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
+ ssl_handshake_timeout=None):
if ssl is None:
raise RuntimeError('stdlib ssl module not available')
+ if ssl_handshake_timeout is None:
+ ssl_handshake_timeout = constants.SSL_HANDSHAKE_TIMEOUT
+ elif ssl_handshake_timeout <= 0:
+ raise ValueError(
+ f"ssl_handshake_timeout should be a positive number, "
+ f"got {ssl_handshake_timeout}")
+
if not sslcontext:
sslcontext = _create_transport_context(
server_side, server_hostname)
self, protocol_factory, path=None, *,
ssl=None, sock=None,
server_hostname=None,
- ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
+ ssl_handshake_timeout=None):
assert server_hostname is None or isinstance(server_hostname, str)
if ssl:
if server_hostname is None:
else:
if server_hostname is not None:
raise ValueError('server_hostname is only meaningful with ssl')
+ if ssl_handshake_timeout is not None:
+ raise ValueError(
+ 'ssl_handshake_timeout is only meaningful with ssl')
if path is not None:
if sock is not None:
async def create_unix_server(
self, protocol_factory, path=None, *,
sock=None, backlog=100, ssl=None,
- ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT):
+ ssl_handshake_timeout=None):
if isinstance(ssl, bool):
raise TypeError('ssl argument must be an SSLContext or None')
+ if ssl_handshake_timeout is not None and not ssl:
+ raise ValueError(
+ 'ssl_handshake_timeout is only meaningful with ssl')
+
if path is not None:
if sock is not None:
raise ValueError(
'A Stream Socket was expected'):
self.loop.run_until_complete(coro)
+ def test_create_server_ssl_timeout_for_plain_socket(self):
+ coro = self.loop.create_server(
+ MyProto, 'example.com', 80, ssl_handshake_timeout=1)
+ with self.assertRaisesRegex(
+ ValueError,
+ 'ssl_handshake_timeout is only meaningful with ssl'):
+ self.loop.run_until_complete(coro)
+
@unittest.skipUnless(hasattr(socket, 'SOCK_NONBLOCK'),
'no socket.SOCK_NONBLOCK (linux only)')
def test_create_server_stream_bittype(self):
self.addCleanup(sock.close)
self.assertRaises(ValueError, self.loop.run_until_complete, coro)
+ def test_create_connection_ssl_timeout_for_plain_socket(self):
+ coro = self.loop.create_connection(
+ MyProto, 'example.com', 80, ssl_handshake_timeout=1)
+ with self.assertRaisesRegex(
+ ValueError,
+ 'ssl_handshake_timeout is only meaningful with ssl'):
+ self.loop.run_until_complete(coro)
+
def test_create_server_empty_host(self):
# if host is empty string use None instead
host = object()
self.test_connect_accepted_socket(server_context, client_context)
+ def test_connect_accepted_socket_ssl_timeout_for_plain_socket(self):
+ sock = socket.socket()
+ self.addCleanup(sock.close)
+ coro = self.loop.connect_accepted_socket(
+ MyProto, sock, ssl_handshake_timeout=1)
+ with self.assertRaisesRegex(
+ ValueError,
+ 'ssl_handshake_timeout is only meaningful with ssl'):
+ self.loop.run_until_complete(coro)
+
@mock.patch('asyncio.base_events.socket')
def create_server_multiple_hosts(self, family, hosts, mock_sock):
@asyncio.coroutine
self.loop.run_until_complete(tasks.sleep(0.2, loop=self.loop))
self.assertTrue(transport.abort.called)
+ def test_handshake_timeout_zero(self):
+ sslcontext = test_utils.dummy_ssl_context()
+ app_proto = mock.Mock()
+ waiter = mock.Mock()
+ with self.assertRaisesRegex(ValueError, 'a positive number'):
+ sslproto.SSLProtocol(self.loop, app_proto, sslcontext, waiter,
+ ssl_handshake_timeout=0)
+
+ def test_handshake_timeout_negative(self):
+ sslcontext = test_utils.dummy_ssl_context()
+ app_proto = mock.Mock()
+ waiter = mock.Mock()
+ with self.assertRaisesRegex(ValueError, 'a positive number'):
+ sslproto.SSLProtocol(self.loop, app_proto, sslcontext, waiter,
+ ssl_handshake_timeout=-10)
+
def test_eof_received_waiter(self):
waiter = asyncio.Future(loop=self.loop)
ssl_proto = self.ssl_protocol(waiter)
finally:
os.unlink(fn)
+ def test_create_unix_server_ssl_timeout_with_plain_sock(self):
+ coro = self.loop.create_unix_server(lambda: None, path='spam',
+ ssl_handshake_timeout=1)
+ with self.assertRaisesRegex(
+ ValueError,
+ 'ssl_handshake_timeout is only meaningful with ssl'):
+ self.loop.run_until_complete(coro)
+
def test_create_unix_connection_path_inetsock(self):
sock = socket.socket()
with sock:
self.loop.run_until_complete(coro)
+ def test_create_unix_connection_ssl_timeout_with_plain_sock(self):
+ coro = self.loop.create_unix_connection(lambda: None, path='spam',
+ ssl_handshake_timeout=1)
+ with self.assertRaisesRegex(
+ ValueError,
+ 'ssl_handshake_timeout is only meaningful with ssl'):
+ self.loop.run_until_complete(coro)
+
+
class UnixReadPipeTransportTests(test_utils.TestCase):