是否可以在 C# 的 HttpClient 中设置自定义 DNS 解析器
Is it possible to set custom DNS resolver in C#'s HttpClient
我到底想要什么:
public static CustomDnsResolver : Dns
{
.....
}
public static void Main(string[] args)
{
var httpClient = new HttpClient();
httpClient.Dns(new CustomDnsResolver());
}
基本上我只是想在 HttpClient 中使用我的自定义 DNS 解析器而不是系统默认解析器,有什么方法可以实现吗?
您的用例正是 Microsoft 构建 HttpClient 堆栈的原因。它允许您在 HttpMessageHandler
class 的帮助下将业务逻辑分层 class。您可以在 ms docs or visualstudiomagazine
中找到一些示例
void Main()
{
var dnsHandler = new DnsHandler(new CustomDnsResolver());
var client = new HttpClient(dnsHandler);
var html = client.GetStringAsync("http://google.com").Result;
}
public class DnsHandler : HttpClientHandler
{
private readonly CustomDnsResolver _dnsResolver;
public DnsHandler(CustomDnsResolver dnsResolver)
{
_dnsResolver = dnsResolver;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var host = request.RequestUri.Host;
var ip = _dnsResolver.Resolve(host);
var builder = new UriBuilder(request.RequestUri);
builder.Host = ip;
request.RequestUri = builder.Uri;
return base.SendAsync(request, cancellationToken);
}
}
public class CustomDnsResolver
{
public string Resolve(string host)
{
return "127.0.0.1";
}
}
不确定这是否适用于所有情况,但它对我的情况非常有效,即使在使用 HTTPS 时也是如此。因此,您要做的是将 URL 中的主机替换为您的自定义解析器已解析的实际 IP-address,然后只需添加一个带有主机名的“主机”header。像这样:
var requestUri = new Uri("https://123.123.123.123/some/path");
using var request = new HttpRequestMessage(HttpMethod.Get, requestUri);
request.Headers.TryAddWithoutValidation("host", "www.host-name.com");
using var response = await httpClient.SendAsync(request);
我希望这会有所帮助,因为这是我第一次 运行 解决这个问题,而且我以前从未能够解决它。
我到底想要什么:
public static CustomDnsResolver : Dns
{
.....
}
public static void Main(string[] args)
{
var httpClient = new HttpClient();
httpClient.Dns(new CustomDnsResolver());
}
基本上我只是想在 HttpClient 中使用我的自定义 DNS 解析器而不是系统默认解析器,有什么方法可以实现吗?
您的用例正是 Microsoft 构建 HttpClient 堆栈的原因。它允许您在 HttpMessageHandler
class 的帮助下将业务逻辑分层 class。您可以在 ms docs or visualstudiomagazine
void Main()
{
var dnsHandler = new DnsHandler(new CustomDnsResolver());
var client = new HttpClient(dnsHandler);
var html = client.GetStringAsync("http://google.com").Result;
}
public class DnsHandler : HttpClientHandler
{
private readonly CustomDnsResolver _dnsResolver;
public DnsHandler(CustomDnsResolver dnsResolver)
{
_dnsResolver = dnsResolver;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var host = request.RequestUri.Host;
var ip = _dnsResolver.Resolve(host);
var builder = new UriBuilder(request.RequestUri);
builder.Host = ip;
request.RequestUri = builder.Uri;
return base.SendAsync(request, cancellationToken);
}
}
public class CustomDnsResolver
{
public string Resolve(string host)
{
return "127.0.0.1";
}
}
不确定这是否适用于所有情况,但它对我的情况非常有效,即使在使用 HTTPS 时也是如此。因此,您要做的是将 URL 中的主机替换为您的自定义解析器已解析的实际 IP-address,然后只需添加一个带有主机名的“主机”header。像这样:
var requestUri = new Uri("https://123.123.123.123/some/path");
using var request = new HttpRequestMessage(HttpMethod.Get, requestUri);
request.Headers.TryAddWithoutValidation("host", "www.host-name.com");
using var response = await httpClient.SendAsync(request);
我希望这会有所帮助,因为这是我第一次 运行 解决这个问题,而且我以前从未能够解决它。