Last active
June 8, 2022 05:39
-
-
Save jonathanpeppers/bb0e9c541d28265bdf97f0c50e9acd8b to your computer and use it in GitHub Desktop.
DelegatingHandler for GZip in ASP.NET Web API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | |
} | |
} |
@hassanbuttar I wrote this 5+ years ago, I'm not sure if it even works with the latest ASP.NET.
@jonathanpeppers I understand this, I am trying to find out the solution but was not able to understand this problem that's why i posted here. I am using Framework 4.8. If you need i can make a sample project for you to understand what's going on (if you are free to help). I am already trying different social channels to get the help for this so hopefully I will be able to find the answers. B.T.W Thanks for the reply.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi, May b its too late but after using this handler I am having another issue, When I send the request using postman I never get the response back and postman keeps on trying however the status code 200 is populated on postman but its still loading the contents.