我制作了一个 ASP .Net Core 2.1 WebAPI,它位于我无法控制的代理后面。此代理添加可能包含非 ASCII 字符的 http 标头 例如 Umlaute ä、ü 或 ö 作为标题值的一部分。
Web 服务器上安装的 Hosting Bundle 版本为 2.2.4
如果我可以使用进程内托管运行 WebAPI,一切都会正常工作,但我们需要目标框架为 .Net Framework 4.7.2,因此只能使用进程外托管。
如果请求具有带有 Umlaute (ä, ö, ü) 的 Http 标头,我们会从 Kestrel 收到 BadRequest 异常 (400)。在 VisualStudio 20017 中调试时,我使用 Postman 对本地主机进行了测试,并在 Http 标头值中尝试了一大堆不同的编码(Base64、UTF-8、Mime、ISO 8859-1),但每一个都失败。
Microsoft.AspNetCore.Server.Kestrel[17]
Connection id "0HLM7UD7429GT" bad request data: "Malformed request: invalid headers."
这种情况发生在红隼的级别如此低的情况下,我找不到捕获异常并自己处理它的方法。我尝试使用 ErrorHandling Middleware 和 ActionFilters 来捕获它。
但是,如果我在 xUnit 测试中使用 System.Net.Http.HttpClient 类并添加带有 Umlaut 值的 HttpHeader,Kestrel 会接受请求并且一切正常。
System.Net.Http.HttpClient client = new Client();
client.DefaultRequestHeaders.Add("myHeader", "ä");
var httpResponse = await Client.GetAsync("/api/values");
httpResponse.EnsureSuccessStatusCode();
因此,在 HttpClient 和 Kestrel 代码中必须实现某种秘密编码/解码机制,但我还没有找到任何有关它的文档。调试 .net 代码也没有帮助。
opts.RequestHeaderEncodingSelector = _ => Encoding.Latin1; })
我发现使用此代码可以解决。 这是 Progaram.cs 中的完整代码:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.ConfigureKestrel(opts => { opts.AddServerHeader = false; opts.RequestHeaderEncodingSelector = _ => Encoding.Latin1; })
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.ConfigureAppConfiguration((builderContext, config) =>
{
config.AddEnvironmentVariables();
})
.ConfigureLogging((hostingContext, logging) =>
{
logging.ClearProviders();
_environmentName = hostingContext.HostingEnvironment.EnvironmentName;
//logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
//logging.AddConsole();
//logging.AddDebug();
//logging.AddEventSourceLogger();
})
.UseStartup<Startup>();
});
}