views:

3526

answers:

2

I've looked around but haven't been able to figure out if I should use both an ETag and a Expires Header or one or the other.

What I"m trying to do is make sure that my flash files (and other images and what not only get updated when there is a change to those files.

I don't want to do anything special like changing the filename or putting some weird chars on the end of the url to make it not get cached.

Also, is there anything I need to do programatically on my end in my php scripts to support this or is it all apache?

G-Man

+5  A: 

By default, Apache will generate an Etag based on the file's inode number, last-modified date, and size, which should be perfectly fine to do what you want. I think it also will generate by default a Last-Modified header based on the last modification time of the file on disk, which is also perfectly fine to do what you want.

You should probably also have Apache send an Expires header dated one year in the future (according to http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21) so that browsers know the content is cacheable. Have a look at mod_expires to configure that.

David Zaslavsky
So the ETag will have the last modified and the expires header will tell it I want it to cache it and when I upload and overwrite my file it will just get pulled down to the user's cache again otherwise a 304 would be generated right?
GeoffreyF67
The Etag depends in a complicated way on the last-modified date; but when you modify the file, the Etag will change. Then the Etag sent by the browser (for its cached version of the file) won't match the Etag of the file on the server, and Apache will send the file rather than a 304 response.
David Zaslavsky
+30  A: 

They are slightly different - the ETag does not have any information that the client can use to determine whether or not to make a request for that file again in the future. If ETag is all it has, it will always have to make a request. However, when the server reads the ETag from the client request, it can then determine whether to send the file (HTTP 200) or tell the client to just use their local copy (HTTP 304). An ETag is basically just a checksum for a file that semantically changes when the content of the file changes.

The Expires header is used by the client (and proxies/caches) to determine whether or not it even needs to make a request to the server at all. The closer you are to the Expires date, the more likely it is the client (or proxy) will make an HTTP request for that file from the server.

So really what you want to do is use BOTH headers - set the Expires header to a reasonable value based on how often the content changes. Then configure ETags to be sent so that when clients DO send a request to the server, it can more easily determine whether or not to send the file back.

One last note about ETag - if you are using a load-balanced server setup with multiple machines running Apache you will probably want to turn off ETag generation. This is because inodes are used as part of the ETag hash algorithm which will be different between the servers. You can configure Apache to not use inodes as part of the calculation but then you'd want to make sure the timestamps on the files are exactly the same, to ensure the same ETag gets generated for all servers.

Marc Novakowski
This answer just made my day. We've been wrestling with the etag question because neither the devs nor the IT manager (who was demanding etags be added) could fully explain the use-cases. Thanks!
Mr. Shiny and New
My work here is done. :)
Marc Novakowski