Compression support for ASP.NET WebAPI and HttpClient
Drop-in module for ASP.Net WebAPI that enables
This module is based on this blog post by Ben Foster which in turn is based on this blog post by Kiran Challa.
This code improves on their work by adding several new options, as well as fixing some issues with the original code.
How to use
You need to add the compression handler as the last applied message handler on outgoing requests, and the first one on incoming requests.
To do that, just add the following line to your
App_Start\WebApiConfig.cs file after adding all your other message handlers:
GlobalConfiguration.Configuration.MessageHandlers.Insert(0, new ServerCompressionHandler(new GZipCompressor(), new DeflateCompressor()));
This will insert the
ServerCompressionHandler to the request pipeline as the first on incoming requests, and the last on outgoing requests.
If you are doing your requests with
Just make sure the
deflate values are included in the
Accept-Encoding header. (Most browsers do this by default)
You need to apply the following code when creating your
var client = new HttpClient(new ClientCompressionHandler(new GZipCompressor(), new DeflateCompressor())); client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
Thats it! You should now immediately start experiencing smaller payloads when doing GET, POST, PUT, etc.
Skip compression of requests/responses that are smaller than a specified value
By default, both
ClientCompressionHandler compress everything larger than
However, this can be overriden by inserting a threshold as the first parameter like this:
var serverCompressionHandler = new ServerCompressionHandler(4096, new GZipCompressor(), new DeflateCompressor()); var clientCompressionHandler = new ClientCompressionHandler(4096, new GZipCompressor(), new DeflateCompressor());
The above code will skip compression for any request/response that is smaller than
4096 bytes /
Disable compression for endpoint
It is possible to disable compression for a specific endpoint. Just add the
[Compression(Enabled = false)] attribute to your endpoint method. (Or the whole controller if you want to disable for all endpoints in it)
When using the OWIN Authentication pipeline, you might encounter errors saying that
Server cannot append header after http headers have been sent. This is a bug with OWIN, but as of this moment it has not been fixed.
The workaround is to install the Microsoft.AspNet.WebApi.Extensions.Compression.Server.Owin package and use the included
OwinServerCompressionHandler instead of the default
ServerCompressionHandler. This class contains code to detect whether the headers have been sent already and prevent any attempts at compression.
- Fixed unnecessary dependency on .NET 4.5.2
- Fixed System.ArgumentException in CompressionAttribute (Thanks to SneakyMax)
- Various readme fixes (Thanks to wiltodelta, IainCole, coni2k and altumano)
- Fixed UWP projects referencing Microsoft.AspNet.WebApi.MessageHandlers.Compression does not compile
- Fixed Remove Microsoft.Bcl dependency in .NET 4.5
- Fixed compressing even when accept encoding is null
- Fixed Possible issue while redirecting after de-compression and Owin UseCookieAuthentication does not work anymore after we insert ServerCompressionHandler
- Fixed Async throttled actions with disabled compression
- Improved performance a little by not always buffering the response. See #6
- Fixed Server cannot append header after HTTP headers have been sent. NOTE: The fix is in a separate package
- Added attribute for disable compression for certain routes
- Fixed clearing of non-standard properties when compressing and decompressing
- Stop trying to compress requests/responses with no content
- Properly copy HTTP headers from the content that is going to be compressed
- Fixed 504 timeout error when returning
- Fixed bug with content stream sometimes being disposed before returning
- Added better test coverage
- Changed default threshold for compression to 860 bytes (what Akamai uses)
- Now reports proper Content-Length
- Simplified usage
- Added support for setting a minimum content size for compressing
- First release, basic compression of server responses and client requests
- Did not support compressing POSTs and PUTs