]> granicus.if.org Git - apache/commitdiff
First pass at a set of caching filters and handlers. This implements a
authorRyan Bloom <rbb@apache.org>
Fri, 17 Nov 2000 18:33:33 +0000 (18:33 +0000)
committerRyan Bloom <rbb@apache.org>
Fri, 17 Nov 2000 18:33:33 +0000 (18:33 +0000)
working disk cache.  There are a lot of improvements to be made to this,
but this is a pretty good start to a dynamic cache.

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

modules/experimental/config.m4
modules/experimental/mod_cache.c [new file with mode: 0644]
modules/experimental/mod_cache.h [new file with mode: 0644]
modules/experimental/mod_disk_cache.c [new file with mode: 0644]

index 665fc5db742878a2eec59b024188d648cca74521..fcead70960e43625e5bba5d4ec12c2cb03cbe168 100644 (file)
@@ -3,5 +3,7 @@ APACHE_MODPATH_INIT(experimental)
 
 APACHE_MODULE(mmap_static, memory mapped file caching, , , no)
 APACHE_MODULE(charset_lite, character set translation, , , no)
+APACHE_MODULE(cache, dynamic file caching, , , no)
+APACHE_MODULE(disk_cache, disk caching module, , , no)
 
 APACHE_MODPATH_FINISH
diff --git a/modules/experimental/mod_cache.c b/modules/experimental/mod_cache.c
new file mode 100644 (file)
index 0000000..003156d
--- /dev/null
@@ -0,0 +1,130 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+#include "apr_strings.h"
+#include "ap_config.h"
+#include "util_filter.h"
+#include "httpd.h"
+#include "http_config.h"
+#include "http_request.h"
+#include "http_core.h"
+#include "http_protocol.h"
+#include "http_log.h"
+#include "http_main.h"
+#include "util_script.h"
+#include "http_core.h" 
+#include "mod_cache.h"
+#include "ap_hooks.h"
+
+module MODULE_VAR_EXPORT cache_module;
+
+AP_HOOK_STRUCT(
+            AP_HOOK_LINK(serve_cache)
+            AP_HOOK_LINK(store_cache)
+)
+
+AP_IMPLEMENT_HOOK_RUN_FIRST(int,serve_cache,(request_rec *r),(r),DECLINED)
+AP_IMPLEMENT_HOOK_RUN_FIRST(int,store_cache,(request_rec *r, ap_bucket_brigade *bb, void **cf),
+                            (r, bb, cf),DECLINED)
+
+static int cache_handler(request_rec *r)
+{
+    /* I am sure there is common error checking that belongs in this function,
+     * but I'm not sure what it is.
+     */
+    return ap_run_serve_cache(r);
+}
+
+typedef struct cache_struct {
+    void *cf;
+} cache_struct;
+
+static int cache_filter(ap_filter_t *f, ap_bucket_brigade *bb)
+{
+    cache_struct *ctx = f->ctx;
+    
+    if (ctx == NULL) {
+        f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx));
+    }
+
+    ap_run_store_cache(f->r, bb, &ctx->cf);
+    ap_pass_brigade(f->next, bb);
+    return APR_SUCCESS;        
+}
+
+static void cache_register_hook(void)
+{
+    ap_register_output_filter("CACHE", cache_filter, AP_FTYPE_HTTP_HEADER);
+}
+
+static const handler_rec cache_handlers[] =
+{
+    {"*/*", cache_handler},
+    {NULL}
+};
+
+module MODULE_VAR_EXPORT cache_module = {
+    STANDARD20_MODULE_STUFF,
+    NULL,                      /* create per-directory config structure */
+    NULL,                      /* merge per-directory config structures */
+    NULL,                      /* create per-server config structure */
+    NULL,                      /* merge per-server config structures */
+    NULL,                      /* command apr_table_t */
+    cache_handlers,            /* handlers */
+    cache_register_hook                /* register hooks */
+};
diff --git a/modules/experimental/mod_cache.h b/modules/experimental/mod_cache.h
new file mode 100644 (file)
index 0000000..81a4d37
--- /dev/null
@@ -0,0 +1,67 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+#include "ap_buckets.h"
+#include "ap_hooks.h"
+#include "httpd.h"
+
+typedef struct cache_funcs cache_funcs;
+
+AP_DECLARE_HOOK(int,serve_cache,(request_rec *r));
+AP_DECLARE_HOOK(int,store_cache,(request_rec *r, ap_bucket_brigade *bb, void **cf));
+
diff --git a/modules/experimental/mod_disk_cache.c b/modules/experimental/mod_disk_cache.c
new file mode 100644 (file)
index 0000000..f0c9165
--- /dev/null
@@ -0,0 +1,171 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+#include "mod_cache.h"
+#include "apr_file_io.h"
+#include "apr_strings.h"
+#include "http_config.h"
+#include "http_log.h"
+#include "util_filter.h"
+
+module MODULE_VAR_EXPORT disk_cache_module;
+
+static int disk_serve(request_rec *r)
+{
+    ap_bucket *e;
+    ap_bucket_brigade *bb = ap_brigade_create(r->pool); 
+    const char *filename;
+    apr_file_t *fd = NULL;
+    apr_status_t rv;
+    ap_filter_t *f;
+    char str[256];
+    apr_off_t offset = 0;
+
+    filename = ap_server_root_relative(r->pool, 
+                        apr_pstrcat(r->pool, "proxy", r->uri, NULL));
+    if ((rv = apr_open(&fd, filename, APR_READ, 
+                 APR_UREAD, r->connection->pool)) != APR_SUCCESS) {
+        return DECLINED;
+    }
+
+    /* skip the cached headers. */
+    do {
+        apr_fgets(str, 256, fd);
+        offset += strlen(str);
+    } while (strcmp(str, CRLF));
+
+    /* If we are serving from the cache, we don't want to try to cache it
+     * again.
+     */
+    for ((f = r->output_filters); (f = f->next);) {
+        if (!strcmp(f->frec->name, "CACHE")) {
+            ap_remove_output_filter(f);
+        }
+    }
+
+    e = ap_bucket_create_file(fd, offset, r->finfo.size);
+
+    AP_BRIGADE_INSERT_HEAD(bb, e);
+    e = ap_bucket_create_eos();
+    AP_BRIGADE_INSERT_TAIL(bb, e);
+
+    ap_pass_brigade(r->output_filters, bb);
+    return OK;
+}
+
+typedef struct cache_struct {
+    const char *filename;
+    apr_file_t *fd;
+    int state;
+} cache_struct;
+
+static int disk_cache(request_rec *r, ap_bucket_brigade *bb, void **cf)
+{
+    cache_struct *ctx = *cf;
+    ap_bucket *e;
+    
+    if (ctx == NULL) {
+        *cf = ctx = apr_pcalloc(r->pool, sizeof(*ctx));
+    }
+    if (ctx->filename == NULL) {
+        apr_status_t rv;
+        apr_make_dir(ap_server_root_relative(r->pool, "proxy"), APR_UREAD | APR_UWRITE | APR_UEXECUTE | APR_GREAD | APR_GWRITE, r->pool);
+
+        /* currently, we are using the uri as the cache key.  This is
+         * probably wrong, but it is much better than a hard-coded filename.
+         */
+        ctx->filename = ap_server_root_relative(r->pool, 
+                            apr_pstrcat(r->pool, "proxy", r->uri, NULL));
+        if ((rv = apr_open(&ctx->fd, ctx->filename, 
+                     APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BUFFERED,
+                     APR_UREAD | APR_UWRITE, r->pool)) != APR_SUCCESS) {
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+                         "Could not create cache file");
+            *cf = NULL;
+            return DECLINED;
+        }
+    } 
+    AP_BRIGADE_FOREACH(e, bb) {
+        const char *str;
+        apr_ssize_t length;
+
+        ap_bucket_read(e, &str, &length, 0);
+        apr_write(ctx->fd, str, &length);
+    }
+    if (AP_BUCKET_IS_EOS(AP_BRIGADE_LAST(bb))) {
+        apr_close(ctx->fd);
+    }
+    return OK; 
+}
+
+static void disk_cache_register_hook(void)
+{
+    ap_hook_store_cache(disk_cache, NULL, NULL, AP_HOOK_MIDDLE);
+    ap_hook_serve_cache(disk_serve, NULL, NULL, AP_HOOK_MIDDLE);
+}
+
+module MODULE_VAR_EXPORT disk_cache_module = {
+    STANDARD20_MODULE_STUFF,
+    NULL,                      /* create per-directory config structure */
+    NULL,                      /* merge per-directory config structures */
+    NULL,                      /* create per-server config structure */
+    NULL,                      /* merge per-server config structures */
+    NULL,                      /* command apr_table_t */
+    NULL,                      /* handlers */
+    disk_cache_register_hook   /* register hooks */
+};