]> granicus.if.org Git - apache/commitdiff
add a optional function ap_cache_generate_key
authorIan Holsman <ianh@apache.org>
Tue, 5 Feb 2002 00:15:42 +0000 (00:15 +0000)
committerIan Holsman <ianh@apache.org>
Tue, 5 Feb 2002 00:15:42 +0000 (00:15 +0000)
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
modules/experimental/mod_cache.c
modules/experimental/mod_cache.h

index 609435e01b7aa4c77a2e6cbaecf649b1b728d26f..f78bc482ff61b0f1a64ac860f5471018d3aaa396 100644 (file)
@@ -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, 
index 7dcf1ea5873c1ae90213d699c266771a7c761f22..170fab9ce09a52c3468d9f2aafc59f40b564c3a7 100644 (file)
@@ -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 =
index e68838e9f3f4a9ce18308f2b47f5c8422feafd5c..937fba025ddc11369580410439e8d341c2e7f41f 100644 (file)
@@ -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*/