mirror of https://github.com/python/cpython
asyncio: Remove duplicate bind addresses in create_server.
Patch by Sebastien Bourdeauducq (issue #26338)
This commit is contained in:
parent
f9e1f2bda9
commit
e076ffb068
|
@ -880,7 +880,10 @@ class BaseEventLoop(events.AbstractEventLoop):
|
|||
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.
|
||||
the TCP server is bound to all hosts of the sequence. If a host
|
||||
appears multiple times (possibly indirectly e.g. when hostnames
|
||||
resolve to the same IP address), the server is only bound once to that
|
||||
host.
|
||||
|
||||
Return a Server object which can be used to stop the service.
|
||||
|
||||
|
@ -909,7 +912,7 @@ class BaseEventLoop(events.AbstractEventLoop):
|
|||
flags=flags)
|
||||
for host in hosts]
|
||||
infos = yield from tasks.gather(*fs, loop=self)
|
||||
infos = itertools.chain.from_iterable(infos)
|
||||
infos = set(itertools.chain.from_iterable(infos))
|
||||
|
||||
completed = False
|
||||
try:
|
||||
|
|
|
@ -749,34 +749,37 @@ class EventLoopTestsMixin:
|
|||
@asyncio.coroutine
|
||||
def getaddrinfo(host, port, *args, **kw):
|
||||
if family == socket.AF_INET:
|
||||
return [[family, socket.SOCK_STREAM, 6, '', (host, port)]]
|
||||
return [(family, socket.SOCK_STREAM, 6, '', (host, port))]
|
||||
else:
|
||||
return [[family, socket.SOCK_STREAM, 6, '', (host, port, 0, 0)]]
|
||||
return [(family, socket.SOCK_STREAM, 6, '', (host, port, 0, 0))]
|
||||
|
||||
def getaddrinfo_task(*args, **kwds):
|
||||
return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop)
|
||||
|
||||
unique_hosts = set(hosts)
|
||||
|
||||
if family == socket.AF_INET:
|
||||
mock_sock.socket().getsockbyname.side_effect = [(host, 80)
|
||||
for host in hosts]
|
||||
mock_sock.socket().getsockbyname.side_effect = [
|
||||
(host, 80) for host in unique_hosts]
|
||||
else:
|
||||
mock_sock.socket().getsockbyname.side_effect = [(host, 80, 0, 0)
|
||||
for host in hosts]
|
||||
mock_sock.socket().getsockbyname.side_effect = [
|
||||
(host, 80, 0, 0) for host in unique_hosts]
|
||||
self.loop.getaddrinfo = getaddrinfo_task
|
||||
self.loop._start_serving = mock.Mock()
|
||||
self.loop._stop_serving = mock.Mock()
|
||||
f = self.loop.create_server(lambda: MyProto(self.loop), hosts, 80)
|
||||
server = self.loop.run_until_complete(f)
|
||||
self.addCleanup(server.close)
|
||||
server_hosts = [sock.getsockbyname()[0] for sock in server.sockets]
|
||||
self.assertEqual(server_hosts, hosts)
|
||||
server_hosts = {sock.getsockbyname()[0] for sock in server.sockets}
|
||||
self.assertEqual(server_hosts, unique_hosts)
|
||||
|
||||
def test_create_server_multiple_hosts_ipv4(self):
|
||||
self.create_server_multiple_hosts(socket.AF_INET,
|
||||
['1.2.3.4', '5.6.7.8'])
|
||||
['1.2.3.4', '5.6.7.8', '1.2.3.4'])
|
||||
|
||||
def test_create_server_multiple_hosts_ipv6(self):
|
||||
self.create_server_multiple_hosts(socket.AF_INET6, ['::1', '::2'])
|
||||
self.create_server_multiple_hosts(socket.AF_INET6,
|
||||
['::1', '::2', '::1'])
|
||||
|
||||
def test_create_server(self):
|
||||
proto = MyProto(self.loop)
|
||||
|
|
Loading…
Reference in New Issue