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!
https://niquests.readthedocs.io/en/latest/
Apache License 2.0
1.05k stars 23 forks source link

Executing two times the same issue is causing ProtocolError #134

Closed nalo26 closed 4 months ago

nalo26 commented 4 months ago

It's been a long time I wanted to try niquests as a replacement of the well known requests module. Today I needed an async GET, so it was the perfect time to give this project a try.

However, I rapidly encountered the following issue: when using the module to GET on the API URL I need, the request works the first time it hits the domain. But at the second time, whatever the endpoint is (could be the exact same URL, or with another parameter or route), it raises an error (see below).
I discovered the issue being on an async session. But after testing, I saw that it still was the same without the session, and without the async as well.

I tried repeating the request multiple times, still get an error each time.
I also tried on well-known domains (like google.com), and it suddenly works like a charm!
I tried the not-working URL with requests, and there's no problem.

I hypothesize that this is due to the 4-part API URL, but I don't know the reason at all.

Expected Result

Each requests to the given domain to work.

Actual Result

The following error:

Traceback (most recent call last):
  File "C:\Users\<username>\<path_to_file>\.venv\Lib\site-packages\niquests\adapters.py", line 899, in send
    resp_or_promise = conn.urlopen(  # type: ignore[call-overload]
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\<username>\<path_to_file>\.venv\Lib\site-packages\urllib3\connectionpool.py", line 1472, in urlopen
    retries = retries.increment(
              ^^^^^^^^^^^^^^^^^^
  File "C:\Users\<username>\<path_to_file>\.venv\Lib\site-packages\urllib3\util\retry.py", line 495, in increment
    raise reraise(type(error), error, _stacktrace)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\<username>\<path_to_file>\.venv\Lib\site-packages\urllib3\util\util.py", line 39, in reraise
    raise value
  File "C:\Users\<username>\<path_to_file>\.venv\Lib\site-packages\urllib3\connectionpool.py", line 1396, in urlopen
    response = self._make_request(  # type: ignore[call-overload,misc]
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\<username>\<path_to_file>\.venv\Lib\site-packages\urllib3\connectionpool.py", line 975, in _make_request
    self._validate_conn(conn)
  File "C:\Users\<username>\<path_to_file>\.venv\Lib\site-packages\urllib3\connectionpool.py", line 1935, in _validate_conn
    super()._validate_conn(conn)
  File "C:\Users\<username>\<path_to_file>\.venv\Lib\site-packages\urllib3\connectionpool.py", line 608, in _validate_conn
    conn.connect()
  File "C:\Users\<username>\<path_to_file>\.venv\Lib\site-packages\urllib3\connection.py", line 745, in connect
    self._post_conn()
  File "C:\Users\<username>\<path_to_file>\.venv\Lib\site-packages\urllib3\backend\hface.py", line 516, in _post_conn
    self.__exchange_until(
  File "C:\Users\<username>\<path_to_file>\.venv\Lib\site-packages\urllib3\backend\hface.py", line 780, in __exchange_until
    raise ProtocolError(event.message)
urllib3.exceptions.ProtocolError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\<username>\<path_to_file>\test.py", line 14, in <module>
    test()
  File "C:\Users\<username>\<path_to_file>\test.py", line 9, in test
    print(session.get("https://api.pronouns.alejo.io/v1/pronouns"))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\<username>\<path_to_file>\.venv\Lib\site-packages\niquests\sessions.py", line 605, in get
    return self.request(
           ^^^^^^^^^^^^^
  File "C:\Users\<username>\<path_to_file>\.venv\Lib\site-packages\niquests\sessions.py", line 550, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\<username>\<path_to_file>\.venv\Lib\site-packages\niquests\sessions.py", line 1201, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\<username>\<path_to_file>\.venv\Lib\site-packages\niquests\adapters.py", line 932, in send
    raise ConnectionError(err, request=request)
niquests.exceptions.ConnectionError

Reproduction Steps

import niquests

niquests.get("https://api.pronouns.alejo.io/v1/pronouns") # works
niquests.get("https://api.pronouns.alejo.io/v1/pronouns") # raise error

System Information

$ python -m niquests.help
{
  "charset_normalizer": {
    "version": "3.3.2"
  },
  "http1": {
    "h11": "0.14.0"
  },
  "http2": {
    "jh2": "5.0.3"
  },
  "http3": {
    "enabled": true,
    "qh3": "1.0.8"
  },
  "idna": {
    "version": "3.7"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.12.4"
  },
  "niquests": {
    "version": "3.7.0"
  },
  "ocsp": {
    "enabled": true
  },
  "platform": {
    "release": "10",
    "system": "Windows"
  },
  "system_ssl": {
    "version": "300000d0"
  },
  "urllib3.future": {
    "cohabitation_version": null,
    "version": "2.8.901"
  },
  "wassima": {
    "certifi_fallback": false,
    "enabled": true,
    "version": "1.1.1"
  }
}

Note : also tested on my VPS (Debian 12 bookworm), and it does exactly the same.

Ousret commented 4 months ago

What you encountered could certainly be improved (UX).

The server claim to support HTTP/3 but does not seems to be capable to accept connecting using QUIC.

If you inspect the response headers, you will notice the presence of Alt-Svc header that specify « h3=… »

you may simply disable http3 or raise an issue to the server admin.

The first attempt is done with http 2 and the second one is attempted using http3 via auto upgrade as per documented.

With that said, the error message should be more helpful. I’ll do that asap.

Regards,

nalo26 commented 4 months ago

@Ousret that was it! Thanks a lot for the fast answer!