summaryrefslogtreecommitdiff
path: root/modules/cache
diff options
context:
space:
mode:
authorStefan Fritsch <sf@sfritsch.de>2011-12-27 19:42:13 +0100
committerStefan Fritsch <sf@sfritsch.de>2011-12-27 19:42:13 +0100
commit1acac7a6b494db24f8f58e44dab7657b6de68742 (patch)
tree9a0dd3753dd6fb8c859ed299ee9794b88173c420 /modules/cache
parent80ba9f34b69a273d82f2f46d7fe231e30e127028 (diff)
downloadapache2-1acac7a6b494db24f8f58e44dab7657b6de68742.tar.gz
Upstream tarball 2.2.6upstream/2.2.6
Diffstat (limited to 'modules/cache')
-rw-r--r--modules/cache/NWGNUdsk_cach19
-rw-r--r--modules/cache/NWGNUmakefile19
-rw-r--r--modules/cache/NWGNUmem_cach19
-rw-r--r--modules/cache/NWGNUmod_cach20
-rw-r--r--modules/cache/cache_cache.c8
-rw-r--r--modules/cache/cache_storage.c64
-rw-r--r--modules/cache/cache_util.c30
-rw-r--r--modules/cache/mod_cache.c138
-rw-r--r--modules/cache/mod_cache.dsp16
-rw-r--r--modules/cache/mod_cache.h6
-rw-r--r--modules/cache/mod_disk_cache.c15
-rw-r--r--modules/cache/mod_disk_cache.dsp16
-rw-r--r--modules/cache/mod_file_cache.dsp20
-rw-r--r--modules/cache/mod_mem_cache.c33
-rw-r--r--modules/cache/mod_mem_cache.dsp16
15 files changed, 314 insertions, 125 deletions
diff --git a/modules/cache/NWGNUdsk_cach b/modules/cache/NWGNUdsk_cach
index 9dc385e7..b91823dd 100644
--- a/modules/cache/NWGNUdsk_cach
+++ b/modules/cache/NWGNUdsk_cach
@@ -65,7 +65,7 @@ XDEFINES += \
$(EOLIST)
XLFLAGS += \
- $(EOLIST)
+ $(EOLIST)
endif
ifeq "$(RELEASE)" "noopt"
@@ -79,7 +79,7 @@ XDEFINES += \
$(EOLIST)
XLFLAGS += \
- $(EOLIST)
+ $(EOLIST)
endif
ifeq "$(RELEASE)" "release"
@@ -101,7 +101,7 @@ endif
# This is used by the link 'name' directive to name the nlm. If left blank
# TARGET_nlm (see below) will be used.
#
-NLM_NAME = dsk_cach
+NLM_NAME = dsk_cach
#
# This is used by the link '-desc ' directive.
@@ -119,7 +119,7 @@ NLM_THREAD_NAME = dsk_cach
# If this is specified, it will override VERSION value in
# $(AP_WORK)\build\NWGNUenvironment.inc
#
-NLM_VERSION =
+NLM_VERSION =
#
# If this is specified, it will override the default of 64K
@@ -145,14 +145,14 @@ NLM_CHECK_SYM =
#
# If this is specified it will be used by the link '-flags' directive
#
-NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION
+NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION
#
# If this is specified it will be linked in with the XDCData option in the def
# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
# by setting APACHE_UNIPROC in the environment
#
-XDCDATA =
+XDCDATA =
#
# Declare all target files (you must add your files here)
@@ -184,7 +184,7 @@ FILES_nlm_objs = \
# These will be added as a library command in the link.opt file.
#
FILES_nlm_libs = \
- libcpre.o \
+ libcpre.o \
$(EOLIST)
#
@@ -228,14 +228,14 @@ FILES_nlm_Ximports = \
FILES_nlm_exports = \
disk_cache_module \
$(EOLIST)
-
+
# @cache.imp \
#
# These are the OBJ files needed to create the LIB target above.
# Paths must all use the '/' character
#
FILES_lib_objs = \
- $(EOLIST)
+ $(EOLIST)
#
# implement targets and dependancies (leave this section alone)
@@ -263,4 +263,3 @@ install :: nlms FORCE
include $(AP_WORK)\build\NWGNUtail.inc
-
diff --git a/modules/cache/NWGNUmakefile b/modules/cache/NWGNUmakefile
index 71d7e1ba..868db548 100644
--- a/modules/cache/NWGNUmakefile
+++ b/modules/cache/NWGNUmakefile
@@ -59,7 +59,7 @@ XDEFINES += \
$(EOLIST)
XLFLAGS += \
- $(EOLIST)
+ $(EOLIST)
endif
ifeq "$(RELEASE)" "noopt"
@@ -73,7 +73,7 @@ XDEFINES += \
$(EOLIST)
XLFLAGS += \
- $(EOLIST)
+ $(EOLIST)
endif
ifeq "$(RELEASE)" "release"
@@ -95,7 +95,7 @@ endif
# This is used by the link 'name' directive to name the nlm. If left blank
# TARGET_nlm (see below) will be used.
#
-NLM_NAME =
+NLM_NAME =
#
# This is used by the link '-desc ' directive.
@@ -113,7 +113,7 @@ NLM_THREAD_NAME =
# If this is specified, it will override VERSION value in
# $(AP_WORK)\build\NWGNUenvironment.inc
#
-NLM_VERSION =
+NLM_VERSION =
#
# If this is specified, it will override the default of 64K
@@ -139,14 +139,14 @@ NLM_CHECK_SYM =
#
# If these are specified it will be used by the link '-flags' directive
#
-NLM_FLAGS =
+NLM_FLAGS =
#
# If this is specified it will be linked in with the XDCData option in the def
# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
# by setting APACHE_UNIPROC in the environment
#
-XDCDATA =
+XDCDATA =
#
# If there is an NLM target, put it here
@@ -156,7 +156,7 @@ TARGET_nlm = \
$(OBJDIR)/mem_cach.nlm \
$(OBJDIR)/dsk_cach.nlm \
$(EOLIST)
-
+
#
# If there is an LIB target, put it here
#
@@ -216,7 +216,7 @@ FILES_nlm_exports = \
# Paths must all use the '/' character
#
FILES_lib_objs = \
- $(EOLIST)
+ $(EOLIST)
#
# implement targets and dependancies (leave this section alone)
@@ -231,7 +231,7 @@ nlms :: libs $(TARGET_nlm)
# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples)
#
install :: nlms FORCE
- copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.*
+ copy $(OBJDIR)\*.nlm $(INSTALL)\$(BASEDIR)\modules\*.*
#
# Any specialized rules here
@@ -244,3 +244,4 @@ install :: nlms FORCE
include $(AP_WORK)\build\NWGNUtail.inc
+
diff --git a/modules/cache/NWGNUmem_cach b/modules/cache/NWGNUmem_cach
index 782d8834..bcf98e7f 100644
--- a/modules/cache/NWGNUmem_cach
+++ b/modules/cache/NWGNUmem_cach
@@ -66,7 +66,7 @@ XDEFINES += \
$(EOLIST)
XLFLAGS += \
- $(EOLIST)
+ $(EOLIST)
endif
ifeq "$(RELEASE)" "noopt"
@@ -80,7 +80,7 @@ XDEFINES += \
$(EOLIST)
XLFLAGS += \
- $(EOLIST)
+ $(EOLIST)
endif
ifeq "$(RELEASE)" "release"
@@ -102,7 +102,7 @@ endif
# This is used by the link 'name' directive to name the nlm. If left blank
# TARGET_nlm (see below) will be used.
#
-NLM_NAME = mem_cach
+NLM_NAME = mem_cach
#
# This is used by the link '-desc ' directive.
@@ -120,7 +120,7 @@ NLM_THREAD_NAME = mem_cach
# If this is specified, it will override VERSION value in
# $(AP_WORK)\build\NWGNUenvironment.inc
#
-NLM_VERSION =
+NLM_VERSION =
#
# If this is specified, it will override the default of 64K
@@ -146,14 +146,14 @@ NLM_CHECK_SYM =
#
# If this is specified it will be used by the link '-flags' directive
#
-NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION
+NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION
#
# If this is specified it will be linked in with the XDCData option in the def
# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
# by setting APACHE_UNIPROC in the environment
#
-XDCDATA =
+XDCDATA =
#
# Declare all target files (you must add your files here)
@@ -188,7 +188,7 @@ FILES_nlm_objs = \
# These will be added as a library command in the link.opt file.
#
FILES_nlm_libs = \
- libcpre.o \
+ libcpre.o \
$(EOLIST)
#
@@ -232,14 +232,14 @@ FILES_nlm_Ximports = \
FILES_nlm_exports = \
mem_cache_module \
$(EOLIST)
-
+
# @cache.imp \
#
# These are the OBJ files needed to create the LIB target above.
# Paths must all use the '/' character
#
FILES_lib_objs = \
- $(EOLIST)
+ $(EOLIST)
#
# implement targets and dependancies (leave this section alone)
@@ -267,4 +267,3 @@ install :: nlms FORCE
include $(AP_WORK)\build\NWGNUtail.inc
-
diff --git a/modules/cache/NWGNUmod_cach b/modules/cache/NWGNUmod_cach
index 125c4567..ff0a9667 100644
--- a/modules/cache/NWGNUmod_cach
+++ b/modules/cache/NWGNUmod_cach
@@ -66,7 +66,7 @@ XDEFINES += \
$(EOLIST)
XLFLAGS += \
- $(EOLIST)
+ $(EOLIST)
endif
ifeq "$(RELEASE)" "noopt"
@@ -80,7 +80,7 @@ XDEFINES += \
$(EOLIST)
XLFLAGS += \
- $(EOLIST)
+ $(EOLIST)
endif
ifeq "$(RELEASE)" "release"
@@ -102,7 +102,7 @@ endif
# This is used by the link 'name' directive to name the nlm. If left blank
# TARGET_nlm (see below) will be used.
#
-NLM_NAME = mod_cach
+NLM_NAME = mod_cach
#
# This is used by the link '-desc ' directive.
@@ -120,7 +120,7 @@ NLM_THREAD_NAME = mod_cach
# If this is specified, it will override VERSION value in
# $(AP_WORK)\build\NWGNUenvironment.inc
#
-NLM_VERSION =
+NLM_VERSION =
#
# If this is specified, it will override the default of 64K
@@ -146,14 +146,14 @@ NLM_CHECK_SYM =
#
# If this is specified it will be used by the link '-flags' directive
#
-NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION
+NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION
#
# If this is specified it will be linked in with the XDCData option in the def
# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
# by setting APACHE_UNIPROC in the environment
#
-XDCDATA =
+XDCDATA =
#
# Declare all target files (you must add your files here)
@@ -182,13 +182,12 @@ FILES_nlm_objs = \
$(OBJDIR)/mod_cache.o \
$(EOLIST)
-# $(OBJDIR)/mod_mem_cache.o \
#
# These are the LIB files needed to create the NLM target above.
# These will be added as a library command in the link.opt file.
#
FILES_nlm_libs = \
- libcpre.o \
+ libcpre.o \
$(EOLIST)
#
@@ -232,13 +231,13 @@ FILES_nlm_exports = \
@mod_cache.imp \
cache_module \
$(EOLIST)
-
+
#
# These are the OBJ files needed to create the LIB target above.
# Paths must all use the '/' character
#
FILES_lib_objs = \
- $(EOLIST)
+ $(EOLIST)
#
# implement targets and dependancies (leave this section alone)
@@ -266,4 +265,3 @@ install :: nlms FORCE
include $(AP_WORK)\build\NWGNUtail.inc
-
diff --git a/modules/cache/cache_cache.c b/modules/cache/cache_cache.c
index 6db98f71..860800bb 100644
--- a/modules/cache/cache_cache.c
+++ b/modules/cache/cache_cache.c
@@ -85,13 +85,7 @@ CACHE_DECLARE(void) cache_free(cache_cache_t *c)
CACHE_DECLARE(void*) cache_find(cache_cache_t* c, const char *key)
{
- void *e;
-
- e = cache_hash_get(c->ht, key, CACHE_HASH_KEY_STRING);
- if (!e)
- return NULL;
-
- return e;
+ return cache_hash_get(c->ht, key, CACHE_HASH_KEY_STRING);
}
CACHE_DECLARE(void) cache_update(cache_cache_t* c, void *entry)
diff --git a/modules/cache/cache_storage.c b/modules/cache/cache_storage.c
index 83352059..0ddf82dd 100644
--- a/modules/cache/cache_storage.c
+++ b/modules/cache/cache_storage.c
@@ -304,6 +304,20 @@ int cache_select(request_rec *r)
}
cache->stale_handle = h;
}
+ else {
+ int irv;
+
+ /*
+ * The copy isn't fresh enough, but we cannot revalidate.
+ * So it is the same case as if there had not been a cached
+ * entry at all. Thus delete the entry from cache.
+ */
+ irv = cache->provider->remove_url(h, r->pool);
+ if (irv != OK) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, irv, r->server,
+ "cache: attempt to remove url from cache unsuccessful.");
+ }
+ }
return DECLINED;
}
@@ -331,10 +345,38 @@ int cache_select(request_rec *r)
apr_status_t cache_generate_key_default(request_rec *r, apr_pool_t* p,
char**key)
{
+ cache_server_conf *conf;
+ cache_request_rec *cache;
char *port_str, *hn, *lcs;
const char *hostname, *scheme;
int i;
+ cache = (cache_request_rec *) ap_get_module_config(r->request_config,
+ &cache_module);
+ if (!cache) {
+ /* This should never happen */
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+ "cache: No cache request information available for key"
+ " generation");
+ *key = "";
+ return APR_EGENERAL;
+ }
+ if (cache->key) {
+ /*
+ * We have been here before during the processing of this request.
+ * So return the key we already have.
+ */
+ *key = apr_pstrdup(p, cache->key);
+ return APR_SUCCESS;
+ }
+
+ /*
+ * Get the module configuration. We need this for the CacheIgnoreQueryString
+ * option below.
+ */
+ conf = (cache_server_conf *) ap_get_module_config(r->server->module_config,
+ &cache_module);
+
/*
* Use the canonical name to improve cache hit rate, but only if this is
* not a proxy request or if this is a reverse proxy request.
@@ -425,9 +467,25 @@ apr_status_t cache_generate_key_default(request_rec *r, apr_pool_t* p,
port_str = apr_psprintf(p, ":%u", ap_get_server_port(r));
}
- /* Key format is a URI */
- *key = apr_pstrcat(p, scheme, "://", hostname, port_str,
- r->parsed_uri.path, "?", r->args, NULL);
+ /* Key format is a URI, optionally without the query-string */
+ if (conf->ignorequerystring) {
+ *key = apr_pstrcat(p, scheme, "://", hostname, port_str,
+ r->parsed_uri.path, "?", NULL);
+ }
+ else {
+ *key = apr_pstrcat(p, scheme, "://", hostname, port_str,
+ r->parsed_uri.path, "?", r->parsed_uri.query, NULL);
+ }
+
+ /*
+ * Store the key in the request_config for the cache as r->parsed_uri
+ * might have changed in the time from our first visit here triggered by the
+ * quick handler and our possible second visit triggered by the CACHE_SAVE
+ * filter (e.g. r->parsed_uri got unescaped). In this case we would save the
+ * resource in the cache under a key where it is never found by the quick
+ * handler during following requests.
+ */
+ cache->key = apr_pstrdup(r->pool, *key);
return APR_SUCCESS;
}
diff --git a/modules/cache/cache_util.c b/modules/cache/cache_util.c
index d7dd14a8..75d35bd6 100644
--- a/modules/cache/cache_util.c
+++ b/modules/cache/cache_util.c
@@ -243,7 +243,8 @@ CACHE_DECLARE(int) ap_cache_check_freshness(cache_handle_t *h,
age = ap_cache_current_age(info, age_c, r->request_time);
/* extract s-maxage */
- if (cc_cresp && ap_cache_liststr(r->pool, cc_cresp, "s-maxage", &val)) {
+ if (cc_cresp && ap_cache_liststr(r->pool, cc_cresp, "s-maxage", &val)
+ && val != NULL) {
smaxage = apr_atoi64(val);
}
else {
@@ -252,7 +253,8 @@ CACHE_DECLARE(int) ap_cache_check_freshness(cache_handle_t *h,
/* extract max-age from request */
if (!conf->ignorecachecontrol
- && cc_req && ap_cache_liststr(r->pool, cc_req, "max-age", &val)) {
+ && cc_req && ap_cache_liststr(r->pool, cc_req, "max-age", &val)
+ && val != NULL) {
maxage_req = apr_atoi64(val);
}
else {
@@ -260,7 +262,8 @@ CACHE_DECLARE(int) ap_cache_check_freshness(cache_handle_t *h,
}
/* extract max-age from response */
- if (cc_cresp && ap_cache_liststr(r->pool, cc_cresp, "max-age", &val)) {
+ if (cc_cresp && ap_cache_liststr(r->pool, cc_cresp, "max-age", &val)
+ && val != NULL) {
maxage_cresp = apr_atoi64(val);
}
else {
@@ -282,7 +285,20 @@ CACHE_DECLARE(int) ap_cache_check_freshness(cache_handle_t *h,
/* extract max-stale */
if (cc_req && ap_cache_liststr(r->pool, cc_req, "max-stale", &val)) {
- maxstale = apr_atoi64(val);
+ if(val != NULL) {
+ maxstale = apr_atoi64(val);
+ }
+ else {
+ /*
+ * If no value is assigned to max-stale, then the client is willing
+ * to accept a stale response of any age (RFC2616 14.9.3). We will
+ * set it to one year in this case as this situation is somewhat
+ * similar to a "never expires" Expires header (RFC2616 14.21)
+ * which is set to a date one year from the time the response is
+ * sent in this case.
+ */
+ maxstale = APR_INT64_C(86400*365);
+ }
}
else {
maxstale = 0;
@@ -290,7 +306,8 @@ CACHE_DECLARE(int) ap_cache_check_freshness(cache_handle_t *h,
/* extract min-fresh */
if (!conf->ignorecachecontrol
- && cc_req && ap_cache_liststr(r->pool, cc_req, "min-fresh", &val)) {
+ && cc_req && ap_cache_liststr(r->pool, cc_req, "min-fresh", &val)
+ && val != NULL) {
minfresh = apr_atoi64(val);
}
else {
@@ -419,6 +436,9 @@ CACHE_DECLARE(int) ap_cache_liststr(apr_pool_t *p, const char *list,
next - val_start);
}
}
+ else {
+ *val = NULL;
+ }
}
return 1;
}
diff --git a/modules/cache/mod_cache.c b/modules/cache/mod_cache.c
index 707aaf77..51341179 100644
--- a/modules/cache/mod_cache.c
+++ b/modules/cache/mod_cache.c
@@ -56,6 +56,8 @@ static int cache_url_handler(request_rec *r, int lookup)
cache_request_rec *cache;
cache_server_conf *conf;
apr_bucket_brigade *out;
+ ap_filter_t *next;
+ ap_filter_rec_t *cache_out_handle;
/* Delay initialization until we know we are handling a GET */
if (r->method_number != M_GET) {
@@ -213,12 +215,29 @@ static int cache_url_handler(request_rec *r, int lookup)
* or not.
*/
if (r->main) {
- ap_add_output_filter_handle(cache_out_subreq_filter_handle, NULL,
- r, r->connection);
+ cache_out_handle = cache_out_subreq_filter_handle;
}
else {
- ap_add_output_filter_handle(cache_out_filter_handle, NULL,
- r, r->connection);
+ cache_out_handle = cache_out_filter_handle;
+ }
+ ap_add_output_filter_handle(cache_out_handle, NULL, r, r->connection);
+
+ /*
+ * Remove all filters that are before the cache_out filter. This ensures
+ * that we kick off the filter stack with our cache_out filter being the
+ * first in the chain. This make sense because we want to restore things
+ * in the same manner as we saved them.
+ * There may be filters before our cache_out filter, because
+ *
+ * 1. We call ap_set_content_type during cache_select. This causes
+ * Content-Type specific filters to be added.
+ * 2. We call the insert_filter hook. This causes filters e.g. like
+ * the ones set with SetOutputFilter to be added.
+ */
+ next = r->output_filters;
+ while (next && (next->frec != cache_out_handle)) {
+ ap_remove_output_filter(next);
+ next = next->next;
}
/* kick off the filter stack */
@@ -299,7 +318,6 @@ static int cache_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
static int cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
{
int rv = !OK;
- int date_in_errhdr = 0;
request_rec *r = f->r;
cache_request_rec *cache;
cache_server_conf *conf;
@@ -433,11 +451,12 @@ static int cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
/* if a Expires header is in the past, don't cache it */
reason = "Expires header already expired, not cacheable";
}
- else if (r->args && exps == NULL) {
- /* if query string present but no expiration time, don't cache it
- * (RFC 2616/13.9)
+ else if (!conf->ignorequerystring && r->parsed_uri.query && exps == NULL &&
+ !ap_cache_liststr(NULL, cc_out, "max-age", NULL)) {
+ /* if a query string is present but no explicit expiration time,
+ * don't cache it (RFC 2616/13.9 & 13.2.1)
*/
- reason = "Query string present but no expires header";
+ reason = "Query string present but no explicit expiration time";
}
else if (r->status == HTTP_NOT_MODIFIED &&
!cache->handle && !cache->stale_handle) {
@@ -456,8 +475,8 @@ static int cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
*/
reason = "No Last-Modified, Etag, or Expires headers";
}
- else if (r->header_only) {
- /* HEAD requests */
+ else if (r->header_only && !cache->stale_handle) {
+ /* Forbid HEAD requests unless we have it cached already */
reason = "HTTP HEAD request";
}
else if (!conf->store_nostore &&
@@ -576,7 +595,12 @@ static int cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
* the headers).
*/
- /* Did we have a stale cache entry that really is stale? */
+ /* Did we have a stale cache entry that really is stale?
+ *
+ * Note that for HEAD requests, we won't get the body, so for a stale
+ * HEAD request, we don't remove the entity - instead we let the
+ * CACHE_REMOVE_URL filter remove the stale item from the cache.
+ */
if (cache->stale_handle) {
if (r->status == HTTP_NOT_MODIFIED) {
/* Oh, hey. It isn't that stale! Yay! */
@@ -584,7 +608,7 @@ static int cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
info = &cache->handle->cache_obj->info;
rv = OK;
}
- else {
+ else if (!r->header_only) {
/* Oh, well. Toss it. */
cache->provider->remove_entity(cache->stale_handle);
/* Treat the request as if it wasn't conditional. */
@@ -592,8 +616,8 @@ static int cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
}
}
- /* no cache handle, create a new entity */
- if (!cache->handle) {
+ /* no cache handle, create a new entity only for non-HEAD requests */
+ if (!cache->handle && !r->header_only) {
rv = cache_create_entity(r, size);
info = apr_pcalloc(r->pool, sizeof(cache_info));
/* We only set info->status upon the initial creation. */
@@ -628,10 +652,7 @@ static int cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
/* Read the date. Generate one if one is not supplied */
dates = apr_table_get(r->err_headers_out, "Date");
- if (dates != NULL) {
- date_in_errhdr = 1;
- }
- else {
+ if (dates == NULL) {
dates = apr_table_get(r->headers_out, "Date");
}
if (dates != NULL) {
@@ -643,25 +664,10 @@ static int cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
now = apr_time_now();
if (info->date == APR_DATE_BAD) { /* No, or bad date */
- char *dates;
/* no date header (or bad header)! */
- /* add one; N.B. use the time _now_ rather than when we were checking
- * the cache
- */
- if (date_in_errhdr == 1) {
- apr_table_unset(r->err_headers_out, "Date");
- }
- date = now;
- dates = apr_pcalloc(r->pool, MAX_STRING_LEN);
- apr_rfc822_date(dates, now);
- apr_table_set(r->headers_out, "Date", dates);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
- "cache: Added date header");
- info->date = date;
- }
- else {
- date = info->date;
+ info->date = now;
}
+ date = info->date;
/* set response_time for HTTP/1.1 age calculations */
info->response_time = now;
@@ -681,32 +687,47 @@ static int cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
}
/* if no expiry date then
- * if lastmod
+ * if Cache-Control: max-age present
+ * expiry date = date + max-age
+ * else if lastmod
* expiry date = date + min((date - lastmod) * factor, maxexpire)
* else
* expire date = date + defaultexpire
*/
if (exp == APR_DATE_BAD) {
- char expire_hdr[APR_RFC822_DATE_LEN];
+ char *max_age_val;
- /* if lastmod == date then you get 0*conf->factor which results in
- * an expiration time of now. This causes some problems with
- * freshness calculations, so we choose the else path...
- */
- if ((lastmod != APR_DATE_BAD) && (lastmod < date)) {
+ if (ap_cache_liststr(r->pool, cc_out, "max-age", &max_age_val) &&
+ max_age_val != NULL) {
+ apr_int64_t x;
+
+ errno = 0;
+ x = apr_atoi64(max_age_val);
+ if (errno) {
+ x = conf->defex;
+ }
+ else {
+ x = x * MSEC_ONE_SEC;
+ }
+ if (x > conf->maxex) {
+ x = conf->maxex;
+ }
+ exp = date + x;
+ }
+ else if ((lastmod != APR_DATE_BAD) && (lastmod < date)) {
+ /* if lastmod == date then you get 0*conf->factor which results in
+ * an expiration time of now. This causes some problems with
+ * freshness calculations, so we choose the else path...
+ */
apr_time_t x = (apr_time_t) ((date - lastmod) * conf->factor);
if (x > conf->maxex) {
x = conf->maxex;
}
exp = date + x;
- apr_rfc822_date(expire_hdr, exp);
- apr_table_set(r->headers_out, "Expires", expire_hdr);
}
else {
exp = date + conf->defex;
- apr_rfc822_date(expire_hdr, exp);
- apr_table_set(r->headers_out, "Expires", expire_hdr);
}
}
info->expire = exp;
@@ -896,6 +917,9 @@ static void * create_cache_config(apr_pool_t *p, server_rec *s)
/* 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;
+ /* flag indicating that query-string should be ignored when caching */
+ ps->ignorequerystring = 0;
+ ps->ignorequerystring_set = 0;
return ps;
}
@@ -941,6 +965,10 @@ static void * merge_cache_config(apr_pool_t *p, void *basev, void *overridesv)
(overrides->ignore_headers_set == CACHE_IGNORE_HEADERS_UNSET)
? base->ignore_headers
: overrides->ignore_headers;
+ ps->ignorequerystring =
+ (overrides->ignorequerystring_set == 0)
+ ? base->ignorequerystring
+ : overrides->ignorequerystring;
return ps;
}
static const char *set_cache_ignore_no_last_mod(cmd_parms *parms, void *dummy,
@@ -1119,6 +1147,19 @@ static const char *set_cache_factor(cmd_parms *parms, void *dummy,
return NULL;
}
+static const char *set_cache_ignore_querystring(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->ignorequerystring = flag;
+ conf->ignorequerystring_set = 1;
+ return NULL;
+}
+
static int cache_post_config(apr_pool_t *p, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec *s)
{
@@ -1168,6 +1209,9 @@ static const command_rec cache_cmds[] =
AP_INIT_ITERATE("CacheIgnoreHeaders", add_ignore_header, NULL, RSRC_CONF,
"A space separated list of headers that should not be "
"stored by the cache"),
+ AP_INIT_FLAG("CacheIgnoreQueryString", set_cache_ignore_querystring,
+ NULL, RSRC_CONF,
+ "Ignore query-string when caching"),
AP_INIT_TAKE1("CacheLastModifiedFactor", set_cache_factor, NULL, RSRC_CONF,
"The factor used to estimate Expires date from "
"LastModified date"),
diff --git a/modules/cache/mod_cache.dsp b/modules/cache/mod_cache.dsp
index 4059498b..ba1653bf 100644
--- a/modules/cache/mod_cache.dsp
+++ b/modules/cache/mod_cache.dsp
@@ -53,7 +53,13 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll
-# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Release/mod_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cache.so /opt:ref
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cache.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_cache.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
!ELSEIF "$(CFG)" == "mod_cache - Win32 Debug"
@@ -79,7 +85,13 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug
-# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Debug/mod_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cache.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cache.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_cache.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
!ENDIF
diff --git a/modules/cache/mod_cache.h b/modules/cache/mod_cache.h
index eb5c8ced..4fe8dfc4 100644
--- a/modules/cache/mod_cache.h
+++ b/modules/cache/mod_cache.h
@@ -150,6 +150,9 @@ typedef struct {
#define CACHE_IGNORE_HEADERS_SET 1
#define CACHE_IGNORE_HEADERS_UNSET 0
int ignore_headers_set;
+ /** ignore query-string when caching */
+ int ignorequerystring;
+ int ignorequerystring_set;
} cache_server_conf;
/* cache info information */
@@ -231,6 +234,9 @@ typedef struct {
apr_time_t lastmod; /* last-modified time */
cache_info *info; /* current cache info */
ap_filter_t *remove_url_filter; /* Enable us to remove the filter */
+ char *key; /* The cache key created for this
+ * request
+ */
} cache_request_rec;
diff --git a/modules/cache/mod_disk_cache.c b/modules/cache/mod_disk_cache.c
index 92c5ad75..6b3e7733 100644
--- a/modules/cache/mod_disk_cache.c
+++ b/modules/cache/mod_disk_cache.c
@@ -403,10 +403,6 @@ static int open_entity(cache_handle_t *h, request_rec *r, const char *key)
len = sizeof(expire);
apr_file_read_full(dobj->hfd, &expire, len, &len);
- if (expire < r->request_time) {
- return DECLINED;
- }
-
varray = apr_array_make(r->pool, 5, sizeof(char*));
rc = read_array(r, varray, dobj->hfd);
if (rc != APR_SUCCESS) {
@@ -823,6 +819,15 @@ static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info
apr_array_header_t* varray;
apr_uint32_t format = VARY_FORMAT_VERSION;
+ /* If we were initially opened as a vary format, rollback
+ * that internal state for the moment so we can recreate the
+ * vary format hints in the appropriate directory.
+ */
+ if (dobj->prefix) {
+ dobj->hdrsfile = dobj->prefix;
+ dobj->prefix = NULL;
+ }
+
mkdir_structure(conf, dobj->hdrsfile, r->pool);
rv = apr_file_mktemp(&dobj->tfd, dobj->tempfile,
@@ -875,8 +880,6 @@ static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info
return rv;
}
- dobj->name = h->cache_obj->key;
-
disk_info.format = DISK_FORMAT_VERSION;
disk_info.date = info->date;
disk_info.expire = info->expire;
diff --git a/modules/cache/mod_disk_cache.dsp b/modules/cache/mod_disk_cache.dsp
index bb6af078..91799b85 100644
--- a/modules/cache/mod_disk_cache.dsp
+++ b/modules/cache/mod_disk_cache.dsp
@@ -53,7 +53,13 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll
-# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Release/mod_disk_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_disk_cache.so /opt:ref
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_disk_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_disk_cache.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_disk_cache.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
!ELSEIF "$(CFG)" == "mod_disk_cache - Win32 Debug"
@@ -79,7 +85,13 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug
-# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Debug/mod_disk_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_disk_cache.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_disk_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_disk_cache.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_disk_cache.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
!ENDIF
diff --git a/modules/cache/mod_file_cache.dsp b/modules/cache/mod_file_cache.dsp
index 984dff1e..3c6afa41 100644
--- a/modules/cache/mod_file_cache.dsp
+++ b/modules/cache/mod_file_cache.dsp
@@ -52,8 +52,14 @@ BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
-# ADD BASE LINK32 /nologo /subsystem:windows /dll /out:"Release/mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so
-# ADD LINK32 /nologo /subsystem:windows /dll /incremental:no /debug /out:"Release/mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so /opt:ref
+# ADD BASE LINK32 /nologo /subsystem:windows /dll /out:".\Release\mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so
+# ADD LINK32 /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_file_cache.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
!ELSEIF "$(CFG)" == "mod_file_cache - Win32 Debug"
@@ -78,8 +84,14 @@ BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
-# ADD BASE LINK32 /nologo /subsystem:windows /dll /incremental:no /debug /out:"Debug/mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so
-# ADD LINK32 /nologo /subsystem:windows /dll /incremental:no /debug /out:"Debug/mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so
+# ADD BASE LINK32 /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so
+# ADD LINK32 /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_file_cache.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
!ENDIF
diff --git a/modules/cache/mod_mem_cache.c b/modules/cache/mod_mem_cache.c
index ea9c45d3..65f35327 100644
--- a/modules/cache/mod_mem_cache.c
+++ b/modules/cache/mod_mem_cache.c
@@ -92,7 +92,7 @@ typedef struct {
static mem_cache_conf *sconf;
#define DEFAULT_MAX_CACHE_SIZE 100*1024
-#define DEFAULT_MIN_CACHE_OBJECT_SIZE 0
+#define DEFAULT_MIN_CACHE_OBJECT_SIZE 1
#define DEFAULT_MAX_CACHE_OBJECT_SIZE 10000
#define DEFAULT_MAX_OBJECT_CNT 1009
#define DEFAULT_MAX_STREAMING_BUFFER_SIZE 100000
@@ -539,12 +539,28 @@ static int remove_url(cache_handle_t *h, apr_pool_t *p)
return OK;
}
+static apr_table_t *deep_table_copy(apr_pool_t *p, const apr_table_t *table)
+{
+ const apr_array_header_t *array = apr_table_elts(table);
+ apr_table_entry_t *elts = (apr_table_entry_t *) array->elts;
+ apr_table_t *copy = apr_table_make(p, array->nelts);
+ int i;
+
+ for (i = 0; i < array->nelts; i++) {
+ if (elts[i].key) {
+ apr_table_add(copy, elts[i].key, elts[i].val);
+ }
+ }
+
+ return copy;
+}
+
static apr_status_t recall_headers(cache_handle_t *h, request_rec *r)
{
mem_cache_object_t *mobj = (mem_cache_object_t*) h->cache_obj->vobj;
- h->req_hdrs = apr_table_copy(r->pool, mobj->req_hdrs);
- h->resp_hdrs = apr_table_copy(r->pool, mobj->header_out);
+ h->req_hdrs = deep_table_copy(r->pool, mobj->req_hdrs);
+ h->resp_hdrs = deep_table_copy(r->pool, mobj->header_out);
return OK;
}
@@ -585,7 +601,7 @@ static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info
* - The original response headers (for returning with a cached response)
* - The body of the message
*/
- mobj->req_hdrs = apr_table_copy(mobj->pool, r->headers_in);
+ mobj->req_hdrs = deep_table_copy(mobj->pool, r->headers_in);
/* Precompute how much storage we need to hold the headers */
headers_out = ap_cache_cacheable_hdrs_out(r->pool, r->headers_out,
@@ -599,7 +615,7 @@ static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info
}
headers_out = apr_table_overlay(r->pool, headers_out, r->err_headers_out);
- mobj->header_out = apr_table_copy(mobj->pool, headers_out);
+ mobj->header_out = deep_table_copy(mobj->pool, headers_out);
/* Init the info struct */
obj->info.status = info->status;
@@ -863,9 +879,12 @@ static const char
apr_size_t val;
if (sscanf(arg, "%" APR_SIZE_T_FMT, &val) != 1) {
- return "MCacheMinObjectSize value must be an integer (bytes)";
+ return "MCacheMinObjectSize value must be an positive integer (bytes)";
}
- sconf->min_cache_object_size = val;
+ if (val > 0)
+ sconf->min_cache_object_size = val;
+ else
+ return "MCacheMinObjectSize value must be an positive integer (bytes)";
return NULL;
}
static const char
diff --git a/modules/cache/mod_mem_cache.dsp b/modules/cache/mod_mem_cache.dsp
index 90141d9c..003e4efc 100644
--- a/modules/cache/mod_mem_cache.dsp
+++ b/modules/cache/mod_mem_cache.dsp
@@ -53,7 +53,13 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll
-# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Release/mod_mem_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mem_cache.so /opt:ref
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_mem_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mem_cache.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_mem_cache.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
!ELSEIF "$(CFG)" == "mod_mem_cache - Win32 Debug"
@@ -79,7 +85,13 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug
-# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Debug/mod_mem_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mem_cache.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_mem_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mem_cache.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_mem_cache.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
!ENDIF