-
A problem that arises from If A workaround like this also makes it difficult to use a Example code for discussion (I'm sure this can be improved in a myriad ways): public async Task<HttpResponseMessage> GetFromIp(IPAddress ip, Uri uri, CancellationToken cancellationToken)
{
var client = new HttpClient(SocketHandlerWithIpPreference(ip));
var request = new HttpRequestMessage(HttpMethod.Get, uri);
return await client.SendAsync(request, cancellationToken);
}
private SocketsHttpHandler SocketHandlerWithIpPreference(IPAddress ip) => new()
{
ConnectCallback = async (context, cancellationToken) =>
{
var dnsEntries = await Dns.GetHostEntryAsync(context.DnsEndPoint.Host, AddressFamily.Unspecified, cancellationToken);
var addresses = dnsEntries.AddressList;
if (addresses.Contains(ip))
{
addresses = [ip];
}
var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
try
{
await socket.ConnectAsync(addresses, context.DnsEndPoint.Port, cancellationToken);
return new NetworkStream(socket, ownsSocket: true);
}
catch
{
socket.Dispose();
throw;
}
}
}; Would it make sense to add support for supplying IP address directly when making requests using |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 3 replies
-
Note this can be a benefit on some restricted corporate/single-purpose networks, which may block DNS to reduce potential attack surface. |
Beta Was this translation helpful? Give feedback.
-
If you want to send a request to a specific Uri, you can set the IP as the request uri, and manually add the host header. No need to go through E.g. something like HttpRequestMessage request = new(HttpMethod.Get, "https://3.230.23.0/get");
request.Headers.Host = "httpbin.org";
using HttpResponseMessage response = await client.SendAsync(request); |
Beta Was this translation helpful? Give feedback.
-
In fact, many components directly rely on the static class Dns. DotNet does not have an abstract DnsProvider, which is designed like TimeProvider. HttpClient may be able to rely on DnsProvider instead, but this is almost impossible for Socket. |
Beta Was this translation helpful? Give feedback.
-
I really think this should be part of HttpRequestMessage and not exposed on HttpClient. |
Beta Was this translation helpful? Give feedback.
That's actually what I did initially, but that fails with "The SSL connection could not be established" against e.g. redirects to Cloudflare-proxied domains (as in, initial target is not Cloudflare-proxied, but the 302 it returns is proxied) if using a
HttpClientHandler
withAllowAutoRedirect
set to true. Disabling that and handling redirects myself is an alternative that works as well.I hadn't figured out the exact cause of the failures when I made this post yesterday, I consider handling the redirects myself an acceptable workaround actually, and have now thrown out the
ConnectCallback
approach, so thanks for getting me to take another look at it @MihaZupan!I still feel that this ques…