8

对于 ASP.NET 4.0 / IIS7 Web 应用程序,我想支持压缩的 HTTP请求。基本上,我想支持将添加Content-Encoding: gzip请求标头的客户端,并相应地压缩正文。

有谁知道我是如何实现这种行为的?

Ps:关于,我有多个端点 REST 和 SOAP,感觉更好的解决方案是支持 HTTP 级别的压缩,而不是每个端点的自定义编码器。

4

3 回答 3

5

对于那些可能感兴趣的人,该实现相当简单IHttpModule,只需过滤传入的请求。

public class GZipDecompressModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += BeginRequest;
    }

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

        if ("gzip" == app.Request.Headers["Content-Encoding"])
        {
            app.Request.Filter = new GZipStream(
               app.Request.Filter, CompressionMode.Decompress);
        }
    }

    public void Dispose()
    {
    }
}

更新:这种方法似乎在 WCF 中引发了问题,因为 WCF 依赖于原始Content-Length而不是解压缩后获得的值。

于 2010-12-11T09:44:52.983 回答
1

在此处尝试 Wiktor 对我的类似问题的回答:

如何为 IIS 7 上的 SOAP WebService 的 POST(上传)请求启用 GZIP 压缩?

...但请注意他在他的博客上的实现包含几个错误/兼容性问题,所以请尝试我在同一页面上发布的 HttpCompressionModule 类的修补版本。

于 2013-05-24T10:03:06.717 回答
0

Content-Length尽管很老套,但即使在请求已解压缩后,您也可以使用原始 WCF 绕过 WCF,方法是使用反射_contentLength在类中设置私有字段。HttpRequest使用 Joannes Vermorel 的代码:

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

        if ("gzip" == app.Request.Headers["Content-Encoding"])
        {
            app.Request.Filter = new GZipStream(
                app.Request.Filter, CompressionMode.Decompress);

            // set private _contentLength field with new content length after the request has been decompressed
            var contentLengthProperty = typeof(HttpRequest).GetField("_contentLength", BindingFlags.NonPublic | BindingFlags.Instance);
            contentLengthProperty.SetValue(app.Request, (Int32)app.Request.InputStream.Length);
        }
    }
于 2019-06-16T20:04:16.457 回答