Skip to content

Instantly share code, notes, and snippets.

@Ousret
Last active June 13, 2023 06:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ousret/0fb70d8bb8e26d5ea494d2a51fd3920f to your computer and use it in GitHub Desktop.
Save Ousret/0fb70d8bb8e26d5ea494d2a51fd3920f to your computer and use it in GitHub Desktop.
Preview HTTP/2, and HTTP/3 with urllib3, and requests with no additional change or effort

I am working on native support for HTTP/2 and HTTP/3 in urllib3 and I reached a point where I need testers. So I am opening that thread to invite anyone willing to explore and report anomalies directly here. It would help with the final design of this implementation.

pip install git+https://github.com/Ousret/urllib3.git@experimental-h2n3 urllib3-ext-hface -U

So what gets installed

➡️ h11, h2, and aioquic get installed. I have no plan to make one of them optional in this experiment.

📝 Patch notes

Currently urllib3 does not offer async http request and the backend is the http.client package shipped alongside Python. This implementation is not scheduled to improve, even less to support latest protocol.

Without proxies, the negotiation is as follow:

  • http requests are always made using HTTP/1.1.

  • https requests are made with HTTP/2 if TLS-ALPN yield its support otherwise HTTP/1.1.

  • https requests may upgrade to HTTP/3 if latest response contain a valid Alt-Svc header.

With proxies:

  • The initial proxy request is always issued using HTTP/1.1 regardless if its http or https.
  • Subsequents requests follow the previous section (Without proxies) at the sole exception that HTTP/3 upgrade is disabled.

You may explicitly disable HTTP/2 or, and, HTTP/3 by passing disabled_svn={HttpVersion.h2} to your BaseHttpConnection instance. Disabling HTTP/1.1 is forbidden and raise an error.

Note that a valid or accepted Alt-Svc header in urllib3 means looking for the "h3" (final specification) protocol and disallow switching hostname for security reasons.

⚠️ Disclaimer!

➡️ Installing this will undoubtfully alter your environment as most dependencies rely on urllib3, so you are warned! Also! You immediately relinquish your "right" to get active support from urllib3, requests, or downstream-ish deps as it is an experimental version.
➡️ Historically, urllib3 mostly lies on http.client package shipped within CPython, this patch completely detaches us from it.

➡️ Understand that my modest piece of work (meaning patched urllib3) isn't meant to be reviewed or merged (ever). It would be hard on the maintainers to caution importing that many LOCs. For curious folks see urllib3/urllib3#3030
➡️ The mainstream/stable version is distributed without warranties of any kind, so you'd imagine that fork, in its experimental phase won't get you any further (if not the opposite).

So this is more for first hours enthusiastic users.

🥼 How to help?

➡️ Install the urllib3 fork, and report directly in this thread so that I can explore deeper and potentially work with better confidence for the next steps in urllib3. It is vital that some of you engage with this, as, this patch imports directly or indirectly more than 2.5k lines of code in urllib3!
➡️ Or actively contribute with me in that task. Get in touch!

Your report is most valuable if it contains at least:

> Python interpreter: e.g. 3.11
> Operating system: e.g. Windows/Mac/Linux
> Remote server: e.g. www.cloudflare.com
> How to reproduce: e.g. Made a POST request with a 120 MiB file and...

You may also, test the implementation using HTTPie! httpie/cli#1512 Or anything based on requests, and urllib3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment