From 8a7fb4574c7f279434bbdcbcb2a77cf1cad9161c Mon Sep 17 00:00:00 2001 From: Ruediger Pluem Date: Tue, 6 Feb 2007 15:55:50 +0000 Subject: [PATCH] * Add CacheIgnoreQueryString directive to cache requests with a query string even if no expiration time is specified. Futhermore the query string will not be used for key generation such that requests to the same URI path, but with different query strings are mapped to the same cache entity. Turning this setting to ON violates RFC 2616/13.9 and thus it is turned off by default. PR: 41484 Submitted by: Fredrik Widlund Reviewed by: rpluem git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@504183 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 +++ docs/manual/mod/mod_cache.xml | 25 +++++++++++++++++++++++++ modules/cache/cache_storage.c | 20 +++++++++++++++++--- modules/cache/mod_cache.c | 25 ++++++++++++++++++++++++- modules/cache/mod_cache.h | 3 +++ 5 files changed, 72 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 8c9799b3f3..1621ca7feb 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.3.0 [Remove entries to the current 2.0 and 2.2 section below, when backported] + *) mod_cache: Add CacheIgnoreQueryString directive. PR 41484. + [Fredrik Widlund ] + *) mod_dbd: Introduce configuration groups to allow inheritance by virtual hosts of database configurations from the main server. Determine the minimal set of distinct configurations and share connection pools diff --git a/docs/manual/mod/mod_cache.xml b/docs/manual/mod/mod_cache.xml index 322ab82418..56981bbaca 100644 --- a/docs/manual/mod/mod_cache.xml +++ b/docs/manual/mod/mod_cache.xml @@ -311,6 +311,31 @@ header. CacheStoreNoStore + +CacheIgnoreQueryString +Ignore query string when caching +CacheIgnoreQueryString On|Off +CacheIgnoreQueryString Off +server configvirtual host + + + +

Ordinarily, requests with query string parameters are cached separately + for each unique query string. This is according to RFC 2616/13.9 done only + if an expiration time is specified. The + CacheIgnoreQueryString directive tells the cache to + cache requests even if no expiration time is specified, and to reply with + a cached reply even if the query string differs. From a caching point of + view the request is treated as if having no query string when this + directive is enabled.

+ + + CacheIgnoreQueryString On + + +
+
+ CacheLastModifiedFactor The factor used to compute an expiry date based on the diff --git a/modules/cache/cache_storage.c b/modules/cache/cache_storage.c index 0b04a2aef8..cb5be3b163 100644 --- a/modules/cache/cache_storage.c +++ b/modules/cache/cache_storage.c @@ -345,10 +345,18 @@ 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; char *port_str, *hn, *lcs; const char *hostname, *scheme; int i; + /* + * 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. @@ -439,9 +447,15 @@ 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->parsed_uri.query, 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); + } return APR_SUCCESS; } diff --git a/modules/cache/mod_cache.c b/modules/cache/mod_cache.c index e8a9517c25..455b9594ff 100644 --- a/modules/cache/mod_cache.c +++ b/modules/cache/mod_cache.c @@ -452,7 +452,7 @@ 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->parsed_uri.query && exps == NULL) { + else if (!conf->ignorequerystring && r->parsed_uri.query && exps == NULL) { /* if query string present but no expiration time, don't cache it * (RFC 2616/13.9) */ @@ -920,6 +920,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; } @@ -966,6 +969,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, @@ -1157,6 +1164,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) { @@ -1208,6 +1228,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.h b/modules/cache/mod_cache.h index 2f6f8b0571..902565c41d 100644 --- a/modules/cache/mod_cache.h +++ b/modules/cache/mod_cache.h @@ -154,6 +154,9 @@ typedef struct { /* Minimum time to keep cached files in msecs */ apr_time_t minex; int minex_set; + /** ignore query-string when caching */ + int ignorequerystring; + int ignorequerystring_set; } cache_server_conf; /* cache info information */ -- 2.50.1