public override void OnResultExecuting(ResultExecutingContext context) { var cont = context.HttpContext; if (cont == null) { return; } var encodings = context.HttpContext.Request.Headers[HeaderNames.AcceptEncoding]; var compressionType = CompressionUtils.GetType(encodings); if (compressionType != CompressionUtils.CompressionType.Unknown) { var response = cont.Response; switch (compressionType) { case CompressionUtils.CompressionType.Brotli: response.Headers.Add(CustomCompressionHeader, "br"); break; case CompressionUtils.CompressionType.GZip: response.Headers.Add(CustomCompressionHeader, "gzip"); break; case CompressionUtils.CompressionType.Deflate: response.Headers.Add(CustomCompressionHeader, "deflate"); break; } } base.OnResultExecuting(context); }
public async Task Invoke(HttpContext context) { // store original response in a variable Stream originalResponseBody = context.Response.Body; using (var memStreamResponse = new MemoryStream()) using (var streamReaderResponse = new StreamReader(memStreamResponse)) { // replace reponse body with an empty stream context.Response.Body = memStreamResponse; // set appropriate compression header // (this is the only way to modify headers after the execution of response) context.Response.OnStarting(state => { var httpContext = (HttpContext)state; var enconding = context.Response.Headers[CompressContentAttribute.CustomCompressionHeader]; if (enconding.Count > 0) { httpContext.Response.Headers[HeaderNames.ContentEncoding] = enconding; httpContext.Response.Headers.Remove(CompressContentAttribute.CustomCompressionHeader); } return(Task.FromResult(0)); }, context); await _next(context); // set response body to its original value context.Response.Body = originalResponseBody; memStreamResponse.Position = 0; string responseBody = await streamReaderResponse.ReadToEndAsync(); memStreamResponse.Position = 0; var compressionType = CompressionUtils.GetType(context.Response.Headers[CompressContentAttribute.CustomCompressionHeader]); if (compressionType != CompressionUtils.CompressionType.Unknown) { try { byte[] bytes; switch (compressionType) { case CompressionUtils.CompressionType.Brotli: bytes = CompressionUtils.Compress <BrotliStream>(responseBody); break; case CompressionUtils.CompressionType.GZip: bytes = CompressionUtils.Compress <GZipStream>(responseBody); break; default: // case CompressionUtils.CompressionType.Deflate: bytes = CompressionUtils.Compress <DeflateStream>(responseBody); break; } await context.Response.Body.WriteAsync(bytes, 0, bytes.Length); } catch (Exception e) { // Checking for size prevents exceptions on cached static file requests... if (!string.IsNullOrEmpty(responseBody)) { await memStreamResponse.CopyToAsync(originalResponseBody); } context.Response.Body = originalResponseBody; } } else { // Checking for size prevents exceptions on cached static file requests... if (!string.IsNullOrEmpty(responseBody)) { await memStreamResponse.CopyToAsync(originalResponseBody); } context.Response.Body = originalResponseBody; } } }