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

时间:2018-11-29 20:35:46

标签: c# http .net-core unix-socket

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

这是我当前的工作代码,但很难看:

const string HTTP_REQUEST = "POST /containers/foo/kill?signal=SIGHUP HTTP/1.0\r\n" +
    "Host: localhost\r\n" +
    "Accept: */*\r\n\r\n";
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 Core库中的类通过unix域套接字处理HTTP请求和响应?

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

1 个答案:

答案 0 :(得分:1)

在 .NET 5 中,一个 ConnectCallback 被添加到 SocketsHttpHandler 这使得这更容易一些,并不是说这是唯一的方法,但对我有用:

    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);
    }