Dajbych.net


How to enable response compression in ASP.NET Core 2 with gzip and Brotli encoding

, 4 minutes to read

In­ter­net traf­fic can be com­pressed to save net­work band­width us­age. While im­ages and web fonts are al­ready com­pressed, text files are stored on the server in hu­man read­able form. HTTP.sys server and Kestrel cur­rently don't have built-in com­pres­sion sup­port. By de­fault, only static files are com­pressed with gzip. What if you want com­press more?

Reasons

There are sev­eral rea­sons why you might want to change com­pres­sion con­fig­u­ra­tion:

Brotli

Two en­gi­neers at Google de­signed a Brotli com­pres­sion for­mat. In com­par­i­son to gzip, Brotli is around 20% more per­for­mant in com­pres­sion and around 20 times faster in de­com­pres­sion. It is used in the WOFF2 for­mat. Brotli uses Huff­mann cod­ing and a vari­ant of the LZ77 al­gorithm. All ma­jor browsers sup­port Brotli (Fire­fox since Jan­uary 2016, Chrome since April 2016, Opera since June 2016, Edge since April 2017 and Sa­fari since Oc­to­ber 2017).

Compress in TLS

Com­pres­sion in TLS is com­promised due to BREACH at­tack. How­ever, if your cook­ies fol­lows same-site pol­icy, your site is pro­tected against CSRF and BREACH at­tacks.

Compress dynamic content

Un­like static files, dy­namic con­tent can­not be cached thus ev­ery re­sponse must be com­pressed in­di­vid­u­ally. It gives you more ef­fi­cient use of band­width but also higher CPU load.

Implementation

Al­low­ing com­pres­sion in ASP.NET Core 2 web app is very easy.

Step 1 – use response compression

In the Startup.cs file call the UseRe­spon­seC­om­pres­sion method:

public class Startup { public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseResponseCompression(); } }

Step 2 – enable gzip compression

In the Startup.cs file call the Con­fig­ure method:

public class Startup { public void ConfigureServices(IServiceCollection services) { services.Configure<GzipCompressionProviderOptions>(options => { options.Level = CompressionLevel.Fastest; }); } }

Step 3 – create a Brotli compression provider

Firstly, you must in­stall the BrotliSharpLib NuGet pack­age be­cause Brotli isn’t cur­rently sup­ported in .NET Core 2.0.0.

Sec­ondly, add a new class that pro­vides Brotli com­pres­sion.

public class BrotliCompressionProvider : ICompressionProvider { public string EncodingName => "br"; public bool SupportsFlush => true; public Stream CreateStream(Stream outputStream) => new BrotliStream(outputStream, CompressionMode.Compress); }

Step 4 – register a Brotli compression provider

In the Startup.cs file call the Ad­dRe­spon­seC­om­pres­sion method:

public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddResponseCompression(options => { options.Providers.Add<BrotliCompressionProvider>(); }); } }

Step 5 – enable compression in TLS connection

In the Startup.cs file in the Ad­dRe­spon­seC­om­pres­sion method call set the En­able­ForHttps prop­erty:

public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddResponseCompression(options => { options.Providers.Add<BrotliCompressionProvider>(); options.EnableForHttps = true; }); } }

Step 6 – declare additional MIME types for compression

By de­fault, only fol­low­ing MIME types are com­pressed by ASP.NET Core 2:

Your web ap­pli­ca­tion may serve more MIME types which can be com­pressed, for ex­am­ple:

In the Startup.cs file call in the Ad­dRe­spon­seC­om­pres­sion method call set the Mime­Types prop­erty:

public class Startup { public void ConfigureServices(IServiceCollection services) { options.Providers.Add<BrotliCompressionProvider>(); options.EnableForHttps = true; options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] { "application/xhtml+xml", "application/atom+xml", "image/svg+xml", }); } }

Step 7 – test it

F12 Dev Tools cur­rently do not show con­tent-en­cod­ing re­sponse header. This is a known bug which takes over a year to fix. You must run an al­ter­na­tive browser to test whether your server re­sponds with the con­tent-en­cod­ing: br HTTP header.

.NET

Further thoughts