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.

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

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"
Classical HTTP compression applies only to responses, here that's the requests I am trying to compress.
No, in the end, we decided to re-implement our own HTTP stack :-(
@JoannesVermorel Try Wiktor's solution here: stackoverflow.com/questions/16671216/… (noting my bugfixes in my own answer).
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.

Comments

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);
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.