How to make the .net HttpClient use http 2.0?
1.Make sure you are on the latest version of Windows 10.
2.Install WinHttpHandler:
Install-Package System.Net.Http.WinHttpHandler
3.Extend WinHttpHandler to add http2.0 support:
public class Http2CustomHandler : WinHttpHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
request.Version = new Version("2.0");
return base.SendAsync(request, cancellationToken);
}
}
4.Pass above handler to the HttpClient constructor
using (var httpClient = new HttpClient(new Http2CustomHandler()))
{
// your custom code
}
In addition to WinHttpHandler
(as described in Shawinder Sekhon's answer), .NET Core 3.0 includes HTTP/2 support in the default SocketsHttpHandler
(#30740). Since HTTP/1.1 is still the default, either the default must be changed by setting HttpClient.DefaultRequestVersion
, or Version
must be changed on each request. The version can be set when the request message is created:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://myapp.cloudapp.net/");
HttpResponseMessage response = await client.SendAsync(
new HttpRequestMessage(HttpMethod.Get, "RestController/Native")
{
Version = HttpVersion.Version20,
});
if (response.IsSuccessStatusCode)
{
await response.Content.CopyToAsync(new MemoryStream(buffer));
}
}
Or by using a custom HttpMessageHandler
, such as:
public class ForceHttp2Handler : DelegatingHandler
{
public ForceHttp2Handler(HttpMessageHandler innerHandler)
: base(innerHandler)
{
}
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Version = HttpVersion.Version20;
return base.SendAsync(request, cancellationToken);
}
}
which can delegate to SocketsHttpHandler
, WinHttpHandler
, or any other HttpMessageHandler
which supports HTTP/2:
using (var client = new HttpClient(new ForceHttp2Handler(new SocketsHttpHandler())))
{
client.BaseAddress = new Uri("https://myapp.cloudapp.net/");
HttpResponseMessage response = await client.GetAsync("RestController/Native");
if (response.IsSuccessStatusCode)
{
await response.Content.CopyToAsync(new MemoryStream(buffer));
}
}