Create a gist now

Instantly share code, notes, and snippets.

DelegatingHandler for GZip in ASP.NET Web API
public class GzipHandler : DelegatingHandler
{
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request.Content != null &&
request.Content.Headers.ContentType != null &&
(request.Content.Headers.ContentType.MediaType == "application/gzip" ||
request.Content.Headers.ContentType.MediaType == "application/deflate"))
{
string encodingType = request.Content.Headers.ContentType.MediaType.Split('/').Last();
Stream stream;
if (encodingType == "gzip")
{
stream = new GZipStream(await request.Content.ReadAsStreamAsync(), CompressionMode.Decompress);
}
else if (encodingType == "deflate")
{
stream = new DeflateStream(await request.Content.ReadAsStreamAsync(), CompressionMode.Decompress);
}
else
{
throw new HttpException(HttpStatusCode.UnsupportedMediaType, string.Format("Encoding '{0}' is not supported. Only supports gzip or deflate encoding.", encodingType));
}
request.Content = new DecompressedContent(request.Content, stream);
}
var response = await base.SendAsync(request, cancellationToken);
if (response.Content != null &&
response.RequestMessage.Headers.AcceptEncoding != null &&
response.RequestMessage.Headers.AcceptEncoding.Count > 0)
{
string encodingType = response.RequestMessage.Headers.AcceptEncoding.First().Value;
response.Content = new CompressedContent(response.Content, encodingType);
}
return response;
}
}
public class CompressedContent : HttpContent
{
private HttpContent _content;
private string _encodingType;
public CompressedContent(HttpContent content, string encodingType)
{
_content = content;
_encodingType = encodingType.ToLowerInvariant();
if (_encodingType != "gzip" && _encodingType != "deflate")
{
throw new HttpException(HttpStatusCode.UnsupportedMediaType, string.Format("Encoding '{0}' is not supported. Only supports gzip or deflate encoding.", _encodingType));
}
// copy the headers from the original content
foreach (KeyValuePair<string, IEnumerable<string>> header in _content.Headers)
{
Headers.TryAddWithoutValidation(header.Key, header.Value);
}
Headers.ContentEncoding.Add(encodingType);
}
protected override bool TryComputeLength(out long length)
{
length = -1;
return false;
}
protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
Stream compressedStream = null;
if (_encodingType == "gzip")
{
compressedStream = new GZipStream(stream, CompressionMode.Compress, leaveOpen: true);
}
else if (_encodingType == "deflate")
{
compressedStream = new DeflateStream(stream, CompressionMode.Compress, leaveOpen: true);
}
try
{
await _content.CopyToAsync(compressedStream);
}
finally
{
compressedStream.Dispose();
}
}
}
public class DecompressedContent : StreamContent
{
public DecompressedContent(HttpContent content, Stream stream) : base(stream)
{
// copy the headers from the original content
foreach (KeyValuePair<string, IEnumerable<string>> header in content.Headers)
{
Headers.TryAddWithoutValidation(header.Key, header.Value);
}
Headers.Remove("Content-Type");
Headers.Add("Content-Type", "application/json");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment