Minimal APIs in ASP.NET Core allow you to easily create RESTful APIs with minimal code and configuration. No matter what type of API we build, it is always important to minimize the amount of data transferred over the network, which saves bandwidth and improves the responsiveness of the app. We do this by compressing the payloads of both requests and responses.
Of course, that means we must decompress those payloads at the other end. In ASP.NET Core 7, request decompression is supported out of the box: You can now use the new request decompression middleware to enable your API endpoints to accept requests that have compressed data.
This article examines how you can work with request compression and decompression in ASP.NET Core 7 Minimal APIs. (Note that we discussed response compression in ASP.NET Core in a previous article.) To use the code examples provided in this article, you should have Visual Studio 2022 installed in your system. If you don’t already have a copy, you can download Visual Studio 2022 here.
Create an ASP.NET Core 7 Minimal Web API project in Visual Studio 2022
First off, let’s create an ASP.NET Core 7 project in Visual Studio 2022 Preview. Follow these steps:
- Launch the Visual Studio 2022 IDE.
- Click on “Create new project.”
- In the “Create new project” window, select “ASP.NET Core Web API” from the list of templates displayed.
- Click Next.
- In the “Configure your new project” window, specify the name and location for the new project.
- Optionally check the “Place solution and project in the same directory” check box, depending on your preferences.
- Click Next.
- In the “Additional Information” window shown next, select “NET 7.0 (Current)” as the framework and uncheck the check box that says “Use controllers…” as we’ll be using minimal APIs in this example. Leave the “Authentication Type” set to “None” (default).
- Ensure that the check boxes “Enable Docker,” “Configure for HTTPS,” and “Enable Open API Support” are unchecked. We won’t be using any of those features here.
- Click Create.
We’ll use this ASP.NET Core 7 Web API project to create a minimal API and implement request compression and decompression in the sections below.
Request decompression middleware in ASP.NET Core 7
ASP.NET Core 7 includes a new request decompression middleware that allows endpoints to accept requests that have compressed content. This eliminates the need to write code explicitly to decompress requests with compressed content.
The Content-Encoding HTTP header is used to identify and decompress compressed content in HTTP requests. In response to an HTTP request that matches the Content-Encoding header value, the request decompression middleware encapsulates the HttpRequest.Body in a suitable decompression stream using the matching provider.
This is followed by the removal of the Content-Encoding header, which indicates that the request body is no longer compressed. Note that the request decompression middleware ignores requests without a Content-Encoding header.
In orther words, when the value of the Content-Encoding header of an HTTP request matches any of the available decompression providers, the requestion decompression middleware takes advantage of a matching provider to wrap the body of the request in an appropriate decompression stream and removes the Content-Encoding header to indicate that the request body is no longer compressed.
The features of the request decompression middleware in ASP.NET Core 7 at a glance:
- It enables API endpoints to accept requests that contain compressed data.
- It leverages the Content-Encoding HTTP header to determine and decompress data pertaining to requests that have compressed content.
- It eliminates the need to write any code to handle decompression of requests that contain compressed data.
The decompression providers supported by default include Brotli, Deflate, and GZip. The default decompression providers and their corresponding content encoding header values are given below:
Compression provider |
Header value |
Brotli |
br |
Deflate |
deflate |
Gzip |
gzip |
Obviously, all of these compression providers are supported by the response compression middleware in ASP.NET Core 7 as well. You can leverage the request decompression middleware in ASP.NET Core 7 using the UseRequestDecompression extension method, which extends the IApplicationBuilder interface, and by calling the AddRequestDecompression extension method on the IServiceCollection interface.
Enable request decompression middleware in ASP.NET Core 7
The following code snippet illustrates how you can enable request decompression for the default Content-Encoding types.
var builder = WebApplication.CreateBuilder(args); builder.Services.AddRequestDecompression(); var app = builder.Build(); app.UseRequestDecompression(); app.MapPost("/", (HttpRequest httpRequest) => Results.Stream(httpRequest.Body)); app.Run();
Request size limits
To prevent “zip bombs” or decompression bombs, the maximum size of the decompressed data is limited to the size of the request body. If the decompressed content size exceeds this limit, an InvalidOperationException is thrown.
Zip bombs, also known as decompression bombs, are malicious files that contain a large amount of highly compressed data. An extracted or decompressed zip bomb expands enormously, consuming large amounts of memory and disk space and potentially causing a denial of service (DoS) attack.
Create a custom decompression provider in ASP.NET Core 7
To provide support for custom encodings, you can create your own decompression providers in ASP.NET Core 7 Minimal APIs. To do this, you should create a class that implements the IDecompressionProvider interface as shown below.
public class CustomDecompressionProvider : IDecompressionProvider { public Stream GetDecompressionStream(Stream stream) { // Write your code here to decompress return stream; } }
You should then register and configure your custom decompression provider in the Program.cs file using the following code.
var builder = WebApplication.CreateBuilder(args); builder.Services.AddRequestDecompression(options => { options.DecompressionProviders.Add("mycustomdecompressionprovider", new CustomDecompressionProvider()); }); var app = builder.Build(); app.UseRequestDecompression(); app.MapPost("/", (HttpRequest request) => Results.Stream(request.Body)); app.Run();
I’ve not implemented the logic for custom compression and decompression here. I will demonstrate this in a follow-up article soon.
If the request decompression middleware is unable to decompress the compressed content of a request, it will forward the request to the next delegate. Whenever a request contains an unsupported Content-Encoding header value, or includes multiple Content-Encoding header values, it will be forwarded to the subsequent delegate. And Brotli, GZip, and Deflate will throw an exception with an appropriate error message, stating that the compression method is not supported.