httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Lichteblau <>
Subject mod_cache and Etag headers
Date Mon, 07 Feb 2005 17:45:06 GMT

we are trying to use mod_proxy/mod_cache as a `reverse proxy' in front
of our webserver.  In our configuration, we would like Apache to cache
all responses from our server, but revalidate them for every new
request.  To do that, we are sending Etag headers and force revalidation
using "Cache-Control: max-age=0,must-revalidate".

This mostly works, but does not perform caching the way we would like it
to, because the Etag headers are not sent to our server when mod_cache
tries to revalidate it cache file.

We would like the following to happen:

  - When a client connects for the first time, Apache asks our server
    (code 200), caches the response (including the Etag header) and sends it
    to the server (code 200), caching the Etag header received.
    (This works!)

  - When a client (which keeps its own cache) connects for the second
    time, Apache finds the cached response, revalidates with our
    server, receives code 304 and sends it back to the client.

    (This happens to work, because the client itself sends along
    "If-None-Match: <our-etag>" in this case.)

  - When a different client (which does not have our Etag in its cache)
    connects, Apache should find the cached response for the URL, revalidate
    with our server, receive code 304 from our server and send
    the cached response to the client (code 200).

The last situation is what does not work -- our server does not receive
an If-None-Match header from Apache in this case.

  0. Is this supposed to work at all?

  1. Looking briefly at the mod_cache source code, there appear to be
     cases dealing with this.  In cache_select_url(), info->etag is
     looked at to decide whether "If-None-Match" should be inserted into
     the request.

     However, info->etag is null at this point.

     If I hack this check so that the etag header is looked up from the
     cached response (see patch below), things work better and our
     server replies with 304.


  2. Apache then sends the 304 response along to the client, although the
     client did not send a conditional request at all and needs the full
     cached response.

     There is a check in cache_save_filter() ("Were we initially a
     conditional request?"), but that check is not reached in this

Thanks for any help,

--- httpd-2.1.2-alpha-orig/modules/cache/cache_storage.c	2004-11-27 20:06:48.000000000 +0100
+++ httpd-2.1.2-alpha/modules/cache/cache_storage.c	2005-02-07 18:14:09.000000000 +0100
@@ -255,6 +255,8 @@
                 /* Make response into a conditional */
                 /* FIXME: What if the request is already conditional? */
+                if (info)
+                    info->etag = apr_table_get(h->resp_hdrs, "etag");
                 if (info && info->etag) {
                     /* if we have a cached etag */
                     cache->stale_headers = apr_table_copy(r->pool,

View raw message