Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal v4.0 b1 (HTTP/2+3, OS Trust Store, Custom DNS, OCSP, ...) #1531

Open
wants to merge 40 commits into
base: master
Choose a base branch
from

Conversation

Ousret
Copy link
Collaborator

@Ousret Ousret commented Oct 3, 2023

This PR showcases how HTTPie could evolve outside of Requests.

Niquests is supposed to be a (mostly) compatible fork of Requests.

Try this preview:

$ pip install "git+https://github.com/Ousret/HTTPie.git@feature-tryout-niquests" -U

Here are the biggest pros of this:

  • OS truststore by default, no more certifi!
  • Object-oriented headers. Could bring additional features!
  • Fully type-annotated!
  • HTTP/3 over QUIC.
  • HTTP/2 by default.
  • Exit Python http.client! in favor of h11.
  • Timeout by default.
  • Inspect peer certificate, HTTP version, TLS version, cipher, and so on via hook/callback before a request is sent.
  • All the features you expose are available in all three protocols.
  • Python 3.7+, no sacrifice needed.
  • Encrypted DNS support. w/ DNS-over-HTTPS, DNS-over-QUIC, DNS-over-TLS and plain DNS-over-UDP.

Obviously, cons:

  • Stricter on emitted requests per RFCs
  • Young project but based on solid bases, knowledge, and experiences.
  • Need to publish new packages to distro. Easy but time-consuming
  • Exit pyopenssl, not supported. more of a pro to me
  • Require major bump? Could be. Should be.

Complete list of changes in the fork: https://github.com/jawah/niquests/blob/main/HISTORY.md

Capture d’écran du 2023-11-27 19-52-12


4.0.0.b1 (unreleased)

  • Make it possible to unset the User-Agent, and Accept-Encoding headers. (#1502)
  • Dependency on requests was changed in favor of compatible niquests. (#1531)
  • Added support for HTTP/2, and HTTP/3 protocols. (#523) (#692) (#1531)
  • Added request metadata for the TLS certificate, negotiated version with cipher, the revocation status and the remote peer IP address. (#1495) (#1023) (#826) (#1531)
  • Added support to load the operating system trust store for the peer certificate validation. (#480) (#1531)
  • Added detailed timings in response metadata with DNS resolution, established, TLS handshake, and request sending delays. (#1023) (#1531)
  • Added support for using alternative DNS resolver using --resolver. DNS over HTTPS, DNS over TLS, DNS over QUIC, and DNS over UDP are accepted. (#99) (#1531)
  • Added support for binding to a specific network adapter with --interface. (#1422) (#1531)
  • Added support for specifying the local port with --local-port. (#1456) (#1531)
  • Added support for forcing either IPv4 or IPv6 to reach the remote HTTP server with -6 or -4. (#94) (#1531)
  • Removed support for pyopenssl. (#1531)
  • Removed support for dead SSL protocols < TLS 1.0 (e.g. sslv3) as per pyopenssl removal. (#1531)
  • Dropped dependency on requests_toolbelt in favor of directly including MultipartEncoder into HTTPie due to its direct dependency to requests. (#1531)
  • Dropped dependency on multidict in favor of implementing an internal one due to often missing pre-built wheels. (#1522) (#1531)
  • Fixed the case when multiple headers where concatenated in the response output. (#1413) (#1531)
  • Fixed an edge case where HTTPie could be lead to believe data was passed in stdin, thus sending a POST by default. (#1551) (#1531)
    This fix has the particularity to consider 0 byte long stdin buffer as absent stdin. Empty stdin buffer will be ignored.
  • Slightly improved performance while downloading by setting chunk size to -1 to retrieve packets as they arrive. (#1531)
  • Added support for using the system trust store to retrieve root CAs for verifying TLS certificates. (#1531)
  • Removed support for keeping the original casing of HTTP headers. This come from an outer constraint by newer protocols, namely HTTP/2+ that normalize header keys by default.
    From the HTTPie user perspective, they are "prettified" on the output by default. e.g. "x-hello-world" is displayed as "X-Hello-World".
  • Fixed multipart form data having filename not rfc2231 compliant when name contain non-ascii characters. (#1401)
  • Fixed issue where the configuration directory was not created at runtime that made the update fetcher run everytime. (#1527)
  • Fixed cookie persistence in HTTPie session when targeting localhost. They were dropped due to the standard library. (#1527)
  • Fixed downloader when trying to fetch compressed content. The process will no longer exit with the "Incomplete download" error. (#1554) (#423) (#1527)
  • Added automated resolution of hosts ending with .localhost to the default loopback address. (#1458) (#1527)

Existing plugins are expected to work without any changes. The only caveat would be that certain plugin explicitly require requests.
Future contributions may be made in order to relax the constraints where applicable.

@Ousret

This comment was marked as resolved.

tests/test_json.py Outdated Show resolved Hide resolved
@Ousret

This comment was marked as resolved.

@Ousret Ousret force-pushed the feature-tryout-niquests branch 3 times, most recently from faf9aef to c12f000 Compare October 13, 2023 16:37
@codecov-commenter
Copy link

codecov-commenter commented Oct 13, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 0.00%. Comparing base (4d7d6b6) to head (7cd6579).
Report is 370 commits behind head on master.

Current head 7cd6579 differs from pull request most recent head e3cbc7f

Please upload reports for the commit e3cbc7f to get more accurate results.

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #1531       +/-   ##
==========================================
- Coverage   97.28%       0   -97.29%     
==========================================
  Files          67       0       -67     
  Lines        4235       0     -4235     
==========================================
- Hits         4120       0     -4120     
+ Misses        115       0      -115     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@Ousret

This comment was marked as outdated.

@Ousret

This comment was marked as resolved.

@Ousret Ousret force-pushed the feature-tryout-niquests branch 4 times, most recently from 52653e4 to 247b382 Compare October 16, 2023 05:45
@Ousret Ousret force-pushed the feature-tryout-niquests branch 2 times, most recently from 0b4eebb to 7dd1152 Compare October 23, 2023 10:56
@Ousret
Copy link
Collaborator Author

Ousret commented Oct 23, 2023

We can add the following arguments and document them:

  • --disable-http2
  • --disable-http3
  • --http3, e.g. force trying it.

@Ousret
Copy link
Collaborator Author

Ousret commented Nov 16, 2023

I've added and documented it.

  • --disable-http2
  • --disable-http3
  • --http3, e.g. force trying it.

Ideally, the connection information (TLS, Cipher, Peer/Issuer Certificate, and OCSP) should be in the request metadata and with a lexer instruction.

@Ousret Ousret changed the title ⚗️ Try compatible fork Niquests to supercharge HTTPie ⚗️ Add support for HTTP/2, HTTP/3, System CA, OCSP Revocation, Extended Conn Info Nov 16, 2023
@Ousret
Copy link
Collaborator Author

Ousret commented Nov 27, 2023

Now, the result is pleasant to the eye.
I have implemented the metadata for Request and the result is as follows:

Capture d’écran du 2023-11-27 19-52-12

Niquests now support tracking upload progress, this can also be done here. It should be straightforward enough.

@Ousret Ousret changed the title ⚗️ Add support for HTTP/2, HTTP/3, System CA, OCSP Revocation, Extended Conn Info Add support for HTTP/2, HTTP/3, System CA, OCSP Revocation, Extended Conn Info Dec 10, 2023
@dwt
Copy link

dwt commented Dec 20, 2023

Damn this looks so tantalizing. I'd love for this to get packaged as a tryout / beta. Something installable via e.g. pip install httpie[niquest] perhaps?

@Ousret
Copy link
Collaborator Author

Ousret commented Apr 9, 2024

However I noticed the absence of a --http2 flag to force http2. Could you touch on the rationale behind that omission?

You cannot force HTTP/2 using Niquests. It is negotiated via ALPN/TLS. So if the server misinterpret ALPN or discard it, HTTP/2 won't come. And yes, RFC allows it, see https://datatracker.ietf.org/doc/html/rfc9113#name-starting-http-2-with-prior- but I decided to follow the simplest path forward (ALPN/TLS), as browsers do (https://stackoverflow.com/questions/34076231/why-do-browser-implementations-of-http-2-require-tls). I might reconsider it in the future, but the use cases are rare.

@dwt
Copy link

dwt commented Apr 9, 2024

I may be missing something here, but does that imply that the client has no way to force http1 2 or 3 according to its wishes? When setting up server support for these protocols, I would like to have the ability to force all of these protocols for debugging purposes?

@Ousret
Copy link
Collaborator Author

Ousret commented Apr 9, 2024

I may be missing something here, but does that imply that the client has no way to force http1 2 or 3 according to its wishes?

There's many possibilities, the only missing piece is "force http2" or "disable http1".

  • "--disable-http2" HTTP/1.1 or HTTP/3
  • "--disable-http2 --disable-http3" HTTP/1.1
  • "--disable-http3" HTTP/1.1 or HTTP/2
  • "--http3" HTTP/3

Hope that clarify.

@Ousret
Copy link
Collaborator Author

Ousret commented Apr 24, 2024

Just updated the docs to include previous comment about protocol combo and the availability of HTTP/3 or not.
Since last time Niquests made HTTP/3 support far more enjoyable with less dependencies and a faster execution time.

Finally, we had to downgrade macos-14 (macos-latest) to macos-13 because it's relatively new and some dependencies like brotlicffi aren't ready for it.

@mshahat
Copy link

mshahat commented May 5, 2024

Hello @Ousret , nice work here ... is there an ETA on when to expect this release to become available? Thank you

@Ousret
Copy link
Collaborator Author

Ousret commented May 6, 2024

No precise ETA. We are waiting upon the owner approval.

@markstos
Copy link

Looks like it could be a big step forward if @jkbrzt approves it. Last week I wanted to test resolving over IPv4 vs IPv6. I found that the released version could not help with this task, but it worked perfectly in the fork, with the same -4 and -6 flags that dig uses.

non https server were expected to receive "secure" cookies...? this seems to be a bug that lied in Requests for quite some time.
@ducaale
Copy link

ducaale commented May 23, 2024

Excited to see HTTP/2 and HTTP/3 soon landing in HTTPie 🎉

I may be missing something here, but does that imply that the client has no way to force http1 2 or 3 according to its wishes?

There's many possibilities, the only missing piece is "force http2" or "disable http1".
"--disable-http2" HTTP/1.1 or HTTP/3
"--disable-http2 --disable-http3" HTTP/1.1
"--disable-http3" HTTP/1.1 or HTTP/2
"--http3" HTTP/3

I was wondering if we could have an equivalent to cURL's http-version flags i.e --http1.0,--http1.1,--http2,--http2-prior-knowledge,--http3? Alternatively, it could be a --http-version flag that accepts either 1.0, 1.1, 2, 2-prior-knowledge or 3

@Ousret
Copy link
Collaborator Author

Ousret commented May 23, 2024

Excited to see HTTP/2 and HTTP/3 soon landing in HTTPie 🎉

Likewise!

I was wondering if we could have an equivalent to cURL's http-version flags

I first need to add a feature into Niquests, which isn't top priority right now.
But it is planed, will be in a future minor. Provided everything goes smooth with this.

regards,

docs/README.md Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment