phifi
phifi

Reputation: 3028

Kestrel: Default Http Header Decoding

I made an ASP .Net Core 2.1 WebAPI which sits behind a Proxy i have no control of. This Proxy adds http headers which possibly contains non ASCII characters like Umlaute ä, ü or ö as part of the header value.

Hosting Bundle installed at the WebServer is version 2.2.4

If i could run the WebAPI with Inprocess hosting, everything would work fine, but we need the target framework to be .Net Framework 4.7.2 and therefore only outofprocess hosting is possible.

If the request has Http headers with Umlaute (ä, ö, ü) we get a BadRequest Exception (400) from Kestrel. I tested this with Postman against the localhost when debugging in VisualStudio 20017 and tried a whole bunch of different Encodings in the Http Header value (Base64, UTF-8, Mime, ISO 8859-1) failing with every single one.

  Microsoft.AspNetCore.Server.Kestrel[17]
  Connection id "0HLM7UD7429GT" bad request data: "Malformed request: invalid headers."

This happens at such a low level of kestrel, that i have found no way of catching the Exception and handle it for myself. I tried to catch it with an ErrorHandling Middleware and with ActionFilters.

But, if I use the System.Net.Http.HttpClient class in my xUnit Tests and add an HttpHeader with Umlaut values, Kestrel accepts the Request and everything works fine.

  System.Net.Http.HttpClient client = new Client();
  client.DefaultRequestHeaders.Add("myHeader", "ä");
  var httpResponse = await Client.GetAsync("/api/values");
  httpResponse.EnsureSuccessStatusCode();

So there must be some sort of secret Encoding/Decoding mechanism implemented in the HttpClient and the Kestrel Code but i haven't found any documentation about it. Also debugging into the .net code didn't help.

Upvotes: 1

Views: 1772

Answers (2)

phifi
phifi

Reputation: 3028

To resolve this issue in .Net Core 6 or newer use the following code to configure the Kestrel WebApplication Host:

    WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
    builder.WebHost.ConfigureKestrel(options => { options.RequestHeaderEncodingSelector = _ => Encoding.Latin1; });

Documentation on 'Configure options for the ASP.NET Core Kestrel web server'

Documentation on 'KestrelServerOptions.RequestHeaderEncodingSelector Property'

Upvotes: 1

thuleduy
thuleduy

Reputation: 91

I've resolved this problem using this code.

ConfigureKestrel(options => {options.RequestHeaderEncodingSelector = _ => Encoding.Latin1; })

This is the full code in Program.cs:

public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder => {
                webBuilder
                    .ConfigureKestrel(options => { options.AddServerHeader = false; options.RequestHeaderEncodingSelector = _ => Encoding.Latin1; })
                    .UseStartup<Startup>();
            });
}

Upvotes: 1

Related Questions