From: Graham Leggett Date: Sun, 3 Oct 2010 13:23:39 +0000 (+0000) Subject: mod_cache: Allow control over the base URL of reverse proxied requests X-Git-Tag: 2.3.9~363 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d29eacb4785a851f9c3961124027617b557c7c19;p=apache mod_cache: Allow control over the base URL of reverse proxied requests using the CacheKeyBaseURL directive, so that the cache key can be calculated from the endpoint URL instead of the server URL. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1003963 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 3dbdf4895f..ad471cdd04 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,11 @@ Changes with Apache 2.3.9 Fix a denial of service attack against mod_reqtimeout. [Stefan Fritsch] + *) mod_cache: Allow control over the base URL of reverse proxied requests + using the CacheKeyBaseURL directive, so that the cache key can be + calculated from the endpoint URL instead of the server URL. [Graham + Leggett] + *) mod_cache: CacheLastModifiedFactor, CacheStoreNoStore, CacheStorePrivate, CacheStoreExpired, CacheIgnoreNoLastMod, CacheDefaultExpire, CacheMinExpire and CacheMaxExpire can be set per directory/location. diff --git a/docs/manual/mod/mod_cache.xml b/docs/manual/mod/mod_cache.xml index 9759230e1b..a160537da4 100644 --- a/docs/manual/mod/mod_cache.xml +++ b/docs/manual/mod/mod_cache.xml @@ -917,4 +917,35 @@ LastModified date. + +CacheKeyBaseURL +Override the base URL of reverse proxied cache keys. +CacheKeyBaseURL URL +CacheKeyBaseURL http://example.com +server config +virtual host + +Available in Apache 2.3.9 and later + + +

When the CacheKeyBaseURL directive + is specified, the URL provided will be used as the base URL to calculate + the URL of the cache keys in the reverse proxy configuration. When not specified, + the scheme, hostname and port of the current virtual host is used to construct + the cache key. When a cluster of machines is present, and all cached entries + should be cached beneath the same cache key, a new base URL can be specified + with this directive.

+ + + # Override the base URL of the cache key.
+ CacheKeyBaseURL http://www.example.com/
+
+ + Take care when setting this directive. If two separate virtual + hosts are accidentally given the same base URL, entries from one virtual host + will be served to the other. + +
+
+ diff --git a/modules/cache/cache_storage.c b/modules/cache/cache_storage.c index 7b07e38533..d96b76c162 100644 --- a/modules/cache/cache_storage.c +++ b/modules/cache/cache_storage.c @@ -414,10 +414,15 @@ apr_status_t cache_generate_key_default(request_rec *r, apr_pool_t* p, * in the reverse proxy case. */ if (!r->proxyreq || (r->proxyreq == PROXYREQ_REVERSE)) { - /* Use _default_ as the hostname if none present, as in mod_vhost */ - hostname = ap_get_server_name(r); - if (!hostname) { - hostname = "_default_"; + if (conf->base_uri && conf->base_uri->hostname) { + hostname = conf->base_uri->hostname; + } + else { + /* Use _default_ as the hostname if none present, as in mod_vhost */ + hostname = ap_get_server_name(r); + if (!hostname) { + hostname = "_default_"; + } } } else if(r->parsed_uri.hostname) { @@ -449,7 +454,12 @@ apr_status_t cache_generate_key_default(request_rec *r, apr_pool_t* p, scheme = lcs; } else { - scheme = ap_http_scheme(r); + if (conf->base_uri && conf->base_uri->scheme) { + scheme = conf->base_uri->scheme; + } + else { + scheme = ap_http_scheme(r); + } } /* @@ -460,7 +470,7 @@ apr_status_t cache_generate_key_default(request_rec *r, apr_pool_t* p, * scheme - if available. Otherwise use the port-number of the current * server. */ - if(r->proxyreq && (r->proxyreq != PROXYREQ_REVERSE)) { + if (r->proxyreq && (r->proxyreq != PROXYREQ_REVERSE)) { if (r->parsed_uri.port_str) { port_str = apr_pcalloc(p, strlen(r->parsed_uri.port_str) + 2); port_str[0] = ':'; @@ -481,8 +491,16 @@ apr_status_t cache_generate_key_default(request_rec *r, apr_pool_t* p, } } else { - /* Use the server port */ - port_str = apr_psprintf(p, ":%u", ap_get_server_port(r)); + if (conf->base_uri && conf->base_uri->port_str) { + port_str = conf->base_uri->port_str; + } + else if (conf->base_uri && conf->base_uri->hostname) { + port_str = ""; + } + else { + /* Use the server port */ + port_str = apr_psprintf(p, ":%u", ap_get_server_port(r)); + } } /* diff --git a/modules/cache/cache_util.h b/modules/cache/cache_util.h index 19cd586bfe..ffcf8e708f 100644 --- a/modules/cache/cache_util.h +++ b/modules/cache/cache_util.h @@ -149,6 +149,8 @@ typedef struct { int x_cache_set; int x_cache_detail; int x_cache_detail_set; + apr_uri_t *base_uri; + int base_uri_set; } cache_server_conf; typedef struct { diff --git a/modules/cache/mod_cache.c b/modules/cache/mod_cache.c index 460887e895..a9475d27bb 100644 --- a/modules/cache/mod_cache.c +++ b/modules/cache/mod_cache.c @@ -1612,6 +1612,10 @@ static void * merge_cache_config(apr_pool_t *p, void *basev, void *overridesv) (overrides->x_cache_detail_set == 0) ? base->x_cache_detail : overrides->x_cache_detail; + ps->base_uri = + (overrides->base_uri_set == 0) + ? base->base_uri + : overrides->base_uri; return ps; } @@ -1981,6 +1985,28 @@ static const char *set_cache_x_cache_detail(cmd_parms *parms, void *dummy, int f return NULL; } +static const char *set_cache_key_base_url(cmd_parms *parms, void *dummy, + const char *arg) +{ + cache_server_conf *conf; + apr_status_t rv; + + conf = + (cache_server_conf *)ap_get_module_config(parms->server->module_config, + &cache_module); + conf->base_uri = apr_pcalloc(parms->pool, sizeof(apr_uri_t)); + rv = apr_uri_parse(parms->pool, arg, conf->base_uri); + if (rv != APR_SUCCESS) { + return apr_psprintf(parms->pool, "Could not parse '%s' as an URL.", arg); + } + else if (!conf->base_uri->scheme && !conf->base_uri->hostname && + !conf->base_uri->port_str) { + return apr_psprintf(parms->pool, "URL '%s' must contain at least one of a scheme, a hostname or a port.", arg); + } + conf->base_uri_set = 1; + return NULL; +} + static int cache_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { @@ -2063,6 +2089,8 @@ static const command_rec cache_cmds[] = AP_INIT_FLAG("CacheDetailHeader", set_cache_x_cache_detail, NULL, RSRC_CONF | ACCESS_CONF, "Add a X-Cache-Detail header to responses. Default is off."), + AP_INIT_TAKE1("CacheKeyBaseURL", set_cache_key_base_url, NULL, RSRC_CONF, + "Override the base URL of reverse proxied cache keys."), {NULL} };