snoyberg / http-client

An HTTP client engine, intended as a base layer for more user-friendly packages.
274 stars 192 forks source link

Implement SOCKS4 proxy support #449

Open ghost opened 3 years ago

ghost commented 3 years ago

I would find SOCKS4 proxy support useful in http-client. SSH provides an easy way to set up a SOCKS4 proxy on your local machine to a remote SSH server. HTTP requests could then be proxied through the remote SSH server.

I have been considering implementing SOCKS4 support for http-client. The Proxy type, which currently only represents HTTP proxies, would be replaced with a choice of either HTTP Proxy or SOCKS4.

Would this feature be useful and accepted into the code base? Is there already a way to do this in a custom way? I thought that withConnection might be useful for implementing the initial SOCKS4 connection setup, but it seems that connectionRead does not block.

Any suggestions would be appreciated.

snoyberg commented 3 years ago

The connection page, which lives underneath http-client-tls, already supports SOCKS proxies. You can configure it here:

https://www.stackage.org/haddock/nightly-2020-12-10/http-client-tls-0.3.5.3/Network-HTTP-Client-TLS.html#v:mkManagerSettings

If I'm not mistaken, using that will automatically use SOCKS proxying for both TLS and non-TLS connections.

ghost commented 3 years ago

Thanks for the swift reply. I'm going to give that a shot.

cblp commented 3 years ago

I'm trying to debug this.

  1. I set environment variable to https_proxy='socks5://localhost:9150'
  2. A manager created with newTlsManager uses the proxy.
  3. A manager created with newTlsManagerWith tlsManagerSettings doesn't use proxy.

I suppose this is because newTlsManagerWith resets managerTlsProxyConnection after it is set to use SOCKS proxy: https://github.com/snoyberg/http-client/blob/master/http-client-tls/Network/HTTP/Client/TLS.hs#L214

cblp commented 3 years ago

Also, it's very hard to debug the library, because

  1. there seem to be 2 different layers of proxy (CKProxy in http-client and SockSettings in -tls)
  2. both Manager and Request are being rewritten too many times, especially 2 times in a row in responseOpen:
(manager, req0) <- getModifiedRequestManager manager' inputReq
go manager (redirectCount req0) req0
...
go manager0 count req' =
  ...
  getModifiedRequestManager manager0 req
diqye commented 2 years ago

image

It is working as well for me @snoyberg