]> granicus.if.org Git - apache/commitdiff
Support files for mod_disk_cache. Some tweaks to arguments on various hook
authorBill Stoddard <stoddard@apache.org>
Sun, 3 Feb 2002 06:24:55 +0000 (06:24 +0000)
committerBill Stoddard <stoddard@apache.org>
Sun, 3 Feb 2002 06:24:55 +0000 (06:24 +0000)
calls. Still lots of cleanup work to do here...

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93196 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 1c3605d347b7c90163ed42045394d0e6bde5af1e..94f93451468bbbc90f070fbaa2d627d4d4cde8db 100644 (file)
@@ -116,7 +116,7 @@ int cache_create_entity(request_rec *r, const char *types, char *url, apr_size_t
     key = cache_create_key(r);
     while (next) {
         type = ap_cache_tokstr(r->pool, next, &next);
-        switch (rv = cache_run_create_entity(h, type, key, size)) {
+        switch (rv = cache_run_create_entity(h, r, type, key, size)) {
         case OK: {
             cache->handle = h;
             return OK;
@@ -171,7 +171,7 @@ int cache_select_url(request_rec *r, const char *types, char *url)
 
     while (next) {
         type = ap_cache_tokstr(r->pool, next, &next);
-        switch ((rv = cache_run_open_entity(cache->handle, type, key))) {
+        switch ((rv = cache_run_open_entity(cache->handle, r->pool, type, key))) {
         case OK: {
             info = &(cache->handle->cache_obj->info);
             /* XXX:
@@ -209,10 +209,10 @@ apr_status_t cache_write_entity_headers(cache_handle_t *h,
     h->write_headers(h, r, info);
     return APR_SUCCESS;
 }
-apr_status_t cache_write_entity_body(cache_handle_t *h, apr_bucket_brigade *b) 
+apr_status_t cache_write_entity_body(cache_handle_t *h, request_rec *r, apr_bucket_brigade *b) 
 {
     apr_status_t rv = APR_SUCCESS;
-    if (h->write_body(h, b) != OK) {
+    if (h->write_body(h, r, b) != OK) {
     }
     return rv;
 }
@@ -229,9 +229,9 @@ apr_status_t cache_read_entity_headers(cache_handle_t *h, request_rec *r)
 
     return APR_SUCCESS;
 }
-apr_status_t cache_read_entity_body(cache_handle_t *h, apr_bucket_brigade *b) 
+apr_status_t cache_read_entity_body(cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *b) 
 {
-    h->read_body(h, b);
+    h->read_body(h, p, b);
     return APR_SUCCESS;
 }
 
@@ -240,13 +240,15 @@ 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, 
+                                      (cache_handle_t *h, request_rec *r, const char *type, 
                                       const char *urlkey, apr_size_t len),
-                                      (h,type,urlkey,len),DECLINED)
+                                      (h, r, type,urlkey,len),DECLINED)
 APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(cache, CACHE, int, open_entity,  
-                                      (cache_handle_t *h, const char *type, 
-                                      const char *urlkey),(h,type,urlkey),
+                                      (cache_handle_t *h, apr_pool_t *p, const char *type, 
+                                      const char *urlkey),(h,p,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 41186dd4ede78234330ad40b1055e8e254ca3712..69b53f09193167346b4746bd9d7a48670ccbd272 100644 (file)
@@ -209,3 +209,183 @@ const char *ap_cache_tokstr(apr_pool_t *p, const char *list, const char **str)
         return NULL;
 
 }
+
+/*
+ * XXX TODO:
+ * These functions were lifted from mod_proxy
+ * Consider putting them in APR or some other common accessable
+ * location.
+ */
+/*
+ * Converts apr_time_t hex digits to a time integer
+ */
+static apr_time_t ap_cache_hex2msec(const char *x)
+{
+    int i, ch;
+    apr_time_t j;
+    for (i = 0, j = 0; i < sizeof(j) * 2; i++) {
+        ch = x[i];
+        j <<= 4;
+        if (apr_isdigit(ch))
+            j |= ch - '0';
+        else if (apr_isupper(ch))
+            j |= ch - ('A' - 10);
+        else
+            j |= ch - ('a' - 10);
+    }
+    return j;
+}
+
+/*
+ * Converts a time integer to apr_time_t hex digits
+ */
+static void ap_cache_msec2hex(apr_time_t j, char *y)
+{
+    int i, ch;
+
+    for (i = (sizeof(j) * 2)-1; i >= 0; i--) {
+        ch = j & 0xF;
+        j >>= 4;
+        if (ch >= 10)
+            y[i] = ch + ('A' - 10);
+        else
+            y[i] = ch + '0';
+    }
+    y[sizeof(j) * 2] = '\0';
+}
+
+int mkdir_structure(char *file, const char *root)
+{
+    
+    /* XXX TODO: Use APR to make a root directory. Do some sanity checking... */
+    return 0;
+}
+
+cache_info * create_cache_el(apr_pool_t *p, cache_handle_t *h, const char *name)
+{
+    cache_info *info = apr_pcalloc(p, sizeof(cache_info));
+    memset(info, '\0', sizeof(cache_info));
+    info->name = (char *)name;
+    return info;
+}
+
+/* These two functions get and put state information into the data 
+ * file for an ap_cache_el, this state information will be read 
+ * and written transparent to clients of this module 
+ */
+int file_cache_read_mydata(apr_file_t *fd, cache_info *info, request_rec *r)
+{
+    apr_status_t rv;
+    char urlbuff[1034];
+    int urllen = sizeof(urlbuff);
+    int offset=0;
+    char * temp;
+
+    if(!info->hdrsfile) {
+       return APR_NOTFOUND;
+    }
+
+    /* read the data from the cache file */
+    /* format
+     * date SP expire SP count CRLF
+     * dates are stored as hex seconds since 1970
+     */
+    rv = apr_file_gets(&urlbuff[0], urllen, fd);
+    if (rv != APR_SUCCESS)
+    {
+       return rv;
+    }
+
+    if ((temp = strchr(&urlbuff[0], '\n')) != NULL) /* trim off new line character */
+       *temp = '\0';      /* overlay it with the null terminator */
+
+    if (!apr_date_checkmask(urlbuff, "&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&"))
+    {
+        return APR_EGENERAL;
+    }
+
+    info->date = ap_cache_hex2msec(urlbuff + offset);
+    offset += (sizeof(info->date)*2) + 1;
+    info->expire = ap_cache_hex2msec(urlbuff + offset);
+    offset += (sizeof(info->expire)*2) + 1;
+    info->version = ap_cache_hex2msec(urlbuff + offset);
+    
+    /* check that we have the same URL */
+    rv = apr_file_gets(&urlbuff[0], urllen, fd);
+    if (rv != APR_SUCCESS)
+    {
+       return rv;
+    }
+
+    if ((temp = strchr(&urlbuff[0], '\n')) != NULL) /* trim off new line character */
+       *temp = '\0';      /* overlay it with the null terminator */
+
+    if (strncmp(urlbuff, "X-NAME: ", 7) != 0)
+    {
+       return APR_EGENERAL;
+    }
+    if (strcmp(urlbuff + 8, info->name) != 0)
+    {
+        return APR_EGENERAL;
+    }
+    
+    return APR_SUCCESS;
+}
+
+static void cache_hash(const char *it, char *val, int ndepth, int nlength)
+{
+    apr_md5_ctx_t context;
+    unsigned char digest[16];
+    char tmp[22];
+    int i, k, d;
+    unsigned int x;
+    static const char enc_table[64] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_@";
+
+    apr_md5_init(&context);
+    apr_md5_update(&context, (const unsigned char *) it, strlen(it));
+    apr_md5_final(digest, &context);
+
+    /* encode 128 bits as 22 characters, using a modified uuencoding 
+     * the encoding is 3 bytes -> 4 characters* i.e. 128 bits is 
+     * 5 x 3 bytes + 1 byte -> 5 * 4 characters + 2 characters
+     */
+    for (i = 0, k = 0; i < 15; i += 3) {
+    x = (digest[i] << 16) | (digest[i + 1] << 8) | digest[i + 2];
+    tmp[k++] = enc_table[x >> 18];
+    tmp[k++] = enc_table[(x >> 12) & 0x3f];
+    tmp[k++] = enc_table[(x >> 6) & 0x3f];
+    tmp[k++] = enc_table[x & 0x3f];
+    }
+
+    /* one byte left */
+    x = digest[15];
+    tmp[k++] = enc_table[x >> 2];    /* use up 6 bits */
+    tmp[k++] = enc_table[(x << 4) & 0x3f];
+
+    /* now split into directory levels */
+    for (i = k = d = 0; d < ndepth; ++d) {
+        memcpy(&val[i], &tmp[k], nlength);
+        k += nlength;
+        val[i + nlength] = '/';
+        i += nlength + 1;
+    }
+    memcpy(&val[i], &tmp[k], 22 - k);
+    val[i + 22 - k] = '\0';
+}
+
+static char *generate_name(apr_pool_t *p, cache_handle_t *h, const char *name)
+{
+    char hashfile[66], *filebase;
+    cache_hash(name, hashfile, h->dirlevels, h->dirlength);
+    filebase = apr_pstrcat(p, h->root, "/", hashfile, "%s", NULL);
+    return filebase;
+}
+char *header_file(cache_handle_t *h, apr_pool_t *p, const char *name)
+{
+    return apr_psprintf(p, generate_name(p, h, name), CACHE_HEADER_SUFFIX);
+}
+char *data_file(cache_handle_t *h, apr_pool_t *p, const char *name)
+{
+    return apr_psprintf(p, generate_name(p, h, name), CACHE_DATA_SUFFIX);
+}
index 263f83650c65184e42aeba97212e8d47da58a95c..7dcf1ea5873c1ae90213d699c266771a7c761f22 100644 (file)
@@ -321,7 +321,7 @@ static int cache_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
      * that stored headers and the entity body in seperate files.
      */
     cache_read_entity_headers(cache->handle, r);    
-    cache_read_entity_body(cache->handle, bb);
+    cache_read_entity_body(cache->handle, r->pool, bb);
 
     /* This filter is done once it has served up its content */
     ap_remove_output_filter(f);
@@ -423,7 +423,7 @@ static int cache_in_filter(ap_filter_t *f, apr_bucket_brigade *in)
         /* pass the brigades into the cache, then pass them
          * up the filter stack
          */
-        cache_write_entity_body(cache->handle, in);
+        cache_write_entity_body(cache->handle, r, in);
         return ap_pass_brigade(f->next, in);
     }
 
@@ -706,7 +706,7 @@ static int cache_in_filter(ap_filter_t *f, apr_bucket_brigade *in)
      * Write away header information to cache.
      */
     cache_write_entity_headers(cache->handle, r, info);
-    cache_write_entity_body(cache->handle, in);    
+    cache_write_entity_body(cache->handle, r, in);    
     return ap_pass_brigade(f->next, in);
 }
 
index 5399651d7b7617f3ada27f5ef7af0e76a9003158..7aef4a6843b48bbee6ce5bb445439dff79d6ba7d 100644 (file)
 #define MIN(a,b)                ((a) < (b) ? (a) : (b))
 #endif
 
+/* Used by mod_disk_cache 
+ * XXX: Perhaps these should be moved to a mod_disk_cache header
+ * file? 
+ */
+#define CACHE_HEADER_SUFFIX ".header"
+#define CACHE_DATA_SUFFIX   ".data"
 
 /* default completion is 60% */
 #define DEFAULT_CACHE_COMPLETION (60)
@@ -167,6 +173,14 @@ struct cache_info {
     apr_time_t request_time;
     apr_time_t response_time;
     apr_size_t len;
+
+    /* Field used by mod_disk_cache */
+    char *datafile;          /* where the data will go */
+    char *hdrsfile;          /* where the hdrs will go */
+    char *name;
+    int version;             /* update count of the file */
+    apr_file_t *fd;          /* pointer to apr_file_t structure for the data file  */
+    apr_off_t file_size;    /*  File size of the cached data file  */    
 };
 
 /* cache handle information */
@@ -178,6 +192,10 @@ struct cache_object {
     void *vobj;         /* Opaque portion (specific to the cache implementation) of the cache object */
     apr_size_t count;   /* Number of body bytes written to the cache so far */
     int complete;
+    /* Used by mod_disk_cache: name of the temporary file, 
+     * used for cache element creation 
+     */
+    char *tempfile;
 };
 
 typedef struct cache_handle cache_handle_t;
@@ -185,9 +203,16 @@ 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);
-    int (*write_body)(cache_handle_t *h, apr_bucket_brigade *b);
+    int (*write_body)(cache_handle_t *h, request_rec *r, apr_bucket_brigade *b);
     int (*read_headers) (cache_handle_t *h, request_rec *r);
-    int (*read_body) (cache_handle_t *h, apr_bucket_brigade *bb); 
+    int (*read_body) (cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb); 
+
+    /* These fields were added for mod_disk_cache but just
+     * use unnecessary storage in mod_mem_cache.
+     */
+    const char *root;           /* the location of the cache directory */
+    int dirlevels;              /* Number of levels of subdirectories */
+    int dirlength;              /* Length of subdirectory names */   
 };
 
 /* per request cache information */
@@ -201,6 +226,13 @@ typedef struct {
 
 
 /* cache_util.c */
+cache_info *create_cache_el(apr_pool_t *p, cache_handle_t *h, const char *name); 
+char *data_file(cache_handle_t *h, apr_pool_t *p, const char *name);
+char *header_file(cache_handle_t *h, apr_pool_t *p, const char *name);
+int file_cache_read_mydata(apr_file_t *fd, cache_info *info, request_rec *r);
+apr_time_t ap_cache_hex2msec(const char *x);
+void ap_cache_msec2hex(apr_time_t j, char *y);
+
 int ap_cache_request_is_conditional(request_rec *r);
 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);
@@ -221,10 +253,10 @@ int cache_select_url(request_rec *r, const char *types, char *url);
 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_status_t cache_write_entity_body(cache_handle_t *h, apr_bucket_brigade *bb);
+apr_status_t cache_write_entity_body(cache_handle_t *h, request_rec *r, apr_bucket_brigade *bb);
 
 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);
+apr_status_t cache_read_entity_body(cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb);
 
 
 /* hooks */
@@ -251,10 +283,10 @@ apr_status_t cache_read_entity_body(cache_handle_t *h, apr_bucket_brigade *bb);
 #endif
 
 APR_DECLARE_EXTERNAL_HOOK(cache, CACHE, int, create_entity, 
-                          (cache_handle_t *h, const char *type,
+                          (cache_handle_t *h, request_rec *r, const char *type,
                            const char *urlkey, apr_size_t len))
 APR_DECLARE_EXTERNAL_HOOK(cache, CACHE, int, open_entity,  
-                          (cache_handle_t *h, const char *type,
+                          (cache_handle_t *h, apr_pool_t *p, const char *type,
                            const char *urlkey))
 APR_DECLARE_EXTERNAL_HOOK(cache, CACHE, int, remove_url, 
                           (const char *type, const char *urlkey))
index 161617167975ad4954669cfdb4f7db296cb6f940..a129df2d77a81178f7091019fef204876b000222 100644 (file)
@@ -118,9 +118,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);
-static int write_body(cache_handle_t *h, apr_bucket_brigade *b);
+static int write_body(cache_handle_t *h, request_rec *r, apr_bucket_brigade *b);
 static int read_headers(cache_handle_t *h, request_rec *r);
-static int read_body(cache_handle_t *h, apr_bucket_brigade *bb);
+static int read_body(cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb);
 
 static void cleanup_cache_object(cache_object_t *obj)
 {
@@ -222,7 +222,7 @@ static void *create_cache_config(apr_pool_t *p, server_rec *s)
     return sconf;
 }
 
-static int create_entity(cache_handle_t *h, 
+static int create_entity(cache_handle_t *h, request_rec *r,
                          const char *type, 
                          const char *key, 
                          apr_size_t len) 
@@ -311,7 +311,7 @@ static int create_entity(cache_handle_t *h,
     return OK;
 }
 
-static int open_entity(cache_handle_t *h, const char *type, const char *key) 
+static int open_entity(cache_handle_t *h, apr_pool_t *p, const char *type, const char *key) 
 {
     cache_object_t *obj;
 
@@ -486,7 +486,7 @@ static int read_headers(cache_handle_t *h, request_rec *r)
 
 }
 
-static int read_body(cache_handle_t *h, apr_bucket_brigade *bb) 
+static int read_body(cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb) 
 {
     apr_bucket *b;
     mem_cache_object_t *mobj = (mem_cache_object_t*) h->cache_obj->vobj;
@@ -557,7 +557,7 @@ static int write_headers(cache_handle_t *h, request_rec *r, cache_info *info)
     return OK;
 }
 
-static int write_body(cache_handle_t *h, apr_bucket_brigade *b) 
+static int write_body(cache_handle_t *h, request_rec *r, apr_bucket_brigade *b) 
 {
     apr_status_t rv;
     mem_cache_object_t *mobj = (mem_cache_object_t*) h->cache_obj->vobj;