Skip to content

Commit

Permalink
ProxyEnvironment: Handle no_proxy="*"
Browse files Browse the repository at this point in the history
Add support for leading dots in no_proxy and "*" as a no_proxy value.

Both are supported in requests and based on
https://about.gitlab.com/blog/2021/01/27/we-need-to-talk-no-proxy/
both are somewhat common.

Signed-off-by: Jussi Kukkonen <[email protected]>
  • Loading branch information
jku committed Feb 14, 2025
1 parent 0490007 commit 3656375
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 4 deletions.
29 changes: 29 additions & 0 deletions tests/test_proxy_environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,35 @@ def test_no_proxy_subdomain_match(self, mock_getproxies: Mock) -> None:
# and a https proxymanager
self.assert_pool_managers(env, [None, "http://localhost:9999"])

@patch("tuf.ngclient._internal.proxy.getproxies")
def test_no_proxy_wildcard(self, mock_getproxies: Mock) -> None:
mock_getproxies.return_value = {
"https": "http://localhost:8888",
"no": "*",
}

env = ProxyEnvironment()
env.get_pool_manager("https", "example.com")
env.get_pool_manager("https", "differentsite.com")
env.get_pool_manager("https", "subdomain.example.com")

# There is a single pool manager, no proxies
self.assert_pool_managers(env, [None])

@patch("tuf.ngclient._internal.proxy.getproxies")
def test_no_proxy_leading_dot(self, mock_getproxies: Mock) -> None:
mock_getproxies.return_value = {
"https": "http://localhost:8888",
"no": ".example.com",
}

env = ProxyEnvironment()
env.get_pool_manager("https", "example.com")
env.get_pool_manager("https", "subdomain.example.com")

# There is a single pool manager, no proxies
self.assert_pool_managers(env, [None])

@patch("tuf.ngclient._internal.proxy.getproxies")
def test_all_proxy_set(self, mock_getproxies: Mock) -> None:
mock_getproxies.return_value = {
Expand Down
11 changes: 7 additions & 4 deletions tuf/ngclient/_internal/proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ def __init__(
if no_proxy is None:
self._no_proxy_hosts = []
else:
# split by comma, remove leading periods
self._no_proxy_hosts = [
h for h in no_proxy.replace(" ", "").split(",") if h
h.lstrip(".") for h in no_proxy.replace(" ", "").split(",") if h
]

def _get_proxy(self, scheme: str | None, host: str | None) -> str | None:
Expand All @@ -50,10 +51,12 @@ def _get_proxy(self, scheme: str | None, host: str | None) -> str | None:
# even for schemes that don't require host (like file)
return None

# does host match "no_proxy" hosts?
# does host match any of the "no_proxy" hosts?
for no_proxy_host in self._no_proxy_hosts:
# exact hostname match or parent domain match
if host == no_proxy_host or host.endswith(f".{no_proxy_host}"):
# wildcard match, exact hostname match, or parent domain match
if no_proxy_host in ("*", host) or host.endswith(
f".{no_proxy_host}"
):
return None

if scheme in self._proxies:
Expand Down

0 comments on commit 3656375

Please sign in to comment.