From: Chuck Murcko Date: Wed, 7 Feb 2001 05:42:10 +0000 (+0000) Subject: additions and deletions for proxy in current codebase X-Git-Tag: APACHE_2_0_2001_02_09~24 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d129951ea52ce11529c645fc1d885b4d1b451ecd;p=apache additions and deletions for proxy in current codebase PR: Obtained from: Submitted by: Reviewed by: git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@88005 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/proxy/Makefile.libdir b/modules/proxy/Makefile.libdir deleted file mode 100644 index 7b5254013a..0000000000 --- a/modules/proxy/Makefile.libdir +++ /dev/null @@ -1,4 +0,0 @@ -This is a place-holder which indicates to Configure that it shouldn't -provide the default targets when building the Makefile in this directory. -Instead it'll just prepend all the important variable definitions, and -copy the Makefile.tmpl onto the end. diff --git a/modules/proxy/proxy_cache.c b/modules/proxy/proxy_cache.c new file mode 100644 index 0000000000..8b0f8994fd --- /dev/null +++ b/modules/proxy/proxy_cache.c @@ -0,0 +1,222 @@ +/* ==================================================================== + * 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 + * . + */ + +#include "apr_strings.h" +#include "proxy_cache.h" +#include "httpd.h" +#include "http_log.h" +#ifdef HAVE_STDIO_H +#include +#endif + +/* struct ap_cache_handle_t, some function pointer in the meth */ +#define VERIFY_IMPL(x, fun) if(!x || !x->meth.fun) return APR_ENOTIMPL + +APR_HOOK_STRUCT( + APR_HOOK_LINK(cache_init) +) + +apr_status_t ap_cache_init(ap_cache_handle_t **h, const char *desc, server_rec *server) +{ + return ap_run_cache_init(h, desc, server); +} +apr_status_t ap_cache_close(ap_cache_handle_t *h) +{ + VERIFY_IMPL(h, cache_close); + return h->meth.cache_close(h); +} +apr_status_t ap_cache_garbage_collect(ap_cache_handle_t *h) +{ + VERIFY_IMPL(h, cache_garbage_coll); + return h->meth.cache_garbage_coll(h); +} +apr_status_t ap_cache_seek(ap_cache_handle_t *h, const char *name, ap_cache_el **el) +{ + VERIFY_IMPL(h, cache_element); + *el = NULL; + return h->meth.cache_element(h, name, el, AP_CACHE_SEEK); +} +apr_status_t ap_cache_create(ap_cache_handle_t *h, const char *name, ap_cache_el **el) +{ + VERIFY_IMPL(h, cache_element); + *el = NULL; + return h->meth.cache_element(h, name, el, AP_CACHE_CREATE); +} +apr_status_t ap_cache_remove(ap_cache_handle_t *h, const char *name) +{ + VERIFY_IMPL(h, cache_element); + return h->meth.cache_element(h, name, NULL, AP_CACHE_REMOVE); +} +struct walk_struct { char **place; apr_pool_t *pool; }; +static int get_first_val(void *datum, const char *name, const char *val) +{ + struct walk_struct *ws = (struct walk_struct *)datum; + *(ws->place) = apr_pstrdup(ws->pool, val); + return 0; +} +apr_status_t ap_cache_el_header(ap_cache_el *el, const char *hdr, char **val) +{ + struct walk_struct ws; + if(!val || !el) return APR_BADARG; + *val = NULL; + ws.place = val; + ws.pool = el->cache->pool; + ap_cache_el_header_walk(el, get_first_val, &ws, hdr, NULL); + return *val ? APR_SUCCESS : APR_ENOENT; +} +apr_status_t ap_cache_el_header_walk(ap_cache_el *el, + int (*comp)(void *, const char *, const char *), void *rec, ...) +{ + va_list args; + apr_status_t ret; + + if(!el) return APR_BADARG; + VERIFY_IMPL(el->cache, cache_el_header_walk); + va_start(args, rec); + ret = el->cache->meth.cache_el_header_walk(el, comp, rec, args); + va_end(args); + return ret; +} +/* +static int merge_tables(void *datum, const char *name, const char *val) +{ + ap_cache_el *el = (ap_cache_el *)datum; + ap_cache_el_header_remove(el, name); + ap_cache_el_header_add(el, name, val); + return APR_SUCCESS; +} +*/ +apr_status_t ap_cache_el_header_merge(ap_cache_el *el, apr_table_t *tbl) +{ + apr_table_entry_t *elts = (apr_table_entry_t *) tbl->a.elts; + int i; +/* + const char *val; +*/ + + for (i = 0; i < tbl->a.nelts; ++i) + ap_cache_el_header_set(el, elts[i].key, elts[i].val); + return APR_SUCCESS; +} +apr_status_t ap_cache_el_header_set(ap_cache_el *el, const char *hdrname, + const char *hdrval) +{ + if(!el) return APR_BADARG; + VERIFY_IMPL(el->cache, cache_el_hdr); + return el->cache->meth.cache_el_hdr(el, hdrname, hdrval, AP_CACHE_CHANGE); +} +apr_status_t ap_cache_el_header_add(ap_cache_el *el, const char *hdrname, + const char *hdrval) +{ + if(!el) return APR_BADARG; + VERIFY_IMPL(el->cache, cache_el_hdr); + return el->cache->meth.cache_el_hdr(el, hdrname, hdrval, AP_CACHE_CREATE); +} +apr_status_t ap_cache_el_header_remove(ap_cache_el *el, const char *hdrname) +{ + if(!el) return APR_BADARG; + VERIFY_IMPL(el->cache, cache_el_hdr); + return el->cache->meth.cache_el_hdr(el, hdrname, NULL, AP_CACHE_REMOVE); +} +apr_status_t ap_cache_el_header_clear(ap_cache_el *el) +{ + if(!el) return APR_BADARG; + VERIFY_IMPL(el->cache, cache_el_reset); + return el->cache->meth.cache_el_reset(el, AP_CACHE_HEADER); +} +apr_status_t ap_cache_el_data(ap_cache_el *el, apr_file_t **b) +{ + if(!b || !el) return APR_BADARG; + *b = NULL; + VERIFY_IMPL(el->cache, cache_el_data); + return el->cache->meth.cache_el_data(el, b); +} +apr_status_t ap_cache_el_data_append(ap_cache_el *el, apr_file_t *data) +{ + apr_file_t *place; + char buffer[HUGE_STRING_LEN]; + apr_status_t ret = APR_SUCCESS; + apr_size_t nbytes, i, o; + + if((ret = ap_cache_el_data(el, &place)) != APR_SUCCESS) return ret; + nbytes = HUGE_STRING_LEN; + while(apr_read(data, buffer, &nbytes) == APR_SUCCESS && nbytes) { + o = 0; + while(nbytes) + { + i = nbytes; + apr_write(place, buffer + o, &i); + o += i; + nbytes -= i; + } + } + return ret; +} +apr_status_t ap_cache_el_data_clear(ap_cache_el *el) +{ + if(!el) return APR_BADARG; + VERIFY_IMPL(el->cache, cache_el_reset); + return el->cache->meth.cache_el_reset(el, AP_CACHE_DATA); +} +apr_status_t ap_cache_el_finalize(ap_cache_el *el) +{ + if(!el) return APR_BADARG; + VERIFY_IMPL(el->cache, cache_el_final); + return el->cache->meth.cache_el_final(el); +} + +/* hooks */ +AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, cache_init, (ap_cache_handle_t **h, const char *desc, server_rec *s), + (h, desc, s), APR_ENOTIMPL) + diff --git a/modules/proxy/proxy_cache.h b/modules/proxy/proxy_cache.h new file mode 100644 index 0000000000..e9cf4a7456 --- /dev/null +++ b/modules/proxy/proxy_cache.h @@ -0,0 +1,366 @@ +/* ==================================================================== + * 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 + * . + */ + +#ifndef __AP_CACHE_H__ +#define __AP_CACHE_H__ + +#include +#include "httpd.h" +#include "apr_file_io.h" +#include "apr_network_io.h" +#include "apr_pools.h" +#include "apr_hooks.h" +#include "httpd.h" + +/** + * @package Apache Caching Module API + */ + +/* Interface to caching modules + * This interface will allow access to special modules that will + * do actual caching calls and maintain elements appropriatly. + * + * To date there is only a file version and a shared memory of these caching + * backends. Clients of thie API need not know where their data will go, in + * general there are several calls (marked A) that will work on the database + * as a whole. From those points you will go onto (B) where you can seek, create + * and remove records. + * Upon seeking or creating records you will have an active ap_cache_el. You may + * continue down into (C) section. + * + * A cache element has two distinct parts, the header (D) and the data (E). + * One of the uses of the header section will, in fact, be internal to the + * cache backends to manage expiration. For example, ap_cache modules may + * use the "Cache-Control" header entry for ap_cache_garbage_collect(). + * All data portions or headers may be used for any purpose, and are not + * actually used by the API, though some headers may have special meanings + * to certain backends. + */ + +/* ********************* + * Example client usage: + * + * ap_cache_handle_t *my_cache; + * ap_cache_el *element; + * apr_file_t *element_buff; + * + * ap_cache_create(&my_cache, "Cache of Farm Animals"); + * + * ap_cache_push(my_cache, "Pig", &element); + * ap_cache_el_header_add(element, "Sound", "Oink"); + * ap_cache_el_data(element, &element_buff); + * ap_bputs("I smell bacon!\n", element_buff); + * ap_cache_el_finalize(element); + * + * ap_cache_seek(my_cache", "Cow", &element); + * ap_cache_el_header_walk(my_cache, some_func, NULL, "Sound", NULL); + * .... + * + * ap_cache_close(my_cache); + * + * A client can do anything it wants to an "active" cache_el however it + * must guarantee that when it is done with the cache element it will + * be finalized. In this way an element in a cache can only be active one + * time (and any cache_seek for this element will fail), for this reason + * one shouldn't stay open for long ammounts of time. The client is also + * responsible for calling garbage_collect periodically to give the cache a + * chance to clean up for itself if this is the behaviour it wants. + */ + +/* Types used by clients of this interface */ +typedef struct ap_cache_handle_t ap_cache_handle_t; +typedef struct ap_cache_el +{ + ap_cache_handle_t *cache; + const char *name; +} ap_cache_el; + +/* A) Works on the cache database as a whole */ +/** + * This will initialize a cache_handle. This is the main entry point into the + * caching API, from this point active caching modules will be asked to fill + * in the cache_handle. + * @param Where to put the handle + * @param A descriptive unique string for your client, this description could + * used by caching modules to determine if the their backend is suitable + * for this client. + * @param Current server_rec, this will be used for retreiving configuration, + * and various other necesar server pieces. + * @deffunc apr_status_t ap_cache_init(ap_cache_handle_t **h, const char *desc, server_rec *r) + */ +apr_status_t ap_cache_init(ap_cache_handle_t **h, const char *desc, server_rec *r); + +/** + * This function will finalize a cache_handle, after this call the handle will + * no longer be usable. + * @param The handle to close + * @deffunc apr_status_t ap_cache_close(ap_cache_handle_t *) + */ +apr_status_t ap_cache_close(ap_cache_handle_t *); + +/** + * Force a garbage collection of the cache_handle, the client should call this periodically, + * the caching module will not do this on its own, however it isn't required to actually + * garbage collect anything, and may defer the call until later. + * @param The handle to force a garbage collection. + * @deffunc apr_status_t ap_cache_garbage_collect(ap_cache_handle_t *h) + */ +apr_status_t ap_cache_garbage_collect(ap_cache_handle_t *h); + +/* B) insertion and query into database */ +/** + * Seek for a given element in an open cache. This call will fail if the requested element + * is already "in use" by previous call to ap_cache_seek or ap_cache_create. + * When finished with the element you must call ap_cache_el_finalize immediatly so the + * element is no longer locked. + * @param The cache to search in. + * @param The name of the record you are looking for + * @param Where to put the cache element if a seek succeeds. + * @deffunc apr_status_t ap_cache_seek(ap_cache_handle_t *h, const char *name, ap_cache_el **) + */ +apr_status_t ap_cache_seek(ap_cache_handle_t *h, const char *name, ap_cache_el **); + +/** + * Create a new element inside of a cache, you must call this first function to put + * something new into a cache; after calling you may use the cache_el passed in as + * you would use one retrieved from an ap_cache_seek. The element will be locked after + * this call. + * When finished with the element you must call ap_cache_el_finalize immediatly so the + * element is no longer locked. + * @param The cache to create this element in. + * @param The name to give this new record + * @param Where to put this new element. + * @deffunc apr_status_t ap_cache_create(ap_cache_handle_t *h, const char *name, ap_cache_el **) + */ +apr_status_t ap_cache_create(ap_cache_handle_t *h, const char *name, ap_cache_el **); + +/** + * Remove a record from a cache. This call will fail if the requested element + * is already "in use" by previous call to ap_cache_seek or ap_cache_create. + * When finished with the element you must call ap_cache_el_finalize immediatly so the + * element is no longer locked. + * @param The cache to remove this record from. + * @param The name of the record to remove from the cache. + * @deffunc apr_status_t ap_cache_remove(ap_cache_handle_t *h, const char *name) + */ +apr_status_t ap_cache_remove(ap_cache_handle_t *h, const char *name); + +/* (C) Works on an actual element */ + +/* (D) Works on the header section */ +/** + * This will retrieve a header value from the element. + * @param A previously ap-cache_seek()'d or ap_cache_create()'d element. + * @param Header name looking to retrieve, must be null terminated. + * @param Where to put the value + * @deffunc apr_status_t ap_cache_el_header(ap_cache_el *el, const char *hdr, char **val) + */ +apr_status_t ap_cache_el_header(ap_cache_el *el, const char *hdr, char **val); + +/** + * Walk through all the headers for given values. This function is synonymous with + * ap_table_walk. + * @param The element to walk through. + * @param The callback function to use for each element. The paramaters for this function: + * 1) Client defined data, as passed in by the next paramater to ap-cache_el_header_walk + * 2) The name of current header that forced this callback. + * 3) The value of the current header. + * @param User defined data passed back to the callback as argument 1. + * @param NULL terminated list of headers to walk through. If the first value + * of this list is NULL then ALL element will be walked over. + * @deffunc apr_status_t ap_cache_el_header_walk(ap_cache_el *el, + * int (*comp)(void *, const char *, const char *), void *rec, ...); + */ +apr_status_t ap_cache_el_header_walk(ap_cache_el *el, + int (*comp)(void *, const char *, const char *), void *rec, ...); + +/** + * This will merge an existing apr_table_t into a cache_el's header section. + * @param The cache element to merge onto. + * @param The filled in apr_table_t to merge in. + * @deffunc apr_status_t ap_cache_el_header_merge(ap_cache_el *el, apr_table_t *tbl) + */ +apr_status_t ap_cache_el_header_merge(ap_cache_el *el, apr_table_t *tbl); + +/** + * This will set the current value of a header name to a given value. Using this function + * the same as first ap_cache_el_header_remove, and then ap-cache_el_header_add. + * @param The cache element to modify + * @param The name of the header to change + * @param The value to assign to the given name. + * @deffunc apr_status_t ap_cache_el_header_set(ap_cache_el *el, const char *hdrname, const char *hdrval) + */ +apr_status_t ap_cache_el_header_set(ap_cache_el *el, const char *hdrname, const char *hdrval); + +/** + * Each header may have more than one value, you may call this function repeatedly and it will + * continue adding values onto a header element. If you want to assign a single value to a + * header you must use ap_cache_el_header_set instead. + * @param The cache element to add to + * @param The name of the header to append values to. + * @param The value to append to the given header name. + * @deffunc apr_status_t ap_cache_el_header_add(ap_cache_el *el, const char *hdrname, const char *hdrval) + */ +apr_status_t ap_cache_el_header_add(ap_cache_el *el, const char *hdrname, const char *hdrval); + +/** + * This will remove all headers of a given name. + * @param The cache element to remove headers from + * @param The name of the header to remove. This will remove ALL values assigned to this + * header (via the ap_cache_el_header_add call). + * @deffunc apr_status_t ap_cache_el_header_remove(ap_cache_el *el, const char *hdr) + */ +apr_status_t ap_cache_el_header_remove(ap_cache_el *el, const char *hdr); + +/** + * This will clear out an entire header section. You may use this if you are intending + * to change the entire value of the header section of a cache element. + * @param The element to clear + * @deffunc apr_status_t ap_cache_el_header_clear(ap_cache_el *el) + */ +apr_status_t ap_cache_el_header_clear(ap_cache_el *el); + +/* (E) Works on the data section */ +/** + * Retrieve a apr_file_t for a given cache element, where this data goes is opaque to all + * clients of this API. You can do all operations on the apr_file_t and trust the underlying + * caching module will accept the data and put it in the appropriate place. + * @param The element to retrieve data + * @param Where to put the apr_file_t structure when it comes back. In some cases this + * will be a normal buff that will either write to a network, or disk - but + * you should not rely on it going anywhere in a caching module as the destination + * for all data is opaque. + * @deffunc apr_status_t ap_cache_el_data(ap_cache_el *el, apr_file_t **) + */ +apr_status_t ap_cache_el_data(ap_cache_el *el, apr_file_t **); + +/** + * Convenience function to put an existing apr_file_t into a cache_el's data section. This + * function will probably not be fully optimal - and will actually just pipe one apr_file_t + * to another. + * @param The element to append to + * @param An existing apr_file_t to append onto the ap_cache_el's stream of data. + * @deffunc apr_status_t ap_cache_el_data_append(ap_cache_el *el, apr_file_t *data) + */ +apr_status_t ap_cache_el_data_append(ap_cache_el *el, apr_file_t *data); + +/** + * Clear the data section of an existing cache_el. You may use this if you are + * intending to change the entire value of the data section of a cache element. + * @param The element to clear + * @deffunc apr_status_t ap_cache_el_data_clear(ap_cache_el *el) + */ +apr_status_t ap_cache_el_data_clear(ap_cache_el *el); + +/** + * This will complete an open element. When you are done working on a caching + * element you must call this so the object will be unlocked and all data will + * be finalized, in some cases that means certain data won't make it into the + * destination backend until this call is made. Each module may decide how much + * this function actually does but you MUST call this function immediatly after + * completing a cache record. + * @param The element to finalize, after calling this function the caching + * element is no longer valid and you must ap_cache_seek for it again if + * you want to make any further changes to it. + * @deffunc apr_status_t ap_cache_el_finalize(ap_cache_el *el) + */ +apr_status_t ap_cache_el_finalize(ap_cache_el *el); + +/* ****************************************************************************/ +/* ****************************************************************************/ +/* This section is internal entirely, but it is exposed because + * implementors of caching modules will need to use some of this. Clients + * of the library are NEVER to use this interface however, and should use + * the above accessors to the cache. + */ + +/* This is how a cache module can grab control. This will be fired once the + * ap_cache_init call is made, each paramater will coorespond to the paramaters + * passed into ap_cache_init. If your cache wants to reject a hook call return + * APR_ENOTIMPL from your hook and the next caching module will be tried. + */ +AP_DECLARE_HOOK(apr_status_t, cache_init, (ap_cache_handle_t **, const char *desc, server_rec *t)) + +/* These are various enum's passed into call back functions (as defined below) */ +typedef enum { AP_CACHE_SEEK, AP_CACHE_CREATE, AP_CACHE_CHANGE, AP_CACHE_REMOVE } ap_cache_query; +typedef enum { AP_CACHE_DATA, AP_CACHE_HEADER } ap_cache_part; + +/* These are the callback functions filled in by handler of the cache_init hook. + * function may be NULL and will in turn return APR_ENOTIMPL by any of the various + * calls in the API. + */ +typedef struct ap_cache_methods +{ + apr_status_t (*cache_close)(ap_cache_handle_t *h); + apr_status_t (*cache_garbage_coll)(ap_cache_handle_t *h); + apr_status_t (*cache_element)(ap_cache_handle_t *h, const char *name, ap_cache_el **, + ap_cache_query flag); + apr_status_t (*cache_el_header_walk)(ap_cache_el *el, + int (*comp)(void *, const char *, const char *), void *rec, va_list); + apr_status_t (*cache_el_hdr)(ap_cache_el *el, const char *name, const char *val, ap_cache_query flag); + apr_status_t (*cache_el_data)(ap_cache_el *el, apr_file_t **); + apr_status_t (*cache_el_reset)(ap_cache_el *, ap_cache_part flag); + apr_status_t (*cache_el_final)(ap_cache_el *el); +} ap_cache_methods; +/* This is declared here because modules need to fill this in, however + * clients of the library should NEVER use this + */ +struct ap_cache_handle_t +{ + apr_pool_t *pool; /* pool for alloc's */ + server_rec *server; /* access to configurations, used on init */ + ap_cache_methods meth; +}; + +#endif /* __AP_CACHE_H__ */