views:

342

answers:

3

Ok, I'm confused. I'm trying to send back the magic headers from my server that will prevent a client from hitting the server again until a resource is stale.

I understand how ETag or Last-Modified works (Validation) - the client will ALWAYS still hit the server, and the server needs to validate the date or etag against the current value to know whether to bother serving up a new one.

Cache-Control and Expires, however, I don't think I understand. I've set the following:

Cache-Control: max-age=86400, must-revalidate

No matter what I do, my client (my browser, curl, NSURLConnection) always hits the server again on the second request. Is this a client thing? What headers should I send back to get the client to use it's private cache for a certain length of time?

+1  A: 

The server needs to check the If-Modified-Since header and return a 304 not modified header if it wants the browser to keep caching.

Nathan
I understand how ETags work. I want to get the client to avoid checking the server at all. Obviously, validation doesn't help me do that. Maybe I'm completely misunderstanding the other kind though?
Sean Clark Hess
Hmm. I got this working about a year ago, let me look up the details.
Nathan
The relevant line in my PHP code for telling the browser not to come back for 24 hours is: `$this->getResponse()->setHttpHeader("Cache-Control", "max-age=".(60*60*24), true);`
Nathan
Any good way to test it? Even if I do exactly that with Cache-Control, a refresh in the browser still hits my server.
Sean Clark Hess
I remember `lwp-request` (a perl utility) being indispensible. And I wrote lots of debugging headers so I could see what was happening.
Nathan
I also found [this report of a bug in the way Safari handles the must-revalidate directive](http://mrclay.org/index.php/2009/02/24/safari-4-beta-cache-controlmust-revalidate-bug/) -- that might be a complicating factor in iPhoneland.
Nathan
+1  A: 

As Nathan hints at in his answer, clients can issue a subsequent request with an If-Modified-Since header to determine whether or not their cache is stale. If the client receives a 304 Not Modified response, it will serve the content out of the local cache.

According to RFC 2616 (the HTTP 1.1 specification), the presence of must-revalidate within the Cache-control header forces clients to re-check their cache's status with the originating server prior to serving out of the cache.

Rob
1st paragraph - If the client receives 304 Not Modified, will it avoid hitting the server for a while? 2nd - that doesn't really match what I've read. `must-revalidate` means that the client must follow "your rules" whatever that means.
Sean Clark Hess
oh yeah, that's right-- `must-revalidate` is not what you want.
Nathan
+1  A: 

For future reference - Mark Nottingham has written a great guide to HTTP caching:

http://www.mnot.net/cache_docs/#CACHE-CONTROL

Mike