Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Примечание.
Это не последняя версия этой статьи. В текущей версии см. версию .NET 10 этой статьи.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущей версии см. версию .NET 10 этой статьи.
Автор: Дэвид Эйкер (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выдается исключение. Brotli может вызывать System.InvalidOperationException: Decoder ran into invalid data. Deflate, GZip и Zstandard могут вызывать 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 значения заголовков |
Описание |
|---|---|
br |
Формат сжатых данных Brotli |
deflate |
Формат сжатых данных Deflate |
gzip |
Формат файлов gzip |
Content-Encoding значения заголовков |
Описание |
|---|---|
br |
Формат сжатых данных Brotli |
deflate |
Формат сжатых данных Deflate |
gzip |
Формат файлов gzip |
zstd |
Формат сжатых данных Zstandard |
Настраиваемые поставщики распаковки
Поддержку пользовательских кодировок можно добавлять, создавая настраиваемые классы поставщиков распаковки, реализующие 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).
Дополнительные ресурсы
ASP.NET Core