Can gzip compression be selectively disabled in ASP.NET/IIS 7?

前端 未结 3 819
长情又很酷
长情又很酷 2020-12-02 15:17

I am using a long-lived asynchronous HTTP connection to send progress updates to a client via AJAX. When compression is enabled, the updates are not received in discrete ch

相关标签:
3条回答
  • 2020-12-02 15:23

    I found a much easier way to do this. Instead of selectively doing your own compression, you can selectively disable the default IIS compression (assuming its enabled in your web.config).

    Simply remove the accept-encoding encoding header on the request and IIS wont compress the page.

    (global.asax.cs:)

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        try
        {
            HttpContext.Current.Request.Headers["Accept-Encoding"] = "";
        }
        catch(Exception){}
    }
    
    0 讨论(0)
  • 2020-12-02 15:34

    What about you set the gzip compression by your self, selectivle when you wish for ? On the Application_BeginRequest check when you like to make and when you dont make compression. Here is a sample code.

    protected void Application_BeginRequest(Object sender, EventArgs e)
    {
        string cTheFile = HttpContext.Current.Request.Path;
        string sExtentionOfThisFile = System.IO.Path.GetExtension(cTheFile);
    
        if (sExtentionOfThisFile.Equals(".aspx", StringComparison.InvariantCultureIgnoreCase))
        {
            string acceptEncoding = MyCurrentContent.Request.Headers["Accept-Encoding"].ToLower();;
    
            if (acceptEncoding.Contains("deflate") || acceptEncoding == "*")
            {
                // defalte
                HttpContext.Current.Response.Filter = new DeflateStream(prevUncompressedStream,
                    CompressionMode.Compress);
                HttpContext.Current.Response.AppendHeader("Content-Encoding", "deflate");
            } else if (acceptEncoding.Contains("gzip"))
            {
                // gzip
                HttpContext.Current.Response.Filter = new GZipStream(prevUncompressedStream,
                    CompressionMode.Compress);
                HttpContext.Current.Response.AppendHeader("Content-Encoding", "gzip");
            }       
        }
    }
    
    0 讨论(0)
  • 2020-12-02 15:37

    @Aristos' answer will work for WebForms, but with his help, I've adapted a solution more inline with ASP.NET/MVC methodology.

    Create a new filter to provide the gzipping functionality:

    public class GzipFilter : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);
    
            var context = filterContext.HttpContext;
            if (filterContext.Exception == null && 
                context.Response.Filter != null &&
                !filterContext.ActionDescriptor.IsDefined(typeof(NoGzipAttribute), true))
            {
                string acceptEncoding = context.Request.Headers["Accept-Encoding"].ToLower();;
    
                if (acceptEncoding.Contains("gzip"))
                {
                    context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
                    context.Response.AppendHeader("Content-Encoding", "gzip");
                }                       
                else if (acceptEncoding.Contains("deflate"))
                {
                    context.Response.Filter = new DeflateStream(context.Response.Filter, CompressionMode.Compress);
                    context.Response.AppendHeader("Content-Encoding", "deflate");
                } 
            }
        }
    }
    

    Create the NoGzip attribute:

    public class NoGzipAttribute : Attribute {
    }
    

    Prevent IIS7 from gzipping using web.config:

    <system.webServer>
        ...
        <urlCompression doStaticCompression="true" doDynamicCompression="false" />
    </system.webServer>
    

    Register your global filter in Global.asax.cs:

    protected void Application_Start()
    {
        ...
        GlobalFilters.Filters.Add(new GzipFilter());
    }
    

    Finally, consume the NoGzip attribute:

    public class MyController : AsyncController
    {
        [NoGzip]
        [NoAsyncTimeout]
        public void GetProgress(int id)
        {
            AsyncManager.OutstandingOperations.Increment();
            ...
        }
    
        public ActionResult GetProgressCompleted() 
        {
            ...
        }
    }
    

    P.S. Once again, many thanks to @Aristos, for his helpful idea and solution.

    0 讨论(0)
提交回复
热议问题