Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Socks4/5 proxy in HttpClient/WebRequests #17740

Closed
abdullah2993 opened this issue Jun 29, 2016 · 31 comments · Fixed by #48883
Closed

Support for Socks4/5 proxy in HttpClient/WebRequests #17740

abdullah2993 opened this issue Jun 29, 2016 · 31 comments · Fixed by #48883
Labels
area-System.Net enhancement Product code improvement that does NOT require public API changes/additions help wanted [up-for-grabs] Good issue for external contributors in-pr There is an active PR which will close this issue when it is merged
Milestone

Comments

@abdullah2993
Copy link

Any chances of this happening?

@davidsh
Copy link
Contributor

davidsh commented Jun 30, 2016

cc: @stephentoub @CIPop @himadrisarkar

@CIPop
Copy link
Member

CIPop commented Jul 5, 2016

The current status:

  • CoreFX (Desktop): WinHTTP does not support SOCKS at all.
  • Windows Store apps: WinINet has support for SOCKS4 but not SOCKS4a or 5. I'm not sure we're exposing this through the Windows.Web APIs.
  • non-Windows: I believe the CURL supports SOCKS. @stephentoub may be able to answer if this is currently exposed and working.

@abdullah2993, can you please share more details about the scenario?

@joshfree
Copy link
Member

@ericeil can you comment on linux/mac socks4/5 proxy?

@abdullah2993
Copy link
Author

@CIPop It would be helpful in almost all possible scenarios where you require a proxy besides socks4/5 proxies are available in abundance and most of the HTTP Stacks support them.
Another plus point would be integration with TOR

@ericeil
Copy link
Contributor

ericeil commented Jul 11, 2016

It looks like CURL does support SOCKS4, 4a, and 5. It also looks like this may already be supported in the current System.Net implementation on Linux/Mac, by setting the request's Proxy property to something that returns, e.g., socks5://proxyhost.domain.com.

@CIPop
Copy link
Member

CIPop commented Jul 11, 2016

@himadrisarkar In order to support this on Windows, the underlying components (WinINet and WinHTTP) need to be changed. Please follow-up with their respective owners internally.

@abdullah2993
Copy link
Author

Any updates?

@davidsh
Copy link
Contributor

davidsh commented Feb 6, 2017

There are no current plans to implement this functionality. Implementing this on Window will require changes to the native HTTP stacks. A linux-only implementation might be possible.

Feel free to submit a PR for this if you need it soon.

@karelz
Copy link
Member

karelz commented Feb 23, 2017

Windows doesn't support it (we would need managed implementation or use curl).
Curl supports it - we may support it there.

@coderb
Copy link

coderb commented Jun 10, 2017

How about creating a pluggable proxy transport underneath the HttpWebRequest/Response?

In other words, allow the user application to register a proxy scheme and have an API for implementing it. The SOCKS protocol is extremely simple but I understand you not wanting to explicitly support it. This would allow others who need it to get by with a "good enough" internal implementation that MS is not on the hook for and have a low support burden.

From what I can tell this would likely involve altering ServicePointManager et al to allow custom ServicePoints. Seems relatively straightforward.

@lobster2012-user
Copy link

Add https/socks5 for SocketsHttpClient.
Thank you.

@mkurz
Copy link

mkurz commented Jul 16, 2018

+1

@Priya91
Copy link
Contributor

Priya91 commented Aug 29, 2018

+1 Please add support for socketshttpclient, and i assume clientwebsocket will automatically benefit

microsoft/live-share#844 (comment)

@karelz
Copy link
Member

karelz commented Aug 29, 2018

Please upvote the top post - that is searchable and sortable via GitHub ;)

@zepprebel
Copy link

how many thumbs up need? to release that

@karelz
Copy link
Member

karelz commented Apr 13, 2019

50+ will start to be interesting ...

@vfrz
Copy link

vfrz commented Oct 26, 2019

Interested about this feature too. Should be possible to implement it through SocketsHttpHandler.

@vova-lantsov-dev
Copy link

There is also an implementation of this feature https://github.com/MihaZupan/HttpToSocks5Proxy

@karelz
Copy link
Member

karelz commented Jan 10, 2020

Maybe we can ask @MihaZupan to chime in, how difficult it would be to port into our repo ...
Anyone is willing to out up a PR?

@MihaZupan
Copy link
Member

For people that just want to use a socks5 proxy in their .Net apps right away, the library mentioned above should work fine and should work in every scenario as it implements the IWebProxy interface.

Having built-in support would be better in terms of performance overhead and resolving issues (some error information is swallowed by the library).

Having looked at the code, adding support shouldn't be too difficult now that there is a common managed implementation between platforms. It also likely wouldn't affect the public API surface at all as the type of proxy (http/socks4/socks4a/socks5) can be specified in the Uri scheme.

I think this is reasonable to implement as I've received a lot of requests for this functionality from the community, hence the aforementioned library.

@MihaZupan
Copy link
Member

If any community member would like to take this and try implementing it, ping me so I can assign the issue to you. I can help out with PR review.

Otherwise I will look into this in the following weeks.

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the Future milestone Jan 31, 2020
@karelz karelz modified the milestones: Future, 5.0 Feb 20, 2020
@karelz karelz removed this from the 5.0 milestone May 6, 2020
@caunt
Copy link

caunt commented Jan 20, 2021

+1

@huoyaoyuan
Copy link
Member

@MihaZupan I'm interested in this because I've read socks5 spec and done some tiny implementation.

@MihaZupan
Copy link
Member

@huoyaoyuan That's great to hear!

The idea would be to allow this:

var handler = new HttpClientHandler
{
    Proxy = new WebProxy("socks5://127.0.0.1", 9050)
};
var httpClient = new HttpClient(handler);

Console.WriteLine(await httpClient.GetStringAsync("https://httpbin.org/ip"));

Essentially allowing socks* Uri schemes for IWebProxys and adding logic to handle them inside handlers.
Just like we have special code-paths to handle http/connect proxying, we would have another one for establishing a socks tunnel.

This will require changes in HttpConnectionPool, AuthenticationHelper and similar, but won't affect the public API.

I'll be happy to assist if you need help with the implementation/in PR review.

@huoyaoyuan
Copy link
Member

@MihaZupan How will this interop with ConnectCallback?
For http proxy, ConnectCallback will deal with a http CONNECT request. But there isn't similar concept for socks.

@MihaZupan
Copy link
Member

MihaZupan commented Feb 9, 2021

ConnectCallback will be used for the connection to the proxy server - same as with an http proxy (including connect).

In case of an HTTP CONNECT, we create the tunnel by asking the connection pool manager to send a new HttpRequestMessage with the Connect method to the proxy. This request ends up using the ConnectToTcpHostAsync helper that takes ConnectCallback into account.
The tunnel (Stream) we use for the actual request is the content stream of the Connect response.

For a Socks tunnel, we would instead use the ConnectToTcpHostAsync helper (to connect to the proxyUri) and perform a Socks tunnel handshake (for the actual host).

@huoyaoyuan
Copy link
Member

I'm meaning that if a user specifies both Socks proxy and ConnectCallback, what will they get?

@MihaZupan
Copy link
Member

MihaZupan commented Feb 9, 2021

ConnectCallback will still be used to establish the connection.
We will use the callback with the Uri of the proxy.

What we do after that (socks handshake / http connect ...) stays the same, regardless of whether the callback was used.

So the behavior for socks would be the same as for an http proxy - if specified, the callback is used for the connection to the proxy (as that is the only connection we're creating ourselves).

ConnectCallback is just used for creating the underlying transport stream. It doesn't care about whether we'll be layering socks/tls on top of it.

@huoyaoyuan
Copy link
Member

So, the InitialRequestMessage will be just the original message? Sure

@MihaZupan
Copy link
Member

So, the InitialRequestMessage will be just the original message?

Yes

@huoyaoyuan
Copy link
Member

After reading implementation, I'm not sure how to carry the information from request to HttpConnectionPool. HttpConnectionKind has complex members because http proxy interacts differently with http and https. However, socks proxy is at socket level and orthogonal with http kind. A new field in HttpConnectionKey feels better to me.

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Mar 9, 2021
@ghost ghost added in-pr There is an active PR which will close this issue when it is merged and removed in-pr There is an active PR which will close this issue when it is merged labels Apr 6, 2021
@karelz karelz modified the milestones: Future, 6.0.0 May 20, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Jun 19, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Net enhancement Product code improvement that does NOT require public API changes/additions help wanted [up-for-grabs] Good issue for external contributors in-pr There is an active PR which will close this issue when it is merged
Projects
None yet
Development

Successfully merging a pull request may close this issue.