On Mon, 30 Jul 2007, Niklas Edmundsson wrote:

However, if stuff is really depending on Date/Expires being what it thinks it is (*shiver*) then I guess there won't be any other options...

Here's a version with a config directive, defaults to disabled.

Thoughts?


/Nikke
--
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 Niklas Edmundsson, Admin @ {acc,hpc2n}.umu.se      |     [EMAIL PROTECTED]
---------------------------------------------------------------------------
 No, no, nurse! I said SLIP off his SPECTACLES!!
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
--- ../dist/modules/cache/mod_cache.c   2006-12-08 13:56:00.000000000 +0100
+++ modules/cache/mod_cache.c   2007-07-30 14:17:17.000000000 +0200
@@ -305,7 +305,7 @@
     cache_server_conf *conf;
     const char *cc_out, *cl;
     const char *exps, *lastmods, *dates, *etag;
-    apr_time_t exp, date, lastmod, now;
+    apr_time_t exp, date, lastmod, now, staleexp=APR_DATE_BAD;
     apr_off_t size;
     cache_info *info = NULL;
     char *reason;
@@ -582,6 +582,8 @@
             /* Oh, hey.  It isn't that stale!  Yay! */
             cache->handle = cache->stale_handle;
             info = &cache->handle->cache_obj->info;
+            /* Save stale expiry timestamp for later perusal */
+            staleexp = info->expire;
             rv = OK;
         }
         else {
@@ -736,14 +738,41 @@
         ap_cache_accept_headers(cache->handle, r, 1);
     }
 
-    /* Write away header information to cache. It is possible that we are
-     * trying to update headers for an entity which has already been cached.
-     *
-     * This may fail, due to an unwritable cache area. E.g. filesystem full,
-     * permissions problems or a read-only (re)mount. This must be handled
-     * later.
-     */
-    rv = cache->provider->store_headers(cache->handle, r, info);
+    rv = APR_EGENERAL;
+    if(conf->relaxupdates && cache->stale_handle && 
+            staleexp != APR_DATE_BAD && now < staleexp) 
+    {
+        /* Avoid storing on-disk headers that are never used. When the
+         * following conditions are fulfilled:
+         * - The body is NOT stale (ie. HTTP_NOT_MODIFIED when revalidating)
+         * - The on-disk header hasn't expired.
+         * - The request has max-age=0
+         * Then there is no use to update the on-disk header since it won't be
+         * used by other max-age=0 requests since they are always revalidated,
+         * and we know it's likely there will be more max-age=0 requests since
+         * objects tend to have the same access pattern.
+         */
+        const char *cc_req;
+        char *val;
+
+        cc_req = apr_table_get(r->headers_in, "Cache-Control");
+        if(cc_req && ap_cache_liststr(r->pool, cc_req, "max-age", &val) &&
+                val != NULL && apr_atoi64(val) == 0) 
+        {
+            /* Yay, we can skip storing the on-disk header */
+            rv = APR_SUCCESS;
+        }
+    }
+    if(rv != APR_SUCCESS) {
+        /* Write away header information to cache. It is possible that we are
+         * trying to update headers for an entity which has already been 
cached.
+         *
+         * This may fail, due to an unwritable cache area. E.g. filesystem 
full,
+         * permissions problems or a read-only (re)mount. This must be handled
+         * later.
+         */
+        rv = cache->provider->store_headers(cache->handle, r, info);
+    }
 
     /* Did we just update the cached headers on a revalidated response?
      *
@@ -896,6 +925,8 @@
     /* array of headers that should not be stored in cache */
     ps->ignore_headers = apr_array_make(p, 10, sizeof(char *));
     ps->ignore_headers_set = CACHE_IGNORE_HEADERS_UNSET;
+    ps->relaxupdates = 0;
+    ps->relaxupdates_set = 0;
     return ps;
 }
 
@@ -941,6 +972,10 @@
         (overrides->ignore_headers_set == CACHE_IGNORE_HEADERS_UNSET)
         ? base->ignore_headers
         : overrides->ignore_headers;
+    ps->relaxupdates  =
+        (overrides->relaxupdates_set == 0)
+        ? base->relaxupdates
+        : overrides->relaxupdates;
     return ps;
 }
 static const char *set_cache_ignore_no_last_mod(cmd_parms *parms, void *dummy,
@@ -1119,6 +1154,19 @@
     return NULL;
 }
 
+static const char *set_cache_relaxupdates(cmd_parms *parms, void *dummy,
+                                          int flag)
+{
+    cache_server_conf *conf;
+
+    conf =
+        (cache_server_conf *)ap_get_module_config(parms->server->module_config,
+                                                  &cache_module);
+    conf->relaxupdates = flag;
+    conf->relaxupdates_set = 1;
+    return NULL;
+}
+
 static int cache_post_config(apr_pool_t *p, apr_pool_t *plog,
                              apr_pool_t *ptemp, server_rec *s)
 {
@@ -1171,6 +1219,11 @@
     AP_INIT_TAKE1("CacheLastModifiedFactor", set_cache_factor, NULL, RSRC_CONF,
                   "The factor used to estimate Expires date from "
                   "LastModified date"),
+    AP_INIT_FLAG("CacheRelaxUpdates", set_cache_relaxupdates,
+                 NULL, RSRC_CONF,
+                 "Optimize for non-transparent caches by relaxing the "
+                 "requirement that max-age=0 forces an update of headers "
+                 "stored in cache"),
     {NULL}
 };
 
--- ../dist/modules/cache/mod_cache.h   2006-07-12 05:38:44.000000000 +0200
+++ modules/cache/mod_cache.h   2007-07-30 14:13:22.000000000 +0200
@@ -150,6 +150,9 @@
     #define CACHE_IGNORE_HEADERS_SET   1
     #define CACHE_IGNORE_HEADERS_UNSET 0
     int ignore_headers_set;
+    /* Relax header updates on max-age=0 accesses */
+    int relaxupdates;
+    int relaxupdates_set;
 } cache_server_conf;
 
 /* cache info information */

Reply via email to