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

发布于 2024-10-07 01:08:27 字数 240 浏览 5 评论 0原文

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

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

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

For an ASP.NET 4.0 / IIS7 web app, I would like to support compressed HTTP requests. Basically, I would like to support clients that would add Content-Encoding: gzip in the request headers, and compress the body accordingly.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

天暗了我发光 2024-10-14 01:08:27

对于那些可能感兴趣的人来说,使用 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 而不是解压缩后获得的值。

For those who might be interested, the implementation is rather straightforward with an IHttpModule that simply filters incoming requests.

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.

掐死时间 2024-10-14 01:08:27

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

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

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

Try Wiktor's answer to my similar question here:

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

...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.

旧竹 2024-10-14 01:08:27

虽然很 hacky,但即使在通过设置 HttpRequest 中的私有 _contentLength 字段解压缩请求之后,您也可以使用原始的 Content-Length 绕过 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);
        }
    }

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. Using Joannes Vermorel's code:

    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);
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文