diff options
author | Stefan Fritsch <sf@sfritsch.de> | 2011-12-27 19:42:13 +0100 |
---|---|---|
committer | Stefan Fritsch <sf@sfritsch.de> | 2011-12-27 19:42:13 +0100 |
commit | 1acac7a6b494db24f8f58e44dab7657b6de68742 (patch) | |
tree | 9a0dd3753dd6fb8c859ed299ee9794b88173c420 /modules/cache | |
parent | 80ba9f34b69a273d82f2f46d7fe231e30e127028 (diff) | |
download | apache2-1acac7a6b494db24f8f58e44dab7657b6de68742.tar.gz |
Upstream tarball 2.2.6upstream/2.2.6
Diffstat (limited to 'modules/cache')
-rw-r--r-- | modules/cache/NWGNUdsk_cach | 19 | ||||
-rw-r--r-- | modules/cache/NWGNUmakefile | 19 | ||||
-rw-r--r-- | modules/cache/NWGNUmem_cach | 19 | ||||
-rw-r--r-- | modules/cache/NWGNUmod_cach | 20 | ||||
-rw-r--r-- | modules/cache/cache_cache.c | 8 | ||||
-rw-r--r-- | modules/cache/cache_storage.c | 64 | ||||
-rw-r--r-- | modules/cache/cache_util.c | 30 | ||||
-rw-r--r-- | modules/cache/mod_cache.c | 138 | ||||
-rw-r--r-- | modules/cache/mod_cache.dsp | 16 | ||||
-rw-r--r-- | modules/cache/mod_cache.h | 6 | ||||
-rw-r--r-- | modules/cache/mod_disk_cache.c | 15 | ||||
-rw-r--r-- | modules/cache/mod_disk_cache.dsp | 16 | ||||
-rw-r--r-- | modules/cache/mod_file_cache.dsp | 20 | ||||
-rw-r--r-- | modules/cache/mod_mem_cache.c | 33 | ||||
-rw-r--r-- | modules/cache/mod_mem_cache.dsp | 16 |
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 |