I've talked a bit about GZip compression (here and here and here) on the server recently. It's pretty straight forward to use GZip compression either by letting IIS do it for you automatically or by using some simple ASP.NET code to compress content.

As a quick review to create GZip content on the server generically I created a couple simple static utility functions that can be called from anywhere to dynamically encode dynamic ASP.NET content:

/// <summary>
/// Determines if GZip is supported
/// </summary>
/// <returns></returns>
public static bool IsGZipSupported()
{
    string AcceptEncoding = HttpContext.Current.Request.Headers["Accept-Encoding"];
    if (!string.IsNullOrEmpty(AcceptEncoding) && 
         ( AcceptEncoding.Contains("gzip") || AcceptEncoding.Contains("deflate") ) )
        return true;
    return false;
}

/// <summary>
/// Sets up the current page or handler to use GZip through a Response.Filter
/// IMPORTANT:  
/// You have to call this method before any output is generated!
/// </summary>
public static void GZipEncodePage()
{
    if (IsGZipSupported())
    {
        HttpResponse Response = HttpContext.Current.Response;                

        string AcceptEncoding = HttpContext.Current.Request.Headers["Accept-Encoding"];
        if (AcceptEncoding.Contains("gzip"))
        {
            Response.Filter = new System.IO.Compression.GZipStream(Response.Filter,
                                      System.IO.Compression.CompressionMode.Compress);
            Response.AppendHeader("Content-Encoding", "gzip");
        }
        else
        {
            Response.Filter = new System.IO.Compression.DeflateStream(Response.Filter,
                                      System.IO.Compression.CompressionMode.Compress);
            Response.AppendHeader("Content-Encoding", "deflate");
        }
    }
}

All that needs to happen in an ASP.NET page (or a handler for that matter) is to call GZipEncodePage() before any Response output is written. The single method call  takes care of checking whether the client supports it and then assigning the filter for compression.

The Client Side

This takes care of the server side and if you're using a browser, GZip support is pretty much automatic - it just works as most browsers can decompress Gzip content. But if you're using an HTTP client in the .NET framework - WebClient or HttpWebRequest - you'll find that Gzip is not natively supported. So how do you make your client request GZip content?

You start by adding an Accept-Encoding header to the request that tells the server to encode responses with GZip. That what the server code above is checking for to decide whether GZip needs to be applied. The client then receives the compressed response from the server and needs to decomress it.

Here's what a simplified method for retrieving a URL to string with GZip compression looks like:

/// <summary>
/// Simple routine to retrieve HTTP Content as a string with
/// optional POST data and GZip encoding.
/// </summary>
/// <param name="Url"></param>
/// <param name="PostData"></param>
/// <param name="GZip"></param>
/// <returns></returns>
public string GetUrl(string Url, string PostData, bool GZip)
{
    HttpWebRequest Http = (HttpWebRequest)WebRequest.Create(Url);

    if (GZip)
        Http.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");

    if (!string.IsNullOrEmpty(PostData))
    {
        Http.Method = "POST";
        byte[] lbPostBuffer = Encoding.Default.GetBytes(PostData);

        Http.ContentLength = lbPostBuffer.Length;

        Stream PostStream = Http.GetRequestStream();
        PostStream.Write(lbPostBuffer, 0, lbPostBuffer.Length);
        PostStream.Close();
    }

    HttpWebResponse WebResponse = (HttpWebResponse)Http.GetResponse();

    Stream responseStream = responseStream = WebResponse.GetResponseStream();
    if (WebResponse.ContentEncoding.ToLower().Contains("gzip"))
        responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
    else if (WebResponse.ContentEncoding.ToLower().Contains("deflate"))
        responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);            

    StreamReader Reader = new StreamReader(responseStream, Encoding.Default);

    string Html = Reader.ReadToEnd();

    WebResponse.Close();
    responseStream.Close();

    return Html;
}

The beauty of the compression streams is that they work on existing streams and so effectively act as a filter for the base stream. This means the compression can usually be plugged into any Stream interface with no other code changes.

It'd be nice if GZip was natively supported by HttpWebRequest, but I suppose this code is easy enough to create a wrapper with. Note that you have to use HttpWebRequest to use GZip encoding - the WebClient class doesn't expose its underlying stream so you can't easily decompress content through that interface.