Laden...

WebAPI: Header eingehender HTTP-Requests nur ASCII und nicht ISO-8859-1

Erstellt von GambaJo vor einem Jahr Letzter Beitrag vor einem Jahr 630 Views
GambaJo Themenstarter:in
105 Beiträge seit 2006
vor einem Jahr
WebAPI: Header eingehender HTTP-Requests nur ASCII und nicht ISO-8859-1

Ich habe das Problem, dass ich in meiner WebAPI in einem Request einen Header-Parameter bekomme, der das Paragraph-Zeichen (§) enthält. Dieser wird nicht korrekt angezeigt. Stattdessen sieht man �.
Eigentlich können HTTP-Header ISO-8859-1-Zeichen enthalten. Die WebAPI kann aber anscheinen nur ASCII decodieren. Oder kann man das irgendwie konfigurieren?

16.842 Beiträge seit 2008
vor einem Jahr

"WebAPI" ist ein Marketingname für eine Microsoft Produktfamilie, die es heute bzw. schon seit Jahren so nicht mehr gibt.
Welche Technologie verwendest Du? ASP.NET 4 MVC? ASP.NET 4 WebAPI (was nur eine Middleware für MVC ist)? ASP.NET Core MVC? ASP.NET Core MinimalAPI?
Gibts auch Code, wie Du das Zeug ausliest?

GambaJo Themenstarter:in
105 Beiträge seit 2006
vor einem Jahr

Wenn man ein neues Projekt diesen Typs anlegt, nennt sich das "ASP.NET Core-Web-API". Habe zwei Projekte, .NET Core 3.1 und .NET 6.0.
Methode im Controller sieht so in der Art aus:


[HttpGet]
[ServiceFilter(typeof(TraceReqestAttribute))]
[Produces(ContentTypes.APPLICATIONJASON)]
public async Task<ActionResult<MyEntity>> Get([FromHeader][Required] string id, [FromHeader][Required] string testString)
{

}

Problem ist hier das Argument "testString".

Ich habe es auch mit einem ServiceFilter versucht, um den Parameter möglichst früh abzugreifen:


    public class TraceReqestAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            if (context.ActionArguments?.Count > 0)
            {
               KeyValuePair<string, object>? parameter = actionArguments.FirstOrDefault(x => x.Key.ToLowerInvariant().Equals("testString"));
               _testString = parameter?.Value.ToString();
            }
            base.OnActionExecuting(context);
        }

Leider das gleiche Ergebnis.
Wenn ich an den Parameter kommen würde, bevor er dekodiert wird, könnte ich ihn selbst korrekt dekodieren. Das scheint aber schon vorher zu passieren, denn parameter.Value ist zwar vom Typ object, darin steckt aber schon ein String.

16.842 Beiträge seit 2008
vor einem Jahr

Der frühere Standard RFC2047, der ISO-8859-1 erlaubte, wurde durch RFC7230 abgelöst.
https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4

Historically, HTTP has allowed field content with text in the
ISO-8859-1 charset [ISO-8859-1], supporting other charsets only
through use of [RFC2047] encoding. In practice, most HTTP header
field values use only a subset of the US-ASCII charset [USASCII].
Newly defined header fields SHOULD limit their field values to
US-ASCII octets. A recipient SHOULD treat other octets in field
content (obs-text) as opaque data.

Heute sind nur noch US-ASCII Header erlaubt.
ASP.NET Core an dieser Stelle ist also korrekt implementiert; der Fehler liegt beim Absender.

Kestrel hat mittlerweile ein Setting, das ungültige Header trotzdem erlaubt; ist aber noch nicht teil der Doku
https://github.com/microsoft/reverse-proxy/issues/1346
Deswegen wars wichtig zu wissen, mit welcher ASP.NET Variante (und nicht der Produktfamilie selbst) Du arbeitest.
WebAPI war früher ein eigenes Modul; ist heute nur noch Marketing-Begriff weil es einfach Teil von ASP.NET MVC ist.

Der interessante Teil hier ist (ich habs selbst noch nicht gebraucht)


"RequestHeaderEncoding": "utf-8"


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

Dokumentiert im Reverse Proxy Sample Code
https://github.com/microsoft/reverse-proxy/blob/16ab855a5be980a0cf5fd21e9a7028190b6e7dda/docs/docfx/articles/http-client-config.md#httpclient

GambaJo Themenstarter:in
105 Beiträge seit 2006
vor einem Jahr

Der frühere Standard RFC2047, der ISO-8859-1 erlaubte, wurde durch RFC7230 abgelöst.

Der erklärt einiges.

ASP.NET Core an dieser Stelle ist also korrekt implementiert; der Fehler liegt beim Absender.

Habe es zunächst über Swagger ausprobiert, aber da kann man ja eingeben, was man will. Postman lässt tatsächlich (nur) ISO-8859-1-Zeichen zu. Wenn man was anderes eingeben will, meckert Postman. Das Paragraphen-Zeichen lässt er zu. Daher dachte ich nicht daran, dass es da noch weitere Einschränkungen gibt.

Deswegen wars wichtig zu wissen, mit welcher ASP.NET Variante (und nicht der Produktfamilie selbst) Du arbeitest.
WebAPI war früher ein eigenes Modul; ist heute nur noch Marketing-Begriff weil es einfach Teil von ASP.NET MVC ist.

Ich blicke bei den Begrifflichkeiten nicht mehr durch.

Der interessante Teil hier ist (ich habs selbst noch nicht gebraucht)

  
"RequestHeaderEncoding": "utf-8"  
  
  
private static IHostBuilder CreateHostBuilder(string[] args) =>  
    Host.CreateDefaultBuilder(args)  
        .ConfigureWebHostDefaults(webBuilder =>  
        {  
            webBuilder.UseStartup<Startup>()  
                      .ConfigureKestrel(kestrel =>  
                      {  
                          kestrel.RequestHeaderEncodingSelector = _ => Encoding.Latin1;  
                      });  
        );  
  

Habe ich ausprobiert, aber das Paragraphen-Zeichen wird trotzdem nicht korrekt dekodiert. 🙁