From: Tom Christie Date: Fri, 31 Jul 2020 09:21:11 +0000 (+0100) Subject: Add support for no-proxy configurations (#1099) X-Git-Tag: 0.14.0~29 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=16893e414fe68bd41890dc52f449328679a65134;p=thirdparty%2Fhttpx.git Add support for no-proxy configurations (#1099) * Add internal URLMatcher class * Use URLMatcher for proxy lookups in transport_for_url * Docstring * Pin pytest * Add support for no-proxies configurations --- diff --git a/httpx/_client.py b/httpx/_client.py index dca8718f..4a7fc030 100644 --- a/httpx/_client.py +++ b/httpx/_client.py @@ -86,7 +86,7 @@ class BaseClient: def _get_proxy_map( self, proxies: typing.Optional[ProxiesTypes], trust_env: bool, - ) -> typing.Dict[str, Proxy]: + ) -> typing.Dict[str, typing.Optional[Proxy]]: if proxies is None: if trust_env: return { @@ -94,15 +94,15 @@ class BaseClient: for key, url in get_environment_proxies().items() } return {} - elif isinstance(proxies, (str, URL, Proxy)): - proxy = Proxy(url=proxies) if isinstance(proxies, (str, URL)) else proxies - return {"all": proxy} - else: + if isinstance(proxies, dict): new_proxies = {} for key, value in proxies.items(): proxy = Proxy(url=value) if isinstance(value, (str, URL)) else value new_proxies[str(key)] = proxy return new_proxies + else: + proxy = Proxy(url=proxies) if isinstance(proxies, (str, URL)) else proxies + return {"all": proxy} @property def headers(self) -> Headers: @@ -472,8 +472,12 @@ class Client(BaseClient): app=app, trust_env=trust_env, ) - self._proxies: typing.Dict[URLMatcher, httpcore.SyncHTTPTransport] = { - URLMatcher(key): self._init_proxy_transport( + self._proxies: typing.Dict[ + URLMatcher, typing.Optional[httpcore.SyncHTTPTransport] + ] = { + URLMatcher(key): None + if proxy is None + else self._init_proxy_transport( proxy, verify=verify, cert=cert, @@ -543,7 +547,7 @@ class Client(BaseClient): if self._proxies and not should_not_be_proxied(url): for matcher, transport in self._proxies.items(): if matcher.matches(url): - return transport + return self._transport if transport is None else transport return self._transport @@ -885,7 +889,8 @@ class Client(BaseClient): def close(self) -> None: self._transport.close() for proxy in self._proxies.values(): - proxy.close() + if proxy is not None: + proxy.close() def __enter__(self) -> "Client": return self @@ -989,8 +994,12 @@ class AsyncClient(BaseClient): app=app, trust_env=trust_env, ) - self._proxies: typing.Dict[URLMatcher, httpcore.AsyncHTTPTransport] = { - URLMatcher(key): self._init_proxy_transport( + self._proxies: typing.Dict[ + URLMatcher, typing.Optional[httpcore.AsyncHTTPTransport] + ] = { + URLMatcher(key): None + if proxy is None + else self._init_proxy_transport( proxy, verify=verify, cert=cert, @@ -1060,7 +1069,7 @@ class AsyncClient(BaseClient): if self._proxies and not should_not_be_proxied(url): for matcher, transport in self._proxies.items(): if matcher.matches(url): - return transport + return self._transport if transport is None else transport return self._transport @@ -1402,7 +1411,8 @@ class AsyncClient(BaseClient): async def aclose(self) -> None: await self._transport.aclose() for proxy in self._proxies.values(): - await proxy.aclose() + if proxy is not None: + await proxy.aclose() async def __aenter__(self) -> "AsyncClient": return self diff --git a/httpx/_types.py b/httpx/_types.py index bfce5650..89a90a2c 100644 --- a/httpx/_types.py +++ b/httpx/_types.py @@ -54,7 +54,7 @@ TimeoutTypes = Union[ Tuple[Optional[float], Optional[float], Optional[float], Optional[float]], "Timeout", ] -ProxiesTypes = Union[URLTypes, "Proxy", Dict[URLTypes, Union[URLTypes, "Proxy"]]] +ProxiesTypes = Union[URLTypes, "Proxy", Dict[URLTypes, Union[None, URLTypes, "Proxy"]]] AuthTypes = Union[ Tuple[Union[str, bytes], Union[str, bytes]], diff --git a/tests/client/test_proxies.py b/tests/client/test_proxies.py index 6120bc1d..d361372c 100644 --- a/tests/client/test_proxies.py +++ b/tests/client/test_proxies.py @@ -58,6 +58,7 @@ PROXY_URL = "http://[::1]" ("http://example.com", {"http://example.net": PROXY_URL}, None), ("http://example.com:443", {"http://example.com": PROXY_URL}, PROXY_URL), ("http://example.com", {"all": PROXY_URL}, PROXY_URL), + ("http://example.com", {"all": PROXY_URL, "http://example.com": None}, None), ("http://example.com", {"http": PROXY_URL}, PROXY_URL), ("http://example.com", {"all://example.com": PROXY_URL}, PROXY_URL), ("http://example.com", {"all://example.com:80": PROXY_URL}, None),