mod_disk_cache.c revision a14ccf0f7e9b44c6848334823542a1799577f669
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
095e49b99a1a9a4604e5750771e062c061cd12bdwrowe * applicable.
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * Licensed under the Apache License, Version 2.0 (the "License");
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * you may not use this file except in compliance with the License.
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * You may obtain a copy of the License at
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * Unless required by applicable law or agreed to in writing, software
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * distributed under the License is distributed on an "AS IS" BASIS,
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * See the License for the specific language governing permissions and
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * limitations under the License.
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * mod_disk_cache: Disk Based HTTP 1.1 Cache.
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * Flow to Find the .data file:
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * Incoming client requests URI /foo/bar/baz
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * Generate <hash> off of /foo/bar/baz
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * Open <hash>.header
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * Read in <hash>.header file (may contain Format #1 or Format #2)
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * If format #1 (Contains a list of Vary Headers):
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * Use each header name (from .header) with our request values (headers_in) to
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * regenerate <hash> using HeaderName+HeaderValue+.../foo/bar/baz
f84cab2da5f8958575b1ce99ca2bf4fda34cecb6mturk * re-read in <hash>.header (must be format #2)
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * read in <hash>.data
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * Format #1:
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * apr_uint32_t format;
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * apr_time_t expire;
a6dc07c0c81b3337399ae0f64ce2617f0de9e140wrowe * apr_array_t vary_headers (delimited by CRLF)
f84cab2da5f8958575b1ce99ca2bf4fda34cecb6mturk * Format #2:
f84cab2da5f8958575b1ce99ca2bf4fda34cecb6mturk * disk_cache_info_t (first sizeof(apr_uint32_t) bytes is the format)
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * entity name (dobj->name) [length is in disk_cache_info_t->name_len]
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * r->headers_out (delimited by CRLF)
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * r->headers_in (delimited by CRLF)
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddardtypedef struct {
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard /* Indicates the format of the header struct stored on-disk. */
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard /* The HTTP status code returned for this response. */
f84cab2da5f8958575b1ce99ca2bf4fda34cecb6mturk /* The size of the entity name that follows. */
f84cab2da5f8958575b1ce99ca2bf4fda34cecb6mturk /* The number of times we've cached this entity. */
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard /* Miscellaneous time values. */
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * disk_cache_object_t
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * Pointed to by cache_object_t::vobj
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddardtypedef struct disk_cache_object {
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard const char *root; /* the location of the cache directory */
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard int dirlevels; /* Number of levels of subdirectories */
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard char *datafile; /* name of file where the data will go */
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard char *hdrsfile; /* name of file where the hdrs will go */
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard char *hashfile; /* Computed hash key for this URI */
83cb9e783386a18eecdb0749d9d17aa8e3bc012estoddard char *name; /* Requested URI without vary bits - suitable for mortals. */
83cb9e783386a18eecdb0749d9d17aa8e3bc012estoddard char *key; /* On-disk prefix; URI with Vary bits (if present) */
43681d859fe7d4cd90a33d6be2232192c108de75wrowe apr_off_t file_size; /* File size of the cached data file */
43681d859fe7d4cd90a33d6be2232192c108de75wrowe disk_cache_info_t disk_info; /* Header information. */
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard * mod_disk_cache configuration
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard/* TODO: Make defaults OS specific */
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard#define CACHEFILE_LEN 20 /* must be less than HASH_LEN/2 */
43681d859fe7d4cd90a33d6be2232192c108de75wrowetypedef struct {
43681d859fe7d4cd90a33d6be2232192c108de75wrowe const char* cache_root;
8e117661fd51fd19d6430fca8d7ae87c67d6de20stoddard int dirlevels; /* Number of levels of subdirectories */
request_rec *r)
return APR_SUCCESS;
return APR_SUCCESS;
char *urlbuff;
return rv;
return rv;
return APR_EGENERAL;
return APR_SUCCESS;
int nvec;
const char *header;
const char **elts;
if (!header) {
char *token;
sizeof(char *), array_alphasort);
return DECLINED;
return OK;
char *nkey;
static int error_logged = 0;
int flags;
if (!error_logged) {
return DECLINED;
return DECLINED;
return DECLINED;
return DECLINED;
return DECLINED;
return DECLINED;
#ifdef APR_SENDFILE_ENABLED
return DECLINED;
return DECLINED;
return OK;
return OK;
return OK;
char w[MAX_STRING_LEN];
return rv;
p = strlen(w);
return APR_SUCCESS;
const char **elts;
&amt);
return rv;
&amt);
char w[MAX_STRING_LEN];
return rv;
p = strlen(w);
++maybeEBCDIC;
++maybeASCII;
r->filename);
return APR_EGENERAL;
while (*l && apr_isspace(*l)) {
return APR_SUCCESS;
return APR_NOTFOUND;
return APR_SUCCESS;
apr_bucket *e;
return APR_SUCCESS;
&amt);
return rv;
&amt);
return rv;
if (r->headers_out) {
const char *tmp;
if (tmp) {
r->pool);
return rv;
return rv;
return rv;
return rv;
if (r->headers_out) {
r->server);
&& r->content_type) {
r->err_headers_out);
return rv;
if (r->headers_in) {
r->server);
return rv;
return rv;
return APR_SUCCESS;
apr_bucket *e;
return rv;
e = APR_BUCKET_NEXT(e))
const char *str;
return APR_EGENERAL;
return APR_EGENERAL;
return APR_EGENERAL;
return APR_EGENERAL;
return APR_SUCCESS;
return conf;
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
{NULL}