From 354c6eab66eb3aadfa558400e9de1f4cd5c64378 Mon Sep 17 00:00:00 2001 From: Rongrong Date: Thu, 15 Aug 2024 01:58:04 +0800 Subject: [PATCH] fix(web.req): regression: IPV6_PRIOR|R_PROXY causes AssertionError Happy eyeballs, available since aiohttp 3.10, cause AssertionError when setting both proxy and socket family. Make them mutually exclusive (proxy takes precedence) since it is always meaningless to set them together. TODO: Is it time to deprecate IPV6_PRIOR and completely rely on Happy Eyeballs (RFC 8305)? Fixes the regression introduced in 88fdb2ce191e395a30e03ec00c10fae225be256d. Signed-off-by: Rongrong --- src/web/req.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/web/req.py b/src/web/req.py index 3676a64122..ddadd29e08 100644 --- a/src/web/req.py +++ b/src/web/req.py @@ -155,16 +155,22 @@ async def _request( host = urlparse(url).hostname semaphore_to_use = locks.hostname_semaphore(host, parse=False) if semaphore in (None, True) \ else (semaphore or nullcontext()) - v6_rr_set = None - try: - v6_rr_set = (await asyncio.wait_for(resolve(host, 'AAAA', lifetime=1), 1.1)).rrset if env.IPV6_PRIOR else None - except DNSException: - pass - except asyncio.TimeoutError: - pass - except Exception as e: - logger.debug(f'Error occurred when querying {url} AAAA:', exc_info=e) - socket_family = AF_INET6 if v6_rr_set else 0 + + # Happy Eyeballs, available since aiohttp 3.10, cause AssertionError when setting both proxy and socket family. + # Make them mutually exclusive (proxy takes precedence) since it is always meaningless to set them together. + # TODO: Is it time to deprecate IPV6_PRIOR and completely rely on Happy Eyeballs (RFC 8305)? + use_proxy: bool = PROXY and proxy_filter(host, parse=False) + socket_family = 0 + if env.IPV6_PRIOR and not use_proxy: + try: + if ( + await asyncio.wait_for(resolve(host, 'AAAA', lifetime=1), 1.1) + ).rrset: + socket_family = AF_INET6 + except (DNSException, asyncio.TimeoutError): + pass + except Exception as e: + logger.debug(f'Error occurred when querying {url} AAAA:', exc_info=e) _headers = HEADER_TEMPLATE.copy() if headers: @@ -215,7 +221,7 @@ async def _fetch(): socket_family = AF_INET proxy_connector = ( ProxyConnector.from_url(PROXY, family=socket_family, ssl=__SSL_CONTEXT) - if (PROXY and proxy_filter(host, parse=False)) + if use_proxy else aiohttp.TCPConnector(family=socket_family, ssl=__SSL_CONTEXT) )