Last active
May 3, 2017 07:18
-
-
Save AndreiGorlov/388745f59145209fa951 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
using System; | |
using System.IO; | |
using System.IO.Compression; | |
using System.Threading.Tasks; | |
using Microsoft.AspNetCore.Http; | |
namespace Middlewares | |
{ | |
/// <summary> | |
/// Experimental compression middleware for self-hosted web app | |
/// </summary> | |
public class CompressionMiddleware | |
{ | |
private readonly RequestDelegate _next; | |
private const long MinimumLength = 2700; | |
public CompressionMiddleware(RequestDelegate next) | |
{ | |
_next = next; | |
} | |
public async Task Invoke(HttpContext context) | |
{ | |
var acceptEncoding = context.Request.Headers["Accept-Encoding"]; | |
if (acceptEncoding.ToString().IndexOf("gzip", StringComparison.CurrentCultureIgnoreCase) < 0) | |
{ | |
await _next(context); | |
return; | |
} | |
using (var buffer = new MemoryStream()) | |
{ | |
var body = context.Response.Body; | |
context.Response.Body = buffer; | |
try | |
{ | |
await _next(context); | |
if (buffer.Length >= MinimumLength) | |
{ | |
using (var compressed = new MemoryStream()) | |
{ | |
using (var gzip = new GZipStream(compressed, CompressionLevel.Optimal, leaveOpen: true)) | |
{ | |
buffer.Seek(0, SeekOrigin.Begin); | |
await buffer.CopyToAsync(gzip); | |
} | |
if (compressed.Length < buffer.Length) | |
{ | |
// write compressed data to response | |
context.Response.Headers.Add("Content-Encoding", new[] { "gzip" }); | |
if (context.Response.Headers["Content-Length"].Count > 0) | |
{ | |
context.Response.Headers["Content-Length"] = compressed.Length.ToString(); | |
} | |
compressed.Seek(0, SeekOrigin.Begin); | |
await compressed.CopyToAsync(body); | |
return; | |
} | |
} | |
} | |
// write uncompressed data to response | |
buffer.Seek(0, SeekOrigin.Begin); | |
await buffer.CopyToAsync(body); | |
} | |
finally | |
{ | |
context.Response.Body = body; | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
hi Andri,
I found compression middleware while searching over for custom middleware implementation, thanks for sharing. When i tried to use the same middle ware , i don't see content-encoding is not present in response header ? Is that i am missing anything here,
thanks
Vimal