mirror of
https://github.com/apache/httpd.git
synced 2026-01-06 09:01:14 +03:00
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
367 lines
17 KiB
C
367 lines
17 KiB
C
/* ====================================================================
|
|
* 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/>.
|
|
*/
|
|
|
|
#ifndef __AP_CACHE_H__
|
|
#define __AP_CACHE_H__
|
|
|
|
#include <stdarg.h>
|
|
#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__ */
|