mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
asyncio: Remove duplicate bind addresses in create_server.
Patch by Sebastien Bourdeauducq (issue #26338)
This commit is contained in:
parent
f9e1f2bda9
commit
e076ffb068
2 changed files with 18 additions and 12 deletions
|
@ -880,7 +880,10 @@ class BaseEventLoop(events.AbstractEventLoop):
|
||||||
to host and port.
|
to host and port.
|
||||||
|
|
||||||
The host parameter can also be a sequence of strings and in that case
|
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.
|
Return a Server object which can be used to stop the service.
|
||||||
|
|
||||||
|
@ -909,7 +912,7 @@ class BaseEventLoop(events.AbstractEventLoop):
|
||||||
flags=flags)
|
flags=flags)
|
||||||
for host in hosts]
|
for host in hosts]
|
||||||
infos = yield from tasks.gather(*fs, loop=self)
|
infos = yield from tasks.gather(*fs, loop=self)
|
||||||
infos = itertools.chain.from_iterable(infos)
|
infos = set(itertools.chain.from_iterable(infos))
|
||||||
|
|
||||||
completed = False
|
completed = False
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -749,34 +749,37 @@ class EventLoopTestsMixin:
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def getaddrinfo(host, port, *args, **kw):
|
def getaddrinfo(host, port, *args, **kw):
|
||||||
if family == socket.AF_INET:
|
if family == socket.AF_INET:
|
||||||
return [[family, socket.SOCK_STREAM, 6, '', (host, port)]]
|
return [(family, socket.SOCK_STREAM, 6, '', (host, port))]
|
||||||
else:
|
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):
|
def getaddrinfo_task(*args, **kwds):
|
||||||
return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop)
|
return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop)
|
||||||
|
|
||||||
|
unique_hosts = set(hosts)
|
||||||
|
|
||||||
if family == socket.AF_INET:
|
if family == socket.AF_INET:
|
||||||
mock_sock.socket().getsockbyname.side_effect = [(host, 80)
|
mock_sock.socket().getsockbyname.side_effect = [
|
||||||
for host in hosts]
|
(host, 80) for host in unique_hosts]
|
||||||
else:
|
else:
|
||||||
mock_sock.socket().getsockbyname.side_effect = [(host, 80, 0, 0)
|
mock_sock.socket().getsockbyname.side_effect = [
|
||||||
for host in hosts]
|
(host, 80, 0, 0) for host in unique_hosts]
|
||||||
self.loop.getaddrinfo = getaddrinfo_task
|
self.loop.getaddrinfo = getaddrinfo_task
|
||||||
self.loop._start_serving = mock.Mock()
|
self.loop._start_serving = mock.Mock()
|
||||||
self.loop._stop_serving = mock.Mock()
|
self.loop._stop_serving = mock.Mock()
|
||||||
f = self.loop.create_server(lambda: MyProto(self.loop), hosts, 80)
|
f = self.loop.create_server(lambda: MyProto(self.loop), hosts, 80)
|
||||||
server = self.loop.run_until_complete(f)
|
server = self.loop.run_until_complete(f)
|
||||||
self.addCleanup(server.close)
|
self.addCleanup(server.close)
|
||||||
server_hosts = [sock.getsockbyname()[0] for sock in server.sockets]
|
server_hosts = {sock.getsockbyname()[0] for sock in server.sockets}
|
||||||
self.assertEqual(server_hosts, hosts)
|
self.assertEqual(server_hosts, unique_hosts)
|
||||||
|
|
||||||
def test_create_server_multiple_hosts_ipv4(self):
|
def test_create_server_multiple_hosts_ipv4(self):
|
||||||
self.create_server_multiple_hosts(socket.AF_INET,
|
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):
|
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):
|
def test_create_server(self):
|
||||||
proto = MyProto(self.loop)
|
proto = MyProto(self.loop)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue