Problems with gzip when using IIS 7.5 as an Origin server for a CDN
I recently decided to try out my friend Sajals new CDN service over at Turbobytes. While setting this up he pointed out some issues I had with my custom origin domain that I run on IIS. IIS has some problems that many CDN doesn’t like.
The “Via” Header
To begin with, many CDNs send a “Via” header to notify the server that they are a proxy. And for some reason IIS doesn’t serve gzipped content to a server that does this. This means that many CDNs just don’t get gzipped content from IIS and therefore don’t serve gzipped content to your customer. To resolve this you have to change some settings in your applicationHost.config.
<location path="Your Site"> <system.webServer> <httpCompression noCompressionForHttp10="false" noCompressionForProxies="false" /> </system.webServer> </location>
The thing to fix the problem with the “Via” header is the two attributes noCompressionForHttp10=” false” and noCompressionForProxies=” false” and they kind of explain themselves. And remember the weirdness with the applicationHost.config to not open them in Notepad++ or any other 32bit based apps. You must edit them with a 64-bit text editor like the built-in notepad in Windows.
curl -I -H Accept-Encoding:gzip,deflate -H Via:Cdn http://example.com/test.css HTTP/1.1 200 OK Content-Length: 5648 Content-Type: text/css Content-Encoding: gzip Last-Modified: Thu, 14 Jul 2011 16:56:26 GMT Accept-Ranges: bytes ETag: "add123f84642cc1:0" Vary: Accept-Encoding Server: Microsoft-IIS/7.5 Date: Mon, 25 Jun 2012 13:01:34 GMT
IIS doesn’t return the first request gzip by default
Another issue with IIS as an origin server is that it doesn’t return the first request of a file as gzipped. I suppose they figured that for a normal user it’s faster to just return the content and then serve the gzipped version to the next user. But a CDN of course only do one request for the file and then sits happy and serves that file. And if that file is not gzipped then it will stay not gzipped. But there is a fix for this as well. Just modify the same section in applicationHost.config as you’ve edited before and you should be fine. I got lots of help with this question on Stack Overflow.
<location path="Your Site"> <system.webServer> <httpCompression noCompressionForHttp10="false" noCompressionForProxies="false" /> <serverRuntime frequentHitThreshold="1" frequentHitTimePeriod="00:00:05" /> </system.webServer> </location>
The “Vary” Header
Another possible issue is that IIS doesn’t return a “Vary” header if the content is not gzipped. This could cause issues if the first request to your file from any client doesn’t request a gzipped file. Since the vary header is not set then the CDN doesn’t try to fetch a new file. As far as I understand it. I just added a custom header to my web. config. The problem with this is that it ads multiple values in the Vary header when I request gzipped content. I don’t know if this is a problem or not. I’ve asked a question about this on Stack Overflow. I will update here when I get some more answers to this.
<httpProtocol> <customHeaders> <remove name="Vary"></remove> <add name="Vary" value="Accept-Encoding" /> </customHeaders> </httpProtocol>
curl -I http://example.com/test.css HTTP/1.1 200 OK Content-Length: 18241 Content-Type: text/css Last-Modified: Thu, 14 Jul 2011 16:56:26 GMT Accept-Ranges: bytes ETag: "add123f84642cc1:0" Vary: Accept-Encoding Server: Microsoft-IIS/7.5 Date: Tue, 26 Jun 2012 12:04:42 GMT
Problem with multiple Vary values.
curl -I -H Accept-Encoding:gzip,deflate http://example.com/theme.css HTTP/1.1 200 OK Content-Length: 4445 Content-Type: text/css Content-Encoding: gzip Last-Modified: Thu, 14 Jul 2011 16:56:26 GMT Accept-Ranges: bytes ETag: "059d5f74642cc1:0" Vary: Accept-Encoding,Accept-Encoding Server: Microsoft-IIS/7.5 Date: Tue, 26 Jun 2012 12:03:00 GMT
