Expires header fails, max-age works: RFC1123 compliance
January 6th, 2011 | by Sean |While I was testing the mobile version of the search at spider.my I noticed that my Nokia phone’s browser was briefly presenting an unformatted version of the page, then applying styles, then adding a small image. Doing that once would have been expected, but it shouldn’t have been doing it on subsequent requests of the search page. I serve my CSS files and images with an Expires header field which should prompt user agents to re-use the previously loaded (and cached) CSS and images.
I saw this article about Expires versus the Cache-Control header’s max-age, so I tried max-age and it worked! With max-age, my Nokia phone was no longer requesting the CSS and image it should already have cached. Doubt that Nokia (their phones just work really, really well) would have broken something so basic and a comment in mnot’s article about missing out a leading ‘0’ on the hour part of the Expires date made me check my code again. Here’s what I was sending:
Expires: Mon, 2 May 2011 01:53:37 GMT
Nothing wrong with the hour, but there is an obvious candidate for a leading zero there. After changing the way my webserver formats dates (I had been formatting them to RFC1123/822, which does specify 2-digit hours), so that it sent 2-digit day-of-month, it worked! The new Expires field looks like this:
Expires: Mon, 02 May 2011 02:03:37 GMT
RFC822 says you can specify 1 or 2 digits for the day-of-month part and RFC1123 (specified as the date format for the Expires header in RFC2616) doesn’t alter that. Sending 1-digit day-of-month parts in a RFC1123 date is to specification.
I just lodged a bug report with Nokia – it seems to me that their phones *should* be accepting the RFC1123-compliant Expires date. I wonder how many other user agents will have this issue, as it seems some people believe that the day-of-month part should have two digits – see Dave Bauman’s comment at the foot of this StackOverflow thread.