简体   繁体   English

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

[英]How to support compressed HTTP requests in Asp.Net 4.0 / IIS7?

For an ASP.NET 4.0 / IIS7 web app, I would like to support compressed HTTP requests . 对于ASP.NET 4.0 / IIS7 Web应用程序,我想支持压缩的HTTP 请求 Basically, I would like to support clients that would add Content-Encoding: gzip in the request headers, and compress the body accordingly. 基本上,我想支持在请求标头中添加Content-Encoding: gzip客户端,并相应地压缩主体。

Does anyone known how I achieve such a behavior? 有谁知道我是如何实现这样的行为的?

Ps: concerning, I have multiple endpoints REST and SOAP, and it feels a better solution to support compression at the HTTP level rather than custom encoders for each endpoint. Ps:关于,我有多个端点REST和SOAP,它感觉更好的解决方案来支持HTTP级别的压缩,而不是每个端点的自定义编码器。

For those who might be interested, the implementation is rather straightforward with an IHttpModule that simply filters incoming requests. 对于那些可能感兴趣的人来说, 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()
    {
    }
}

Update: It appears that this approach trigger a problem in WCF, as WCF relies on the original Content-Length and not the value obtained after decompressing. 更新:此方法似乎在WCF中触发了问题,因为WCF依赖于原始Content-Length而不是解压缩后获得的值。

Try Wiktor's answer to my similar question here: 在这里尝试Wiktor对我类似问题的回答:

How do I enable GZIP compression for POST (upload) requests to a SOAP WebService on IIS 7? 如何为IIS 7上的SOAP WebService的POST(上载)请求启用GZIP压缩?

...but please note his implementation on his blog contained a couple of bugs / compatibility issues, so please try my patched version of the HttpCompressionModule class posted on the same page. ...但请注意他在博客上的实现包含一些错误/兼容性问题,所以请尝试在同一页面上发布的HttpCompressionModule类的修补版本。

Although hacky, you can get around WCF using the original Content-Length even after the request has been decompressed by setting the private _contentLength field in the HttpRequest class using reflection. 虽然hacky,但是即使在解压缩请求之后,您也可以使用反射通过在HttpRequest类中设置private _contentLength字段来使用原始Content-Length来绕过WCF。 Using Joannes Vermorel's code: 使用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);
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM