TLS connection fails through HTTPS proxy after CONNECT tunnel is established
See original GitHub issueI set proxy by this code:
class HttpProxyMiddleware(object):
def process_request(self, request, spider):
request.meta['proxy'] = 'https://127.0.0.1:8787'
It’s error is:
scrapy.core.downloader.handlers.http11.TunnelError: Could not open CONNECT tunnel with proxy 127.0.0.1:8787
Then I test the proxy by requests:
resp = requests.get('https://......', proxies={'https': 'https://127.0.0.1:8787'})
It’ work!
So, what is it happen?
Issue Analytics
- State:
- Created 7 years ago
- Comments:10 (7 by maintainers)
Top Results From Across the Web
The HTTP CONNECT tunnel
To solve this problem, the browser sends a HTTP request with method CONNECT and the target hostname and port number to the proxy....
Read more >Issue 29394: Cannot tunnel TLS connection through TLS ...
The following two scenarios are working perfectly fine: 1) Establishing a TLS-secured connection to the proxy and then tunnel traffic ...
Read more >Failing to connect to HTTPS service using HTTP tunnel proxy ...
The direct TLS handshake mostly succeeds with the remote server, only the server certificate cannot be validated: "SSL3_GET_SERVER_CERTIFICATE: ...
Read more >HTTPS (HTTP Secure or HTTP over TLS) - Squid Cache Wiki
The CONNECT method is a way to tunnel any kind of connection through an HTTP proxy. By default, the proxy establishes a TCP...
Read more >Resolve the client SSL/TLS negotiation error when connecting ...
A client TLS negotiation error means that a TLS connection initiated by the client was unable to establish a session with the load...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Alright, I think I figured this one out. What happens in that Scrapy’s
TunnelingTCP4ClientEndpoint
does not consume all of the proxy’s response to the CONNECT request (it only checks that the status code is 200), and becauseTunnelingTCP4ClientEndpoint.processProxyResponse()
is called with chunks of the response, the remaining bytes on the transport are fed into the TLS layer, as if sent by the server as a response to theClientHello
, but these are plain ASCII bytes and therefore OpenSSL says “No way!”Step 0: send CONNECT
Step 1: receive first chunk:
Step 2: Scrapy says: “Cool! the proxy is ready, let’s initiate the TLS connection.” a
ClientHello
is sent over the TCP connection…Step 3: there are more bytes from the proxy where the HTTP 200 came from…
Step 4: OpenSSL is not happy with these bytes (there are not a
ServerHello
) and aborts the connectionSimple fix: add a small buffer when reading the initial response from the proxy and detect
\r\n\r\n
before starting the TLS negotiation.Advanced fix: use some HTTP parsing state machine (Twisted’s?) to do this properly.
Thanks very much. 👍