From a6056fb388c886970a9fbe4a5f4da7c5a1833fa9 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Sun, 14 Nov 2021 14:37:53 +0200 Subject: [PATCH] Restored ability to connect IPv6-only host. (#6309) --- CHANGES/6195.bugfix | 1 + aiohttp/resolver.py | 26 ++++++++++++++++---------- tests/test_resolver.py | 2 +- 3 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 CHANGES/6195.bugfix diff --git a/CHANGES/6195.bugfix b/CHANGES/6195.bugfix new file mode 100644 index 0000000000..dec44169e2 --- /dev/null +++ b/CHANGES/6195.bugfix @@ -0,0 +1 @@ +Restored ability to connect IPv6-only host. diff --git a/aiohttp/resolver.py b/aiohttp/resolver.py index 886b605b0b..531ce93fcc 100644 --- a/aiohttp/resolver.py +++ b/aiohttp/resolver.py @@ -41,17 +41,23 @@ async def resolve( hosts = [] for family, _, proto, _, address in infos: if family == socket.AF_INET6: - if not (socket.has_ipv6 and address[3]): # type: ignore[misc] + if len(address) < 3: + # IPv6 is not supported by Python build, + # or IPv6 is not enabled in the host continue - # This is essential for link-local IPv6 addresses. - # LL IPv6 is a VERY rare case. Strictly speaking, we should use - # getnameinfo() unconditionally, but performance makes sense. - host, _port = socket.getnameinfo( - address, socket.NI_NUMERICHOST | socket.NI_NUMERICSERV - ) - port = int(_port) - else: - host, port = address[:2] + if address[3]: # type: ignore[misc] + # This is essential for link-local IPv6 addresses. + # LL IPv6 is a VERY rare case. Strictly speaking, we should use + # getnameinfo() unconditionally, but performance makes sense. + host, _port = socket.getnameinfo( + address, socket.NI_NUMERICHOST | socket.NI_NUMERICSERV + ) + port = int(_port) + else: + host, port = address[:2] + else: # IPv4 + assert family == socket.AF_INET + host, port = address # type: ignore[misc] hosts.append( { "hostname": hostname, diff --git a/tests/test_resolver.py b/tests/test_resolver.py index 8aac95c731..6140e385cc 100644 --- a/tests/test_resolver.py +++ b/tests/test_resolver.py @@ -40,7 +40,7 @@ async def fake(*args, **kwargs): if not hosts: raise socket.gaierror - return list((None, None, None, None, [h, 0]) for h in hosts) + return [(socket.AF_INET, None, socket.SOCK_STREAM, None, [h, 0]) for h in hosts] return fake