Uh oh!
There was an error while loading. Please reload this page.
Add support for HTTPS Proxy - #714
Conversation
karpetrosyan
commented
Jun 9, 2023
The proxy logic now looks very similar to urllib3 proxies with one exception: they support HTTPS in HTTPS (forwarding) using |
Exapmlesproxy_ssl_contextimporthttpcorepool=httpcore.HTTPProxy('https://127.0.0.1:8080', proxy_mode="FORWARDING")
resp=pool.request("GET", 'https://www.youtube.com')
# httpcore.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:992)importhttpcoreimportsslproxy_context=ssl.create_default_context()
proxy_context.check_hostname=Falseproxy_context.verify_mode=Falsepool=httpcore.HTTPProxy('https://127.0.0.1:8080', proxy_mode="FORWARDING", proxy_ssl_context=proxy_context)
resp=pool.request("GET", 'https://www.youtube.com')
print(resp.status)
200 |
lovelydinosaur
commented
Jun 9, 2023
Ah this is very neat, thanks! 😎 Could we keep it sharp, and just add one change-per-pull-request. Adding just |
karpetrosyan
commented
Jun 9, 2023
I got it, and thanks for reviewing; I'll open another PR for proxy_mode. |
lovelydinosaur
commented
Jun 13, 2023
Okay, here's where I've go to with testing this... I referred back to a previous comment https://github.com/encode/httpx/issues/1434#issuecomment-846938725 in order to try this out with $ venv/bin/pip install trustme-cli proxy.py
$ venv/bin/trustme-cli $ venv/bin/proxy --port 6000 --hostname 127.0.0.1 --cert-file server.pem --key-file server.key Testing with urllib3As a point-of-reference let's start out by testing connecting through our SSL proxy with importcertifiimporturllib3importsslproxy_ssl_context=ssl.create_default_context()
proxy_ssl_context.load_verify_locations("client.pem")
withurllib3.ProxyManager(
'https://127.0.0.1:6000/',
ca_certs=certifi.where(),
proxy_ssl_context=proxy_ssl_context
) ashttp:
r=http.request('GET', 'https://example.com/')
print(r, r.status)
# <urllib3.response.HTTPResponse object at 0x10f302080> 200Testing with httpcore, trioimporthttpcoreimportcertifiimportsslimporttrioproxy_ssl_context=ssl.create_default_context()
proxy_ssl_context.load_verify_locations("client.pem")
ssl_context=ssl.create_default_context()
ssl_context.load_verify_locations(certifi.where())
asyncdefmain():
asyncwithhttpcore.AsyncHTTPProxy(
'https://127.0.0.1:6000/',
ssl_context=ssl_context,
proxy_ssl_context=proxy_ssl_context
) ashttp:
r=awaithttp.request('GET', 'https://example.com/')
print(r)
# <Response [200]>trio.run(main)Testing with httpcore, asyncioimporthttpcoreimportcertifiimportsslimportasyncioproxy_ssl_context=ssl.create_default_context()
proxy_ssl_context.load_verify_locations("client.pem")
ssl_context=ssl.create_default_context()
ssl_context.load_verify_locations(certifi.where())
asyncdefmain():
asyncwithhttpcore.AsyncHTTPProxy(
'https://127.0.0.1:6000/',
ssl_context=ssl_context,
proxy_ssl_context=proxy_ssl_context
) ashttp:
r=awaithttp.request('GET', 'https://example.com/')
print(r)
# <Response [200]>asyncio.run(main())Testing with httpcore, syncimporthttpcoreimportcertifiimportsslproxy_ssl_context=ssl.create_default_context()
proxy_ssl_context.load_verify_locations("client.pem")
ssl_context=ssl.create_default_context()
ssl_context.load_verify_locations(certifi.where())
withhttpcore.HTTPProxy(
'https://127.0.0.1:6000/',
ssl_context=ssl_context,
proxy_ssl_context=proxy_ssl_context
) ashttp:
r=http.request('GET', 'https://example.com/')
print(r)
# ...# httpcore.ConnectError: [SSL: UNEXPECTED_MESSAGE] unexpected message (_ssl.c:997)The one bit that doesn't currently work is the sync case with an HTTPS proxy connecting to an HTTPS endpoint. This isn't surprising... Here's @florimondmanca's comment on this from https://github.com/encode/httpx/issues/1434
And a link to the Upshot... in order to make this work our |
karpetrosyan
commented
Jun 13, 2023
For minimal changes, I believe we should implement |
lovelydinosaur
commented
Jun 13, 2023
Agreed, yes. |
…re into add-https-proxy-support
karpetrosyan
commented
Jun 14, 2023
Perhaps we should rename |
Ohhh... nice work. I'd suggest that the Given the trade-off between clarity of the codebase & simpler operation vs some-slight-subtleties-in-timeout-behaviour-for-tls-in-tls, I'd recommend we drop that. |
karpetrosyan
commented
Jun 14, 2023
But do we have to stick with this timeout strategy? I'm talking about decreasing the timeout with each tcp operation. |
lovelydinosaur
commented
Jun 14, 2023
I see it, but... at least from my perspective, KISS is really important before getting into the fancy stuff. In terms of review it'd be beneficial to...
|
karpetrosyan
commented
Jun 14, 2023
Isn't this a |
lovelydinosaur
commented
Jun 14, 2023
Hrm. Okay different question... in order to get this into a mergeable state we need test coverage. Since we have the backends documented and part of the public API, testing them at that layer would be the sharpest option.
I suppose the iterative approach would be to start with implementing the just the first of those in a PR independent of this work. |
karpetrosyan
commented
Jun 14, 2023
But are we prepared for tests and coverage? If you want to remove "OverallTimeout" we must first re-implement timeouts and then work on tests/coverage. |
lovelydinosaur
commented
Jun 14, 2023
I've opened an issue for this at #722 so that we're documenting our work neatly. |
karpetrosyan
commented
Jul 4, 2023
Since the tls-in-tls implementation has moved to #732 , I'll open another PR to work through this more carefully. |
karpetrosyan
commented
Jul 4, 2023
Re-opened in #745 |
Add support for HTTPS proxies
Refs