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

别说谁变了你拦得住时间么 提交于 2019-12-05 07:42:12

I had the same thing happen when forcing gzip on a WebForms application. In order to fix it I had to clear the filter in the Application_Error method in Global.asax.cs

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

The reason this is happening is b/c the filter is being set before the app has an error. And for some reason the yellow screen error message clears the Content-encoding header but doesn't do anything to the response filter.

If you have an exception, then the server will flush the currently set headers and content, because they're wrong, as you did after all have an exeption.

At the very least, it's clear that the 200 status you were going to send (because all successful responses that don't change the status send a 200, and upon an unhandled exception it was no longer succesful) is wrong, but everything else related to something you were going to do but failed to achieve, so it's all wrong and it all goes.

Filters aren't reset though.

Either reset the headers in the error page if appropriate, or don't set the filter unless you can be sure that everything is ready to flush. I'd go for the former, no reason why error pages can't be compressed too.

You can't send a header if you've called Flush(), because well, because you've flushed. Where's the header going to go?

I encountered this problem as well. It was complicated to track down. I am unsure of the exact specifics of this whole situation, but what I think happens is that there is a memory leak.

When you first do this:

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

you are assigning an unmanaged resource to Filter. Normally this would be wrapped in a using statement so that it would be properly disposed in case anything went wrong.

So, when something does go wrong, there is a problem. The Filter contains a stream which is still open even though the response is being written to with the yellow screen of death. What ensues is madness (as shown in your screen shot).

Fear not! There is actually an easy way to overcome this issue. Dispose of the filter. Luckily, there is already a place to apply this global check for filter disposal.

global.asax.cs

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

error handler namespace

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;
        }
    }
}

I test your code and I can not find any issue. Yes the gzip is not set, but the filter also not have been set and asp gets the control and send an error.

Forcing the header to flush make a real problem

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

If I force the gzip header then the page is not render correctly.

Two thinks here maybe is your issue. You do not have set the page encoding

context.Response.ContentEncoding = new UTF8Encoding();

and you do not have set ContentType

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

Maybe some of this is the reason that you get not corrected page render. How ever in my tests even with that the issue you describe not appears.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!