psf / requests

A simple, yet elegant, HTTP library.
https://requests.readthedocs.io/en/latest/
Apache License 2.0
52.17k stars 9.33k forks source link

HTTPS Request through HTTP Proxy is sent incorrectly when using chunked body #6279

Open moshec2 opened 2 years ago

moshec2 commented 2 years ago

I am using the chunked request body feature (data=generator). When defining a HTTP proxy and sending a request to a HTTPS URL, requests is trying to perform a TLS handshake with the (HTTP) proxy server, instead of sending a CONNECT request and performing the handshake with the target server through the tunnel. This behaviour prevents the request from completing successfully.

Expected Result

requests should send a CONNECT request to the proxy and negotiate TLS with the target server through the tunnel.

Actual Result

requests tries to negotiate TLS directly with the HTTP proxy server, and fails to do so.

Reproduction Steps

Run an HTTP proxy on 127.0.0.1:8080 and execute the following code:

  import requests

  def body_generator():
    yield "test"
    return

  requests.post("https://www.google.com/",
    proxies={"https": "http://127.0.0.1:8080/"},
    data=body_generator(),
  )

More info

The chunked encoding generator feature is implemented in requests/adapters.py:

try:
    if not chunked:
        resp = conn.urlopen(
            ...
        )

    # Send the request.
    else:
        if hasattr(conn, "proxy_pool"):
            conn = conn.proxy_pool

        low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT)

        try:
            ... Send request with chunked body ...

In the case of chunked encoding, instead of using conn.urlopen to send the request, it uses conn._get_conn and sends the request manually. It seems like, for some reason, conn._get_conn is not handling the proxy correctly.

sveint commented 1 year ago

I can confirm this is still an issue on latest release. I filed a duplicate issue (now closed) here: https://github.com/psf/requests/issues/6371

SteniMariyaThomas commented 1 year ago

I am using requests 2.28.2 with urllib3 as 1.26.14, and getting below issue when calling the api (proxy is not added).

requests.exceptions.SSLError: HTTPSConnectionPool(host="my client host", port="my client port"): Max retries exceeded with url: /v1/omni-channel/message (Caused by SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1129)')))

Is there anything else that I need to check?

MozarM commented 1 year ago

Seems there is an issue with the SSL/TLS connection when making the API call.

You can check few things -

  1. Verify the URL: Ensure that the URL you are using is correct and corresponds to the intended API endpoint.
  2. Updating the libraries 'requests' and its dependencies 'urllib' and 'ssl' to the latest one.
  3. Verify the SSL/TLS version compatibility with the client-server versions