From: Graham Leggett
Date: Sat, 12 Mar 2011 01:15:28 +0000 (+0000)
Subject: mod_cache: Make CacheEnable and CacheDisable configurable per
X-Git-Tag: 2.3.12~251
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e8f8ab78634d97321d3120fbd26584a91343fc7a;p=thirdparty%2Fapache%2Fhttpd.git
mod_cache: Make CacheEnable and CacheDisable configurable per
directory in addition to per server, making them work from within
a LocationMatch.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1080834 13f79535-47bb-0310-9956-ffa450edef68
---
diff --git a/CHANGES b/CHANGES
index 6930b277dd3..cd1aa5a3e2b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,10 @@
Changes with Apache 2.3.12
+ *) mod_cache: Make CacheEnable and CacheDisable configurable per
+ directory in addition to per server, making them work from within
+ a LocationMatch. [Graham Leggett]
+
*) worker, event, prefork: Correct several issues when built as
DSOs; most notably, the scoreboard was reinitialized during graceful
restart, such that processes of the previous generation were not
diff --git a/docs/manual/mod/mod_cache.xml b/docs/manual/mod/mod_cache.xml
index 97d7c117602..943ef2f66e3 100644
--- a/docs/manual/mod/mod_cache.xml
+++ b/docs/manual/mod/mod_cache.xml
@@ -332,17 +332,20 @@
CacheEnable
Enable caching of specified URLs using a specified storage
manager
-CacheEnable cache_type url-string
+CacheEnable cache_type [url-string]
server configvirtual host
+directory.htaccess
The CacheEnable directive instructs
mod_cache to cache urls at or below
url-string. The cache storage manager is specified with the
- cache_type argument. If the CacheEnable
- directive is placed inside a Location
- directive, the url-string becomes optional.
+ cache_type argument. The CacheEnable
+ directive can alternatively be placed inside either
+ Location or
+ LocationMatch sections to indicate
+ the content is cacheable.
cache_type disk
instructs
mod_cache to use the disk based storage manager
implemented by mod_cache_disk.
@@ -351,13 +354,28 @@ manager
each possible storage manager will be run until the first one that
actually processes the request. The order in which the storage managers are
run is determined by the order of the CacheEnable
- directives in the configuration file.
+ directives in the configuration file. CacheEnable
+ directives within Location or
+ LocationMatch sections are processed
+ before globally defined CacheEnable directives.
When acting as a forward proxy server, url-string can
also be used to specify remote sites and proxy protocols which
caching should be enabled for.
-
+
+ # Cache content
+ <Location /foo>
+
+ CacheEnable disk
+
+ </Location>
+ # Cache regex
+ <LocationMatch foo$>
+
+ CacheEnable disk
+
+ </LocationMatch>
# Cache proxied url's
CacheEnable disk /
# Cache FTP-proxied url's
@@ -390,6 +408,7 @@ manager
Disable caching of specified URLs
CacheDisable url-string | on
server configvirtual host
+directory.htaccess
@@ -407,11 +426,13 @@ manager
Example
<Location /foo>
+
CacheDisable on
+
</Location>
- The no-cache
environment variable can be set to
+
The no-cache
environment variable can be set to
disable caching on a finer grained set of resources in versions
2.2.12 and later.
diff --git a/modules/cache/cache_util.c b/modules/cache/cache_util.c
index 7c36617f4ea..d359f0a8d4f 100644
--- a/modules/cache/cache_util.c
+++ b/modules/cache/cache_util.c
@@ -126,51 +126,58 @@ static int uri_meets_conditions(const apr_uri_t *filter, const int pathlen,
return !strncmp(filter->path, url->path, pathlen);
}
+static cache_provider_list *get_provider(request_rec *r, struct cache_enable *ent,
+ cache_provider_list *providers)
+{
+ /* Fetch from global config and add to the list. */
+ cache_provider *provider;
+ provider = ap_lookup_provider(CACHE_PROVIDER_GROUP, ent->type,
+ "0");
+ if (!provider) {
+ /* Log an error! */
+ }
+ else {
+ cache_provider_list *newp;
+ newp = apr_pcalloc(r->pool, sizeof(cache_provider_list));
+ newp->provider_name = ent->type;
+ newp->provider = provider;
+
+ if (!providers) {
+ providers = newp;
+ }
+ else {
+ cache_provider_list *last = providers;
+
+ while (last->next) {
+ if (last->provider == provider) {
+ return providers;
+ }
+ last = last->next;
+ }
+ if (last->provider == provider) {
+ return providers;
+ }
+ last->next = newp;
+ }
+ }
+
+ return providers;
+}
+
cache_provider_list *cache_get_providers(request_rec *r,
cache_server_conf *conf,
apr_uri_t uri)
{
+ cache_dir_conf *dconf = dconf = ap_get_module_config(r->per_dir_config, &cache_module);
cache_provider_list *providers = NULL;
int i;
- /* loop through all the cacheenable entries */
- for (i = 0; i < conf->cacheenable->nelts; i++) {
- struct cache_enable *ent =
- (struct cache_enable *)conf->cacheenable->elts;
- if (uri_meets_conditions(&ent[i].url, ent[i].pathlen, &uri)) {
- /* Fetch from global config and add to the list. */
- cache_provider *provider;
- provider = ap_lookup_provider(CACHE_PROVIDER_GROUP, ent[i].type,
- "0");
- if (!provider) {
- /* Log an error! */
- }
- else {
- cache_provider_list *newp;
- newp = apr_pcalloc(r->pool, sizeof(cache_provider_list));
- newp->provider_name = ent[i].type;
- newp->provider = provider;
-
- if (!providers) {
- providers = newp;
- }
- else {
- cache_provider_list *last = providers;
-
- while (last->next) {
- last = last->next;
- }
- last->next = newp;
- }
- }
- }
+ /* per directory cache disable */
+ if (dconf->disable) {
+ return NULL;
}
- /* then loop through all the cachedisable entries
- * Looking for urls that contain the full cachedisable url and possibly
- * more.
- * This means we are disabling cachedisable url and below...
- */
+ /* global cache disable */
for (i = 0; i < conf->cachedisable->nelts; i++) {
struct cache_disable *ent =
(struct cache_disable *)conf->cachedisable->elts;
@@ -180,6 +187,22 @@ cache_provider_list *cache_get_providers(request_rec *r,
}
}
+ /* loop through all the per directory cacheenable entries */
+ for (i = 0; i < dconf->cacheenable->nelts; i++) {
+ struct cache_enable *ent =
+ (struct cache_enable *)dconf->cacheenable->elts;
+ providers = get_provider(r, &ent[i], providers);
+ }
+
+ /* loop through all the global cacheenable entries */
+ for (i = 0; i < conf->cacheenable->nelts; i++) {
+ struct cache_enable *ent =
+ (struct cache_enable *)conf->cacheenable->elts;
+ if (uri_meets_conditions(&ent[i].url, ent[i].pathlen, &uri)) {
+ providers = get_provider(r, &ent[i], providers);
+ }
+ }
+
return providers;
}
diff --git a/modules/cache/cache_util.h b/modules/cache/cache_util.h
index ba8c9c31b77..dc28b6d2c6b 100644
--- a/modules/cache/cache_util.h
+++ b/modules/cache/cache_util.h
@@ -164,6 +164,10 @@ typedef struct {
apr_time_t defex;
/* factor for estimating expires date */
double factor;
+ /* cache enabled for this location */
+ apr_array_header_t *cacheenable;
+ /* cache disabled for this location */
+ int disable:1;
/* set X-Cache headers */
int x_cache:1;
int x_cache_detail:1;
@@ -188,6 +192,8 @@ typedef struct {
int store_expired_set:1;
int store_private_set:1;
int store_nostore_set:1;
+ int enable_set:1;
+ int disable_set:1;
} cache_dir_conf;
/* A linked-list of authn providers. */
diff --git a/modules/cache/mod_cache.c b/modules/cache/mod_cache.c
index afaaf997ee7..5ff8c2c621d 100644
--- a/modules/cache/mod_cache.c
+++ b/modules/cache/mod_cache.c
@@ -1720,6 +1720,9 @@ static void *create_dir_config(apr_pool_t *p, char *dummy)
dconf->stale_on_error = DEFAULT_CACHE_STALE_ON_ERROR;
+ /* array of providers for this URL space */
+ dconf->cacheenable = apr_array_make(p, 10, sizeof(struct cache_enable));
+
return dconf;
}
@@ -1764,6 +1767,12 @@ static void *merge_dir_config(apr_pool_t *p, void *basev, void *addv) {
new->stale_on_error_set = add->stale_on_error_set
|| base->stale_on_error_set;
+ new->cacheenable = add->enable_set ? apr_array_append(p, base->cacheenable,
+ add->cacheenable) : base->cacheenable;
+ new->enable_set = add->enable_set || base->enable_set;
+ new->disable = (add->disable_set == 0) ? base->disable : add->disable;
+ new->disable_set = add->disable_set || base->disable_set;
+
return new;
}
@@ -1993,6 +2002,7 @@ static const char *add_cache_enable(cmd_parms *parms, void *dummy,
const char *type,
const char *url)
{
+ cache_dir_conf *dconf = (cache_dir_conf *)dummy;
cache_server_conf *conf;
struct cache_enable *new;
@@ -2023,7 +2033,15 @@ static const char *add_cache_enable(cmd_parms *parms, void *dummy,
conf =
(cache_server_conf *)ap_get_module_config(parms->server->module_config,
&cache_module);
- new = apr_array_push(conf->cacheenable);
+
+ if (parms->path) {
+ new = apr_array_push(dconf->cacheenable);
+ dconf->enable_set = 1;
+ }
+ else {
+ new = apr_array_push(conf->cacheenable);
+ }
+
new->type = type;
if (apr_uri_parse(parms->pool, url, &(new->url))) {
return NULL;
@@ -2040,6 +2058,7 @@ static const char *add_cache_enable(cmd_parms *parms, void *dummy,
static const char *add_cache_disable(cmd_parms *parms, void *dummy,
const char *url)
{
+ cache_dir_conf *dconf = (cache_dir_conf *)dummy;
cache_server_conf *conf;
struct cache_disable *new;
@@ -2065,6 +2084,13 @@ static const char *add_cache_disable(cmd_parms *parms, void *dummy,
conf =
(cache_server_conf *)ap_get_module_config(parms->server->module_config,
&cache_module);
+
+ if (parms->path) {
+ dconf->disable = 1;
+ dconf->disable_set = 1;
+ return NULL;
+ }
+
new = apr_array_push(conf->cachedisable);
if (apr_uri_parse(parms->pool, url, &(new->url))) {
return NULL;