如何在 dotnet 核心中为 HttpClient 指定 HTTP/2 "prior knowledge" 模式?
How to specify HTTP/2 "prior knowledge" mode for HttpClient in dotnet core?
使用 dotnet Core 3.1,以下服务器接受 HTTP/2 个请求:
using System;
using System.Threading.Tasks;
using System.Net.Http;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore;
using System.Threading;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core;
namespace http2
{
class Program
{
static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ListenLocalhost(8080, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2; // this line is important
});
});
}
class Startup
{
public void Configure(IApplicationBuilder app)
{
app.Run(context => ProcessAsync(context));
}
internal async Task<bool> ProcessAsync(HttpContext context)
{
await context.Response.WriteAsync("This is the response: toto");
return true;
}
}
}
例如,如果您尝试以下操作,您会得到响应:
curl --silent --http2-prior-knowledge http://localhost:8080
我的问题是如何实际执行 curl
正在做的事情?但是在 C# 中。
我试过:
static void ClientCode(object parameter)
{
SocketsHttpHandler handler = new SocketsHttpHandler();
using (var client = new HttpClient(handler))
{
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:8080");
request.Version = new Version(2, 0);
var response = client.SendAsync(request).Result;
if (response.IsSuccessStatusCode)
{
var s = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(s);
}
}
}
但我只是遇到了一个例外。
是否可以在 C# 和 dotnet Core 中将 prior knowledge mode 与 HttpClient 一起使用?
My question is about how to actually do what curl is doing ? But in C#.
请尝试将 System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport
开关设置为 true
,如下所示。
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
SocketsHttpHandler handler = new SocketsHttpHandler();
using (var client = new HttpClient(handler))
{
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:8080");
request.Version = new Version(2, 0);
var response = client.SendAsync(request).Result;
if (response.IsSuccessStatusCode)
{
var s = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(s);
}
}
测试结果
我在 net5.0 上,只有在显式设置 VersionPolicy 时才能使其工作
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:5001/test");
request.Version = new Version(2, 0);
request.VersionPolicy = HttpVersionPolicy.RequestVersionExact;
使用 dotnet Core 3.1,以下服务器接受 HTTP/2 个请求:
using System;
using System.Threading.Tasks;
using System.Net.Http;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore;
using System.Threading;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core;
namespace http2
{
class Program
{
static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ListenLocalhost(8080, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2; // this line is important
});
});
}
class Startup
{
public void Configure(IApplicationBuilder app)
{
app.Run(context => ProcessAsync(context));
}
internal async Task<bool> ProcessAsync(HttpContext context)
{
await context.Response.WriteAsync("This is the response: toto");
return true;
}
}
}
例如,如果您尝试以下操作,您会得到响应:
curl --silent --http2-prior-knowledge http://localhost:8080
我的问题是如何实际执行 curl
正在做的事情?但是在 C# 中。
我试过:
static void ClientCode(object parameter)
{
SocketsHttpHandler handler = new SocketsHttpHandler();
using (var client = new HttpClient(handler))
{
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:8080");
request.Version = new Version(2, 0);
var response = client.SendAsync(request).Result;
if (response.IsSuccessStatusCode)
{
var s = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(s);
}
}
}
但我只是遇到了一个例外。
是否可以在 C# 和 dotnet Core 中将 prior knowledge mode 与 HttpClient 一起使用?
My question is about how to actually do what curl is doing ? But in C#.
请尝试将 System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport
开关设置为 true
,如下所示。
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
SocketsHttpHandler handler = new SocketsHttpHandler();
using (var client = new HttpClient(handler))
{
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:8080");
request.Version = new Version(2, 0);
var response = client.SendAsync(request).Result;
if (response.IsSuccessStatusCode)
{
var s = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(s);
}
}
测试结果
我在 net5.0 上,只有在显式设置 VersionPolicy 时才能使其工作
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:5001/test");
request.Version = new Version(2, 0);
request.VersionPolicy = HttpVersionPolicy.RequestVersionExact;