Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Примечание.
Это не последняя версия этой статьи. В текущей версии см. версию .NET 10 этой статьи.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущем выпуске см . версию .NET 9 этой статьи.
Автор: Дэвид Эйкер (David Acker)
ПО промежуточного слоя для распаковки запросов предоставляет такие преимущества:
- позволяет конечным точкам API принимать запросы со сжатым содержимым;
- использует заголовок HTTP
Content-Encoding, чтобы автоматически обнаруживать и распаковывать запросы, содержащие сжатое содержимое; - устраняет необходимость писать код для обработки сжатых запросов.
Если значение заголовка 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) и включает распаковку запроса для UseRequestDecompression:Content-Encoding
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 |
Description |
|---|---|
br |
Формат сжатых данных Brotli |
deflate |
Формат сжатых данных Deflate |
gzip |
Формат файлов gzip |
Настраиваемые поставщики распаковки
Поддержку пользовательских кодировок можно добавлять, создавая настраиваемые классы поставщиков распаковки, реализующие IDecompressionProvider:
public class CustomDecompressionProvider : IDecompressionProvider
{
public Stream GetDecompressionStream(Stream stream)
{
// Perform custom decompression logic here
return stream;
}
}
Настраиваемые поставщики распаковки регистрируются с использованием RequestDecompressionOptions вместе с соответствующими значениями заголовков 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();
Предельный размер запросов
Чтобы защититься от zip-бомб или декомпрессийных бомб:
- максимальный размер текста распакованного запроса ограничивается согласно лимиту на размер текста запроса в конечной точке или на сервере;
- если из потока текста распаковываемого запроса считывается количество байт, превышающее ограничение, создается исключение InvalidOperationException, чтобы предотвратить чтение дополнительных байтов из потока.
Максимальный размер запроса для конечной точки задается в порядке приоритета следующим образом:
- IRequestSizeLimitMetadata.MaxRequestBodySize, например RequestSizeLimitAttribute или DisableRequestSizeLimitAttribute для конечных точек MVC.
- Глобальное серверное ограничение размера — IHttpMaxRequestBodySizeFeature.MaxRequestBodySize.
MaxRequestBodySizeможно переопределить для каждого запроса, используя свойство IHttpMaxRequestBodySizeFeature.MaxRequestBodySize, но по умолчанию применяется ограничение, настроенное для реализации веб-сервера.
| Реализация веб-сервера |
MaxRequestBodySizeКонфигурация |
|---|---|
| HTTP.sys | HttpSysOptions.MaxRequestBodySize |
| IIS | IISServerOptions.MaxRequestBodySize |
| Kestrel | KestrelServerLimits.MaxRequestBodySize |
Предупреждение
Отключение лимита для размера текста запроса создает риск для безопасности, связанный с неконтролируемым потреблением ресурсов, особенно если текст запроса буферизуется. Убедитесь, что приняты меры по безопасности, чтобы снизить риск атак типа отказ в обслуживании (DoS).