29. April 2007 11:55
My previous post on restricting the cacheability of static content focused on IIS5/6. Now lets check out IIS 7 on Windows Vista. Note that all of these settings work at folder level, so you should put your static content in one or more subfolders to make this work.
The bad news first: The IIS 7 Manager doesn't expose any of the following settings. You must use appcmd.exe and your favorite Windows command line interpreter to update your server and application configuration. By the way, if you find yourself struggling with appcmd.exe and its less than intuitive syntax, try Kanwaljeet Singla's excellent AppcmdUI.
- First, you'll likely need to unlock the configuration section for static content handling. By default, most configuration sections are locked down at server level and cannot be overridden by application settings unless unlocked.
appcmd unlock config /section:staticContent
- Now you're good to change the caching options for static content. IIS 7 offers the following options here:
- Make static content non-cacheable by setting "Cache-Control: no-cache":
appcmd set config "Default Web Site/<Application>/<Folder>" /section:staticContent /clientCache.cacheControlMode:DisableCache
(Replace <Application>/<Folder> with the virtual path to your static content.)
- Make static content expire after a fixed duration by setting "Cache-Control: max-age":
appcmd set config "Default Web Site/<Application>/<Folder>" /section:staticContent /clientCache.cacheControlMode:UseMaxAge
The default value for max-age is 86400 seconds (i.e. one day). To change this, use
appcmd set config "Default Web Site/
" /section:staticContent /clientCache.cacheControlMaxAge:"<hh>:<mm>:<ss>"
(Replace <hh>:<mm>:<ss> with an appropriate time span.)
- Make static content expire at a fixed point in time by setting the "Expires" header. That's the same appcmd command as before, but instead of
UseExpires, and set
/clientCache.httpExpires to your desired expiration date.
- Issue your own Cache-Control headers by setting
/clientCache.cacheControlCustom:<Header>. This also works in combination with the previously mentioned options. This is useful for setting headers like "Cache-Control: no-store" or "Cache-Control: must-revalidate".
- If you want to revert to the default behavior of not setting any caching headers, use
appcmd set config "Default Web Site/<Application>/<Folder>" /section:staticContent /clientCache.cacheControlMode:NoControlNote that this does not affect any custom headers set by
/clientCache.cacheControlCustom. To get rid of those, set
The astute reader will notice a couple of issues here. First of all, there's no way to combine HTTP 1.1 and HTTP 1.0 headers like "Cache-Control: max-age" and "Expires". Secondly, the current "Expires" implementation is rather useless—configuring a fixed expiration time stamp requires a configuration update each time the expiration date has been reached. "Expires" needs to be computed based on an expiration interval, and that's exactly how it is done in IIS 5/6. I assume all these issues are only shortcomings of the current Vista implementation. Unfortunately, I haven't had time to delve into any of the Longhorn Server Betas and their respective IIS 7 implementations so far, but once I've got Beta 3 up and running I will post another update.
Windows Server 2008 Beta 3 update (29-07-2007): Same behavior as described above