9

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.

Joannes Vermorel
  • 8,976
  • 12
  • 64
  • 104

3 Answers3

5

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.

Joannes Vermorel
  • 8,976
  • 12
  • 64
  • 104
  • I was under the impression that it's possible to configure compression at IIS level rather within your hosted application. However I don't know much about it, just a suggestion google "IIS Compression" – e36M3 Dec 13 '10 at 21:02
  • 2
    Classical HTTP compression applies only to **responses**, here that's the **requests** I am trying to compress. – Joannes Vermorel Dec 13 '10 at 21:36
  • No, in the end, we decided to re-implement our own HTTP stack :-( – Joannes Vermorel Aug 22 '12 at 13:19
  • 1
    @JoannesVermorel Try Wiktor's solution here: http://stackoverflow.com/questions/16671216/how-do-i-enable-gzip-compression-for-post-upload-requests-to-a-soap-webservice (noting my bugfixes in my own answer). – NickG May 24 '13 at 10:00
1

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.

Community
  • 1
  • 1
NickG
  • 9,315
  • 16
  • 75
  • 115
1

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);
        }
    }
greentrees
  • 53
  • 1
  • 6