From 15a425222578ef14c0fec8a3e811a777b87f24be Mon Sep 17 00:00:00 2001 From: Ian Holsman Date: Tue, 5 Feb 2002 00:15:42 +0000 Subject: [PATCH] add a optional function ap_cache_generate_key which allows a 3rd party module to generate the key name based on the request_rec. the idea here is for it to also be able to mess with expiry times and cachability add another option.. CacheIgnoreCacheControl. this ignores a 'incoming request's attempts to get a fresh copy. Mainly I see this as being usefull in r-proxy's git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93242 13f79535-47bb-0310-9956-ffa450edef68 --- modules/experimental/cache_storage.c | 30 ++++++++++---- modules/experimental/mod_cache.c | 59 +++++++++++++++++++++++----- modules/experimental/mod_cache.h | 14 ++++++- 3 files changed, 85 insertions(+), 18 deletions(-) diff --git a/modules/experimental/cache_storage.c b/modules/experimental/cache_storage.c index 609435e01b..f78bc482ff 100644 --- a/modules/experimental/cache_storage.c +++ b/modules/experimental/cache_storage.c @@ -66,6 +66,8 @@ APR_HOOK_STRUCT( APR_HOOK_LINK(open_entity) ) +extern APR_OPTIONAL_FN_TYPE(ap_cache_generate_key) *cache_generate_key; + extern module AP_MODULE_DECLARE_DATA cache_module; /* -------------------------------------------------------------- */ @@ -78,9 +80,13 @@ int cache_remove_url(request_rec *r, const char *types, char *url) { const char *next = types; const char *type; - const char *key; + apr_status_t rv; + char *key; - key = cache_create_key(r); + rv = cache_generate_key(r,r->pool,&key); + if (rv != APR_SUCCESS) { + return rv; + } /* for each specified cache type, delete the URL */ while(next) { @@ -107,13 +113,16 @@ int cache_create_entity(request_rec *r, const char *types, char *url, apr_size_t cache_handle_t *h = apr_pcalloc(r->pool, sizeof(h)); const char *next = types; const char *type; - const char *key; + char *key; apr_status_t rv; cache_request_rec *cache = (cache_request_rec *) ap_get_module_config(r->request_config, &cache_module); + rv = cache_generate_key(r,r->pool,&key); + if (rv != APR_SUCCESS) { + return rv; + } /* for each specified cache type, delete the URL */ - key = cache_create_key(r); while (next) { type = ap_cache_tokstr(r->pool, next, &next); switch (rv = cache_run_create_entity(h, r, type, key, size)) { @@ -162,10 +171,14 @@ int cache_select_url(request_rec *r, const char *types, char *url) const char *type; apr_status_t rv; cache_info *info; - const char *key; + char *key; cache_request_rec *cache = (cache_request_rec *) ap_get_module_config(r->request_config, &cache_module); - key = cache_create_key(r); + + rv = cache_generate_key(r,r->pool,&key); + if (rv != APR_SUCCESS) { + return rv; + } /* go through the cache types till we get a match */ cache->handle = apr_palloc(r->pool, sizeof(cache_handle_t)); @@ -235,9 +248,10 @@ apr_status_t cache_read_entity_body(cache_handle_t *h, apr_pool_t *p, apr_bucket return APR_SUCCESS; } -const char* cache_create_key( request_rec *r ) +apr_status_t cache_generate_key_default( request_rec *r, apr_pool_t*p, char**key ) { - return r->uri; + *key = apr_pstrdup(p,r->uri); + return APR_SUCCESS; } APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(cache, CACHE, int, create_entity, (cache_handle_t *h, request_rec *r, const char *type, diff --git a/modules/experimental/mod_cache.c b/modules/experimental/mod_cache.c index 7dcf1ea587..170fab9ce0 100644 --- a/modules/experimental/mod_cache.c +++ b/modules/experimental/mod_cache.c @@ -61,6 +61,7 @@ #include "mod_cache.h" module AP_MODULE_DECLARE_DATA cache_module; +APR_OPTIONAL_FN_TYPE(ap_cache_generate_key) *cache_generate_key; /* -------------------------------------------------------------- */ @@ -147,14 +148,20 @@ static int cache_url_handler(request_rec *r) "cache: URL exceeds length threshold: %s", url); return DECLINED; } - if (ap_cache_liststr(cc_in, "no-store", NULL) || - ap_cache_liststr(pragma, "no-cache", NULL) || (auth != NULL)) { - /* delete the previously cached file */ - cache_remove_url(r, cache->types, url); - + if (conf->ignorecachecontrol_set == 1 && conf->ignorecachecontrol == 1 && auth == NULL) { ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server, - "cache: no-store forbids caching of %s", url); - return DECLINED; + "incoming request is asking for a uncached version of %s, but we know better and are ignoring it", url); + } + else { + if (ap_cache_liststr(cc_in, "no-store", NULL) || + ap_cache_liststr(pragma, "no-cache", NULL) || (auth != NULL)) { + /* delete the previously cached file */ + cache_remove_url(r, cache->types, url); + + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server, + "cache: no-store forbids caching of %s", url); + return DECLINED; + } } /* @@ -396,7 +403,7 @@ static int cache_in_filter(ap_filter_t *f, apr_bucket_brigade *in) /* check first whether running this filter has any point or not */ if(r->no_cache) { - ap_remove_output_filter(f); + ap_remove_output_filter(f); return ap_pass_brigade(f->next, in); } @@ -738,6 +745,8 @@ static void * create_cache_config(apr_pool_t *p, server_rec *s) ps->complete_set = 0; ps->no_last_mod_ignore_set = 0; ps->no_last_mod_ignore = 0; + ps->ignorecachecontrol = 0; + ps->ignorecachecontrol_set = 0 ; return ps; } @@ -772,6 +781,11 @@ static void * merge_cache_config(apr_pool_t *p, void *basev, void *overridesv) (overrides->no_last_mod_ignore_set) ? base->no_last_mod_ignore : overrides->no_last_mod_ignore; + ps->ignorecachecontrol = + (overrides->ignorecachecontrol_set) ? + base->ignorecachecontrol : + overrides->ignorecachecontrol; + return ps; } static const char @@ -785,6 +799,7 @@ static const char return NULL; } + static const char *set_cache_on(cmd_parms *parms, void *dummy, int flag) { @@ -795,6 +810,17 @@ static const char conf->cacheon_set = 1; return NULL; } +static const char +*set_cache_ignore_cachecontrol( cmd_parms *parms, void *dummy, int flag) +{ + cache_server_conf *conf = ap_get_module_config(parms->server->module_config, + &cache_module); + + conf->ignorecachecontrol = 1; + conf->ignorecachecontrol_set = 1; + return NULL; + +} static const char *add_cache_enable(cmd_parms *parms, @@ -905,6 +931,18 @@ static const char conf->complete_set = 1; return NULL; } +static cache_post_config(apr_pool_t *p, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + /* This is the means by which unusual (non-unix) os's may find alternate + * means to run a given command (e.g. shebang/registry parsing on Win32) + */ + cache_generate_key = APR_RETRIEVE_OPTIONAL_FN(ap_cache_generate_key); + if (!cache_generate_key) { + cache_generate_key = cache_generate_key_default; + } + return OK; +} static const command_rec cache_cmds[] = { @@ -935,7 +973,9 @@ static const command_rec cache_cmds[] = AP_INIT_FLAG("CacheIgnoreNoLastMod", set_cache_ignore_no_last_mod, NULL, RSRC_CONF, "Ignore Responses where there is no Last Modified Header"), - + AP_INIT_FLAG("CacheIgnoreCacheControl", set_cache_ignore_cachecontrol, NULL, + RSRC_CONF, + "Ignore requests from the client for uncached content"), AP_INIT_TAKE1("CacheLastModifiedFactor", set_cache_factor, NULL, RSRC_CONF, "The factor used to estimate Expires date from LastModified date"), AP_INIT_TAKE1("CacheForceCompletion", set_cache_complete, NULL, RSRC_CONF, @@ -964,6 +1004,7 @@ register_hooks(apr_pool_t *p) ap_register_output_filter("CACHE_CONDITIONAL", cache_conditional_filter, AP_FTYPE_CONTENT+1); + ap_hook_post_config(cache_post_config, NULL, NULL, APR_HOOK_REALLY_FIRST); } module AP_MODULE_DECLARE_DATA cache_module = diff --git a/modules/experimental/mod_cache.h b/modules/experimental/mod_cache.h index e68838e9f3..937fba025d 100644 --- a/modules/experimental/mod_cache.h +++ b/modules/experimental/mod_cache.h @@ -74,6 +74,7 @@ #include "apr_md5.h" #include "apr_pools.h" #include "apr_strings.h" +#include "apr_optional.h" #define APR_WANT_STRFUNC #include "apr_want.h" @@ -168,9 +169,12 @@ typedef struct { int factor_set; int complete; /* Force cache completion after this point */ int complete_set; - /* ignore the last-modified header when deciding to cache this request */ + /** ignore the last-modified header when deciding to cache this request */ int no_last_mod_ignore_set; int no_last_mod_ignore; + /** ignore client's requests for uncached responses */ + int ignorecachecontrol; + int ignorecachecontrol_set; } cache_server_conf; /* cache info information */ @@ -250,6 +254,7 @@ int cache_remove_url(request_rec *r, const char *types, char *url); int cache_create_entity(request_rec *r, const char *types, char *url, apr_size_t size); int cache_remove_entity(request_rec *r, const char *types, cache_handle_t *h); int cache_select_url(request_rec *r, const char *types, char *url); +apr_status_t cache_generate_key_default( request_rec *r, apr_pool_t*p, char**key ); /** * create a key for the cache based on the request record * this is the 'default' version, which can be overridden by a default function @@ -295,4 +300,11 @@ APR_DECLARE_EXTERNAL_HOOK(cache, CACHE, int, open_entity, APR_DECLARE_EXTERNAL_HOOK(cache, CACHE, int, remove_url, (const char *type, const char *urlkey)) + + +APR_DECLARE_OPTIONAL_FN(apr_status_t, + ap_cache_generate_key, + (request_rec *r, apr_pool_t*p, char**key )); + + #endif /*MOD_CACHE_H*/ -- 2.40.0