.NET: Is it possible to get HttpWebRequest to automatically decompress gzip'd responses?

Cheeso picture Cheeso · May 12, 2010 · Viewed 24.2k times · Source

In this answer, I described how I resorted to wrappnig a GZipStream around the response stream in a HttpWebResponse, in order to decompress it.

The relevant code looks like this:

HttpWebRequest hwr = (HttpWebRequest) WebRequest.Create(url);
hwr.CookieContainer =
    PersistentCookies.GetCookieContainerForUrl(url);
hwr.Accept = "text/xml, */*";
hwr.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate");
hwr.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-us");
hwr.UserAgent = "My special app";
hwr.KeepAlive = true;

using (var resp = (HttpWebResponse) hwr.GetResponse()) 
{
    using(Stream s = resp.GetResponseStream())
    {
        Stream s2 = s;
        if (resp.ContentEncoding.ToLower().Contains("gzip"))
            s2 = new GZipStream(s2, CompressionMode.Decompress);
        else if (resp.ContentEncoding.ToLower().Contains("deflate"))
            s2 = new DeflateStream(s2, CompressionMode.Decompress);

         ... use s2 ...
    }
}

Is there a way to get HttpWebResponse to provide a de-compressing stream, automatically? In other words, a way for me to eliminate the following from the above code:

      Stream s2 = s;
      if (resp.ContentEncoding.ToLower().Contains("gzip"))
          s2 = new GZipStream(s2, CompressionMode.Decompress);
      else if (resp.ContentEncoding.ToLower().Contains("deflate"))
          s2 = new DeflateStream(s2, CompressionMode.Decompress);

Thanks.

Answer

Bradley Grainger picture Bradley Grainger · May 12, 2010

Use the HttpWebRequest.AutomaticDecompression property as follows:

HttpWebRequest hwr = (HttpWebRequest) WebRequest.Create(url);
hwr.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;

It's not necessary to manually add the Accept-Encoding HTTP header; it will automatically be added when that property is used.

(Also, I know this is just example code, but the HttpWebResponse object should be placed in a using block so it's disposed correctly when you've finished using it.)