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);
        }
Example #2
0
        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;
                    }
                }
        }