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

Add Unix Sockets #16339

Closed
ThatRendle opened this issue Feb 10, 2016 · 17 comments
Closed

Add Unix Sockets #16339

ThatRendle opened this issue Feb 10, 2016 · 17 comments
Labels
area-System.Net enhancement Product code improvement that does NOT require public API changes/additions os-linux Linux OS (any supported distro) os-mac-os-x macOS aka OSX
Milestone

Comments

@ThatRendle
Copy link

I previously opened #15159 asking about exposing Unix Socket functionality in the CurlHandler, and @stephentoub closed the issue with an excellent explanation.

However, as things in .NET Core Land have progressed, I'm wondering again about this.

Basically, the dotnet/corert project is looking to enable native compilation, which means that C# can potentially be used to create useful, native cross-platform tools, much like Go.

It's very common for these command-line applications or services on Linux to need to communicate over Unix Sockets; for example, /var/run/docker.sock is used to talk to the local Docker daemon.

I had a quick look at the HttpClient and HttpRequestMessage APIs, and the internal handling of HttpRequestMessage by CurlHandler.

There is a potential opportunity to introduce this functionality in an obscure but workable way without breaking or even changing the public API, by using the Properties dictionary on HttpRequestMessage (which is a Dictionary<string, object>). One could set a property in here, perhaps like:

var message = new HttpRequestMessage(HttpMethod.Get, "http://localhost/api/list");
message.Properties["Curl.UnixSocketPath"] = "/var/run/docker.sock";

CurlHandler could then check for this property and set CURLOPT_UNIX_SOCKET_PATH using Interop.Http.EasySetOptionString.

An application or library developer using this feature could easily create extension methods on HttpClient to give themselves a nicer syntax.

If that API would be acceptable, I'd be happy to have a go at implementing it.

Thoughts?

@stephentoub
Copy link
Member

Thanks, @markrendle. This is interesting.

@davidsh, what's the purpose of HttpRequestMessage.Properties? Is it intended for passing arbitrary data to be interpreted by handlers? Or if not, is there some other member somewhere that is?

@davidsh
Copy link
Contributor

davidsh commented Feb 10, 2016

It was intended as an arbitrary dictionary of name/value pairs for developers to pass to their own custom handlers.

We have not, to date, embraced using it as a mechanism to control our own main handers such as HttpClientHandler, WinHttpHandler, CurlHandler. Once we do that, we will need to support it for a long time. If we go down this route, we will want to come up with a useuful and unique mechanism to identity properties that these specific handlers might care about vs. other name/value pairs that a developer wants to use for custom handlers that they write.

cc: @CIPop @SidharthNabar

@friism
Copy link

friism commented Feb 11, 2016

There's some discussion on this on the cURL mailing list.

unix:///var/run/http.socket?http%3A%2F%2Fcurl.haxx.se%2F 

It's pretty nasty though.

Here's another nasty idea:

http+unix://%2Ftmp%2Fprofilesvc.sock/status/pid

@markrendle couldn't you implement a custom handler that does the business (perhaps calling out to cURL)?

@ThatRendle
Copy link
Author

@friism I have thought about that, and of course there's a very nice MIT-licensed CurlHandler that I could just copy and add a couple of lines to... 😎

@stephentoub
Copy link
Member

@SidharthNabar, can you comment on this? With CurlHandler not exposed publically, we're limited in options, and this seems like a reasonable one, i.e. using HttpRequestMessage.Properties to pass additional info into the handler, namely a string to pass to libcurl's CURLOPT_UNIX_SOCKET_PATH option. If in the future we do expose CurlHandler, then we'd also expose this as a property, and the implementation would fall back to continuing to check Properties for compatibility.

@SidharthNabar
Copy link

@stephentoub @markrendle - This is indeed an interesting idea to get developers unblocked.
@vijaykota since this is mainly concerning CurlHandler implementation

Here are the issues we need to worry about:

  1. Clearly defining and testing the behavior on each platform where HttpRequestMessage API is supported (which is all .NET platforms including .NET desktop, .NET Core for UWP, ASP.NET on Windows and ASP.NET on Unix, CoreRT). I assume that we would only change CurlHandler implementation to look for this property - all other handler implementations are a no-op.
  2. When we do expose CurlHandler, would we deprecate this property; or would we continue to support this "side channel"?
  3. The addition of this field to HttpRequestMessage.Properties goes against the object model - since this option is per Handler granularity (if I understand it correctly), but the Properties bag is per request. What happens if I specify different values for different requests being sent by the same handler? What if the handler has already been instantiated and used to send a few requests, and then I set this option on a subsequent request?
  4. Adding this property option and supporting it going forward is almost the same as adding API surface (except with less mechanics). Hence, we should propose and review a good naming, behavior, default value, etc. @markrendle - Would you like to add this info to this thread? (Similar to a new API proposal)

Thanks,
Sid

@stephentoub
Copy link
Member

Thanks, @SidharthNabar.

I assume that we would only change CurlHandler implementation to look for this property - all other handler implementations are a no-op.

Yes, this particular property only makes sense on Unix.

When we do expose CurlHandler, would we deprecate this property; or would we continue to support this "side channel"?

I don't think we can simply stop supporting it, but as I alluded to, I think we'd expose a property, we'd check that property first, and then if that property wasn't set we'd fall back to checking the properties bag purely for compat purposes.

since this option is per Handler granularity (if I understand it correctly), but the Properties bag is per request. What happens if I specify different values for different requests being sent by the same handler? What if the handler has already been instantiated and used to send a few requests, and then I set this option on a subsequent request?

The actual underlying option on libcurl is specified per request as well, as is true for pretty much every other option exposed on the handler. We configure every request individually based on the values on the handler.

Adding this property option and supporting it going forward is almost the same as adding API surface (except with less mechanics)

Yes. That is of course the other option: we could simply expose CurlHandler publically now.

@jstarks
Copy link

jstarks commented Apr 8, 2016

@markrendle I'm working on finishing a fully managed HttpClientHandler that will be able to talk to any stream, including Unix domain sockets, Windows named pipes, and of course TCP, a la Go. This is based on some work started by the aspnet team and abandoned. I am doing this specifically to talk to the Docker daemon running on Linux or Windows. I'm also planning on supporting the connection hijacking stuff that's necessary for Docker attach -- I don't think libcurl can support this, but I'm not sure yet.

I've been planning on incorporating it into https://github.com/ahmetalpbalkan/Docker.DotNet, but we could put it elsewhere once it has stabilized (or even sooner if there is a lot of demand).

I suspect the right long-term thing is to move this functionality into corefx. CoreCLR is currently getting a lot of benefit from wrapping existing platform libraries, but it's a shame to be limited to Windows and Curl levels of functionality in the long run. It's really cool what you can do in Go when everything is written to standard interfaces and can be plugged together in interesting ways.

My two cents, I think it would be unwise to expose CurlHandler functionality from corefx since that will make it harder to eliminate this dependency in the future.

cc/@swernli, @ahmetalpbalkan, @jterry75 FYI

@ThatRendle
Copy link
Author

@ahmetalpbalkan That's brilliant. The main reason I wanted the
functionality personally was for a Docker client, and you've got one, so
thanks!

I agree that fully managed libraries like that are the way to go (no pun
intended), but I think the MS guys are likely to stick to WinHTTP on
Windows. But this is a new ballgame now, and alternative libs are going to
be on a more equal footing (IMHO).

I'll happily contribute to your existing Docker project, and if you elect
to separate out the Handler, I'll help with that too.

On Fri, 8 Apr 2016, 19:33 John Starks, notifications@github.com wrote:

@markrendle https://github.com/markrendle I'm working on finishing a
fully managed HttpClientHandler that will be able to talk to any stream,
including Unix domain sockets, Windows named pipes, and of course TCP, a la
Go. This is based on some work started by the aspnet team and abandoned. I
am doing this specifically to talk to the Docker daemon running on Linux or
Windows. I'm also planning on supporting the connection hijacking stuff
that's necessary for Docker attach -- I don't think libcurl can support
this, but I'm not sure yet.

I've been planning on incorporating it into
https://github.com/ahmetalpbalkan/Docker.DotNet, but we could put it
elsewhere once it has stabilized (or even sooner if there is a lot of
demand).

I suspect the right long-term thing is to move this functionality into
corefx. CoreCLR is currently getting a lot of benefit from wrapping
existing platform libraries, but it's a shame to be limited to Windows and
Curl levels of functionality in the long run. It's really cool what you can
do in Go when everything is written to standard interfaces and can be
plugged together in interesting ways.

My two cents, I think it would be unwise to expose CurlHandler
functionality from corefx since that will make it harder to eliminate this
dependency in the future.

cc/@swernli https://github.com/swernli, @ahmetalpbalkan
https://github.com/ahmetalpbalkan, @jterry75
https://github.com/jterry75 FYI


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
https://github.com/dotnet/corefx/issues/5999#issuecomment-207647232

@ThatRendle
Copy link
Author

@jstarks Sorry, I misaddressed that reply because I was on my phone in the queue for Goofy's Barnstormer.

Is your managed HttpClientHandler anywhere I could access it?

@ThatRendle
Copy link
Author

@stephentoub wrote:

Yes. That is of course the other option: we could simply expose CurlHandler publically now.

and @markrendle nodded enthusiastically. "Yes," he wrote, "you definitely could do that."

😀

@DrSensor
Copy link

Any update/workaround for this?

@stephentoub
Copy link
Member

Any update/workaround for this?

For .NET Core 2.1 we've switched away from using libcurl and are now using a managed implementation. We have not added unix domain socket support to it, and there are currently no plans to do so.

@karelz karelz changed the title System.Net.Http.CurlHandler and Unix Sockets Add Unix Sockets May 22, 2018
@karelz
Copy link
Member

karelz commented Oct 2, 2019

Triage: Per @stephentoub it seems to be irrelevant now (we are deleting libcurl from .NET Core).

@karelz karelz closed this as completed Oct 2, 2019
@tmds
Copy link
Member

tmds commented Oct 3, 2019

Relates to SocketsHttpHandler should support custom Dialers.

@stephentoub
Copy link
Member

stephentoub commented Oct 3, 2019

Relates to

Yes. There are two things here:

  1. We're deleting the internal CurlHandler in .NET 5, so the specific thing this issue relates to won't be available, making the issue moot.
  2. As @tmds highlights, we plan to add the ability to let SocketsHttpHandler use a callback that supports a Uri=>Stream mapping, such that a dev can do whatever they want to open a relevant connection. That includes creating/connecting a Socket with a UnixDomainSocketEndPoint (already available), which then satisfies this request.

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 5.0 milestone Jan 31, 2020
@scalablecory
Copy link
Contributor

This has been resolved via the API added here in .NET 5: #41949

@ghost ghost locked as resolved and limited conversation to collaborators Jan 2, 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 os-linux Linux OS (any supported distro) os-mac-os-x macOS aka OSX
Projects
None yet
Development

No branches or pull requests