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 */