Dekompresja żądań w ASP.NET Core

Autor: David Acker

Oprogramowanie pośredniczące dekompresji żądania:

  • Umożliwia punktom końcowym interfejsu API akceptowanie żądań ze skompresowaną zawartością.
  • Używa nagłówka HTTP do automatycznego identyfikowania Content-Encoding i dekompresowania żądań zawierających skompresowaną zawartość.
  • Eliminuje konieczność pisania kodu do obsługi skompresowanych żądań.

Gdy wartość nagłówka Content-Encoding żądania jest zgodna z jednym z dostępnych dostawców dekompresji, oprogramowanie pośredniczące:

  • Używa zgodnego dostawcy do zawijania HttpRequest.Body w odpowiednim strumieniu dekompresji.
  • Content-Encoding Usuwa nagłówek wskazujący, że treść żądania nie jest już kompresowana.

Żądania, które nie zawierają nagłówka Content-Encoding , są ignorowane przez oprogramowanie pośredniczące dekompresacji żądania.

Dekompresji:

  • Występuje, gdy treść żądania jest odczytywana. Oznacza to, że dekompresja występuje w punkcie końcowym powiązania modelu. Treść żądania nie jest zdekompresowana z niecierpliwością.
  • Podczas próby odczytania zdekompresowanej treści żądania z nieprawidłowymi skompresowanymi danymi dla określonego Content-Encodingobiektu zgłaszany jest wyjątek. Brotli może zgłaszać: System.InvalidOperationExceptionDecoder ran into invalid data. Deflate i GZip mogą zgłaszać :System.IO.InvalidDataExceptionThe archive entry was compressed using an unsupported compression method.

Jeśli oprogramowanie pośredniczące napotka żądanie ze skompresowaną zawartością, ale nie może go zdekompresować, żądanie zostanie przekazane do następnego delegata w potoku. Na przykład żądanie z nieobsługiwaną Content-Encoding wartością nagłówka lub wieloma Content-Encoding wartościami nagłówka jest przekazywanych do następnego delegata w potoku.

Konfigurowanie

Poniższy kod używa instrukcji i UseRequestDecompression w celu włączenia dekompresji żądań dla typów domyślnychContent-Encoding:AddRequestDecompression(IServiceCollection)

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRequestDecompression();

var app = builder.Build();

app.UseRequestDecompression();

app.MapPost("/", (HttpRequest request) => Results.Stream(request.Body));

app.Run();

Domyślni dostawcy dekompresji

Wartości Content-Encoding nagłówka obsługiwane przez oprogramowanie pośredniczące dekompresji żądań są domyślnie wymienione w poniższej tabeli:

Content-Encoding wartości nagłówka opis
br Format skompresowanych danych Brotli
deflate Format skompresowanych danych DEFLATE
gzip Format pliku Gzip

Niestandardowi dostawcy dekompresji

Obsługę niestandardowych kodowań można dodać przez utworzenie niestandardowych klas dostawcy dekompresji, które implementują :IDecompressionProvider

public class CustomDecompressionProvider : IDecompressionProvider
{
    public Stream GetDecompressionStream(Stream stream)
    {
        // Perform custom decompression logic here
        return stream;
    }
}

Niestandardowi dostawcy dekompresji są zarejestrowani wraz z odpowiednimi Content-Encoding wartościami RequestDecompressionOptions nagłówka:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRequestDecompression(options =>
{
    options.DecompressionProviders.Add("custom", new CustomDecompressionProvider());
});

var app = builder.Build();

app.UseRequestDecompression();

app.MapPost("/", (HttpRequest request) => Results.Stream(request.Body));

app.Run();

Limity rozmiaru żądań

Aby chronić przed bombami zip lub bombami dekompresyjnymi:

  • Maksymalny rozmiar zdekompresowanej treści żądania jest ograniczony do limitu rozmiaru treści żądania wymuszonego przez punkt końcowy lub serwer.
  • Jeśli liczba bajtów odczytanych ze strumienia treści żądania dekompresowanego przekracza limit, zgłaszany jest wyjątek InvalidOperationException, aby zapobiec odczytywaniu dodatkowych bajtów ze strumienia.

W kolejności pierwszeństwa maksymalny rozmiar żądania dla punktu końcowego jest ustawiany przez:

  1. IRequestSizeLimitMetadata.MaxRequestBodySize, na przykład RequestSizeLimitAttribute lub DisableRequestSizeLimitAttribute dla punktów końcowych MVC.
  2. Globalny limit IHttpMaxRequestBodySizeFeature.MaxRequestBodySizerozmiaru serwera. MaxRequestBodySize można zastąpić dla żądania wartością IHttpMaxRequestBodySizeFeature.MaxRequestBodySize, ale domyślnie jest to limit skonfigurowany dla implementacji serwera internetowego.
Implementacja serwera sieci Web Konfiguracja widoku MaxRequestBodySize
HTTP.sys HttpSysOptions.MaxRequestBodySize
IIS IISServerOptions.MaxRequestBodySize
Kestrel KestrelServerLimits.MaxRequestBodySize

Ostrzeżenie

Wyłączenie limitu rozmiaru treści żądania stanowi zagrożenie bezpieczeństwa w odniesieniu do niekontrolowanych zużycia zasobów, szczególnie jeśli treść żądania jest buforowana. Upewnij się, że obowiązują zabezpieczenia w celu ograniczenia ryzyka ataków typu "odmowa usługi " (DoS).

Dodatkowe zasoby