]> granicus.if.org Git - apache/commitdiff
I haven't created the optional function to specify the cache_key yet,
authorIan Holsman <ianh@apache.org>
Fri, 25 Jan 2002 20:09:33 +0000 (20:09 +0000)
committerIan Holsman <ianh@apache.org>
Fri, 25 Jan 2002 20:09:33 +0000 (20:09 +0000)
That will come after this patch.

ok.. brief summary of whats changed

* new Optional Directives
* CacheMemEntrySize -- max size of a individual entry in memory
cache
* CacheIgnoreNoLastMod - so we can cache mod-included files

* it tries to figure out the size of the request based on buckets if the
content-length header isn't set

* mem_cache now caches the subprocess_env & notes tables
* the CACHE_IN/OUT/CONDITIONAL run at FTYPE_CONTENT+1, so that
all other content filters run BEFORE the cache in.

note: the code is still experimental, and we need a bit more work
mainly...
* garbage collection
* cache stats/reporting
* manual removal of a key.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93030 13f79535-47bb-0310-9956-ffa450edef68

modules/experimental/cache_storage.c
modules/experimental/cache_util.c
modules/experimental/mod_cache.c
modules/experimental/mod_cache.h
modules/experimental/mod_mem_cache.c

index 36e15462457202a98cd0daab36b64cb2c24ef60b..1c3605d347b7c90163ed42045394d0e6bde5af1e 100644 (file)
@@ -78,11 +78,14 @@ int cache_remove_url(request_rec *r, const char *types, char *url)
 {
     const char *next = types;
     const char *type;
+    const char *key;
+
+    key = cache_create_key(r);
 
     /* for each specified cache type, delete the URL */
     while(next) {
         type = ap_cache_tokstr(r->pool, next, &next);
-        cache_run_remove_url(type, url);
+        cache_run_remove_url(type, key);
     }
     return OK;
 }
@@ -104,14 +107,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;
     apr_status_t rv;
-    cache_request_rec *cache = (cache_request_rec *) ap_get_module_config(r->request_config, 
-                                                                          &cache_module);
+    cache_request_rec *cache = (cache_request_rec *) 
+                         ap_get_module_config(r->request_config, &cache_module);
 
     /* 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, type, url, size)) {
+        switch (rv = cache_run_create_entity(h, type, key, size)) {
         case OK: {
             cache->handle = h;
             return OK;
@@ -157,15 +162,16 @@ int cache_select_url(request_rec *r, const char *types, char *url)
     const char *type;
     apr_status_t rv;
     cache_info *info;
-    cache_request_rec *cache = (cache_request_rec *) ap_get_module_config(r->request_config, 
-                                                                          &cache_module);
-
+    const char *key;
+    cache_request_rec *cache = (cache_request_rec *) 
+                         ap_get_module_config(r->request_config, &cache_module);
+    key = cache_create_key(r);
     /* go through the cache types till we get a match */
     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(cache->handle, type, url))) {
+        switch ((rv = cache_run_open_entity(cache->handle, type, key))) {
         case OK: {
             info = &(cache->handle->cache_obj->info);
             /* XXX:
@@ -196,10 +202,11 @@ int cache_select_url(request_rec *r, const char *types, char *url)
     return DECLINED;
 }
 
-apr_status_t cache_write_entity_headers(cache_handle_t *h, request_rec *r, cache_info *info,
-                                        apr_table_t *headers)
+apr_status_t cache_write_entity_headers(cache_handle_t *h, 
+                                        request_rec *r, 
+                                        cache_info *info)
 {
-    h->write_headers(h, r, info, headers);
+    h->write_headers(h, r, info);
     return APR_SUCCESS;
 }
 apr_status_t cache_write_entity_body(cache_handle_t *h, apr_bucket_brigade *b) 
@@ -210,17 +217,15 @@ apr_status_t cache_write_entity_body(cache_handle_t *h, apr_bucket_brigade *b)
     return rv;
 }
 
-apr_status_t cache_read_entity_headers(cache_handle_t *h, request_rec *r, 
-                                       apr_table_t **headers)
+apr_status_t cache_read_entity_headers(cache_handle_t *h, request_rec *r)
 {
     cache_info *info = &(h->cache_obj->info);
 
     /* Build the header table from info in the info struct */
-    *headers = apr_table_make(r->pool, 15);
-
-    h->read_headers(h, r, *headers);
+    h->read_headers(h, r);
 
     r->content_type = apr_pstrdup(r->pool, info->content_type);
+    r->filename = apr_pstrdup(r->pool, info->filename );
 
     return APR_SUCCESS;
 }
@@ -230,37 +235,18 @@ apr_status_t cache_read_entity_body(cache_handle_t *h, apr_bucket_brigade *b)
     return APR_SUCCESS;
 }
 
+const char* cache_create_key( request_rec *r ) 
+{
+    return r->uri;
+}
 APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(cache, CACHE, int, create_entity, 
                                       (cache_handle_t *h, const char *type, 
-                                      char *url, apr_size_t len),(h,type,url,len),DECLINED)
+                                      const char *urlkey, apr_size_t len),
+                                      (h,type,urlkey,len),DECLINED)
 APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(cache, CACHE, int, open_entity,  
                                       (cache_handle_t *h, const char *type, 
-                                      char *url),(h,type,url),DECLINED)
+                                      const char *urlkey),(h,type,urlkey),
+                                      DECLINED)
 APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(cache, CACHE, int, remove_url, 
-                                    (const char *type, char *url),(type,url),OK,DECLINED)
-#if 0
-/* BillS doesn't think these should be hooks.
- * All functions which accept a cache_handle * argument should use
- * function pointers in the cache_handle. Leave them here for now as 
- * points for discussion...
- */
-
-APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(cache, CACHE, int, remove_entity, 
-                                     (cache_handle *h),(h),DECLINED)
-
-APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(cache, CACHE, int, read_entity_headers, 
-                                     (cache_handle *h, request_rec *r,
-                                      apr_table_t **headers),
-                                      (h,info,headers_in,headers_out),DECLINED)
-APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(cache, CACHE, int, read_entity_body, 
-                                     (cache_handle *h,
-                                      apr_bucket_brigade *out),(h,out),DECLINED)
-APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(cache, CACHE, int, write_entity_headers, 
-                                     (cache_handle *h, cache_info *info,
-                                      apr_table_t *headers_in, 
-                                      apr_table_t *headers_out),
-                                      (h,info,headers_in,headers_out),DECLINED)
-APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(cache, CACHE, int, write_entity_body, 
-                                     (cache_handle *h,
-                                      apr_bucket_brigade *in),(h,in),DECLINED)
-#endif
+                                    (const char *type, const char *urlkey),
+                                    (type,urlkey),OK,DECLINED)
index 48af63620b9ba0d880bbe1736bf6810afff21071..41186dd4ede78234330ad40b1055e8e254ca3712 100644 (file)
@@ -72,7 +72,7 @@ int ap_cache_request_is_conditional(request_rec *r)
         apr_table_get(r->headers_in, "If-Modified-Since") ||
         apr_table_get(r->headers_in, "If-Unmodified-Since")) {
 
-       return 1;
+        return 1;
     }
     return 0;
 }
@@ -97,33 +97,37 @@ void ap_cache_reset_output_filters(request_rec *r)
     }
 }
 
-const char *ap_cache_get_cachetype(request_rec *r, cache_server_conf *conf, const char *url)
+const char *ap_cache_get_cachetype(request_rec *r, 
+                                   cache_server_conf *conf, 
+                                   const char *url)
 {
     const char *type = 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;
-       const char *thisurl = ent[i].url;
-       const char *thistype = ent[i].type;
-       if ((thisurl) && !strncasecmp(thisurl, url, strlen(thisurl))) {
-           if (!type) {
-               type = thistype;
-           }
-           else {
-               type = apr_pstrcat(r->pool, type, ",", thistype, NULL);
-           }
-       }
+        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;
+            }
+            else {
+                type = apr_pstrcat(r->pool, type, ",", thistype, NULL);
+            }
+        }
     }
 
     /* then loop through all the cachedisable entries */
     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;
-       }
+        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;
+        }
     }
 
     return type;
@@ -145,35 +149,35 @@ int ap_cache_liststr(const char *list, const char *key, char **val)
     len = strlen(key);
 
     while (list != NULL) {
-       p = strchr((char *) list, ',');
-       if (p != NULL) {
-           i = p - list;
-           do
-               p++;
-           while (ap_isspace(*p));
-       }
-       else
-           i = strlen(list);
-
-       while (i > 0 && ap_isspace(list[i - 1]))
-           i--;
-       if (i == len && strncasecmp(list, key, len) == 0) {
-           if (val) {
-               p = strchr((char *) list, ',');
-               while (ap_isspace(*list)) {
-                   list++;
-               }
-               if ('=' == list[0])
-                   list++;
-               while (ap_isspace(*list)) {
-                   list++;
-               }
-               strncpy(valbuf, list, MIN(p-list, sizeof(valbuf)-1));
-               *val = valbuf;
-           }
-           return 1;
-       }
-       list = p;
+        p = strchr((char *) list, ',');
+        if (p != NULL) {
+            i = p - list;
+            do
+            p++;
+            while (ap_isspace(*p));
+        }
+        else
+            i = strlen(list);
+
+        while (i > 0 && ap_isspace(list[i - 1]))
+            i--;
+        if (i == len && strncasecmp(list, key, len) == 0) {
+            if (val) {
+            p = strchr((char *) list, ',');
+            while (ap_isspace(*list)) {
+                list++;
+            }
+            if ('=' == list[0])
+                list++;
+            while (ap_isspace(*list)) {
+                list++;
+            }
+            strncpy(valbuf, list, MIN(p-list, sizeof(valbuf)-1));
+            *val = valbuf;
+            }
+            return 1;
+        }
+        list = p;
     }
     return 0;
 }
@@ -186,21 +190,22 @@ const char *ap_cache_tokstr(apr_pool_t *p, const char *list, const char **str)
 
     s = ap_strchr_c(list, ',');
     if (s != NULL) {
-       i = s - list;
-       do
-           s++;
-       while (apr_isspace(*s));
+        i = s - list;
+        do
+            s++;
+        while (apr_isspace(*s))
+            ; /* noop */
     }
     else
-       i = strlen(list);
+        i = strlen(list);
 
     while (i > 0 && apr_isspace(list[i - 1]))
-       i--;
+        i--;
 
     *str = s;
     if (i)
-       return apr_pstrndup(p, list, i);
+        return apr_pstrndup(p, list, i);
     else
-       return NULL;
+        return NULL;
 
 }
index aa30a3b7d247aca4cc2e00abf488eef5df13685d..80979d54a88dfa48b6ef5bf0e38cbea5c70f40fa 100644 (file)
@@ -83,8 +83,6 @@ module AP_MODULE_DECLARE_DATA cache_module;
  *     oh well.
  */
 
-int ap_url_cache_handler(request_rec *r);
-
 int ap_url_cache_handler(request_rec *r)
 {
     apr_status_t rv;
@@ -95,8 +93,9 @@ int ap_url_cache_handler(request_rec *r)
     const char *types;
     cache_info *info = NULL;
     cache_request_rec *cache;
-    cache_server_conf *conf = (cache_server_conf *) ap_get_module_config(r->server->module_config, 
-                                                                         &cache_module);
+    cache_server_conf *conf = 
+        (cache_server_conf *) ap_get_module_config(r->server->module_config, 
+                                                   &cache_module);
 
     /* we don't handle anything but GET */
     if (r->method_number != M_GET) return DECLINED;
@@ -111,7 +110,8 @@ int ap_url_cache_handler(request_rec *r)
                  "cache: URL %s is being handled by %s", path, types);
 
     /* make space for the per request config */
-    cache = (cache_request_rec *) ap_get_module_config(r->request_config, &cache_module);
+    cache = (cache_request_rec *) ap_get_module_config(r->request_config, 
+                                                       &cache_module);
     if (!cache) {
         cache = ap_pcalloc(r->pool, sizeof(cache_request_rec));
         ap_set_module_config(r->request_config, &cache_module, cache);
@@ -182,7 +182,8 @@ int ap_url_cache_handler(request_rec *r)
 
             /* fresh data available */
             ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server,
-                         "cache: fresh cache - add cache_out filter and handle request");
+                         "cache: fresh cache - add cache_out filter and "
+                         "handle request");
 
             /* We are in the quick handler hook, which means that no output
              * filters have been set. So lets run the insert_filter hook.
@@ -203,7 +204,9 @@ int ap_url_cache_handler(request_rec *r)
             out = apr_brigade_create(r->pool);
             if (APR_SUCCESS != (rv = ap_pass_brigade(r->output_filters, out))) {
                 ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
-                             "cache: error returned while trying to return %s cached data", cache->type);
+                             "cache: error returned while trying to return %s "
+                             "cached data", 
+                             cache->type);
                 return rv;
             }
             return OK;
@@ -214,8 +217,10 @@ int ap_url_cache_handler(request_rec *r)
                          "cache: stale cache - test conditional");
             /* if conditional request */
             if (ap_cache_request_is_conditional(r)) {
-                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server,
-                             "cache: conditional - add cache_in filter and DECLINE");
+                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, 
+                             r->server,
+                             "cache: conditional - add cache_in filter and "
+                             "DECLINE");
                 /* add cache_in filter */
                 ap_add_output_filter("CACHE_IN", NULL, r, r->connection);
                 /* return DECLINED */
@@ -225,30 +230,43 @@ int ap_url_cache_handler(request_rec *r)
             else {
                 /* fudge response into a conditional */
                 if (info && info->etag) {
-                    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server,
-                                 "cache: nonconditional - fudge conditional by etag");
+                    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, 
+                                 r->server,
+                                 "cache: nonconditional - fudge conditional "
+                                 "by etag");
                     /* if we have a cached etag */
                     apr_table_set(r->headers_in, "If-None-Match", info->etag);
                 }
                 else if (info && info->lastmods) {
-                    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server,
-                                 "cache: nonconditional - fudge conditional by lastmod");
+                    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, 
+                                 r->server,
+                                 "cache: nonconditional - fudge conditional "
+                                 "by lastmod");
                     /* if we have a cached IMS */
-                    apr_table_set(r->headers_in, "If-Modified-Since", info->lastmods);
+                    apr_table_set(r->headers_in, 
+                                  "If-Modified-Since", 
+                                  info->lastmods);
                 }
                 else {
                     /* something else - pretend there was no cache */
-                    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server,
-                                 "cache: nonconditional - no cached etag/lastmods - add cache_in and DECLINE");
+                    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, 
+                                 r->server,
+                                 "cache: nonconditional - no cached "
+                                 "etag/lastmods - add cache_in and DECLINE");
                     /* add cache_in filter to cache this request */
                     ap_add_output_filter("CACHE_IN", NULL, r, r->connection);
                     /* return DECLINED */
                     return DECLINED;
                 }
                 /* add cache_conditional filter */
-                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server,
-                             "cache: nonconditional - add cache_conditional and DECLINE");
-                ap_add_output_filter("CACHE_CONDITIONAL", NULL, r, r->connection);
+                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, 
+                             r->server,
+                             "cache: nonconditional - add cache_conditional and"
+                             " DECLINE");
+                ap_add_output_filter("CACHE_CONDITIONAL", 
+                                     NULL, 
+                                     r, 
+                                     r->connection);
                 /* return DECLINED */
                 return DECLINED;
             }
@@ -256,8 +274,11 @@ int ap_url_cache_handler(request_rec *r)
     }
     else {
         /* error */
-        ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
-                     "cache: error returned while checking for cached file by %s cache", cache->type);
+        ap_log_error(APLOG_MARK, APLOG_ERR, rv, 
+                     r->server,
+                     "cache: error returned while checking for cached file by "
+                     "%s cache", 
+                     cache->type);
         return DECLINED;
     }
 }
@@ -268,14 +289,12 @@ int ap_url_cache_handler(request_rec *r)
  *
  * Deliver cached content (headers and body) up the stack.
  */
-int ap_cache_out_filter(ap_filter_t *f, apr_bucket_brigade *bb);
-
 int ap_cache_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
 {
     request_rec *r = f->r;
-    apr_table_t *headers;
-    cache_request_rec *cache = (cache_request_rec *) ap_get_module_config(r->request_config, 
-                                                                          &cache_module);
+    cache_request_rec *cache = 
+        (cache_request_rec *) ap_get_module_config(r->request_config, 
+                                                   &cache_module);
 
     if (!cache) {
         /* user likely configured CACHE_OUT manually; they should use mod_cache
@@ -287,10 +306,9 @@ int ap_cache_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
     }
 
     ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server,
-                "cache: running CACHE_OUT filter");
+            "cache: running CACHE_OUT filter");
 
-    cache_read_entity_headers(cache->handle, r, &headers);
-    r->headers_out = headers;
+    cache_read_entity_headers(cache->handle, r);    
     cache_read_entity_body(cache->handle, bb);
 
     /* This filter is done once it has served up its content */
@@ -310,7 +328,6 @@ int ap_cache_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
  * Otherwise
  *   replace ourselves with cache_in filter
  */
-int ap_cache_conditional_filter(ap_filter_t *f, apr_bucket_brigade *in);
 
 int ap_cache_conditional_filter(ap_filter_t *f, apr_bucket_brigade *in)
 {
@@ -343,7 +360,6 @@ int ap_cache_conditional_filter(ap_filter_t *f, apr_bucket_brigade *in)
  *   pass the data to the next filter (the network)
  *
  */
-int ap_cache_in_filter(ap_filter_t *f, apr_bucket_brigade *in);
 
 int ap_cache_in_filter(ap_filter_t *f, apr_bucket_brigade *in)
 {
@@ -387,7 +403,9 @@ int ap_cache_in_filter(ap_filter_t *f, apr_bucket_brigade *in)
      * if the setup section (see below) is complete.
      */
 
-    /* have we already run the cachability check and set up the cached file handle? */
+    /* have we already run the cachability check and set up the cached file 
+     * handle? 
+     */
     if(cache->in_checked) {
         /* pass the brigades into the cache, then pass them
          * up the filter stack
@@ -447,7 +465,8 @@ int ap_cache_in_filter(ap_filter_t *f, apr_bucket_brigade *in)
      * telling us to serve the cached copy. */
     if ((r->status != HTTP_OK && r->status != HTTP_NON_AUTHORITATIVE && 
          r->status != HTTP_MULTIPLE_CHOICES && 
-         r->status != HTTP_MOVED_PERMANENTLY && r->status != HTTP_NOT_MODIFIED) ||
+         r->status != HTTP_MOVED_PERMANENTLY && 
+         r->status != HTTP_NOT_MODIFIED) ||
 
     /* if a broken Expires header is present, don't cache it */
         (exps != NULL && exp == APR_DATE_BAD) ||
@@ -456,8 +475,13 @@ int ap_cache_in_filter(ap_filter_t *f, apr_bucket_brigade *in)
      * this untouched to the user agent, it's not for us. */
         (r->status == HTTP_NOT_MODIFIED && (NULL == cache->handle)) ||
 
-    /* 200 OK response from HTTP/1.0 and up without a Last-Modified header/Etag */
-        (r->status == HTTP_OK && lastmods == NULL && etag == NULL) ||
+    /* 200 OK response from HTTP/1.0 and up without a Last-Modified header/Etag 
+     */
+    /* XXX mod-include clears last_modified/expires/etags - this is why we have
+     * a optional function for a key-gen ;-) 
+     */
+        (r->status == HTTP_OK && lastmods == NULL && etag == NULL 
+            && (conf->no_last_mod_ignore ==0)) ||
 
     /* HEAD requests */
         r->header_only ||
@@ -515,8 +539,29 @@ int ap_cache_in_filter(ap_filter_t *f, apr_bucket_brigade *in)
         if (cl) {
             size = atol(cl);
         }
-        else
-            size = -1;
+        else {
+
+            /* if we don't get the content-length, see if we have all the 
+             * buckets and use their length to calculate the size 
+             */
+            apr_bucket *e;
+            int all_buckets_here=0;
+            size=0;
+            APR_BRIGADE_FOREACH(e, in) {
+                if (APR_BUCKET_IS_EOS(e)) {
+                    all_buckets_here=1;
+                    break;
+                }
+                if (APR_BUCKET_IS_FLUSH(e)) {
+                    continue;
+                }
+                size += e->length;
+            }
+
+            if (!all_buckets_here) {
+                size = -1;
+            }
+        }
     }
 
     /* It's safe to cache the response.
@@ -579,10 +624,12 @@ int ap_cache_in_filter(ap_filter_t *f, apr_bucket_brigade *in)
         info->date = APR_DATE_BAD;
 
     now = apr_time_now();
-    if (info->date == APR_DATE_BAD) {  /* No, or bad date */
+    if (info->date == APR_DATE_BAD) {  /* No, or bad date */
         char *dates;
         /* no date header! */
-        /* add one; N.B. use the time _now_ rather than when we were checking the cache */
+        /* add one; N.B. use the time _now_ rather than when we were checking
+         * the cache 
+         */
         date = now;
         dates = apr_pcalloc(r->pool, MAX_STRING_LEN);
         apr_rfc822_date(dates, now);
@@ -605,11 +652,13 @@ int ap_cache_in_filter(ap_filter_t *f, apr_bucket_brigade *in)
     /* XXX FIXME we're referencing date on a path where we didn't set it */
     if (lastmod != APR_DATE_BAD && lastmod > date)
     {
-       /* if its in the future, then replace by date */
+        /* if its in the future, then replace by date */
         lastmod = date;
         lastmods = dates;
-        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server,
-                     "cache: Last modified is in the future, replacing with now");
+        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, 
+                     r->server,
+                     "cache: Last modified is in the future, "
+                     "replacing with now");
     }
     info->lastmod = lastmod;
 
@@ -638,11 +687,12 @@ int ap_cache_in_filter(ap_filter_t *f, apr_bucket_brigade *in)
     info->expire = exp;
 
     info->content_type = apr_pstrdup(r->pool, r->content_type);
+    info->filename = apr_pstrdup(r->pool, r->filename );
 
     /*
      * Write away header information to cache.
      */
-    cache_write_entity_headers(cache->handle, r, info, r->headers_out);
+    cache_write_entity_headers(cache->handle, r, info);
     cache_write_entity_body(cache->handle, in);    
     return ap_pass_brigade(f->next, in);
 }
@@ -673,6 +723,8 @@ static void * create_cache_config(apr_pool_t *p, server_rec *s)
     /* default percentage to force cache completion */
     ps->complete = DEFAULT_CACHE_COMPLETION;
     ps->complete_set = 0;
+    ps->no_last_mod_ignore_set = 0;
+    ps->no_last_mod_ignore = 0;
     return ps;
 }
 
@@ -683,11 +735,16 @@ static void * merge_cache_config(apr_pool_t *p, void *basev, void *overridesv)
     cache_server_conf *overrides = (cache_server_conf *) overridesv;
 
     /* 1 if the cache is enabled, 0 otherwise */
-    ps->cacheon = (overrides->cacheon_set == 0) ? base->cacheon : overrides->cacheon;
+    ps->cacheon = 
+        (overrides->cacheon_set == 0) ? base->cacheon : overrides->cacheon;
     /* array of URL prefixes for which caching is disabled */
-    ps->cachedisable = ap_append_arrays(p, base->cachedisable, overrides->cachedisable);
+    ps->cachedisable = ap_append_arrays(p, 
+                                        base->cachedisable, 
+                                        overrides->cachedisable);
     /* array of URL prefixes for which caching is enabled */
-    ps->cacheenable = ap_append_arrays(p, base->cacheenable, overrides->cacheenable);
+    ps->cacheenable = ap_append_arrays(p, 
+                                       base->cacheenable, 
+                                       overrides->cacheenable);
     /* maximum time to cache a document */
     ps->maxex = (overrides->maxex_set == 0) ? base->maxex : overrides->maxex;
     /* default time to cache a document */
@@ -695,15 +752,31 @@ static void * merge_cache_config(apr_pool_t *p, void *basev, void *overridesv)
     /* factor used to estimate Expires date from LastModified date */
     ps->factor = (overrides->factor_set == 0) ? base->factor : overrides->factor;
     /* default percentage to force cache completion */
-    ps->complete = (overrides->complete_set == 0) ? base->complete : overrides->complete;
+    ps->complete =
+        (overrides->complete_set == 0) ? base->complete : overrides->complete;
 
+    ps->no_last_mod_ignore =
+        (overrides->no_last_mod_ignore_set) ? 
+                    base->no_last_mod_ignore : 
+                    overrides->no_last_mod_ignore;
     return ps;
 }
+static const char
+*set_cache_ignore_no_last_mod( cmd_parms *parms, void *dummy, int flag)
+{
+    cache_server_conf *conf = ap_get_module_config(parms->server->module_config, 
+                                                   &cache_module);
 
+    conf->no_last_mod_ignore = 1;
+    conf->no_last_mod_ignore_set = 1;
+    return NULL;
+
+}
 static const char
 *set_cache_on(cmd_parms *parms, void *dummy, int flag)
 {
-    cache_server_conf *conf = ap_get_module_config(parms->server->module_config, &cache_module);
+    cache_server_conf *conf = ap_get_module_config(parms->server->module_config,
+                                                   &cache_module);
 
     conf->cacheon = 1;
     conf->cacheon_set = 1;
@@ -711,9 +784,13 @@ static const char
 }
 
 static const char
-*add_cache_enable(cmd_parms *parms, void *dummy, const char *type, const char *url)
+*add_cache_enable(cmd_parms *parms, 
+                  void *dummy, 
+                  const char *type, 
+                  const char *url)
 {
-    cache_server_conf *conf = ap_get_module_config(parms->server->module_config, &cache_module);
+    cache_server_conf *conf = ap_get_module_config(parms->server->module_config,
+                                                   &cache_module);
     struct cache_enable *new;
 
     new = apr_array_push(conf->cacheenable);
@@ -725,7 +802,8 @@ static const char
 static const char
 *add_cache_disable(cmd_parms *parms, void *dummy, const char *url)
 {
-    cache_server_conf *conf = ap_get_module_config(parms->server->module_config, &cache_module);
+    cache_server_conf *conf = ap_get_module_config(parms->server->module_config, 
+                                                   &cache_module);
     struct cache_enable *new;
 
     new = apr_array_push(conf->cachedisable);
@@ -736,7 +814,8 @@ static const char
 static const char
 *set_cache_maxex(cmd_parms *parms, void *dummy, const char *arg)
 {
-    cache_server_conf *conf = ap_get_module_config(parms->server->module_config, &cache_module);
+    cache_server_conf *conf = ap_get_module_config(parms->server->module_config,
+                                                   &cache_module);
     double val;
 
     if (sscanf(arg, "%lg", &val) != 1)
@@ -748,7 +827,8 @@ static const char
 static const char
 *set_cache_maxex_min(cmd_parms *parms, void *dummy, const char *arg)
 {
-    cache_server_conf *conf = ap_get_module_config(parms->server->module_config, &cache_module);
+    cache_server_conf *conf = ap_get_module_config(parms->server->module_config,
+                                                   &cache_module);
     long val;
 
     val = atol(arg);
@@ -761,7 +841,8 @@ static const char
 static const char
 *set_cache_defex(cmd_parms *parms, void *dummy, const char *arg)
 {
-    cache_server_conf *conf = ap_get_module_config(parms->server->module_config, &cache_module);
+    cache_server_conf *conf = ap_get_module_config(parms->server->module_config, 
+                                                   &cache_module);
     double val;
 
     if (sscanf(arg, "%lg", &val) != 1)
@@ -773,7 +854,8 @@ static const char
 static const char
 *set_cache_defex_min(cmd_parms *parms, void *dummy, const char *arg)
 {
-    cache_server_conf *conf = ap_get_module_config(parms->server->module_config, &cache_module);
+    cache_server_conf *conf = ap_get_module_config(parms->server->module_config, 
+                                                   &cache_module);
     long val;
 
     val = atol(arg);
@@ -786,7 +868,8 @@ static const char
 static const char
 *set_cache_factor(cmd_parms *parms, void *dummy, const char *arg)
 {
-    cache_server_conf *conf = ap_get_module_config(parms->server->module_config, &cache_module);
+    cache_server_conf *conf = ap_get_module_config(parms->server->module_config, 
+                                                   &cache_module);
     double val;
 
     if (sscanf(arg, "%lg", &val) != 1)
@@ -799,7 +882,8 @@ static const char
 static const char
 *set_cache_complete(cmd_parms *parms, void *dummy, const char *arg)
 {
-    cache_server_conf *conf = ap_get_module_config(parms->server->module_config, &cache_module);
+    cache_server_conf *conf = ap_get_module_config(parms->server->module_config, 
+                                                   &cache_module);
     int val;
 
     if (sscanf(arg, "%u", &val) != 1)
@@ -835,6 +919,9 @@ static const command_rec cache_cmds[] =
      "The default time in hours to cache a document"),
      AP_INIT_TAKE1("CacheDefaultExpireMin", set_cache_defex_min, NULL, RSRC_CONF,
      "The default time in Minutes to cache a document"),
+     AP_INIT_TAKE1("CacheIgnoreNoLastMod", set_cache_ignore_no_last_mod, NULL, 
+             RSRC_CONF, 
+             "Ignore Responses where there is no Last Modified Header"),
 
     AP_INIT_TAKE1("CacheLastModifiedFactor", set_cache_factor, NULL, RSRC_CONF,
      "The factor used to estimate Expires date from LastModified date"),
@@ -853,19 +940,26 @@ register_hooks(apr_pool_t *p)
      * XXX The cache filters need to run right after the handlers and before
      * any other filters. Consider creating AP_FTYPE_CACHE for this purpose.
      * Make them AP_FTYPE_CONTENT for now.
+     * XXX ianhH:they should run AFTER all the other content filters.
      */
-    ap_register_output_filter("CACHE_IN", ap_cache_in_filter, AP_FTYPE_CONTENT);
-    ap_register_output_filter("CACHE_OUT", ap_cache_out_filter, AP_FTYPE_CONTENT);
-    ap_register_output_filter("CACHE_CONDITIONAL", ap_cache_conditional_filter, AP_FTYPE_CONTENT);
+    ap_register_output_filter("CACHE_IN", 
+                              ap_cache_in_filter, 
+                              AP_FTYPE_CONTENT+1);
+    ap_register_output_filter("CACHE_OUT", 
+                              ap_cache_out_filter, 
+                              AP_FTYPE_CONTENT+1);
+    ap_register_output_filter("CACHE_CONDITIONAL", 
+                              ap_cache_conditional_filter, 
+                              AP_FTYPE_CONTENT+1);
 }
 
 module AP_MODULE_DECLARE_DATA cache_module =
 {
     STANDARD20_MODULE_STUFF,
-    NULL,                      /* create per-directory config structure */
-    NULL,                      /* merge per-directory config structures */
-    create_cache_config,       /* create per-server config structure */
-    merge_cache_config,                /* merge per-server config structures */
-    cache_cmds,                        /* command apr_table_t */
+    NULL,                   /* create per-directory config structure */
+    NULL,                   /* merge per-directory config structures */
+    create_cache_config,    /* create per-server config structure */
+    merge_cache_config,     /* merge per-server config structures */
+    cache_cmds,             /* command apr_table_t */
     register_hooks
 };
index 1afa94a061973b2a4929112b41bcb8da8544995b..d9d2979c409f97cbfad8dd56db68bad9fd23d10b 100644 (file)
@@ -142,12 +142,15 @@ typedef struct {
     apr_array_header_t *cachedisable;  /* URLs not to cache */
     apr_time_t maxex;                  /* Maximum time to keep cached files in msecs */
     int maxex_set;
-    apr_time_t defex;                  /* default time to keep cached file in msecs */
+    apr_time_t defex;           /* default time to keep cached file in msecs */
     int defex_set;
-    double factor;                     /* factor for estimating expires date */
+    double factor;              /* factor for estimating expires date */
     int factor_set;
-    int complete;                      /* Force cache completion after this point */
+    int complete;               /* Force cache completion after this point */
     int complete_set;
+    /* ignore the last-modified header when deciding to cache this request */
+    int no_last_mod_ignore_set;
+    int no_last_mod_ignore; 
 } cache_server_conf;
 
 /* cache info information */
@@ -155,7 +158,8 @@ typedef struct cache_info cache_info;
 struct cache_info {
     const char *content_type;
     const char *etag;
-    const char *lastmods;      /* last modified of cache entity */
+    const char *lastmods;     /* last modified of cache entity */
+    const char *filename;   
     apr_time_t date;
     apr_time_t lastmod;
     char lastmod_str[APR_RFC822_DATE_LEN];
@@ -180,9 +184,9 @@ typedef struct cache_handle cache_handle_t;
 struct cache_handle {
     cache_object_t *cache_obj;
     int (*remove_entity) (cache_handle_t *h);
-    int (*write_headers)(cache_handle_t *h, request_rec *r, cache_info *i, apr_table_t *headers);
+    int (*write_headers)(cache_handle_t *h, request_rec *r, cache_info *i);
     int (*write_body)(cache_handle_t *h, apr_bucket_brigade *b);
-    int (*read_headers) (cache_handle_t *h, request_rec *r, apr_table_t *headers);
+    int (*read_headers) (cache_handle_t *h, request_rec *r);
     int (*read_body) (cache_handle_t *h, apr_bucket_brigade *bb); 
 };
 
@@ -210,12 +214,16 @@ 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);
+/**
+ * create a key for the cache based on the request record
+ * this is the 'default' version, which can be overridden by a default function
+ */
+const char* cache_create_key( request_rec*r );
 
-apr_status_t cache_write_entity_headers(cache_handle_t *h, request_rec *r, cache_info *info, 
-                                        apr_table_t *headers);
+apr_status_t cache_write_entity_headers(cache_handle_t *h, request_rec *r, cache_info *info);
 apr_status_t cache_write_entity_body(cache_handle_t *h, apr_bucket_brigade *bb);
 
-apr_status_t cache_read_entity_headers(cache_handle_t *h, request_rec *r, apr_table_t **headers);
+apr_status_t cache_read_entity_headers(cache_handle_t *h, request_rec *r);
 apr_status_t cache_read_entity_body(cache_handle_t *h, apr_bucket_brigade *bb);
 
 
@@ -244,28 +252,11 @@ apr_status_t cache_read_entity_body(cache_handle_t *h, apr_bucket_brigade *bb);
 
 APR_DECLARE_EXTERNAL_HOOK(cache, CACHE, int, create_entity, 
                           (cache_handle_t *h, const char *type,
-                           char *url, apr_size_t len))
+                           const char *urlkey, apr_size_t len))
 APR_DECLARE_EXTERNAL_HOOK(cache, CACHE, int, open_entity,  
                           (cache_handle_t *h, const char *type,
-                           char *url))
+                           const char *urlkey))
 APR_DECLARE_EXTERNAL_HOOK(cache, CACHE, int, remove_url, 
-                          (const char *type, char *url))
-
-#if 0
-APR_DECLARE_EXTERNAL_HOOK(cache, CACHE, int, remove_entity, 
-                          (cache_handle *h))
-APR_DECLARE_EXTERNAL_HOOK(cache, CACHE, int, read_entity_headers, 
-                          (cache_handle *h, cache_info **info,
-                           apr_table_t **headers))
-APR_DECLARE_EXTERNAL_HOOK(cache, CACHE, int, read_entity_body, 
-                          (cache_handle *h,
-                           apr_bucket_brigade *out))
-APR_DECLARE_EXTERNAL_HOOK(cache, CACHE, int, write_entity_headers, 
-                          (cache_handle *h, cache_info *info,
-                           apr_table_t *headers))
-APR_DECLARE_EXTERNAL_HOOK(cache, CACHE, int, write_entity_body, 
-                          (cache_handle *h,
-                           apr_bucket_brigade *in))
-#endif
+                          (const char *type, const char *urlkey))
 
 #endif /*MOD_CACHE_H*/
index 9b5cf5fe5c9c2b6f520e631454a8c80e20795258..934e22c696685d79915f115d28d908cf747282d3 100644 (file)
@@ -66,7 +66,7 @@
 #error This module does not currently compile unless you have a thread-capable APR. Sorry!
 #endif
 
-#define MAX_CACHE 5000
+static apr_size_t max_cache_entry_size = 5000;
 module AP_MODULE_DECLARE_DATA mem_cache_module;
 
 /* 
@@ -93,8 +93,12 @@ typedef struct {
 
 typedef struct mem_cache_object {
     cache_type_e type;
-    apr_ssize_t num_headers;
-    cache_header_tbl_t *tbl;
+    apr_ssize_t num_header_out;
+    apr_ssize_t num_subprocess_env;
+    apr_ssize_t num_notes;
+    cache_header_tbl_t *header_out;
+    cache_header_tbl_t *subprocess_env;
+    cache_header_tbl_t *notes;
     apr_size_t m_len;
     void *m;
 } mem_cache_object_t;
@@ -113,10 +117,9 @@ static mem_cache_conf *sconf;
 
 /* Forward declarations */
 static int remove_entity(cache_handle_t *h);
-static int write_headers(cache_handle_t *h, request_rec *r, cache_info *i,
-                         apr_table_t *headers);
+static int write_headers(cache_handle_t *h, request_rec *r, cache_info *i);
 static int write_body(cache_handle_t *h, apr_bucket_brigade *b);
-static int read_headers(cache_handle_t *h, request_rec *r, apr_table_t *headers);
+static int read_headers(cache_handle_t *h, request_rec *r);
 static int read_body(cache_handle_t *h, apr_bucket_brigade *bb);
 
 static void cleanup_cache_object(cache_object_t *obj)
@@ -166,9 +169,18 @@ static void cleanup_cache_object(cache_object_t *obj)
     if (mobj->m) {
         free(mobj->m);
     }
-
+    /* XXX should freeing of the info be done here or in cache_storage ? 
+    if (obj->info.content_type ) {
+        free((char*)obj->info.content_type );
+        obj->info.content_type =NULL;
+    }
+    if (obj->info.filename ) {
+        free( (char*)obj->info.filename );
+        obj->info.filename= NULL;
+    }
+    */
     /* XXX Cleanup the headers */
-    if (mobj->num_headers) {
+    if (mobj->num_header_out) {
         
     }
     free(mobj);
@@ -199,10 +211,6 @@ static void *create_cache_config(apr_pool_t *p, server_rec *s)
 
     sconf = apr_pcalloc(p, sizeof(mem_cache_conf));
     sconf->space = DEFAULT_CACHE_SPACE;
-#if 0
-    sconf->maxexpire = DEFAULT_CACHE_MAXEXPIRE;
-    sconf->defaultexpire = DEFAULT_CACHE_EXPIRE;
-#endif
 
     ap_mpm_query(AP_MPMQ_IS_THREADED, &threaded_mpm);
     if (threaded_mpm) {
@@ -214,7 +222,10 @@ static void *create_cache_config(apr_pool_t *p, server_rec *s)
     return sconf;
 }
 
-static int create_entity(cache_handle_t *h, const char *type, char *key, apr_size_t len) 
+static int create_entity(cache_handle_t *h, 
+                         const char *type, 
+                         const char *key, 
+                         apr_size_t len) 
 {
     cache_object_t *obj, *tmp_obj;
     mem_cache_object_t *mobj;
@@ -226,7 +237,7 @@ static int create_entity(cache_handle_t *h, const char *type, char *key, apr_siz
     /* XXX Check len to see if it is withing acceptable bounds 
      * max cache check should be configurable variable.
      */
-    if (len < 0 || len > MAX_CACHE) {
+    if (len < 0 || len > max_cache_entry_size) {
         return DECLINED;
     }
     /* XXX Check total cache size and number of entries. Are they within the
@@ -256,7 +267,9 @@ static int create_entity(cache_handle_t *h, const char *type, char *key, apr_siz
         cleanup_cache_object(obj);
     }
     memset(mobj,'\0', sizeof(*mobj));
-    obj->vobj = mobj;    /* Reference the mem_cache_object_t out of cache_object_t */
+    obj->vobj = mobj;    /* Reference the mem_cache_object_t out of 
+                          * cache_object_t 
+                          */
     mobj->m_len = len;    /* Duplicates info in cache_object_t info */
 
 
@@ -268,7 +281,9 @@ static int create_entity(cache_handle_t *h, const char *type, char *key, apr_siz
     if (sconf->lock) {
         apr_thread_mutex_lock(sconf->lock);
     }
-    tmp_obj = (cache_object_t *) apr_hash_get(sconf->cacheht, key, APR_HASH_KEY_STRING);
+    tmp_obj = (cache_object_t *) apr_hash_get(sconf->cacheht, 
+                                              key, 
+                                              APR_HASH_KEY_STRING);
     if (!tmp_obj) {
         apr_hash_set(sconf->cacheht, obj->key, strlen(obj->key), obj);
     }
@@ -296,7 +311,7 @@ static int create_entity(cache_handle_t *h, const char *type, char *key, apr_siz
     return OK;
 }
 
-static int open_entity(cache_handle_t *h, const char *type, char *key) 
+static int open_entity(cache_handle_t *h, const char *type, const char *key) 
 {
     cache_object_t *obj;
 
@@ -307,7 +322,9 @@ static int open_entity(cache_handle_t *h, const char *type, char *key)
     if (sconf->lock) {
         apr_thread_mutex_lock(sconf->lock);
     }
-    obj = (cache_object_t *) apr_hash_get(sconf->cacheht, key, APR_HASH_KEY_STRING);
+    obj = (cache_object_t *) apr_hash_get(sconf->cacheht, 
+                                          key, 
+                                          APR_HASH_KEY_STRING);
     if (sconf->lock) {
         apr_thread_mutex_unlock(sconf->lock);
     }
@@ -343,9 +360,69 @@ static int remove_entity(cache_handle_t *h)
     
     return OK;
 }
+static int serialize_table( cache_header_tbl_t **obj, 
+                            int*nelts, 
+                            apr_table_t *table) 
+{
+   apr_table_entry_t *elts = (apr_table_entry_t *) table->a.elts;
+   apr_ssize_t i;
+   apr_size_t len = 0;
+   apr_size_t idx = 0;
+   char *buf;
+   
+   *nelts = table->a.nelts;
+   if (*nelts ==0 ) {
+       *obj=NULL;
+       return OK;
+   }
+    *obj = malloc(sizeof(cache_header_tbl_t) * table->a.nelts);
+    if (NULL == *obj) {
+        /* cleanup_cache_obj(h->cache_obj); */
+        return DECLINED;
+    }
+    for (i = 0; i < table->a.nelts; ++i) {
+        len += strlen(elts[i].key);
+        len += strlen(elts[i].val);
+        len += 2;  /* Extra space for NULL string terminator for key and val */
+    }
+
+    /* Transfer the headers into a contiguous memory block */
+    buf = malloc(len);
+    if (!buf) {
+        free(obj);
+        *obj = NULL;
+        /* cleanup_cache_obj(h->cache_obj); */
+        return DECLINED;
+    }
+
+    for (i = 0; i < *nelts; ++i) {
+        (*obj)[i].hdr = &buf[idx];
+        len = strlen(elts[i].key) + 1;              /* Include NULL terminator */
+        strncpy(&buf[idx], elts[i].key, len);
+        idx+=len;
+
+        (*obj)[i].val = &buf[idx];
+        len = strlen(elts[i].val) + 1;
+        strncpy(&buf[idx], elts[i].val, len);
+        idx+=len;
+    }
+    return OK;
+}
+static int unserialize_table( cache_header_tbl_t *ctbl, 
+                              int num_headers, 
+                              apr_table_t *t )
+{
+    int i;
 
+    for (i = 0; i < num_headers; ++i) {
+        apr_table_setn(t, ctbl[i].hdr, ctbl[i].val);
+    } 
+
+    return OK;
+}
 /* Define request processing hook handlers */
-static int remove_url(const char *type, char *key) 
+static int remove_url(const char *type, const char *key) 
 {
     cache_object_t *obj;
 
@@ -363,7 +440,9 @@ static int remove_url(const char *type, char *key)
     if (sconf->lock) {
         apr_thread_mutex_lock(sconf->lock);
     }
-    obj = (cache_object_t *) apr_hash_get(sconf->cacheht, key, APR_HASH_KEY_STRING);
+    obj = (cache_object_t *) apr_hash_get(sconf->cacheht, 
+                                          key, 
+                                          APR_HASH_KEY_STRING);
     if (sconf->lock) {
         apr_thread_mutex_unlock(sconf->lock);
     }
@@ -386,16 +465,25 @@ static int remove_url(const char *type, char *key)
     return OK;
 }
 
-static int read_headers(cache_handle_t *h, request_rec *r, apr_table_t *headers
+static int read_headers(cache_handle_t *h, request_rec *r) 
 {
+    int rc;
     mem_cache_object_t *mobj = (mem_cache_object_t*) h->cache_obj->vobj;
-    int i;
 
-    for (i = 0; i < mobj->num_headers; ++i) {
-        apr_table_setn(headers, mobj->tbl[i].hdr, mobj->tbl[i].val);
-    } 
+    r->headers_out = apr_table_make(r->pool,mobj->num_header_out);
+    r->subprocess_env = apr_table_make(r->pool, mobj->num_subprocess_env);
+    r->notes = apr_table_make(r->pool, mobj->num_notes);
+    rc = unserialize_table( mobj->header_out,
+                            mobj->num_header_out, 
+                            r->headers_out);
+    rc = unserialize_table( mobj->subprocess_env, 
+                            mobj->num_subprocess_env, 
+                            r->subprocess_env);
+    rc = unserialize_table( mobj->notes,
+                            mobj->num_notes,
+                            r->notes);
+    return rc;
 
-    return OK;
 }
 
 static int read_body(cache_handle_t *h, apr_bucket_brigade *bb) 
@@ -411,49 +499,33 @@ static int read_body(cache_handle_t *h, apr_bucket_brigade *bb)
     return OK;
 }
 
-static int write_headers(cache_handle_t *h, request_rec *r, cache_info *info, apr_table_t *headers)
+
+static int write_headers(cache_handle_t *h, request_rec *r, cache_info *info)
 {
     cache_object_t *obj = h->cache_obj;
     mem_cache_object_t *mobj = (mem_cache_object_t*) h->cache_obj->vobj;
-    apr_table_entry_t *elts = (apr_table_entry_t *) headers->a.elts;
-    apr_ssize_t i;
-    apr_size_t len = 0;
-    apr_size_t idx = 0;
-    char *buf;
+    int rc;
 
     /* Precompute how much storage we need to hold the headers */
-    mobj->tbl = malloc(sizeof(cache_header_tbl_t) * headers->a.nelts);
-    if (NULL == mobj->tbl) {
-        /* cleanup_cache_obj(h->cache_obj); */
-        return DECLINED;
+    rc = serialize_table(&mobj->header_out, 
+                         &mobj->num_header_out, 
+                         r->headers_out);   
+    if (rc != OK ) {
+        return rc;
     }
-    for (i = 0; i < headers->a.nelts; ++i) {
-        len += strlen(elts[i].key);
-        len += strlen(elts[i].val);
-        len += 2;        /* Extra space for NULL string terminator for key and val */
+    rc = serialize_table(&mobj->subprocess_env,
+                         &mobj->num_subprocess_env, 
+                         r->subprocess_env );
+    if (rc != OK ) {
+        return rc;
     }
 
-    /* Transfer the headers into a contiguous memory block */
-    buf = malloc(len);
-    if (!buf) {
-        free(mobj->tbl);
-        mobj->tbl = NULL;
-        /* cleanup_cache_obj(h->cache_obj); */
-        return DECLINED;
-    }
-    mobj->num_headers = headers->a.nelts;
-    for (i = 0; i < mobj->num_headers; ++i) {
-        mobj->tbl[i].hdr = &buf[idx];
-        len = strlen(elts[i].key) + 1;              /* Include NULL terminator */
-        strncpy(&buf[idx], elts[i].key, len);
-        idx+=len;
-
-        mobj->tbl[i].val = &buf[idx];
-        len = strlen(elts[i].val) + 1;
-        strncpy(&buf[idx], elts[i].val, len);
-        idx+=len;
+    rc = serialize_table(&mobj->notes, &mobj->num_notes, r->notes);
+    if (rc != OK ) {
+        return rc;
     }
 
     /* Init the info struct */
     if (info->date) {
         obj->info.date = info->date;
@@ -472,6 +544,15 @@ static int write_headers(cache_handle_t *h, request_rec *r, cache_info *info, ap
         }
         strcpy((char*) obj->info.content_type, info->content_type);
     }
+    if ( info->filename) {
+        obj->info.filename = (char*) malloc(strlen(info->filename )+1);
+        if (!obj->info.filename ) {
+            free( (char*)obj->info.content_type );
+            obj->info.content_type =NULL;
+            return DECLINED;
+        }
+        strcpy((char*) obj->info.filename, info->filename );
+    }
 
     return OK;
 }
@@ -522,7 +603,6 @@ static int write_body(cache_handle_t *h, apr_bucket_brigade *b)
          */
         AP_DEBUG_ASSERT(h->cache_obj->count > mobj->m_len);
     }
-
     return OK;
 }
 
@@ -537,45 +617,19 @@ static const char
     sconf->space = val;
     return NULL;
 }
-#if 0
-static const char
-*set_cache_factor(cmd_parms *parms, void *dummy, char *arg)
+static const char 
+*set_cache_entry_size(cmd_parms *parms, void *in_struct_ptr, const char *arg)
 {
-    double val;
-
-    if (sscanf(arg, "%lg", &val) != 1)
-        return "CacheLastModifiedFactor value must be a float";
-    sconf->lmfactor = val;
+    int val;
 
+    if (sscanf(arg, "%d", &val) != 1) {
+        return "CacheSize value must be an integer (bytes)";
+    }
+    max_cache_entry_size = val;
     return NULL;
 }
-#endif
-#if 0
-static const char
-*set_cache_maxex(cmd_parms *parms, void *dummy, char *arg)
-{
-    mem_cache_conf *pc = ap_get_module_config(parms->server->module_config, &mem_cache_module);
-    double val;
 
-    if (sscanf(arg, "%lg", &val) != 1)
-        return "CacheMaxExpire value must be a float";
-    sconf->maxexpire = (apr_time_t) (val * MSEC_ONE_HR);
-    return NULL;
-}
-#endif
-#if 0
-static const char
-*set_cache_defex(cmd_parms *parms, void *dummy, char *arg)
-{
-    mem_cache_conf *pc = ap_get_module_config(parms->server->module_config, &mem_cache_module);
-    double val;
 
-    if (sscanf(arg, "%lg", &val) != 1)
-        return "CacheDefaultExpire value must be a float";
-    pc->defaultexpire = (apr_time_t) (val * MSEC_ONE_HR);
-    return NULL;
-}
-#endif
 static const command_rec cache_cmds[] =
 {
     /* XXX
@@ -585,8 +639,10 @@ static const command_rec cache_cmds[] =
      * max entry size, and max size of the cache should
      * be managed by this module. 
      */
-    AP_INIT_TAKE1("CacheSizeMem", set_cache_size, NULL, RSRC_CONF,
-     "The maximum disk space used by the cache in Kb"),
+    AP_INIT_TAKE1("CacheMemSize", set_cache_size, NULL, RSRC_CONF,
+     "The maximum space used by the cache in Kb"),
+    AP_INIT_TAKE1("CacheMemEntrySize", set_cache_entry_size, NULL, RSRC_CONF,
+     "The maximum size (in bytes) that a entry can take"),
     {NULL}
 };