如何在Asp.Net 4.0 / IIS7中支持压缩的HTTP请求?

时间:2010-12-10 16:25:22

标签: asp.net iis request gzip http-compression

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

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

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

3 个答案:

答案 0 :(得分: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而不是解压缩后获得的值。

答案 1 :(得分:1)

在这里尝试Wiktor对我类似问题的回答:

How do I enable GZIP compression for POST (upload) requests to a SOAP WebService on IIS 7?

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

答案 2 :(得分:0)

尽管很hacky,但是即使通过使用反射在Content-Length类中设置私有_contentLength字段对请求进行解压缩后,也可以使用原始HttpRequest来解决WCF。使用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);
        }
    }