HTTP modules can be very useful. In fact, I love them. The scope of this post is unfortunately not to explain what they are or what they do. If you're not familiar with what a HTTP module is, get an overview here and see how to create one here.
ASP.NET features some built in handlers: WebResource.axd and ScriptResource.axd. You'll see requests to these in any ASP.NET application, as they're used to serve builtin scripts for e.g. postback or client side form validation. By default, the ASP.NET application will configure these to expire from cache after a year.
Today I discovered a side effect I had not thought about. HTTP modules are loaded by the application, and are hooked into the event pipeline for each and every request handled by the ASP.NET application. In fact, this also includes requests to the WebResource.axd and ScriptResource.axd handlers!
Say you make an HTTP module that sets the cache policy for all responses — this is a nice trick to enforce a coherent cache policy for all pages across a website. Well, you just enforced your policy upon the built in handlers, which was probably not what you wanted. By default their response will be cached for an entire year, and reducing their time to live will obviously affect the load on your servers. You might even expire them immediately, forcing users to reload unchanged scripts on every page load (I know someone who did).
So, keep in mind that HTTP modules are also run for the built in handlers — or be prepared to taste the side effects.
As a final note, since we're discussing WebResource.aspx and caching: Make sure that the ASP.NET application is run with the <compilation debug="false"> setting, or else the framework will ensure that built in resources are not cached. ScottGu explains why on his blog, and one of the ASP.NET engineers elaborate further on the details of this setting on her blog.
To verifiy that the cache setting for the WebResource.axd is sane, use e.g. the Fiddler tool to inspect the response headers. You should see a date header with the current date, and an expires header with a date a year into the future, like this:
Date: Mon, 08 Nov 2010 14:57:24 GMT
Expires: Tue, 08 Nov 2011 14:57:24 GMT
Happy caching.
Software security blog by André N. Klingsheim, who's learning to love .NET and Microsoft servers.
Nov 8, 2010
Subscribe to:
Post Comments (Atom)
Read other popular posts
-
I just found out that Terminal services manager does not exist in Windows 7. But fear not, the Remote Desktop Services Manager will do the ...
-
The release of Firesheep a week ago brought a lot of attention to a problem that has been known for many, many years: cookies sent over both...
-
Security headers in an HTTP response There are many things to consider when securing a web application but a definite "quick win&qu...
-
Yesterday I was playing around with the validateIntegratedModeConfiguration="true" setting on IIS 7.5. To my surprise I got an ...
-
If you work in an environment where several people fiddle around on the same servers, every once in a while you'll get the message "...
-
Well, when I have trouble reaching particular websites I often check whether Google works — to verify that my Internet connection is working...
-
If one of your ASP.NET applications need to access to a certificate from the certificate store along with its private key, you'll probab...
-
I'm baffled. IIS 7.5 does not log to files by default, you have to enable the feature manually. In the settings it's called "HT...
-
Today I had to add a new HttpModule to A LOT of web.configs. Adding it manually would be too tedious, so I had to figure out how to search f...
-
IIS refuses to serve static files that cannot be mapped to a particular MIME type. Since I'm a Windows n00b I spent some time figuring t...
It's a good trick to set cache expiration to "infinite" and instead use a version number in the query string to the resource. Then for each new version the users with the old outdated resource will immediately fetch the new resource from the server. If a resource lives for a long time without being changed then users never have to refetch it for that time.
ReplyDeleteThe page that references the resources either is always expired, or has a very short expiration.
Ex: <script src="myfile.js?version=1"></script>
You're right! This is essentially what happens for resources served by WebResource.axd.
ReplyDeleteAwesome post, I learned something new today! I just forwarded your post to the BlogEngine.Net team as something they should be aware of.
ReplyDeleteI'm glad to hear that you found this information useful!
ReplyDelete