httpx
httpx copied to clipboard
Respect system proxy exclusions.
- [x] Initially raised as discussion #1513
We're currently leaning on urllib.request.getproxies()
to determine the system proxy setup, and setup which mounts should be a proxy transport and which should be a regular transport.
However, we're not using urllib.request.proxy_bypass(host)
.
This all works as expected when environment settings are being used. HTTP_PROXY
, HTTPS_PROXY
, and ALL_PROXY
. In that case we're reading NO_PROXY
, and ensuring anything hostname patterns there are mounted as a regular transport...
https://github.com/encode/httpx/blob/68cf1ff88a7f6c0b084bb62455c043aa503713ef/httpx/_utils.py#L304-L320
However, in the case when none of those environment variables are set getproxies()
instead falls back to system proxy configuration. For windows this is registry based. ProxyEnable
and ProxyOverride
. For Mac this is sysconf based.
In those cases, we're correctly getting the configured proxies, but we aren't dealing with proxy exclusions.
We'd like to be able to setup these exclusions with our neat hostname pattern matched mounts system, which actually
means we can't just fallback to urllib.request.proxy_bypass(host)
, because that needs to be called per-host.
So, first steps...
- What exactly is the format of the windows registry
ProxyOverride
field? - What exactly is the format of the "exceptions" field returned by
from _scproxy import _get_proxy_settings()
?
- The windows registry
ProxyOverride
field.
A useful starting point is here...
https://github.com/python/cpython/blob/030a713183084594659aefd77b76fe30178e23c8/Lib/urllib/request.py#L2746
proxyOverride = proxyOverride.split(';')
# now check if we match one of the registry values.
for test in proxyOverride:
if test == '<local>':
if '.' not in rawHost:
return 1
test = test.replace(".", r"\.") # mask dots
test = test.replace("*", r".*") # change glob sequence
test = test.replace("?", r".") # change glob char
- The "exceptions" field returned by
from _scproxy import _get_proxy_settings()
On my system this returns...
>>> _get_proxy_settings()
{'exclude_simple': False, 'exceptions': ('*.local', '169.254/16',)}
There's also an example documented in the urllib
source code here...
https://github.com/python/cpython/blob/030a713183084594659aefd77b76fe30178e23c8/Lib/urllib/request.py#L2556
{ 'exclude_simple': bool, 'exceptions': ['foo.bar', '*.bar.com', '127.0.0.1', '10.1', '10.0/16']}
So, "10.0/16"
and '169.254/16'
here are not IPs, but IP ranges. Those are a bit awkward for us since we don't currently support subnet matching on transport mounts.
Thanks!
I think httpx
can drop the support for system proxy settings, only uses environment settings:
- It's hard to handle system proxy exclusions for
httpx
's mounts system. - If you use the system proxy settings, you should check the system proxy-bypass settings, otherwise it's not correct.
Besides, for the field 'exceptions' ,'10.1'
='10.1/16'
='10.1.1.1/16'
.If httpx
needs to mount system proxy-bypass settings on Windows and macosx, which can be unified into form like 10.1.*
, then calls socket.gethostbyname
to check both hostname and ip for request url, or simply not calls socket.gethostbyname
which means DNS lookups is not supported.
Sticking to environment only settings would be one option, yes, though I'm not convinced that'd be the best from a user-experiance point of view.
Being able to pick up and use the system proxy settings — especially proxy auto config — would be a benefit in certain environments, even if it’s an option and not the default. I’m no longer in a situation like that, but Python PAC support on macOS could have made configuring some projects much easier. It might have been a reason to choose a library like HTTPX over another.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Still valid at the moment. Could do with a review and possibly extra docs.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Upping the durations on you, @stalebot. Shoo.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Nothing's changed in this topic i presume?