HTTP_ConditionalGet

Last-Modified is unknown : use hash of content for ETag

When Last-Modified is unknown, you can still use ETags, but you need a short string that is unique for that content. In the worst case, you have to generate all the content first, then instantiate HTTP_ConditionalGet, setting the array key contentHash to the output of a hash function of the content. Since we have the full content, we might as well also use setContentLength(strlen($content)) in the case where we need to send it.

This script emulates a document that changes every 20 seconds.
This is version: Mon, 23 Dec 2024 11:57:40 -0500

Notes

How to distinguish 200 and 304 responses

For these pages all 200 responses are sent in chunks a second apart, so you should notice that 304 responses are quicker. You can also use HTTP sniffers like Fiddler (win) and LiveHTTPHeaders (Firefox add-on) to verify headers and content being sent.

Browser notes

Opera
Opera has a couple behaviors against the HTTP spec: Manual refreshes (F5) prevents the ETag/If-Modified-Since headers from being sent; it only sends them when following a link or bookmark. Also, Opera will not honor the must-revalidate Cache-Control value unless max-age is set. To get Opera to follow the spec, ConditionalGet will send Opera max-age=0 (if one is not already set).
Safari
ETag validation is unsupported, but Safari supports HTTP/1.0 validation via If-Modified-Since headers as long as the cache is explicitly marked "public" or "private" ("private" is default in ConditionalGet).