update: wrote the answer differently and more clearly
I have a solution which works without modifying the current HTTP protocol. I'd love to see an implementation of this.
Instead of telling the server our Etag we ASK the server about its Etag, and we compare it to the one we already have.
Pseudo code:
If (file_not_in_cache)
{
page=http_get_request();
page.display();
page.put_in_cache();
}
else
{
page=load_from_cache();
client_etag=page.extract_etag();
server_etag=http_HEAD_request().extract_etag();
//Instead of saying "my etag is xyz",
//the client says: what is YOUR etag, server?"
if (server_etag==client_etag)
{
page.display();
}
else
{
page.remove_from_cache();
page=http_get_request();
page.display();
page.put_in_cache();
}
}
HTTP conversation example with solution 1:
Client:
HEAD /posts/46328
host: security.stackexchange.com
Server:
HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
ETag: "ABCDE"
Content-Type: text/html
Content-Length: 131
Case 1, Client has an identical etag:
Connection closes, client loads page from cache.
Case 2, client has a mismatching etag:
GET...... //and a normal http conversation begins.
Edit: It is worth noting that there is a minor overhead, the server has to send the HTTP header twice: Once in response to the HEAD, and once in response to the GET. One theoretical workaround for this is modifying the HTTP protocol and adding a new method which requests header-less content. Then the client would request the HEAD only, and then the content only, if the etags mismatch.
Edit 2: I've followed makerofthings7's advice and posted this as a question on stackoverflow.