jawah / niquests

“Safest, Fastest, Easiest, and Most advanced” Python HTTP Client. Production Ready! Drop-in replacement for Requests. HTTP/1.1, HTTP/2, and HTTP/3 supported. With WebSocket, and SSE!
https://niquests.readthedocs.io/en/latest/
Apache License 2.0
1.07k stars 23 forks source link

Override ":authority" via headers #125

Closed whitehatboxer closed 6 months ago

whitehatboxer commented 6 months ago

I deeped into docs and searched old issues, and cannot found a effective way to set custom headers. By the way, I also try to read source code but I thought it won't be useful at once, and it turns out right.

I used code below. My test server return 400 and log that client have sent out of pseudo headers when I try set header.

with niquests.Session() as s:
    # failed.
    # s.headers = {":authority": "a.b.com"}
    s.headers = {"host": "a.b.com"}
    s.quic_cache_layer.add_domain("192.168.87.77", 7443)
    r = s.get("https://192.168.87.77:7443/cool", verify=False)
    # failed as well
    # r = s.get("https://192.168.87.77:7443/cool", verify=False, headers={"host": "a.b.com"})
    print(r)

My test server was nginx/1.26.0, its error log looked like

2024/05/25 09:04:56 [info] 754638#0: *125 client sent out of order pseudo-headers while reading client request, client: 192.168.87.13, server: a.b.com, request: "GET /cool HTTP/3.0", host: "a.b.com"
Ousret commented 6 months ago

First, we do not support setting :authority manually, at least, we did not intend to support it. But the Host entry should work as-is, and later be converted accordingly.

There's two way we could do this:

A) Using the Host header

import niquests

if __name__ == "__main__":

    with niquests.Session() as s:
        s.quic_cache_layer.add_domain("192.168.87.77", 7443)
        r = s.get("https://192.168.87.77:7443/cool", headers={"host": "a.b.com"}, verify=False)

        print(r)

B) Using a custom resolver

import niquests

if __name__ == "__main__":

    with niquests.Session(resolver="in-memory://default/?hosts=a.b.com:192.168.87.77") as s:
        s.quic_cache_layer.add_domain("a.b.com", 7443)
        r = s.get("https://a.b.com:7443/cool", verify=False)

        print(r)

Something doesn't look right on our end for A. Your intuition did not fail you. We are providing an immediate fix for this. Run pip install urllib3.future -U.

The documentation update is welcomed, if you are willing to submit a PR for it. If the issue is fixed, feel free to close the issue.

regards,

Ousret commented 6 months ago

I am considering the issue resolved. If this is not the case, feel free to ping me. According to my testing, it is solved.

regards,

whitehatboxer commented 6 months ago

Yes, it works! And thanks for your awesome reaction of bugfix.

First, we do not support setting :authority manually, at least, we did not intend to support it. But the Host entry should work as-is, and later be converted accordingly.

There's two way we could do this:

A) Using the Host header

import niquests

if __name__ == "__main__":

    with niquests.Session() as s:
        s.quic_cache_layer.add_domain("192.168.87.77", 7443)
        r = s.get("https://192.168.87.77:7443/cool", headers={"host": "a.b.com"}, verify=False)

        print(r)

B) Using a custom resolver

import niquests

if __name__ == "__main__":

   with niquests.Session(resolver="in-memory://default/?hosts=a.b.com:192.168.87.77") as s:
       s.quic_cache_layer.add_domain("a.b.com", 7443)
       r = s.get("https://a.b.com:7443/cool", verify=False)

       print(r)

Something doesn't look right on our end for A. Your intuition did not fail you. We are providing an immediate fix for this. Run pip install urllib3.future -U.

The documentation update is welcomed, if you are willing to submit a PR for it. If the issue is fixed, feel free to close the issue.

regards,

Ousret commented 6 months ago

:ok_hand: