Пример #1
0
        /// <summary>
        /// Handles the BeginRequest event of the context control.
        /// </summary>
        /// <param name="sender">The source of the event</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data</param>
        private void PreRequestHandlerExecute(object sender, EventArgs e)
        {
            if (!_configuration.IsCompressionEnabled())
            {
                return;
            }

            IHttpCompressionManager compressionManager =
                _compressionManager ?? HttpCompressionManager.Current;
            HttpContext  context    = ((HttpApplication)sender).Context;
            HttpRequest  request    = context.Request;
            HttpResponse response   = context.Response;
            string       httpMethod = request.HttpMethod;
            string       currentUrl = request.RawUrl;

            if (compressionManager.IsSupportedHttpStatusCode(response.StatusCode) &&
                compressionManager.IsSupportedHttpMethod(httpMethod) &&
                compressionManager.IsProcessablePage(currentUrl) &&
                !request.Path.EndsWith("WebResource.axd", StringComparison.OrdinalIgnoreCase))
            {
                context.Items["originalResponseFilter"] = response.Filter;

                string acceptEncoding = request.Headers["Accept-Encoding"];
                response.Filter = new HttpCompressionFilterStream(new HttpResponseWrapper(response),
                                                                  compressionManager, acceptEncoding);
            }
        }
Пример #2
0
        public void OnLoad(EventArgs e)
        {
            if (DisableCompression)
            {
                return;
            }

            IHttpCompressionManager compressionManager =
                _compressionManager ?? HttpCompressionManager.Current;
            HttpContext  context    = HttpContext.Current;
            HttpRequest  request    = context.Request;
            HttpResponse response   = context.Response;
            string       httpMethod = request.HttpMethod;
            string       currentUrl = request.RawUrl;

            if (response.StatusCode == 200 &&
                compressionManager.IsSupportedHttpMethod(httpMethod) &&
                compressionManager.IsProcessablePage(currentUrl))
            {
                context.Items["originalResponseFilter"] = response.Filter;

                string acceptEncoding = request.Headers["Accept-Encoding"];
                response.Filter = new HttpCompressionFilterStream(new HttpResponseWrapper(response),
                                                                  compressionManager, acceptEncoding);
            }
        }
        /// <summary>
        /// Override to compress the content that is generated by an action method
        /// </summary>
        /// <param name="filterContext">Filter context</param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (!_configuration.IsCompressionEnabled())
            {
                return;
            }

            IHttpCompressionManager compressionManager =
                _compressionManager ?? HttpCompressionManager.Current;
            HttpContextBase  context    = filterContext.HttpContext;
            HttpRequestBase  request    = context.Request;
            HttpResponseBase response   = context.Response;
            string           httpMethod = request.HttpMethod;
            string           currentUrl = request.RawUrl;

            if (response.Filter != null && response.StatusCode == 200 &&
                compressionManager.IsSupportedHttpMethod(httpMethod) &&
                compressionManager.IsProcessablePage(currentUrl))
            {
                context.Items["originalResponseFilter"] = response.Filter;

                string acceptEncoding = request.Headers["Accept-Encoding"];
                response.Filter = new HttpCompressionFilterStream(response, compressionManager, acceptEncoding);
            }
        }
Пример #4
0
        private void Initialize()
        {
            if (_wrapperInitializedFlag.Set())
            {
                HttpRequest  request  = _context.Request;
                HttpResponse response = _context.Response;

                if (response.StatusCode == 200)
                {
                    string   httpMethod  = request.Method;
                    string   contentType = response.ContentType;
                    string   mediaType   = null;
                    Encoding encoding    = null;

                    if (contentType != null)
                    {
                        MediaTypeHeaderValue mediaTypeHeader;

                        if (MediaTypeHeaderValue.TryParse(contentType, out mediaTypeHeader))
                        {
                            mediaType = mediaTypeHeader.MediaType
#if ASPNETCORE2
                                        .Value
#endif
                                        .ToLowerInvariant()
                            ;
                            encoding = mediaTypeHeader.Encoding;
                        }
                    }

                    string      currentUrl  = request.Path.Value;
                    QueryString queryString = request.QueryString;
                    if (queryString.HasValue)
                    {
                        currentUrl += queryString.Value;
                    }

                    IHeaderDictionary responseHeaders = response.Headers;
                    bool isEncodedContent             = responseHeaders.IsEncodedContent();

                    if (_minificationManagers.Count > 0)
                    {
                        foreach (IMarkupMinificationManager minificationManager in _minificationManagers)
                        {
                            if (minificationManager.IsSupportedHttpMethod(httpMethod) &&
                                mediaType != null && minificationManager.IsSupportedMediaType(mediaType) &&
                                minificationManager.IsProcessablePage(currentUrl))
                            {
                                if (isEncodedContent)
                                {
                                    throw new InvalidOperationException(
                                              string.Format(
                                                  AspNetCommonStrings.MarkupMinificationIsNotApplicableToEncodedContent,
                                                  responseHeaders[HeaderNames.ContentEncoding]
                                                  )
                                              );
                                }

                                _currentMinificationManager = minificationManager;
                                _cachedStream        = new MemoryStream();
                                _minificationEnabled = true;

                                break;
                            }
                        }
                    }

                    if (_compressionManager != null && !isEncodedContent &&
                        _compressionManager.IsSupportedHttpMethod(httpMethod) &&
                        _compressionManager.IsSupportedMediaType(mediaType) &&
                        _compressionManager.IsProcessablePage(currentUrl))
                    {
                        string      acceptEncoding = request.Headers[HeaderNames.AcceptEncoding];
                        ICompressor compressor     = InitializeCurrentCompressor(acceptEncoding);

                        if (compressor != null)
                        {
                            _compressionStream  = compressor.Compress(_originalStream);
                            _compressionEnabled = true;
                        }
                    }

                    _currentUrl = currentUrl;
                    _encoding   = encoding;
                }
            }
        }
        public async Task Invoke(HttpContext context)
        {
            bool useMinification = _options.IsMinificationEnabled() && _minificationManagers.Count > 0;
            bool useCompression  = _options.IsCompressionEnabled() && _compressionManager != null;

            if (!useMinification && !useCompression)
            {
                await _next.Invoke(context);

                return;
            }

            HttpRequest  request  = context.Request;
            HttpResponse response = context.Response;

            using (var cachedStream = new MemoryStream())
            {
                Stream originalStream = response.Body;
                response.Body = cachedStream;

                try
                {
                    await _next.Invoke(context);
                }
                catch (Exception)
                {
                    response.Body = originalStream;
                    cachedStream.Clear();

                    throw;
                }

                byte[] cachedBytes     = cachedStream.ToArray();
                int    cachedByteCount = cachedBytes.Length;
                bool   isProcessed     = false;

                response.Body = originalStream;
                cachedStream.Clear();

                if (cachedByteCount == 0)
                {
                    return;
                }

                if (response.StatusCode == 200)
                {
                    string   httpMethod  = request.Method;
                    string   contentType = response.ContentType;
                    string   mediaType   = null;
                    Encoding encoding    = null;

                    if (contentType != null)
                    {
                        MediaTypeHeaderValue mediaTypeHeader;

                        if (MediaTypeHeaderValue.TryParse(contentType, out mediaTypeHeader))
                        {
                            mediaType = mediaTypeHeader.MediaType
#if ASPNETCORE2
                                        .Value
#endif
                                        .ToLowerInvariant()
                            ;
                            encoding = mediaTypeHeader.Encoding;
                        }
                    }

                    encoding = encoding ?? Encoding.GetEncoding(0);

                    string      currentUrl  = request.Path.Value;
                    QueryString queryString = request.QueryString;
                    if (queryString.HasValue)
                    {
                        currentUrl += queryString.Value;
                    }

                    string            content          = encoding.GetString(cachedBytes);
                    string            processedContent = content;
                    IHeaderDictionary responseHeaders  = response.Headers;
                    bool isEncodedContent = responseHeaders.IsEncodedContent();
                    Action <string, string> appendHttpHeader = (key, value) =>
                    {
                        responseHeaders.Append(key, new StringValues(value));
                    };

                    if (useMinification && _options.IsAllowableResponseSize(cachedByteCount))
                    {
                        foreach (IMarkupMinificationManager minificationManager in _minificationManagers)
                        {
                            if (minificationManager.IsSupportedHttpMethod(httpMethod) &&
                                mediaType != null && minificationManager.IsSupportedMediaType(mediaType) &&
                                minificationManager.IsProcessablePage(currentUrl))
                            {
                                if (isEncodedContent)
                                {
                                    throw new InvalidOperationException(
                                              string.Format(
                                                  AspNetCommonStrings.MarkupMinificationIsNotApplicableToEncodedContent,
                                                  responseHeaders["Content-Encoding"]
                                                  )
                                              );
                                }

                                IMarkupMinifier minifier = minificationManager.CreateMinifier();

                                MarkupMinificationResult minificationResult = minifier.Minify(processedContent,
                                                                                              currentUrl, encoding, minificationManager.GenerateStatistics);
                                if (minificationResult.Errors.Count == 0)
                                {
                                    processedContent = minificationResult.MinifiedContent;
                                    if (_options.IsPoweredByHttpHeadersEnabled())
                                    {
                                        minificationManager.AppendPoweredByHttpHeader(appendHttpHeader);
                                    }

                                    isProcessed = true;
                                }
                            }

                            if (isProcessed)
                            {
                                break;
                            }
                        }
                    }

                    if (useCompression && !isEncodedContent &&
                        _compressionManager.IsSupportedHttpMethod(httpMethod) &&
                        _compressionManager.IsSupportedMediaType(mediaType) &&
                        _compressionManager.IsProcessablePage(currentUrl))
                    {
                        byte[] processedBytes = encoding.GetBytes(processedContent);

                        using (var inputStream = new MemoryStream(processedBytes))
                            using (var outputStream = new MemoryStream())
                            {
                                string      acceptEncoding = request.Headers["Accept-Encoding"];
                                ICompressor compressor     = _compressionManager.CreateCompressor(acceptEncoding);

                                using (Stream compressedStream = compressor.Compress(outputStream))
                                {
                                    await inputStream.CopyToAsync(compressedStream);
                                }

                                byte[] compressedBytes     = outputStream.ToArray();
                                int    compressedByteCount = compressedBytes.Length;

                                outputStream.Clear();
                                inputStream.Clear();

                                responseHeaders["Content-Length"] = compressedByteCount.ToString();
                                compressor.AppendHttpHeaders(appendHttpHeader);
                                await originalStream.WriteAsync(compressedBytes, 0, compressedByteCount);
                            }

                        isProcessed = true;
                    }
                    else
                    {
                        if (isProcessed)
                        {
                            byte[] processedBytes     = encoding.GetBytes(processedContent);
                            int    processedByteCount = processedBytes.Length;

                            responseHeaders["Content-Length"] = processedByteCount.ToString();
                            await originalStream.WriteAsync(processedBytes, 0, processedByteCount);
                        }
                    }
                }

                if (!isProcessed)
                {
                    await originalStream.WriteAsync(cachedBytes, 0, cachedByteCount);
                }
            }
        }