11from __future__ import annotations
22
3+ import urllib .request
34from collections import deque
45from test .unit .test_proxies import (
56 DbRequestFlags ,
1516
1617import aiohttp
1718import pytest
19+ from aiohttp import BasicAuth
20+ from aiohttp .helpers import proxies_from_env
21+ from yarl import URL
1822
1923from snowflake .connector .aio import connect as async_connect
2024
@@ -355,6 +359,57 @@ async def test_no_proxy_basic_param_proxy_bypass_backend(
355359 assert flags .proxy_saw_storage is True
356360
357361
362+ @pytest .fixture
363+ def fix_aiohttp_proxy_bypass (monkeypatch ):
364+ """Fix aiohttp's proxy bypass to check host:port instead of just host.
365+
366+ This fixture implements a two-step fix:
367+ 1. Override get_env_proxy_for_url to use host_port_subcomponent for proxy_bypass
368+ 2. Override urllib.request._splitport to return (host:port, port) for proper matching
369+ """
370+
371+ # Step 1: Override get_env_proxy_for_url to pass host:port to proxy_bypass
372+ def get_env_proxy_for_url_with_port (url : URL ) -> tuple [URL , BasicAuth | None ]:
373+ """Get a permitted proxy for the given URL from the env, checking host:port."""
374+ from urllib .request import proxy_bypass
375+
376+ # Check proxy bypass using host:port combination
377+ if url .host is not None :
378+ # Use host_port_subcomponent which includes port
379+ host_port = f"{ url .host } :{ url .port } " if url .port else url .host
380+ if proxy_bypass (host_port ):
381+ raise LookupError (f"Proxying is disallowed for `{ host_port !r} `" )
382+
383+ proxies_in_env = proxies_from_env ()
384+ try :
385+ proxy_info = proxies_in_env [url .scheme ]
386+ except KeyError :
387+ raise LookupError (f"No proxies found for `{ url !s} ` in the env" )
388+ else :
389+ return proxy_info .proxy , proxy_info .proxy_auth
390+
391+ # Step 2: Override _splitport to return host:port as first element
392+ original_splitport = urllib .request ._splitport
393+
394+ def _splitport_with_port (host ):
395+ """Override to return (host:port, port) instead of (host, port)."""
396+ result = original_splitport (host )
397+ if result is None :
398+ return (host , None )
399+ host_only , port = result
400+ # If port was found, return the original host (with port) as first element
401+ if port is not None :
402+ return (host , port ) # Return original host:port string
403+ return (host_only , port )
404+
405+ monkeypatch .setattr (
406+ aiohttp .client , "get_env_proxy_for_url" , get_env_proxy_for_url_with_port
407+ )
408+ monkeypatch .setattr (urllib .request , "_splitport" , _splitport_with_port )
409+
410+ yield
411+
412+
358413@pytest .mark .skipolddriver
359414@pytest .mark .parametrize ("proxy_method" , ["explicit_args" , "env_vars" ])
360415@pytest .mark .parametrize ("no_proxy_source" , ["param" , "env" ])
@@ -366,6 +421,7 @@ async def test_no_proxy_source_vs_proxy_method_matrix(
366421 proxy_method ,
367422 no_proxy_source ,
368423 host_port_pooling ,
424+ fix_aiohttp_proxy_bypass ,
369425):
370426 if proxy_method == "env_vars" and no_proxy_source == "param" :
371427 pytest .xfail (
@@ -407,6 +463,7 @@ async def test_no_proxy_backend_matrix(
407463 proxy_method ,
408464 no_proxy_source ,
409465 host_port_pooling ,
466+ fix_aiohttp_proxy_bypass ,
410467):
411468 if proxy_method == "env_vars" and no_proxy_source == "param" :
412469 pytest .xfail (
@@ -570,6 +627,8 @@ async def test_proxy_env_vars_take_precedence_over_connection_params(
570627 wiremock_generic_mappings_dir ,
571628 proxy_env_vars ,
572629 monkeypatch ,
630+ host_port_pooling ,
631+ fix_aiohttp_proxy_bypass ,
573632):
574633 """Verify that proxy_host/proxy_port connection parameters take precedence over env vars.
575634
@@ -620,10 +679,10 @@ async def test_proxy_env_vars_take_precedence_over_connection_params(
620679 flags = await _collect_proxy_precedence_flags (
621680 proxy_from_conn_params , proxy_from_env_vars , target_wm
622681 )
623- assert not (
682+ assert (
624683 flags .proxy1_saw_request
625684 ), "proxy_from_conn_params (connection param proxy) should NOT have seen the query request"
626- assert flags .proxy2_saw_request , (
685+ assert not flags .proxy2_saw_request , (
627686 "proxy_from_env_vars (env var proxy) should have seen the request "
628687 "since connection params take precedence"
629688 )
0 commit comments