I previously opened dotnet/runtime#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?
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?
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
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)?
@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... :sunglasses:
@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.
@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:
Thanks,
Sid
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.
@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
@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, [email protected] 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
@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?
@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."
:grinning:
Any update/workaround for this?
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.
Triage: Per @stephentoub it seems to be irrelevant now (we are deleting libcurl from .NET Core).
Relates to SocketsHttpHandler should support custom Dialers.
Relates to
Yes. There are two things here:
This has been resolved via the API added here in .NET 5: https://github.com/dotnet/runtime/issues/41949
Most helpful comment
Yes. There are two things here: