Decompressione delle richieste in ASP.NET Core

Di David Acker

Middleware di decompressione della richiesta:

  • Consente agli endpoint API di accettare richieste con contenuto compresso.
  • Usa l'intestazione Content-Encoding HTTP per identificare e decomprimere automaticamente le richieste che contengono contenuto compresso.
  • Elimina la necessità di scrivere codice per gestire le richieste compresse.

Quando il valore dell'intestazione Content-Encoding in una richiesta corrisponde a uno dei provider di decompressione disponibili, il middleware:

  • Usa il provider corrispondente per eseguire il wrapping di HttpRequest.Body in un flusso di decompressione appropriato.
  • Rimuove l'intestazione Content-Encoding , a indicare che il corpo della richiesta non è più compresso.

Le richieste che non includono un'intestazione Content-Encoding vengono ignorate dal middleware di decompressione della richiesta.

Decompressione:

  • Si verifica quando il corpo della richiesta viene letto. Ovvero, la decompressione si verifica nell'endpoint nell'associazione di modelli. Il corpo della richiesta non viene decompresso in modo eager.
  • Quando si tenta di leggere il corpo della richiesta decompressa con dati compressi non validi per l'oggetto specificato Content-Encoding, viene generata un'eccezione. Brotli può generare System.InvalidOperationException: Decoder ran into invalid data. Deflate e GZip possono generare System.IO.InvalidDataException: The archive entry was compressed using an unsupported compression method.

Se il middleware rileva una richiesta con contenuto compresso ma non è in grado di decomprimerla, la richiesta viene passata al delegato successivo nella pipeline. Ad esempio, una richiesta con un valore di intestazione non supportato Content-Encoding o più Content-Encoding valori di intestazione viene passata al delegato successivo nella pipeline.

Impostazione

Il codice seguente usa AddRequestDecompression(IServiceCollection) e per abilitare la decompressione delle richieste per i tipi predefinitiContent-Encoding:UseRequestDecompression

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRequestDecompression();

var app = builder.Build();

app.UseRequestDecompression();

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

app.Run();

Provider di decompressione predefiniti

I Content-Encoding valori di intestazione supportati dal middleware di decompressione della richiesta per impostazione predefinita sono elencati nella tabella seguente:

Content-Encoding valori di intestazione Descrizione
br Formato di dati compressi Brotli
deflate Formato di dati compressi DEFLATE
gzip Formato di file Gzip

Provider di decompressione personalizzati

È possibile aggiungere il supporto per le codifiche personalizzate creando classi di provider di decompressione personalizzate che implementano IDecompressionProvider:

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

I provider di decompressione personalizzati vengono registrati insieme ai RequestDecompressionOptions valori di intestazione corrispondenti Content-Encoding :

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();

Limiti di dimensioni di richiesta

Per proteggersi dalle bombe zip o dalla decompressione:

  • La dimensione massima del corpo della richiesta decompressa è limitata al limite di dimensioni del corpo della richiesta applicato dall'endpoint o dal server.
  • Se il numero di byte letti dal flusso del corpo della richiesta decompressa supera il limite, viene generata un'eccezione InvalidOperationException per impedire la lettura di byte aggiuntivi dal flusso.

In ordine di precedenza, le dimensioni massime delle richieste per un endpoint sono impostate da:

  1. IRequestSizeLimitMetadata.MaxRequestBodySize, ad esempio RequestSizeLimitAttribute o DisableRequestSizeLimitAttribute per gli endpoint MVC.
  2. Limite delle dimensioni IHttpMaxRequestBodySizeFeature.MaxRequestBodySizedel server globale. MaxRequestBodySize può essere sottoposto a override per ogni richiesta con IHttpMaxRequestBodySizeFeature.MaxRequestBodySize, ma per impostazione predefinita viene impostato il limite configurato per l'implementazione del server Web.
Implementazione del server Web Configurazione MaxRequestBodySize
HTTP.sys HttpSysOptions.MaxRequestBodySize
IIS IISServerOptions.MaxRequestBodySize
Kestrel KestrelServerLimits.MaxRequestBodySize

Avviso

La disabilitazione del limite di dimensioni del corpo della richiesta comporta un rischio di sicurezza per quanto riguarda l'utilizzo non controllato delle risorse, in particolare se il corpo della richiesta viene memorizzato nel buffer. Assicurarsi che siano applicate misure di sicurezza per ridurre il rischio di attacchi Denial of Service (DoS).

Risorse aggiuntive