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: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d29eacb4785a851f9c3961124027617b557c7c19;p=thirdparty%2Fapache%2Fhttpd.git 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 3dbdf4895f2..ad471cdd044 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 9759230e1b7..a160537da42 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 7b07e385332..d96b76c1622 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 19cd586bfe3..ffcf8e708fe 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 460887e8956..a9475d27bbd 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} };