diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2015-09-21 16:33:43 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2015-09-21 16:33:43 (GMT) |
commit | 5e4a7d8dc7781a4c0dfacecdc4db0eb34beb1391 (patch) | |
tree | 09d044b9d851a9869cf1b2fba06a6c42565f5830 /Lib/asyncio | |
parent | f7dc7fb74d7c44a60f36a69437125f5ff70e32e5 (diff) | |
download | cpython-5e4a7d8dc7781a4c0dfacecdc4db0eb34beb1391.zip cpython-5e4a7d8dc7781a4c0dfacecdc4db0eb34beb1391.tar.gz cpython-5e4a7d8dc7781a4c0dfacecdc4db0eb34beb1391.tar.bz2 |
Issue #23630, asyncio: host parameter of loop.create_server() can now be a
sequence of strings. Patch written by Yann Sionneau.
Diffstat (limited to 'Lib/asyncio')
-rw-r--r-- | Lib/asyncio/base_events.py | 35 | ||||
-rw-r--r-- | Lib/asyncio/events.py | 3 |
2 files changed, 30 insertions, 8 deletions
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index c205445..a50e005 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -18,6 +18,7 @@ import collections import concurrent.futures import heapq import inspect +import itertools import logging import os import socket @@ -787,6 +788,15 @@ class BaseEventLoop(events.AbstractEventLoop): return transport, protocol @coroutine + def _create_server_getaddrinfo(self, host, port, family, flags): + infos = yield from self.getaddrinfo(host, port, family=family, + type=socket.SOCK_STREAM, + flags=flags) + if not infos: + raise OSError('getaddrinfo({!r}) returned empty list'.format(host)) + return infos + + @coroutine def create_server(self, protocol_factory, host=None, port=None, *, family=socket.AF_UNSPEC, @@ -795,7 +805,13 @@ class BaseEventLoop(events.AbstractEventLoop): backlog=100, ssl=None, reuse_address=None): - """Create a TCP server bound to host and port. + """Create a TCP server. + + The host parameter can be a string, in that case the TCP server is bound + to host and port. + + The host parameter can also be a sequence of strings and in that case + the TCP server is bound to all hosts of the sequence. Return a Server object which can be used to stop the service. @@ -813,13 +829,18 @@ class BaseEventLoop(events.AbstractEventLoop): reuse_address = os.name == 'posix' and sys.platform != 'cygwin' sockets = [] if host == '': - host = None + hosts = [None] + elif (isinstance(host, str) or + not isinstance(host, collections.Iterable)): + hosts = [host] + else: + hosts = host - infos = yield from self.getaddrinfo( - host, port, family=family, - type=socket.SOCK_STREAM, proto=0, flags=flags) - if not infos: - raise OSError('getaddrinfo() returned empty list') + fs = [self._create_server_getaddrinfo(host, port, family=family, + flags=flags) + for host in hosts] + infos = yield from tasks.gather(*fs, loop=self) + infos = itertools.chain.from_iterable(infos) completed = False try: diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index d5f0d45..1e42ddd 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -305,7 +305,8 @@ class AbstractEventLoop: If host is an empty string or None all interfaces are assumed and a list of multiple sockets will be returned (most likely - one for IPv4 and another one for IPv6). + one for IPv4 and another one for IPv6). The host parameter can also be a + sequence (e.g. list) of hosts to bind to. family can be set to either AF_INET or AF_INET6 to force the socket to use IPv4 or IPv6. If not set it will be determined |