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

前端 未结 3 2050
萌比男神i
萌比男神i 2021-02-15 14:37

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

相关标签:
3条回答
  • 2021-02-15 14:54

    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.

    0 讨论(0)
  • 2021-02-15 14:59

    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.

    0 讨论(0)
  • 2021-02-15 15:12

    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);
            }
        }
    
    0 讨论(0)
提交回复
热议问题