Enabling dynamic compression (gzip, deflate) for WCF Data Feeds, OData and other custom services in IIS7
I'm working on a thing that uses an HttpWebRequest to talk to a backend WCF Data Service and it'd be ideal if the traffic was using HTTP Compression (gzip, deflate, etc).
On the client side, it's easy to just add code like this
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
or more manually
var request = HttpWebRequest.Create("http://foofoo");
request.Headers["Accept"] = "application/json";
request.Headers["Accept-Encoding"] = "gzip, deflate";
However, you need to make sure this is installed and turned on in IIS7 in you server.
Launch your IIS Manager and go to the Compression module.
There's check boxes, but it's not installed you may see this yellow alert on the right side.
If it's not installed, go to the Server Manager, Roles, Web Server. Under Role Services, check your installed Roles. If Dynamic Compression isn't installed, click Add Roles and install it.
You can go back to compression for your site and ensure Dynamic Compression is checked. At this point, Dynamic Compression should be setup, but you really need to be specific about what mimeTypes will be compressed.
Back in IIS Manager, go to the page for the SERVER, not the SITE. Click on Configuration Editor:
From the dropdown, select system.webServer/httpCompression:
Then click on Dynamic Types and now that you're in the list editor, think about what types you want compressed. By default */* is False, but you could just turn that on. I chose to be a little more picky and added application/atom+xml, application/json, and application/atom+xml;charset=utf-8 as seen below. It's a little gotcha that application/atom+xml and application/atom+xml;charset=utf-8 are separate entries. Feel free to add what ever mimeTypes you like in here.
After you've added them and closed the dialog, be sure to click Apply and Restart your IIS Service to load the new module.
GUIs suck! Command Lines Rule!
If you find all this clicking and screenshots offensive, then do it all from the command line using AppCmd for IIS7. That's lovely also.
appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json',enabled='True']" /commit:apphost
appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/atom%u002bxml',enabled='True']" /commit:apphost
appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/atom%u002bxml;charset=utf-8',enabled='True']" /commit:apphost
Do check your ApplicationHost.config after running this command. See how we had to escape the "+" in "atom+xml" above and made it "atom%u002bxml"? Make sure that + got into your applicationHost.config unescaped. It should look like this in the System.webServer/httpCompression section.
Now, use Fiddler to confirm that compression is turned on by sending a request with the header "Accept-Encoding: gzip, deflate" included. Make sure that Fiddler's "AutoDecode" and Transforms are turned off if you really want to be sure you're looking at the raw stuff.
Turning on Compression is a VERY low effort and VERY high reward thing to do on your servers, presuming they aren't already totally CPU-bound. If you're doing anything with phones or services over low-bandwidth 3G or EDGE networks, it's a total no brainer. Make sure you know what's compressed on your systems and what's not, and if not, why not.
Be explicit and know what your system/sites HTTP Headers are doing. Compression is step 0 in service optimization. I think I mentioned this in 2004. :)