I was playing around with Compression a bit today as I ran into an article about the built-in compression features in IIS 6. Basically by setting up a few switches and metabase tweak you can get IIS to compress all your content using Gzip.dll. The savings in bandwidth and performance can be significant for this compression and it’s easy to apply to just about all of your Web content.

 

Static content in IIS gets compressed and cached in a configurable directory. Dynamic content gets compressed on the fly and thus incurs some processing overhead on the server for every page served. Essentially compression is meant for page content which actually can be compressed easily. You need to specifically configure the extensions that IIS compresses which can be done in the IIS 6 metabase (and has to be done manually in the XML file apparently).

 

There is an excellent discussion on how to set up IIS compression here:

http://orcsweb.com/articles/iis_compression_6.0.aspx

 

Most browsers support GZIP compression natively and in fact send off a header to ask for it if available, so if IIS has compression enabled most browsers will immediately take advantage of the compression functionality

 

The real value of compression however seems to be for distributed applications where the content of large SOAP packages or XML streams can really benefit from automatic compression. My first thought was to give this a quick spin with wwHTTP my Fox HTTP component and see if it would indeed use the compression. By default it doesn’t. Although wwHTTP uses WinInet, WinInet doesn’t send the default headers that IE sends so the prompting for compression is not automatic.

 

The browser asks for compression by way of an Accept header specifically Accept-Encoding which gets set to gzip, deflate. Using the indispensable Fiddler Http Snooper it was easy to find the header and the easy fix for WinInet by providing a custom header:

 

o = CREATEOBJECT("wwHTTP")

o.cexTRAHEADERS = "Accept-Encoding: gzip, deflate" + CHR(13)+ CHR(10)

? o.HttpGet("http://localhost/pricing.htm")

 

For those not using wwHTTP, with plain WinInet code you supply the headers as part of the HttpSendRequest() method:

 

lnRetval=HttpSendRequest(hHTTPResult,;

   tcHeaders,LEN(tcHeaders),;

   lcPostBuffer,tnPostSize)

 

This is easy enough to do the main thing is to remember to include it! In fact, for a generic WinInet client it might make sense to default this header into any client wrappers like wwHTTP.

 

I tried the same thing with .NET and the WebRequest client and it doesn’t support Gzip internally. You’d have to build a GZip decompressor to be able to receive compressed content from the server. The process of requesting content in GZip is the same – you simply provide the Accept-Encoding header in the Headers collection of the Web Request. On the receiving end you will need some third party tool to unzip. A few people have been down this path so if you need this functionality it can be found. I found an example here, but didn’t have a chance to try this out:

 

http://feralboy.com/log/archives/000420/

 

The idea is that you basically get the zipped stream back in WebResponseStream and you need to unzip it before processing the content as you would normally do.  What this means is that with WebRequest this process is a lot more involved as it’s not native to the platform and this means that you probably will use this functionality only on special occasions.

 

For Web Services things get even more difficult as you have no direct access to the underlying HTTP client. Instead you'd have to hook the client parsing pipeline and hook into it to decode the incoming content.