You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Justin Erenkrantz <ju...@erenkrantz.com> on 2004/08/04 21:39:30 UTC

[PATCH] mod_cache: Use provider API

This patch removes the mod_cache dependencies upon the odd vtable and hooks 
and standardizes upon the ap_provider_* API.  mod_auth uses this provider 
interface now as has mod_dav.

Besides removing a bunch of code, this has a number of beneficial side-effects:

- All operations related to a cache are in *one* location/structure (yay!)
- Removal of some cache wrappers that shouldn't have been there.
- The remaining cache wrappers don't have to lookup/parse the 'type' string 
every time.  Instead, it can just walk the pre-built provider list.
- If a cache handler is invoked, instead of doing strcmp's to ensure it was 
meant to be called, they can just invoke - skipping these checks.
- The ordering still remains the same (first cache to have it wins).

I do have some code commented out that needs to be deleted entirely, but you 
can get the idea of the patch from this one.

FWIW, the caching directive syntax remains the same.  It's just an internal 
reorganization.  -- justin

Re: [PATCH] mod_cache: Use provider API

Posted by Sander Striker <st...@apache.org>.
Sander Striker wrote:
> Justin Erenkrantz wrote:
> 
>> --On Wednesday, August 4, 2004 12:39 PM -0700 Justin Erenkrantz 
>> <ju...@erenkrantz.com> wrote:
>>
>>> This patch removes the mod_cache dependencies upon the odd vtable and 
>>> hooks
>>> and standardizes upon the ap_provider_* API.  mod_auth uses this 
>>> provider
>>> interface now as has mod_dav.
> 
> 
> +1 (concept).

Huh?! In that same thread justin had a nice comment:

  "<place bag over head>"

I'll go do that now.

FYI, this happens if you try and get your mail sorted out over two years
and you forget to sort it by date in your mailer...

Sander 'Doh' Striker

Re: [PATCH] mod_cache: Use provider API

Posted by Sander Striker <st...@apache.org>.
Justin Erenkrantz wrote:
> --On Wednesday, August 4, 2004 12:39 PM -0700 Justin Erenkrantz 
> <ju...@erenkrantz.com> wrote:
> 
>> This patch removes the mod_cache dependencies upon the odd vtable and 
>> hooks
>> and standardizes upon the ap_provider_* API.  mod_auth uses this provider
>> interface now as has mod_dav.

+1 (concept).


Sander

Re: [PATCH] mod_cache: Use provider API

Posted by Justin Erenkrantz <ju...@erenkrantz.com>.
--On Wednesday, August 4, 2004 12:39 PM -0700 Justin Erenkrantz 
<ju...@erenkrantz.com> wrote:

> This patch removes the mod_cache dependencies upon the odd vtable and hooks
> and standardizes upon the ap_provider_* API.  mod_auth uses this provider
> interface now as has mod_dav.

<place bag over head>  -- justin

Index: modules/experimental/cache_storage.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/experimental/cache_storage.c,v
retrieving revision 1.35
diff -u -r1.35 cache_storage.c
--- modules/experimental/cache_storage.c	3 Aug 2004 08:20:21 -0000	1.35
+++ modules/experimental/cache_storage.c	4 Aug 2004 05:01:08 -0000
@@ -17,12 +17,6 @@

 #include "mod_cache.h"

-APR_HOOK_STRUCT(
-	APR_HOOK_LINK(remove_url)
-	APR_HOOK_LINK(create_entity)
-	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;
@@ -33,22 +27,25 @@
  * delete all URL entities from the cache
  *
  */
-int cache_remove_url(request_rec *r, const char *types, char *url)
+int cache_remove_url(request_rec *r, char *url)
 {
-    const char *next = types;
-    const char *type;
+    cache_provider_list *list;
     apr_status_t rv;
     char *key;
+    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;
     }

+    list = cache->providers;
+
     /* for each specified cache type, delete the URL */
-    while(next) {
-        type = ap_cache_tokstr(r->pool, next, &next);
-        cache_run_remove_url(type, key);
+    while(list) {
+        list->provider->remove_url(key);
+        list = list->next;
     }
     return OK;
 }
@@ -65,11 +62,10 @@
  * decide whether or not it wants to cache this particular entity.
  * If the size is unknown, a size of -1 should be set.
  */
-int cache_create_entity(request_rec *r, const char *types, char *url, 
apr_off_t size)
+int cache_create_entity(request_rec *r, char *url, apr_off_t size)
 {
+    cache_provider_list *list;
     cache_handle_t *h = apr_pcalloc(r->pool, sizeof(cache_handle_t));
-    const char *next = types;
-    const char *type;
     char *key;
     apr_status_t rv;
     cache_request_rec *cache = (cache_request_rec *)
@@ -79,15 +75,19 @@
     if (rv != APR_SUCCESS) {
         return rv;
     }
+
+    list = cache->providers;
     /* for each specified cache type, delete the URL */
-    while (next) {
-        type = ap_cache_tokstr(r->pool, next, &next);
-        switch (rv = cache_run_create_entity(h, r, type, key, size)) {
+    while (list) {
+        switch (rv = list->provider->create_entity(h, r, key, size)) {
         case OK: {
             cache->handle = h;
+            cache->provider = list->provider;
+            cache->provider_name = list->provider_name;
             return OK;
         }
         case DECLINED: {
+            list = list->next;
             continue;
         }
         default: {
@@ -99,19 +99,6 @@
 }

 /*
- * remove a specific URL entity from the cache
- *
- * The specific entity referenced by the cache_handle is removed
- * from the cache, and the cache_handle is closed.
- */
-/* XXX Don't think we need to pass in request_rec or types ... */
-int cache_remove_entity(request_rec *r, const char *types, cache_handle_t *h)
-{
-    h->remove_entity(h);
-    return 1;
-}
-
-/*
  * select a specific URL entity in the cache
  *
  * It is possible to store more than one entity per URL. Content
@@ -122,10 +109,9 @@
  * This function returns OK if successful, DECLINED if no
  * cached entity fits the bill.
  */
-int cache_select_url(request_rec *r, const char *types, char *url)
+int cache_select_url(request_rec *r, char *url)
 {
-    const char *next = types;
-    const char *type;
+    cache_provider_list *list;
     apr_status_t rv;
     cache_handle_t *h;
     char *key;
@@ -139,17 +125,20 @@
     /* go through the cache types till we get a match */
     h = cache->handle = apr_palloc(r->pool, sizeof(cache_handle_t));

-    while (next) {
-        type = ap_cache_tokstr(r->pool, next, &next);
-        switch ((rv = cache_run_open_entity(h, r, type, key))) {
+    list = cache->providers;
+
+    while (list) {
+        switch ((rv = list->provider->open_entity(h, r, key))) {
         case OK: {
             char *vary = NULL;
             const char *varyhdr = NULL;
-            if (cache_recall_entity_headers(h, r) != APR_SUCCESS) {
+            if (list->provider->recall_headers(h, r) != APR_SUCCESS) {
                 /* TODO: Handle this error */
                 return DECLINED;
             }

+            r->filename = apr_pstrdup(r->pool, h->cache_obj->info.filename);
+
             /*
              * Check Content-Negotiation - Vary
              *
@@ -205,10 +194,13 @@
                     return DECLINED;
                 }
             }
+            cache->provider = list->provider;
+            cache->provider_name = list->provider_name;
             return OK;
         }
         case DECLINED: {
             /* try again with next cache type */
+            list = list->next;
             continue;
         }
         default: {
@@ -222,41 +214,6 @@
     return DECLINED;
 }

-apr_status_t cache_store_entity_headers(cache_handle_t *h,
-                                        request_rec *r,
-                                        cache_info *info)
-{
-    return (h->store_headers(h, r, info));
-}
-
-apr_status_t cache_store_entity_body(cache_handle_t *h, request_rec *r,
-                                     apr_bucket_brigade *b)
-{
-    return (h->store_body(h, r, b));
-}
-
-apr_status_t cache_recall_entity_headers(cache_handle_t *h, request_rec *r)
-{
-    apr_status_t rv;
-    cache_info *info = &(h->cache_obj->info);
-
-    /* Build the header table from info in the info struct */
-    rv = h->recall_headers(h, r);
-    if (rv != APR_SUCCESS) {
-        return rv;
-    }
-
-    r->filename = apr_pstrdup(r->pool, info->filename );
-
-    return APR_SUCCESS;
-}
-
-apr_status_t cache_recall_entity_body(cache_handle_t *h, apr_pool_t *p,
-                                    apr_bucket_brigade *b)
-{
-    return (h->recall_body(h, p, b));
-}
-
 apr_status_t cache_generate_key_default( request_rec *r, apr_pool_t*p, 
char**key )
 {
     if (r->hostname) {
@@ -267,17 +224,3 @@
     }
     return APR_SUCCESS;
 }
-
-APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(cache, CACHE, int, create_entity,
-                                      (cache_handle_t *h, request_rec *r, 
const char *type,
-                                      const char *urlkey, apr_off_t len),
-                                      (h, r, type,urlkey,len),DECLINED)
-APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(cache, CACHE, int, open_entity,
-                                      (cache_handle_t *h, request_rec *r, 
const char *type,
-                                      const char *urlkey),(h,r,type,urlkey),
-                                      DECLINED)
-APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(cache, CACHE, int, remove_url,
-                                    (const char *type, const char *urlkey),
-                                    (type,urlkey),OK,DECLINED)
-
-
Index: modules/experimental/cache_util.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/experimental/cache_util.c,v
retrieving revision 1.32
diff -u -r1.32 cache_util.c
--- modules/experimental/cache_util.c	9 Feb 2004 20:29:18 -0000	1.32
+++ modules/experimental/cache_util.c	4 Aug 2004 05:01:09 -0000
@@ -17,7 +17,7 @@

 #include "mod_cache.h"

-
+#include <ap_provider.h>

 /* -------------------------------------------------------------- */

@@ -33,28 +33,46 @@
     return 0;
 }

-CACHE_DECLARE(const char *)ap_cache_get_cachetype(request_rec *r,
+CACHE_DECLARE(cache_provider_list *)ap_cache_get_providers(request_rec *r,
                                                   cache_server_conf *conf,
                                                   const char *url)
 {
-    const char *type = NULL;
+    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;
-        const char *thisurl = ent[i].url;
-        const char *thistype = ent[i].type;
-        if ((thisurl) && !strncasecmp(thisurl, url, strlen(thisurl))) {
-            if (!type) {
-                type = thistype;
+        if ((ent[i].url) && !strncasecmp(url, ent[i].url, ent[i].urllen)) {
+            /* 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 {
-                type = apr_pstrcat(r->pool, type, ",", thistype, NULL);
+                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;
+                }
             }
         }
     }
@@ -67,13 +85,13 @@
     for (i = 0; i < conf->cachedisable->nelts; i++) {
         struct cache_disable *ent =
                                (struct cache_disable 
*)conf->cachedisable->elts;
-        const char *thisurl = ent[i].url;
-        if ((thisurl) && !strncasecmp(thisurl, url, strlen(thisurl))) {
-            type = NULL;
+        if ((ent[i].url) && !strncasecmp(url, ent[i].url, ent[i].urllen)) {
+            /* Stop searching now. */
+            return NULL;
         }
     }

-    return type;
+    return providers;
 }


Index: modules/experimental/mod_cache.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/experimental/mod_cache.c,v
retrieving revision 1.87
diff -u -r1.87 mod_cache.c
--- modules/experimental/mod_cache.c	3 Aug 2004 08:20:21 -0000	1.87
+++ modules/experimental/mod_cache.c	4 Aug 2004 05:01:09 -0000
@@ -53,7 +53,7 @@
     char *url;
     apr_size_t urllen;
     char *path;
-    const char *types;
+    cache_provider_list *providers;
     cache_info *info;
     cache_request_rec *cache;
     cache_server_conf *conf;
@@ -75,7 +75,7 @@
     /*
      * Which cache module (if any) should handle this request?
      */
-    if (!(types = ap_cache_get_cachetype(r, conf, path))) {
+    if (!(providers = ap_cache_get_providers(r, conf, path))) {
         return DECLINED;
     }

@@ -87,8 +87,8 @@
         ap_set_module_config(r->request_config, &cache_module, cache);
     }

-    /* save away the type */
-    cache->types = types;
+    /* save away the possible providers */
+    cache->providers = providers;

     /*
      * Are we allowed to serve cached info at all?
@@ -119,9 +119,6 @@
     else {
         if (ap_cache_liststr(NULL, 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, 0, r->server,
                          "cache: no-cache or authorization forbids caching "
                          "of %s", url);
@@ -143,7 +140,7 @@
      *       add cache_conditional filter (which updates cache)
      */

-    rv = cache_select_url(r, cache->types, url);
+    rv = cache_select_url(r, url);
     if (rv != OK) {
         if (rv == DECLINED) {
             if (!lookup) {
@@ -156,7 +153,7 @@
             /* error */
             ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
                          "cache: error returned while checking for cached "
-                         "file by %s cache", cache->type);
+                         "file by %s cache", cache->provider_name);
         }
         return DECLINED;
     }
@@ -227,7 +224,7 @@
         ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
                      "cache: error returned while trying to return %s "
                      "cached data",
-                     cache->type);
+                     cache->provider_name);
         return rv;
     }

@@ -260,8 +257,8 @@
     ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server,
                  "cache: running CACHE_OUT filter");

-    /* cache_recall_entity_headers() was called in cache_select_url() */
-    cache_recall_entity_body(cache->handle, r->pool, bb);
+    /* recall_body() was called in cache_select_url() */
+    cache->provider->recall_body(cache->handle, r->pool, bb);

     /* This filter is done once it has served up its content */
     ap_remove_output_filter(f);
@@ -369,7 +366,7 @@
         /* pass the brigades into the cache, then pass them
          * up the filter stack
          */
-        rv = cache_store_entity_body(cache->handle, r, in);
+        rv = cache->provider->store_body(cache->handle, r, in);
         if (rv != APR_SUCCESS) {
             ap_remove_output_filter(f);
         }
@@ -513,7 +510,7 @@
          * BillS Asks.. Why do we need to make this call to remove_url?
          * leave it in for now..
          */
-        cache_remove_url(r, cache->types, url);
+        cache_remove_url(r, url);

         /* remove this filter from the chain */
         ap_remove_output_filter(f);
@@ -580,7 +577,7 @@
      */
     /* no cache handle, create a new entity */
     if (!cache->handle) {
-        rv = cache_create_entity(r, cache->types, url, size);
+        rv = cache_create_entity(r, url, size);
     }
     /* pre-existing cache handle and 304, make entity fresh */
     else if (r->status == HTTP_NOT_MODIFIED) {
@@ -597,8 +594,8 @@
      * with this one
      */
     else {
-        cache_remove_entity(r, cache->types, cache->handle);
-        rv = cache_create_entity(r, cache->types, url, size);
+        cache->provider->remove_entity(cache->handle);
+        rv = cache_create_entity(r, url, size);
     }

     if (rv != OK) {
@@ -708,9 +705,9 @@
     /*
      * Write away header information to cache.
      */
-    rv = cache_store_entity_headers(cache->handle, r, info);
+    rv = cache->provider->store_headers(cache->handle, r, info);
     if (rv == APR_SUCCESS) {
-        rv = cache_store_entity_body(cache->handle, r, in);
+        rv = cache->provider->store_body(cache->handle, r, in);
     }
     if (rv != APR_SUCCESS) {
         ap_remove_output_filter(f);
@@ -824,6 +821,7 @@
     new = apr_array_push(conf->cacheenable);
     new->type = type;
     new->url = url;
+    new->urllen = strlen(url);
     return NULL;
 }

@@ -838,6 +836,7 @@
                                                   &cache_module);
     new = apr_array_push(conf->cachedisable);
     new->url = url;
+    new->urllen = strlen(url);
     return NULL;
 }

Index: modules/experimental/mod_cache.h
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/experimental/mod_cache.h,v
retrieving revision 1.47
diff -u -r1.47 mod_cache.h
--- modules/experimental/mod_cache.h	3 Aug 2004 08:20:21 -0000	1.47
+++ modules/experimental/mod_cache.h	4 Aug 2004 05:01:09 -0000
@@ -107,10 +107,12 @@
 struct cache_enable {
     const char *url;
     const char *type;
+    apr_size_t urllen;
 };

 struct cache_disable {
     const char *url;
+    apr_size_t urllen;
 };

 /* static information about the local cache */
@@ -175,20 +177,41 @@
 };

 typedef struct cache_handle cache_handle_t;
-struct cache_handle {
-    cache_object_t *cache_obj;
+
+#define CACHE_PROVIDER_GROUP "cache"
+
+typedef struct {
     int (*remove_entity) (cache_handle_t *h);
     apr_status_t (*store_headers)(cache_handle_t *h, request_rec *r, 
cache_info *i);
     apr_status_t (*store_body)(cache_handle_t *h, request_rec *r, 
apr_bucket_brigade *b);
     apr_status_t (*recall_headers) (cache_handle_t *h, request_rec *r);
     apr_status_t (*recall_body) (cache_handle_t *h, apr_pool_t *p, 
apr_bucket_brigade *bb);
+    int (*create_entity) (cache_handle_t *h, request_rec *r,
+                           const char *urlkey, apr_off_t len);
+    int (*open_entity) (cache_handle_t *h, request_rec *r,
+                           const char *urlkey);
+    int (*remove_url) (const char *urlkey);
+} cache_provider;
+
+/* A linked-list of authn providers. */
+typedef struct cache_provider_list cache_provider_list;
+
+struct cache_provider_list {
+    const char *provider_name;
+    const cache_provider *provider;
+    cache_provider_list *next;
+};
+
+struct cache_handle {
+    cache_object_t *cache_obj;
     apr_table_t *req_hdrs;   /* These are the original request headers */
 };

 /* per request cache information */
 typedef struct {
-    const char *types;			/* the types of caches allowed */
-    const char *type;			/* the type of cache selected */
+    cache_provider_list *providers;         /* possible cache providers */
+    const cache_provider *provider;         /* current cache provider */
+    const char *provider_name;              /* current cache provider name */
     int fresh;				/* is the entitey fresh? */
     cache_handle_t *handle;		/* current cache handle */
     int in_checked;			/* CACHE_IN must cache the entity */
@@ -218,7 +241,7 @@
                                     int dirlength,
                                     const char *name);
 CACHE_DECLARE(int) ap_cache_request_is_conditional(request_rec *r);
-CACHE_DECLARE(const char *)ap_cache_get_cachetype(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, const char *url);
 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);
@@ -231,10 +254,9 @@
 /**
  * cache_storage.c
  */
-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_off_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);
+int cache_remove_url(request_rec *r, char *url);
+int cache_create_entity(request_rec *r, char *url, apr_off_t size);
+int cache_select_url(request_rec *r, 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
@@ -242,12 +264,13 @@
  */
 const char* cache_create_key( request_rec*r );

+/*
 apr_status_t cache_store_entity_headers(cache_handle_t *h, request_rec *r, 
cache_info *info);
 apr_status_t cache_store_entity_body(cache_handle_t *h, request_rec *r, 
apr_bucket_brigade *bb);

 apr_status_t cache_recall_entity_headers(cache_handle_t *h, request_rec *r);
 apr_status_t cache_recall_entity_body(cache_handle_t *h, apr_pool_t *p, 
apr_bucket_brigade *bb);
-
+*/

 /* hooks */

@@ -271,17 +294,6 @@
 #define CACHE_DECLARE_NONSTD(type)     __declspec(dllimport) type
 #define CACHE_DECLARE_DATA             __declspec(dllimport)
 #endif
-
-APR_DECLARE_EXTERNAL_HOOK(cache, CACHE, int, create_entity,
-                          (cache_handle_t *h, request_rec *r, const char 
*type,
-                           const char *urlkey, apr_off_t len))
-APR_DECLARE_EXTERNAL_HOOK(cache, CACHE, int, open_entity,
-                          (cache_handle_t *h, request_rec *r, const char 
*type,
-                           const char *urlkey))
-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,
Index: modules/experimental/mod_disk_cache.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/experimental/mod_disk_cache.c,v
retrieving revision 1.55
diff -u -r1.55 mod_disk_cache.c
--- modules/experimental/mod_disk_cache.c	3 Aug 2004 08:20:21 -0000	1.55
+++ modules/experimental/mod_disk_cache.c	4 Aug 2004 05:01:09 -0000
@@ -290,7 +290,6 @@
  */
 #define AP_TEMPFILE "/aptmpXXXXXX"
 static int create_entity(cache_handle_t *h, request_rec *r,
-                         const char *type,
                          const char *key,
                          apr_off_t len)
 {
@@ -301,10 +300,6 @@
     disk_cache_object_t *dobj;
     apr_file_t *tmpfile;

-    if (strcasecmp(type, "disk")) {
-        return DECLINED;
-    }
-
     if (conf->cache_root == NULL) {
         return DECLINED;
     }
@@ -337,11 +332,6 @@
     if (rv == APR_SUCCESS) {
         /* Populate the cache handle */
         h->cache_obj = obj;
-        h->recall_body = &recall_body;
-        h->recall_headers = &recall_headers;
-        h->store_body = &store_body;
-        h->store_headers = &store_headers;
-        h->remove_entity = &remove_entity;

         ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
                      "disk_cache: Caching URL %s",  key);
@@ -356,7 +346,7 @@
     return OK;
 }

-static int open_entity(cache_handle_t *h, request_rec *r, const char *type, 
const char *key)
+static int open_entity(cache_handle_t *h, request_rec *r, const char *key)
 {
     apr_status_t rc;
     static int error_logged = 0;
@@ -375,10 +365,6 @@
     h->cache_obj = NULL;

     /* Look up entity keyed to 'url' */
-    if (strcasecmp(type, "disk")) {
-        return DECLINED;
-    }
-
     if (conf->cache_root == NULL) {
         if (!error_logged) {
             error_logged = 1;
@@ -437,12 +423,6 @@
     }

     /* Initialize the cache_handle callback functions */
-    h->recall_body = &recall_body;
-    h->recall_headers = &recall_headers;
-    h->store_body = &store_body;
-    h->store_headers = &store_headers;
-    h->remove_entity = &remove_entity;
-
     ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
                  "disk_cache: Serving Cached URL %s",  dobj->name);
     return OK;
@@ -455,6 +435,12 @@
     return OK;
 }

+static int remove_url(const char *key)
+{
+    /* XXX: Delete file from cache! */
+    return OK;
+}
+
 /*
  * Reads headers from a buffer and returns an array of headers.
  * Returns NULL on file error
@@ -902,12 +888,23 @@
     {NULL}
 };

+static const cache_provider cache_disk_provider =
+{
+    &remove_entity,
+    &store_headers,
+    &store_body,
+    &recall_headers,
+    &recall_body,
+    &create_entity,
+    &open_entity,
+    &remove_url,
+};
+
 static void disk_cache_register_hook(apr_pool_t *p)
 {
     /* cache initializer */
-    cache_hook_create_entity(create_entity, NULL, NULL, APR_HOOK_MIDDLE);
-    cache_hook_open_entity(open_entity,  NULL, NULL, APR_HOOK_MIDDLE);
-/*    cache_hook_remove_entity(remove_entity, NULL, NULL, APR_HOOK_MIDDLE); */
+    ap_register_provider(p, CACHE_PROVIDER_GROUP, "disk", "0",
+                         &cache_disk_provider);
 }

 module AP_MODULE_DECLARE_DATA disk_cache_module = {
Index: modules/experimental/mod_mem_cache.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/experimental/mod_mem_cache.c,v
retrieving revision 1.111
diff -u -r1.111 mod_mem_cache.c
--- modules/experimental/mod_mem_cache.c	3 Aug 2004 08:20:21 -0000	1.111
+++ modules/experimental/mod_mem_cache.c	4 Aug 2004 05:01:09 -0000
@@ -349,26 +349,13 @@
     return sconf;
 }

-static int create_entity(cache_handle_t *h, request_rec *r,
-                         const char *type,
-                         const char *key,
-                         apr_off_t len)
+static int create_entity(cache_handle_t *h, cache_type_e type_e,
+                         request_rec *r, const char *key, apr_off_t len)
 {
     cache_object_t *obj, *tmp_obj;
     mem_cache_object_t *mobj;
-    cache_type_e type_e;
     apr_size_t key_len;

-    if (!strcasecmp(type, "mem")) {
-        type_e = CACHE_TYPE_HEAP;
-    }
-    else if (!strcasecmp(type, "fd")) {
-        type_e = CACHE_TYPE_FILE;
-    }
-    else {
-        return DECLINED;
-    }
-
     if (len == -1) {
         /* Caching a streaming response. Assume the response is
          * less than or equal to max_streaming_buffer_size. We will
@@ -471,23 +458,27 @@

     /* Populate the cache handle */
     h->cache_obj = obj;
-    h->recall_body = &recall_body;
-    h->recall_headers = &recall_headers;
-    h->store_body = &store_body;
-    h->store_headers = &store_headers;
-    h->remove_entity = &remove_entity;

     return OK;
 }

-static int open_entity(cache_handle_t *h, request_rec *r, const char *type, 
const char *key)
+static int create_mem_entity(cache_handle_t *h, request_rec *r,
+                             const char *key, apr_off_t len)
+{
+    return create_entity(h, CACHE_TYPE_HEAP, r, key, len);
+}
+
+static int create_fd_entity(cache_handle_t *h, request_rec *r,
+                            const char *key, apr_off_t len)
+{
+    return create_entity(h, CACHE_TYPE_FILE, r, key, len);
+}
+
+static int open_entity(cache_handle_t *h, request_rec *r, const char *key)
 {
     cache_object_t *obj;

     /* Look up entity keyed to 'url' */
-    if (strcasecmp(type, "mem") && strcasecmp(type, "fd")) {
-        return DECLINED;
-    }
     if (sconf->lock) {
         apr_thread_mutex_lock(sconf->lock);
     }
@@ -526,11 +517,6 @@
     }

     /* Initialize the cache_handle */
-    h->recall_body = &recall_body;
-    h->recall_headers = &recall_headers;
-    h->store_body = &store_body;
-    h->store_headers = &store_headers;
-    h->remove_entity = &remove_entity;
     h->cache_obj = obj;
     h->req_hdrs = NULL;  /* Pick these up in recall_headers() */
     return OK;
@@ -620,13 +606,10 @@
     return APR_SUCCESS;
 }
 /* Define request processing hook handlers */
-static int remove_url(const char *type, const char *key)
+static int remove_url(const char *key)
 {
     cache_object_t *obj;

-    if (strcasecmp(type, "mem") && strcasecmp(type, "fd")) {
-        return DECLINED;
-    }
     /* Order of the operations is important to avoid race conditions.
      * First, remove the object from the cache. Remember, all additions
      * deletions from the cache are protected by sconf->lock.
@@ -1128,14 +1111,44 @@
     {NULL}
 };

+static const cache_provider cache_mem_provider =
+{
+    &remove_entity,
+    &store_headers,
+    &store_body,
+    &recall_headers,
+    &recall_body,
+    &create_mem_entity,
+    &open_entity,
+    &remove_url,
+};
+
+static const cache_provider cache_fd_provider =
+{
+    &remove_entity,
+    &store_headers,
+    &store_body,
+    &recall_headers,
+    &recall_body,
+    &create_fd_entity,
+    &open_entity,
+    &remove_url,
+};
+
 static void register_hooks(apr_pool_t *p)
 {
     ap_hook_post_config(mem_cache_post_config, NULL, NULL, APR_HOOK_MIDDLE);
     /* cache initializer */
     /* cache_hook_init(cache_mem_init, NULL, NULL, APR_HOOK_MIDDLE);  */
+    /*
     cache_hook_create_entity(create_entity, NULL, NULL, APR_HOOK_MIDDLE);
     cache_hook_open_entity(open_entity,  NULL, NULL, APR_HOOK_MIDDLE);
     cache_hook_remove_url(remove_url, NULL, NULL, APR_HOOK_MIDDLE);
+    */
+    ap_register_provider(p, CACHE_PROVIDER_GROUP, "mem", "0",
+                         &cache_mem_provider);
+    ap_register_provider(p, CACHE_PROVIDER_GROUP, "fs", "0",
+                         &cache_fd_provider);
 }

 module AP_MODULE_DECLARE_DATA mem_cache_module =