httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ian Holsman <i...@apache.org>
Subject [PATCH] -- cache modules
Date Tue, 22 Jan 2002 23:26:20 GMT
Here are some changes to the caching module.
I thought I'd just mail them first to make sure everyone is happy.

I haven't created the optional function to specify the cache_key yet,
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.

..Ian


Index: cache_storage.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/experimental/cache_storage.c,v
retrieving revision 1.10
diff -u -r1.10 cache_storage.c
--- cache_storage.c	10 Jan 2002 09:11:32 -0000	1.10
+++ cache_storage.c	22 Jan 2002 23:15:09 -0000
@@ -78,11 +78,14 @@
  {
      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 @@
      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);

      /* 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 @@
      const char *type;
      apr_status_t rv;
      cache_info *info;
+    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,9 @@
      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 +215,15 @@
      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 +233,15 @@
      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: mod_cache.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/experimental/mod_cache.c,v
retrieving revision 1.18
diff -u -r1.18 mod_cache.c
--- mod_cache.c	4 Jan 2002 17:58:36 -0000	1.18
+++ mod_cache.c	22 Jan 2002 23:15:09 -0000
@@ -83,8 +83,6 @@
   *     oh well.
   */

-int ap_url_cache_handler(request_rec *r);
-
  int ap_url_cache_handler(request_rec *r)
  {
      apr_status_t rv;
@@ -268,12 +266,9 @@
   *
   * 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);

@@ -287,10 +282,9 @@
      }

      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 +304,6 @@
   * 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 +336,6 @@
   *   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)
  {
@@ -457,7 +449,10 @@
          (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) ||
+    /* 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 +510,29 @@
          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.
@@ -638,11 +654,12 @@
      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 +690,8 @@
      /* 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;
  }

@@ -697,9 +716,19 @@
      /* default percentage to force cache completion */
      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)
  {
@@ -835,6 +864,8 @@
       "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,10 +884,11 @@
       * 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 =
Index: mod_cache.h
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/experimental/mod_cache.h,v
retrieving revision 1.12
diff -u -r1.12 mod_cache.h
--- mod_cache.h	4 Jan 2002 17:58:36 -0000	1.12
+++ mod_cache.h	22 Jan 2002 23:15:09 -0000
@@ -142,12 +142,15 @@
      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 @@
  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 @@
  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_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_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: mod_mem_cache.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/experimental/mod_mem_cache.c,v
retrieving revision 1.12
diff -u -r1.12 mod_mem_cache.c
--- mod_mem_cache.c	4 Jan 2002 17:58:36 -0000	1.12
+++ mod_mem_cache.c	22 Jan 2002 23:15:09 -0000
@@ -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 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 @@

  /* 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 @@
      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 @@

      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,7 @@
      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 +234,7 @@
      /* 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
@@ -296,7 +304,7 @@
      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;

@@ -343,9 +351,65 @@

      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;

@@ -386,16 +450,19 @@
      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 +478,29 @@
      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;
-    }
-    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->header_out, &mobj->num_header_out, 
r->headers_out);
+    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;
+    rc = serialize_table(&mobj->subprocess_env 
,&mobj->num_subprocess_env, r->subprocess_env );
+    if (rc != OK ) {
+        return rc;
      }
-    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 +519,15 @@
          }
          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 +578,6 @@
           */
          AP_DEBUG_ASSERT(h->cache_obj->count > mobj->m_len);
      }
-
      return OK;
  }

@@ -537,45 +592,19 @@
      sconf->space = val;
      return NULL;
  }
-#if 0
-static const char
-*set_cache_factor(cmd_parms *parms, void *dummy, char *arg)
-{
-    double val;
-
-    if (sscanf(arg, "%lg", &val) != 1)
-        return "CacheLastModifiedFactor value must be a float";
-    sconf->lmfactor = val;
+static const char
+*set_cache_entry_size(cmd_parms *parms, void *in_struct_ptr, const char 
*arg)
+{
+    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 +614,10 @@
       * 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}
  };


Mime
View raw message