From acf227a49242003d921f7c3432a40056fb5c7ce3 Mon Sep 17 00:00:00 2001
From: Colm MacCarthaigh
Date: Tue, 23 Aug 2005 15:43:23 +0000
Subject: [PATCH] Enhance CacheEnable/CacheDisable to control caching on a
per-protocol, per-host and per-path basis. Makes Cache(En|Dis)able useful for
forward proxy servers.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@239421 13f79535-47bb-0310-9956-ffa450edef68
---
CHANGES | 4 +++
docs/manual/mod/mod_cache.html.en | 21 ++++++++++--
docs/manual/mod/mod_cache.xml | 21 ++++++++++--
modules/cache/cache_util.c | 56 +++++++++++++++++++++++++++----
modules/cache/mod_cache.c | 29 ++++++++++------
modules/cache/mod_cache.h | 10 +++---
6 files changed, 115 insertions(+), 26 deletions(-)
diff --git a/CHANGES b/CHANGES
index b64ee4e3f4..f99b9019b9 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,10 @@
Changes with Apache 2.3.0
[Remove entries to the current 2.0 and 2.2 section below, when backported]
+ *) mod_cache: Enhance CacheEnable/CacheDisable to control caching on a
+ per-protocol, per-host and per-path basis. Intended for proxy
+ configurations. [Colm MacCarthaigh]
+
*) Teach mod_ssl to use arbitraty OIDs in an SSLRequire directive,
allowing string-valued client certificate attributes to be used for
access control, as in: SSLRequire "value" in OID("1.3.6.1.4.1.18060.1")
diff --git a/docs/manual/mod/mod_cache.html.en b/docs/manual/mod/mod_cache.html.en
index cd7e3ff10f..c408f4b27a 100644
--- a/docs/manual/mod/mod_cache.html.en
+++ b/docs/manual/mod/mod_cache.html.en
@@ -87,8 +87,8 @@
<IfModule mod_cache.c>
#LoadModule disk_cache_module modules/mod_disk_cache.so
- # If you want to use mod_disk_cache instead of mod_mem_cache,
- # uncomment the line above and comment out the LoadModule line below.
+ # If you want to use mod_disk_cache instead of mod_mem_cache,
+ # uncomment the line above and comment out the LoadModule line below.
<IfModule mod_disk_cache.c>
CacheRoot c:/cacheroot
@@ -108,6 +108,9 @@
MCacheMaxObjectSize 2048
</IfModule>
+
+ # When acting as a proxy, don't cache the list of security updates
+ CacheDisable http://security.update.server/update-list/
</IfModule>
@@ -185,6 +188,20 @@ manager
CacheEnable disk /
diff --git a/docs/manual/mod/mod_cache.xml b/docs/manual/mod/mod_cache.xml
index cda4ea22d0..e1829e641d 100644
--- a/docs/manual/mod/mod_cache.xml
+++ b/docs/manual/mod/mod_cache.xml
@@ -86,8 +86,8 @@
<IfModule mod_cache.c>
#LoadModule disk_cache_module modules/mod_disk_cache.so
- # If you want to use mod_disk_cache instead of mod_mem_cache,
- # uncomment the line above and comment out the LoadModule line below.
+ # If you want to use mod_disk_cache instead of mod_mem_cache,
+ # uncomment the line above and comment out the LoadModule line below.
<IfModule mod_disk_cache.c>
CacheRoot c:/cacheroot
@@ -107,6 +107,9 @@
MCacheMaxObjectSize 2048
</IfModule>
+
+ # When acting as a proxy, don't cache the list of security updates
+ CacheDisable http://security.update.server/update-list/
</IfModule>
@@ -145,6 +148,20 @@ manager
CacheEnable fd /images
CacheEnable disk /
+
+
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 proxied url's
+ CacheEnable disk /
+ # Cache FTP-proxied url's
+ CacheEnable disk ftp://
+ # Cache content from www.apache.org
+ CacheEnable disk http://www.apache.org/
+
+
diff --git a/modules/cache/cache_util.c b/modules/cache/cache_util.c
index 21c6fee5bb..7ed7a726ed 100644
--- a/modules/cache/cache_util.c
+++ b/modules/cache/cache_util.c
@@ -24,23 +24,65 @@
extern module AP_MODULE_DECLARE_DATA cache_module;
+/* Determine if "url" matches the hostname, scheme and port and path
+ * in "filter". All but the path comparisons are case-insensitive.
+ */
+static int uri_meets_conditions(apr_uri_t filter, int pathlen, apr_uri_t url)
+{
+ /* Compare the hostnames */
+ if(filter.hostname) {
+ if (!url.hostname) {
+ return 0;
+ }
+ else if (strcasecmp(filter.hostname, url.hostname)) {
+ return 0;
+ }
+ }
+
+ /* Compare the schemes */
+ if(filter.scheme) {
+ if (!url.scheme) {
+ return 0;
+ }
+ else if (strcasecmp(filter.scheme, url.scheme)) {
+ return 0;
+ }
+ }
+
+ /* Compare the ports */
+ if(filter.port_str) {
+ if (url.port_str && filter.port != url.port) {
+ return 0;
+ }
+ /* NOTE: ap_port_of_scheme will return 0 if given NULL input */
+ else if (filter.port != apr_uri_port_of_scheme(url.scheme)) {
+ return 0;
+ }
+ }
+ else if(url.port_str && filter.scheme) {
+ if (apr_uri_port_of_scheme(filter.scheme) == url.port) {
+ return 0;
+ }
+ }
+
+ /* Url has met all of the filter conditions so far, determine
+ * if the paths match.
+ */
+ return !strncmp(filter.path, url.path, pathlen);
+}
CACHE_DECLARE(cache_provider_list *)ap_cache_get_providers(request_rec *r,
cache_server_conf *conf,
- const char *url)
+ apr_uri_t uri)
{
cache_provider_list *providers = NULL;
int i;
- /* we can't cache if there's no URL */
- /* Is this case even possible?? */
- if (!url) return NULL;
-
/* 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 ((ent[i].url) && !strncasecmp(url, ent[i].url, ent[i].urllen)) {
+ 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,
@@ -77,7 +119,7 @@ CACHE_DECLARE(cache_provider_list *)ap_cache_get_providers(request_rec *r,
for (i = 0; i < conf->cachedisable->nelts; i++) {
struct cache_disable *ent =
(struct cache_disable *)conf->cachedisable->elts;
- if ((ent[i].url) && !strncasecmp(url, ent[i].url, ent[i].urllen)) {
+ if (uri_meets_conditions(ent[i].url, ent[i].pathlen, uri)) {
/* Stop searching now. */
return NULL;
}
diff --git a/modules/cache/mod_cache.c b/modules/cache/mod_cache.c
index 6362ee0000..0bd4d23663 100644
--- a/modules/cache/mod_cache.c
+++ b/modules/cache/mod_cache.c
@@ -50,8 +50,6 @@ static int cache_url_handler(request_rec *r, int lookup)
{
apr_status_t rv;
const char *auth;
- apr_uri_t uri;
- char *path;
cache_provider_list *providers;
cache_request_rec *cache;
cache_server_conf *conf;
@@ -62,16 +60,13 @@ static int cache_url_handler(request_rec *r, int lookup)
return DECLINED;
}
- uri = r->parsed_uri;
- path = uri.path;
-
conf = (cache_server_conf *) ap_get_module_config(r->server->module_config,
&cache_module);
/*
* Which cache module (if any) should handle this request?
*/
- if (!(providers = ap_cache_get_providers(r, conf, path))) {
+ if (!(providers = ap_cache_get_providers(r, conf, r->parsed_uri))) {
return DECLINED;
}
@@ -984,8 +979,15 @@ static const char *add_cache_enable(cmd_parms *parms, void *dummy,
&cache_module);
new = apr_array_push(conf->cacheenable);
new->type = type;
- new->url = url;
- new->urllen = strlen(url);
+ if (apr_uri_parse(parms->pool, url, &(new->url))) {
+ return NULL;
+ }
+ if (new->url.path) {
+ new->pathlen = strlen(new->url.path);
+ } else {
+ new->pathlen = 1;
+ new->url.path = "/";
+ }
return NULL;
}
@@ -999,8 +1001,15 @@ static const char *add_cache_disable(cmd_parms *parms, void *dummy,
(cache_server_conf *)ap_get_module_config(parms->server->module_config,
&cache_module);
new = apr_array_push(conf->cachedisable);
- new->url = url;
- new->urllen = strlen(url);
+ if (apr_uri_parse(parms->pool, url, &(new->url))) {
+ return NULL;
+ }
+ if (new->url.path) {
+ new->pathlen = strlen(new->url.path);
+ } else {
+ new->pathlen = 1;
+ new->url.path = "/";
+ }
return NULL;
}
diff --git a/modules/cache/mod_cache.h b/modules/cache/mod_cache.h
index 0da7724fcf..9c4f88e475 100644
--- a/modules/cache/mod_cache.h
+++ b/modules/cache/mod_cache.h
@@ -104,14 +104,14 @@
#endif
struct cache_enable {
- const char *url;
+ apr_uri_t url;
const char *type;
- apr_size_t urllen;
+ apr_size_t pathlen;
};
struct cache_disable {
- const char *url;
- apr_size_t urllen;
+ apr_uri_t url;
+ apr_size_t pathlen;
};
/* static information about the local cache */
@@ -257,7 +257,7 @@ CACHE_DECLARE(void) ap_cache_usec2hex(apr_time_t j, char *y);
CACHE_DECLARE(char *) ap_cache_generate_name(apr_pool_t *p, int dirlevels,
int dirlength,
const char *name);
-CACHE_DECLARE(cache_provider_list *)ap_cache_get_providers(request_rec *r, cache_server_conf *conf, const char *url);
+CACHE_DECLARE(cache_provider_list *)ap_cache_get_providers(request_rec *r, cache_server_conf *conf, apr_uri_t uri);
CACHE_DECLARE(int) ap_cache_liststr(apr_pool_t *p, const char *list,
const char *key, char **val);
CACHE_DECLARE(const char *)ap_cache_tokstr(apr_pool_t *p, const char *list, const char **str);
--
2.40.0