简体   繁体   English

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

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

How can I enable compression for POSTed data uploaded to a .NET WebService (SOAP, not WCF)? 如何为上传到.NET WebService(SOAP,而不是WCF)的POSTed数据启用压缩? I thought it would be a simple matter of enabling dynamic compression in IIS but after enabling, it's only compressing the response , not the POST request . 我认为在IIS中启用动态压缩是一件简单的事情,但在启用后,它只会压缩响应 ,而不是压缩POST 请求

I've added it as a Service Reference and I can't find any settings on the generated SOAPClient to enable compression of requests. 我已将其添加为服务引用,但我无法在生成的SOAPClient上找到任何设置来启用请求压缩。

It seems I might be missing a configuration setting or code on the client side to compress the request before sending it to the server? 似乎我可能在客户端缺少配置设置或代码来压缩请求,然后再将其发送到服务器? Or is what I'm trying to do (GZipping POST data) not even supported? 或者我正在尝试做什么(GZipping POST数据)甚至不支持?

Further info: I'm using .NET 4.0 on the client and server. 更多信息:我在客户端和服务器上使用.NET 4.0。

I've blogged on that 4 years ago 我4年前写过这篇博文

http://netpl.blogspot.com/2009/07/aspnet-webservices-two-way-response-and.html http://netpl.blogspot.com/2009/07/aspnet-webservices-two-way-response-and.html

I wonder why you haven't found this by googling. 我想知道为什么你没有通过谷歌搜索找到这个。 Anyway, this should work for you, we have it working in a production environment for 4 years now. 无论如何,这应该对你有用,我们现在在生产环境中工作了4年。

In the end, I used Wiktor Zychla's answer but came across a couple of bugs (also mentioned in the comments of his article). 最后,我使用了Wiktor Zychla的回答,但遇到了一些错误(在他的文章的评论中也提到过)。 For completeness, I'll post my fixed version of the HttpCompression module here but the rest of the code (and implementation guidelines) you need are in Wiktor's article . 为了完整起见,我将在此处发布我的固定版本的HttpCompression模块,但您需要的其他代码(和实现指南)在Wiktor的文章中

UPDATE: 更新:

I've actually had to stop using this code as it has a bug I can't fix (even with my improved version below). 我实际上不得不停止使用此代码,因为它有一个我无法修复的错误(即使我的改进版本如下)。 For many people behind proxy servers it comes up with an error which says "the magic number in the gzip header is incorrect" and I can't figure out how to fix this. 对于代理服务器背后的许多人,它会出现一个错误,上面写着“gzip标头中的幻数不正确”,我无法弄清楚如何解决这个问题。 I think it's because proxy servers decompress GZIP and this code doesn't allow for receiving both zipped and non-zipped responses in its current form. 我认为这是因为代理服务器解压缩GZIP,并且此代码不允许以当前形式接收压缩和非压缩响应。

using System;
using System.IO.Compression;
using System.Web;
using System.Web.Security;

/// <summary>
/// Implement two way HTTP compression for the SOAP API
/// Code taken from: http://netpl.blogspot.co.uk/2009/07/aspnet-webservices-two-way-    response-and.html
/// Fix: Set Content-encoding: gzip header when an Exception occurs on the server.
/// Fix: Do not attempt to decrypt GZIP request stream when request was not GZIPed.
/// </summary>
public class HttpCompressionModule : IHttpModule
{
    private bool isDisposed = false;

    ~HttpCompressionModule()
    {
            Dispose(false);
    }

    public void Init(HttpApplication context)
    {
            context.BeginRequest += new EventHandler(Context_BeginRequest);
            context.PreSendRequestHeaders += new EventHandler(context_PreSendRequestHeaders);
    }

    void context_PreSendRequestHeaders(object sender, EventArgs e)
    {
            // Fix headers having been lost if an exception occurred.
            HttpApplication app = sender as HttpApplication;
            HttpContext ctx = app.Context;
            if (app.Response.Filter is GZipStream) SetEncoding("gzip");
            else if (app.Response.Filter is DeflateStream) SetEncoding("deflate");

            // Fix double header
            if (ctx.Response.Headers["Content-encoding"] == "gzip,gzip")
                    ctx.Response.Headers.Set("Content-encoding", "gzip");
    }

    public void Context_BeginRequest(object sender, EventArgs e)
    {
            HttpApplication app = sender as HttpApplication;
            HttpContext ctx = app.Context;

            // Currently only enable for the Uploader API webservice
            if (!ctx.Request.Url.PathAndQuery.ToLower().Contains("uploaderapi.asmx"))
            {
                    return;
            }

            // Add request filter if request was GZIP encoded
            string requestEncoding = ctx.Request.Headers["Content-encoding"];
            if (requestEncoding != null && requestEncoding == "gzip")
            {
               app.Request.Filter =
                    new System.IO.Compression.GZipStream(app.Request.Filter, CompressionMode.Decompress);
            }

            // Add response compression filter if the client accepts compressed responses
            if (IsEncodingAccepted("gzip"))
            {
                    app.Response.Filter = new GZipStream(app.Response.Filter, CompressionMode.Compress);
                    SetEncoding("gzip");
            }
            else if (IsEncodingAccepted("deflate"))
            {
                    app.Response.Filter = new DeflateStream(app.Response.Filter, CompressionMode.Compress);
                    SetEncoding("deflate");
            }
    }

    private bool IsEncodingAccepted(string encoding)
    {
            return HttpContext.Current.Request.Headers["Accept-encoding"] != null &&
                    HttpContext.Current.Request.Headers["Accept-encoding"].Contains(encoding);
    }

    private void SetEncoding(string encoding)
    {
            HttpContext ctx = HttpContext.Current;
            string responseEncodings = ctx.Response.Headers.Get("Content-encoding");
            if (responseEncodings == null || !responseEncodings.Contains(encoding))
                    HttpContext.Current.Response.AppendHeader("Content-encoding", encoding);
    }

    public void Dispose()
    {
            Dispose(true);
    }

    private void Dispose(bool dispose)
    {
            isDisposed = dispose;
    }
}

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

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