无法在同一响应中将GzipStream和Content-Encoding设置为gzip

时间:2014-01-09 19:31:50

标签: c# .net gzip

我正在开发一个在web.config中使用的CompressionModule,我已经在这个案例中解决了一个更大的问题,我很难过。

对于这个例子,我创建了一个新的MVC4互联网应用程序,并对web.config进行了以下修改:

<handlers>
  <!--
  <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
  <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
  <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  -->
  <add name="Content" path="*" verb="*" preCondition="integratedMode" type="System.Web.StaticFileHandler" />
</handlers>
<modules>
        <remove name="monorailRouting" />
      <add name="compressionModule" type="Platform.Web.CompressionModule" />
  <!--
  <add name="ErrorHandlerModule" type="System.Web.Mobile.ErrorHandlerModule, System.Web.Mobile, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      -->
</modules>

压缩模块在哪里

namespace Platform.Web {
public class CompressionModule : IHttpModule {

    #region HTTP Header Constants
    private const string DEFLATE = "deflate";
    private const string GZIP = "gzip";
    private const string CONTENT_ENCODING = "Content-Encoding";
    private const string ACCEPT_ENCODING = "Accept-Encoding";
    private const string VARY = "Vary";
    #endregion

    #region IHttpModule Members
    public void Dispose() {
        //noop
    }

    public void Init(HttpApplication context) {
        context.BeginRequest += new EventHandler(context_CompressResponse);
    }


    void context_CompressResponse(object sender, EventArgs e) {
        HttpApplication app = (HttpApplication)sender;

        string encodings = app.Request.Headers.Get(ACCEPT_ENCODING);

        if (encodings == null)
        {
            return;
        }

        encodings = encodings.ToLower();

        if (encodings.Contains(GZIP))
        {
            //1
            app.Response.Filter = new GZipStream(app.Response.Filter, CompressionMode.Compress);

            //2
            app.Response.AppendHeader(CONTENT_ENCODING, GZIP);

        }

        app.Response.AppendHeader(VARY, CONTENT_ENCODING);



    }

    #endregion
}
}

我遇到了以下问题:

  1. 如果存在第1行和第2行,则应用加载正常。但显然没有什么 gzipped在标题,也不是身体。我是通过Fiddler确定的。

  2. 如果第1行存在但是2没有应用程序加载但是gzip不可读     显示在浏览器中。

  3. 如果第1行不存在但是2确实无法加载,但是     内容编码:gzip位于标题中。

  4. 有人对我可能做错了什么有一些建议吗?

2 个答案:

答案 0 :(得分:0)

我认为应该做的两件事是,

  1. 应将响应过滤器纳入流
  2. 的副本
  3. 必须更改标题的变化
  4. 请尝试以下代码:

    void context_CompressResponse(object sender, EventArgs e)
    {
        HttpApplication app = (HttpApplication)sender;
    
        string encodings = app.Request.Headers.Get(ACCEPT_ENCODING);
        if (encodings == null)
        {
            return;
        }
    
        encodings = encodings.ToLower();
    
        if (encodings.Contains(GZIP))
        {
            Stream baseStream = app.Response.Filter;
    
            //1
            app.Response.Filter = new GZipStream(baseStream, CompressionMode.Compress);
    
            //2
            app.Response.AppendHeader(CONTENT_ENCODING, GZIP);
        }
        Response.Cache.VaryByHeaders[ACCEPT_ENCODING] = true;
    }
    

    此外,如需进一步讨论,请查看此S O article

答案 1 :(得分:0)

原来Fiddler2没有正确读取标题。

如果我在Chrome中查看回复,我可以看到Content-Encoding正在设置为gzip。

-Geoff