如何(很好地)通过.NET Core中的unix域套接字发送HTTP



在.NET Core中,我可以通过unix域套接字发送原始HTTP,但我希望使用库中的HTTP处理类,而不是将自己的HTTP处理拼凑在一起。

这是我目前正在工作但很难看的代码:

const string HTTP_REQUEST = "POST /containers/foo/kill?signal=SIGHUP HTTP/1.0rn" +
"Host: localhostrn" +
"Accept: */*rnrn";
socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);
socket.ReceiveTimeout = 2000; // 2 seconds
var endpoint = new UnixDomainSocketEndPoint("/var/run/docker.sock");
socket.Connect(endpoint);
byte[] requestBytes = Encoding.ASCII.GetBytes(HTTP_REQUEST);
socket.Send(requestBytes);
byte[] recvBytes = new byte[1024];
int numBytes = socket.Receive(recvBytes, 1024, SocketFlags.None);
socket.Disconnect(false);
Console.WriteLine( Encoding.ASCII.GetString(recvBytes));

有没有一种方法可以使用.NET核心库中的类来处理unix域套接字上的HTTP请求和响应?

[edit]在这个特定的用例中,我知道有Docker.DotNet库可以实现我想要的,但这个问题总体上仍然值得一问。

在.NET 5中,向SocketsHttpHandler添加了一个ConnectCallback,这让这变得更容易了,并不是说这是唯一的方法,但对我来说很有效:

private static readonly HttpClient _httpClient = new HttpClient(new SocketsHttpHandler
{
ConnectCallback = async (context, token) =>
{
var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);
var endpoint = new UnixDomainSocketEndPoint("/var/run/test.sock");
await socket.ConnectAsync(endpoint);
return new NetworkStream(socket, ownsSocket: true);
}
});
public async Task TestSocket(string url)
{
var result = await _httpClient.GetStringAsync(url);
}