ASP.NET Core 中的要求解壓縮

作者:David Acker

要求解壓縮中介軟體:

  • 可讓 API 端點接受具有壓縮內容的要求。
  • 使用 Content-Encoding HTTP 標頭來自動識別並解壓縮包含壓縮內容的要求。
  • 不需要撰寫程式碼來處理壓縮的要求。

當要求的 Content-Encoding 標頭值符合其中一個可用的解壓縮提供者時,中介軟體會:

  • 使用相符的提供者,將 HttpRequest.Body 包裝在適當的解壓縮資料流中。
  • 移除 Content-Encoding 標頭,表示要求本文不再壓縮。

要求解壓縮中介軟體會忽略不包含 Content-Encoding 標頭的要求。

解壓縮:

  • 發生於讀取要求的本文時。 也就是說,解壓縮發生於模型繫結的端點。 要求本文不會急切地解壓縮。
  • 嘗試針對 Content-Encoding 讀取具有無效壓縮資料的解壓縮要求本文時,系統會擲回例外狀況。 Brotli 可擲回 System.InvalidOperationException:Decoder ran into invalid data. Deflate 和 GZip 可擲回 System.IO.InvalidDataException:The archive entry was compressed using an unsupported compression method.

如果中介軟體遇到具有壓縮內容但無法解壓縮的要求,則會將要求傳遞至管線中的下一個委派。 例如,具有不支援 Content-Encoding 標頭值或多個 Content-Encoding 標頭值的要求會傳遞至管線中的下一個委派。

組態

下列程式代碼會使用 AddRequestDecompression(IServiceCollection) 和 來啟用預設Content-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();

預設解壓縮提供者

下表列出要求解壓縮中介軟體預設支援的 Content-Encoding 標頭值:

Content-Encoding 標頭值 描述
br Brotli 壓縮資料格式
deflate DEFLATE 壓縮資料格式
gzip GZIP 檔案格式

自訂解壓縮提供者

藉由建立實作 IDecompressionProvider 的自訂解壓縮提供者類別,即可新增自訂編碼的支援:

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

自訂解壓縮提供者會連同其對應的 Content-Encoding 標頭值一起向 RequestDecompressionOptions 註冊:

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

要求大小限制

為了防範 zip 炸彈或解壓縮炸彈

  • 解壓縮的要求本文大小上限受限於端點或伺服器強制的要求本文大小限制。
  • 如果從解壓縮的要求本文資料流讀取的位元組數目超過限制,則會擲回 InvalidOperationException,以防止從資料流讀取其他位元組。

根據優先順序,端點的要求大小上限是由以下項目設定:

  1. IRequestSizeLimitMetadata.MaxRequestBodySize,例如 MVC 端點的 RequestSizeLimitAttributeDisableRequestSizeLimitAttribute
  2. 全域伺服器大小限制 IHttpMaxRequestBodySizeFeature.MaxRequestBodySize。 可使用 IHttpMaxRequestBodySizeFeature.MaxRequestBodySize 來覆寫每個要求的 MaxRequestBodySize,但預設為針對 Web 服務器實作所設定的限制。
Web 服務器實作 MaxRequestBodySize 設定
HTTP.sys HttpSysOptions.MaxRequestBodySize
IIS IISServerOptions.MaxRequestBodySize
Kestrel KestrelServerLimits.MaxRequestBodySize

警告

停用要求本文大小限制會對不受控的資源取用造成安全性風險,特別是當要求本文正在緩衝處理時。 確定已做好防護措施,以降低拒絕服務 (DoS) 攻擊的風險。

其他資源