Content-encoding header disappears from HttpHandler response if an exception occurs

I have a custom HttpHandler in which I manually enable output compression, for example:

context.Response.AppendHeader("Content-encoding", "gzip");
context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);

This works well for most requests, but when an exception occurs, the "Content-encoding" header disappears from the response, while the compression filter remains in place. As a result, the gzip error page is compressed, but the browser does not receive a header indicating this fact. Then the browser tries to display the still compressed data in the form of text that gobbledygook .

The full code for the test code is shown below. Try disabling compression one at a time or not throwing an exception.

Can someone shed some light on why the "Content-encoding" header disappears?

I suppose I can just turn on compression as the last thing the handler does, so if an exception occurs, it never reaches the point where the compression filter is added; but the behavior that I see amazes me like a mistake. Can anyone confirm?

public class TestHandler : IHttpHandler 
{
    public void ProcessRequest(HttpContext context)
    {
        CompressResponse(context);
        context.Response.Write("Hello world");

        // Throw an exception for testing purposes
        throw new Exception("Just testing...");
    }

    private void CompressResponse(HttpContext context)
    {
        string acceptEncoding = context.Request.Headers["Accept-Encoding"];
        if (String.IsNullOrEmpty(acceptEncoding))
        {
            return;
        }

        // gzip or wildcard
        if (acceptEncoding.ToLower().Contains("gzip") || acceptEncoding.Contains("*"))
        {
            context.Response.AppendHeader("Content-encoding", "gzip");
            context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
            return;
        }

        // Also handles deflate (not shown here)
        // <snip>
    }

    public bool IsReusable
    {
        get { return true; }
    }
}

EDIT: Screenshot of the still encoded answer that I see in my test case: http://i.imgur.com/49Vcl.png

+5
source share
4 answers

If you have an exception, then the server will clear the current installed headers and contents, because they are mistaken, since you still had the exit.

, , 200, ( , , 200, ) , -, , , .

reset.

reset , , , , . , , .

, Flush(), , . ?

0

. . , , .

:

context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);

Filter. using, , - .

, - , . Filter , , . , , - ( ).

! . . , .

Global.asax.cs

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
        filters.Add(new HandleErrorAttribute());//default handler
        filters.Add(new HandleErrorEncodingAttribute());//extra check for filter disposal
}

public class HandleErrorEncodingAttribute : FilterAttribute, IExceptionFilter
{
    public virtual void OnException(ExceptionContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }
        if (filterContext.IsChildAction)
        {
            return;
        }
        // If custom errors are disabled, we need to let the normal ASP.NET exception handler
        // execute so that the user can see useful debugging information.
        if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
        {
            filterContext.HttpContext.Response.Filter.Dispose();//fixes response stream
            return;
        }
    }
}
0

, gzip WebForms. , Application_Error Global.asax.cs

protected void Application_Error(Object sender, EventArgs e)
{
    Response.Filter = null;
}

, , - b/c , . - Content-encoding, .

0

, . , gzip , , asp .

 CompressResponse(context);
 context.Response.Flush(); 

gzip, .

Two think maybe this is your problem. You did not set the page encoding

context.Response.ContentEncoding = new UTF8Encoding();

and you did not specify ContentType

context.Response.ContentType = "text/plain";

Perhaps this is the reason why you did not adjust the page rendering. Like never in my tests, even with what you describe, does not appear.

-1
source

All Articles