C# 我能检测到我的HttpModule中的内容是否已被压缩吗?

C# 我能检测到我的HttpModule中的内容是否已被压缩吗?,c#,asp.net,iis,C#,Asp.net,Iis,我有一个HttpModule,用于动态压缩来自ASP.NET(MVC3)web应用程序的内容。该方法与中的CompressionModule非常相似(模块将GZip筛选器应用于HttpResponse并设置正确的内容编码头) 出于这样或那样的原因,这需要在经典模式下运行,而不是在集成管道模式下运行 我遇到的问题是,在一些启用了IIS压缩的服务器上,IIS压缩内容,然后我的模块压缩内容 结果是,我将内容压缩了两次,并进行了编码: Content-encoding: gzip,gzip 一个来自I

我有一个HttpModule,用于动态压缩来自ASP.NET(MVC3)web应用程序的内容。该方法与中的CompressionModule非常相似(模块将GZip筛选器应用于HttpResponse并设置正确的内容编码头)

出于这样或那样的原因,这需要在经典模式下运行,而不是在集成管道模式下运行

我遇到的问题是,在一些启用了IIS压缩的服务器上,IIS压缩内容,然后我的模块压缩内容

结果是,我将内容压缩了两次,并进行了编码:

Content-encoding: gzip,gzip
一个来自IIS,另一个来自我的代码中的此行:

 httpResponse.AppendHeader("Content-encoding", "gzip");
有人知道在经典模式下,我可以通过检查内容是否已经压缩,或者服务器上是否启用了压缩来绕过我自己的压缩吗

在管道模式下,此检查非常简单

if (httpResponse.Headers["Content-encoding"]!= null)
{
   return;
}
i、 e.检查是否已经设置了内容编码,如果已经设置了,则不执行任何操作

然而,我在经典模式中被难倒了。不幸的是,在经典模式下不允许访问
HttpResponse.Headers
,因此我无法进行屏障检查


所有想法都得到了感激。

理论上,您可以使用反射查看
HttpRequest.\u cacheHeaders
字段,其中ASP.NET显然以经典模式存储所有尚未发送的标题:

if (this._wr is IIS7WorkerRequest)
{
    this.Headers.Add(HttpResponseHeader.MaybeEncodeHeader(name), HttpResponseHeader.MaybeEncodeHeader(value));
}
else if (flag)
{
    if (this._cacheHeaders == null)
    {
        this._cacheHeaders = new ArrayList();
    }
    this._cacheHeaders.Add(new HttpResponseHeader(knownResponseHeaderIndex, value));
}

我找到了一种相对简单的方法来检查输出是否已经被压缩;我的方法甚至适用于在经典模式下运行的IIS,尽管它可能被认为是一种“黑客”,但我发现它工作得相当一致;这个想法大致如下

// checks if the response is already compressed
private bool IsResponseCompressed(HttpApplication app)
{
    string filter = app.Response.Filter.ToString().ToLower();
    if (filter.Contains("gzip") | filter.Contains("deflate")) 
    {
      return true;
    }
    return false;
}

基本上,代码通过检查响应过滤器名称来工作;如果输出流被压缩,则名称包含“gzip”或“deflate”,因此很容易检查压缩情况

我认为您只能通过经典模式下的ISAPI模块来执行此操作。事实上-尽管您真的不希望对每一个请求都会调用的这段生产代码使用反射。@Rob尝试这种方法()使用编译的lambdas。这似乎是一个巨大的性能差异。现在这是一个有趣的方法-我要试一试。这对我不起作用。响应对象的_headers字段返回为null。这对我不起作用。Response.Filter是一个流,.ToString()只返回流类的名称。