Kestrel:默认 Http 标头解码

问题描述 投票:0回答:1

我制作了一个 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 代码也没有帮助。

  • 有没有办法配置 Kestrel 默认情况下如何解码标头值?
  • 如果没有,我该如何编码我的http标头值以便kestrel自动解码? (就像它与 HttpClient 类一起工作的方式一样)
c# character-encoding http-headers kestrel-http-server kestrel
1个回答
0
投票
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>();
            });
}
© www.soinside.com 2019 - 2024. All rights reserved.