Add optional gzip compression to selfhosted WCF service

custom-attributes, gzip, rest, wcf

Solution

This is not an attribute, but it is the basic code that will compress WCF service responses, and can be wrapped up into an attribute if desired.

public static void CompressResponseStream(HttpContext context = null)
{
    if (context == null)
        context = HttpContext.Current;

    string encodings = context.Request.Headers.Get("Accept-Encoding");

    if (!string.IsNullOrEmpty(encodings))
    {
        encodings = encodings.ToLowerInvariant();

        if (encodings.Contains("deflate"))
        {
            context.Response.Filter = new DeflateStream(context.Response.Filter, CompressionMode.Compress);
            context.Response.AppendHeader("Content-Encoding", "deflate");
            context.Response.AppendHeader("X-CompressResponseStream", "deflate");
        }
        else if (encodings.Contains("gzip"))
        {
            context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
            context.Response.AppendHeader("Content-Encoding", "gzip");
            context.Response.AppendHeader("X-CompressResponseStream", "gzip");
        }
        else
        {
            context.Response.AppendHeader("X-CompressResponseStream", "no-known-accept");
        }
    }
}

[EDIT] to address comments:

Simply call it anywhere in the body of your web service operation, as it sets properties on the response:

[OperationContract]
public ReturnType GetInformation(...) {
    // do some stuff
    CompressResponseStream();
}

Problem

How can I add a optional gzip compression for my selfhosted WCF service? I'm using for this senario the `WebHttpBinding`. I want to check if the `Accept` header contains the string `gzip` and compress than the content. I would like to use a custom Attribute. So far I curriently use a custom Attribute allows me to switch between XML and JSON output, but I have just now no idea how to compress the output. In my encoder switch attribute I implemented the `IDispatchMessageFormatter` interface to change on demand the `XmlObjectSerializer`. But I don't unterstand how the output is generated to modify it. It would be nice if somebody could point my to a possible solution.

Original source