/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "apr_lib.h"
#include "apr_file_io.h"
#include "apr_strings.h"
#include "apr_buckets.h"

#include "apr_version.h"
#if !APR_VERSION_AT_LEAST(2,0,0)
#include "apu_version.h"
#endif

#include "httpd.h"
#include "http_config.h"
#include "http_log.h"
#include "http_core.h"
#include "http_protocol.h"
#include "ap_provider.h"
#include "ap_socache.h"
#include "util_filter.h"
#include "util_script.h"
#include "util_charset.h"
#include "util_mutex.h"

#include "mod_cache.h"
#include "mod_status.h"

#include "cache_socache_common.h"

/*
 * mod_cache_socache: Shared Object Cache Based HTTP 1.1 Cache.
 *
 * Flow to Find the entry:
 *   Incoming client requests URI /foo/bar/baz
 *   Fetch URI key (may contain Format #1 or Format #2)
 *   If format #1 (Contains a list of Vary Headers):
 *      Use each header name (from .header) with our request values (headers_in) to
 *      regenerate key using HeaderName+HeaderValue+.../foo/bar/baz
 *      re-read in key (must be format #2)
 *
 * Format #1:
 *   apr_uint32_t format;
 *   apr_time_t expire;
 *   apr_array_t vary_headers (delimited by CRLF)
 *
 * Format #2:
 *   cache_socache_info_t (first sizeof(apr_uint32_t) bytes is the format)
 *   entity name (sobj->name) [length is in cache_socache_info_t->name_len]
 *   r->headers_out (delimited by CRLF)
 *   CRLF
 *   r->headers_in (delimited by CRLF)
 *   CRLF
 */

module AP_MODULE_DECLARE_DATA cache_socache_module;

/*
 * cache_socache_object_t
 * Pointed to by cache_object_t::vobj
 */
typedef struct cache_socache_object_t
{
    apr_pool_t *pool; /* pool */
    unsigned char *buffer; /* the cache buffer */
    apr_size_t buffer_len; /* size of the buffer */
    apr_bucket_brigade *body; /* brigade containing the body, if any */
    apr_table_t *headers_in; /* Input headers to save */
    apr_table_t *headers_out; /* Output headers to save */
    cache_socache_info_t socache_info; /* Header information. */
    apr_size_t body_offset; /* offset to the start of the body */
    apr_off_t body_length; /* length of the cached entity body */
    apr_time_t expire; /* when to expire the entry */

    const char *name; /* Requested URI without vary bits - suitable for mortals. */
    const char *key; /* On-disk prefix; URI with Vary bits (if present) */
    apr_off_t offset; /* Max size to set aside */
    apr_time_t timeout; /* Max time to set aside */
    unsigned int newbody :1; /* whether a new body is present */
    unsigned int done :1; /* Is the attempt to cache complete? */
} cache_socache_object_t;

/*
 * mod_cache_socache configuration
 */
#define DEFAULT_MAX_FILE_SIZE 100*1024
#define DEFAULT_MAXTIME 86400
#define DEFAULT_MINTIME 600
#define DEFAULT_READSIZE 0
#define DEFAULT_READTIME 0

typedef struct cache_socache_provider_conf
{
    const char *args;
    ap_socache_provider_t *socache_provider;
    ap_socache_instance_t *socache_instance;
} cache_socache_provider_conf;

typedef struct cache_socache_conf
{
    cache_socache_provider_conf *provider;
} cache_socache_conf;

typedef struct cache_socache_dir_conf
{
    apr_off_t max; /* maximum file size for cached files */
    apr_time_t maxtime; /* maximum expiry time */
    apr_time_t mintime; /* minimum expiry time */
    apr_off_t readsize; /* maximum data to attempt to cache in one go */
    apr_time_t readtime; /* maximum time taken to cache in one go */
    unsigned int max_set :1;
    unsigned int maxtime_set :1;
    unsigned int mintime_set :1;
    unsigned int readsize_set :1;
    unsigned int readtime_set :1;
} cache_socache_dir_conf;

/* Shared object cache and mutex */
static const char * const cache_socache_id = "cache-socache";
static apr_global_mutex_t *socache_mutex = NULL;

/*
 * Local static functions
 */

static apr_status_t read_array(request_rec *r, apr_array_header_t *arr,
        unsigned char *buffer, apr_size_t buffer_len, apr_size_t *slider)
{
    apr_size_t val = *slider;

    while (*slider < buffer_len) {
        if (buffer[*slider] == '\r') {
            if (val == *slider) {
                (*slider)++;
                return APR_SUCCESS;
            }
            *((const char **) apr_array_push(arr)) = apr_pstrndup(r->pool,
                    (const char *) buffer + val, *slider - val);
            (*slider)++;
            if (buffer[*slider] == '\n') {
                (*slider)++;
            }
            val = *slider;
        }
        else if (buffer[*slider] == '\0') {
            (*slider)++;
            return APR_SUCCESS;
        }
        else {
            (*slider)++;
        }
    }

    return APR_EOF;
}

static apr_status_t store_array(apr_array_header_t *arr, unsigned char *buffer,
        apr_size_t buffer_len, apr_size_t *slider)
{
    int i, len;
    const char **elts;

    elts = (const char **) arr->elts;

    for (i = 0; i < arr->nelts; i++) {
        apr_size_t e_len = strlen(elts[i]);
        if (e_len + 3 >= buffer_len - *slider) {
            return APR_EOF;
        }
        len = apr_snprintf(buffer ? (char *) buffer + *slider : NULL,
                buffer ? buffer_len - *slider : 0, "%s" CRLF, elts[i]);
        *slider += len;
    }
    if (buffer) {
        memcpy(buffer + *slider, CRLF, sizeof(CRLF) - 1);
    }
    *slider += sizeof(CRLF) - 1;

    return APR_SUCCESS;
}

static apr_status_t read_table(cache_handle_t *handle, request_rec *r,
        apr_table_t *table, unsigned char *buffer, apr_size_t buffer_len,
        apr_size_t *slider)
{
    apr_size_t key = *slider, colon = 0, len = 0;

    while (*slider < buffer_len) {
        if (buffer[*slider] == ':') {
            if (!colon) {
                colon = *slider;
            }
            (*slider)++;
        }
        else if (buffer[*slider] == '\r') {
            len = colon;
            if (key == *slider) {
                (*slider)++;
                if (buffer[*slider] == '\n') {
                    (*slider)++;
                }
                return APR_SUCCESS;
            }
            if (!colon || buffer[colon++] != ':') {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02344)
                        "Premature end of cache headers.");
                return APR_EGENERAL;
            }
            /* Do not go past the \r from above as apr_isspace('\r') is true */
            while (apr_isspace(buffer[colon]) && (colon < *slider)) {
                colon++;
            }
            apr_table_addn(table, apr_pstrmemdup(r->pool, (const char *) buffer
                    + key, len - key), apr_pstrmemdup(r->pool,
                    (const char *) buffer + colon, *slider - colon));
            (*slider)++;
            if (buffer[*slider] == '\n') {
                (*slider)++;
            }
            key = *slider;
            colon = 0;
        }
        else if (buffer[*slider] == '\0') {
            (*slider)++;
            return APR_SUCCESS;
        }
        else {
            (*slider)++;
        }
    }

    return APR_EOF;
}

static apr_status_t store_table(apr_table_t *table, unsigned char *buffer,
        apr_size_t buffer_len, apr_size_t *slider)
{
    int i, len;
    apr_table_entry_t *elts;

    elts = (apr_table_entry_t *) apr_table_elts(table)->elts;
    for (i = 0; i < apr_table_elts(table)->nelts; ++i) {
        if (elts[i].key != NULL) {
            apr_size_t key_len = strlen(elts[i].key);
            apr_size_t val_len = strlen(elts[i].val);
            if (key_len + val_len + 5 >= buffer_len - *slider) {
                return APR_EOF;
            }
            len = apr_snprintf(buffer ? (char *) buffer + *slider : NULL,
                    buffer ? buffer_len - *slider : 0, "%s: %s" CRLF,
                    elts[i].key, elts[i].val);
            *slider += len;
        }
    }
    if (3 >= buffer_len - *slider) {
        return APR_EOF;
    }
    if (buffer) {
        memcpy(buffer + *slider, CRLF, sizeof(CRLF) - 1);
    }
    *slider += sizeof(CRLF) - 1;

    return APR_SUCCESS;
}

static const char* regen_key(apr_pool_t *p, apr_table_t *headers,
                             apr_array_header_t *varray, const char *oldkey,
                             apr_size_t *newkeylen)
{
    struct iovec *iov;
    int i, k;
    int nvec;
    const char *header;
    const char **elts;

    nvec = (varray->nelts * 2) + 1;
    iov = apr_palloc(p, sizeof(struct iovec) * nvec);
    elts = (const char **) varray->elts;

    /* TODO:
     *    - Handle multiple-value headers better. (sort them?)
     *    - Handle Case in-sensitive Values better.
     *        This isn't the end of the world, since it just lowers the cache
     *        hit rate, but it would be nice to fix.
     *
     * The majority are case insenstive if they are values (encoding etc).
     * Most of rfc2616 is case insensitive on header contents.
     *
     * So the better solution may be to identify headers which should be
     * treated case-sensitive?
     *  HTTP URI's (3.2.3) [host and scheme are insensitive]
     *  HTTP method (5.1.1)
     *  HTTP-date values (3.3.1)
     *  3.7 Media Types [excerpt]
     *     The type, subtype, and parameter attribute names are case-
     *     insensitive. Parameter values might or might not be case-sensitive,
     *     depending on the semantics of the parameter name.
     *  4.20 Except [excerpt]
     *     Comparison of expectation values is case-insensitive for unquoted
     *     tokens (including the 100-continue token), and is case-sensitive for
     *     quoted-string expectation-extensions.
     */

    for (i = 0, k = 0; i < varray->nelts; i++) {
        header = apr_table_get(headers, elts[i]);
        if (!header) {
            header = "";
        }
        iov[k].iov_base = (char*) elts[i];
        iov[k].iov_len = strlen(elts[i]);
        k++;
        iov[k].iov_base = (char*) header;
        iov[k].iov_len = strlen(header);
        k++;
    }
    iov[k].iov_base = (char*) oldkey;
    iov[k].iov_len = strlen(oldkey);
    k++;

    return apr_pstrcatv(p, iov, k, newkeylen);
}

static int array_alphasort(const void *fn1, const void *fn2)
{
    return strcmp(*(char**) fn1, *(char**) fn2);
}

static void tokens_to_array(apr_pool_t *p, const char *data,
        apr_array_header_t *arr)
{
    char *token;

    while ((token = ap_get_list_item(p, &data)) != NULL) {
        *((const char **) apr_array_push(arr)) = token;
    }

    /* Sort it so that "Vary: A, B" and "Vary: B, A" are stored the same. */
    qsort((void *) arr->elts, arr->nelts, sizeof(char *), array_alphasort);
}

/*
 * Hook and mod_cache callback functions
 */
static int create_entity(cache_handle_t *h, request_rec *r, const char *key,
        apr_off_t len, apr_bucket_brigade *bb)
{
    cache_socache_dir_conf *dconf =
            ap_get_module_config(r->per_dir_config, &cache_socache_module);
    cache_socache_conf *conf = ap_get_module_config(r->server->module_config,
            &cache_socache_module);
    cache_object_t *obj;
    cache_socache_object_t *sobj;
    apr_size_t total;

    if (conf->provider == NULL) {
        return DECLINED;
    }

    /* we don't support caching of range requests (yet) */
    /* TODO: but we could */
    if (r->status == HTTP_PARTIAL_CONTENT) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02345)
                "URL %s partial content response not cached",
                key);
        return DECLINED;
    }

    /*
     * We have a chicken and egg problem. We don't know until we
     * attempt to store_headers just how big the response will be
     * and whether it will fit in the cache limits set. But we
     * need to make a decision now as to whether we plan to try.
     * If we make the wrong decision, we could prevent another
     * cache implementation, such as cache_disk, from getting the
     * opportunity to cache, and that would be unfortunate.
     *
     * In a series of tests, from cheapest to most expensive,
     * decide whether or not to ignore this attempt to cache,
     * with a small margin just to be sure.
     */
    if (len < 0) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02346)
                "URL '%s' had no explicit size, ignoring", key);
        return DECLINED;
    }
    if (len > dconf->max) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02347)
                "URL '%s' body larger than limit, ignoring "
                "(%" APR_OFF_T_FMT " > %" APR_OFF_T_FMT ")",
                key, len, dconf->max);
        return DECLINED;
    }

    /* estimate the total cached size, given current headers */
    total = len + sizeof(cache_socache_info_t) + strlen(key);
    if (APR_SUCCESS != store_table(r->headers_out, NULL, dconf->max, &total)
            || APR_SUCCESS != store_table(r->headers_in, NULL, dconf->max,
                    &total)) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02348)
                "URL '%s' estimated headers size larger than limit, ignoring "
                "(%" APR_SIZE_T_FMT " > %" APR_OFF_T_FMT ")",
                key, total, dconf->max);
        return DECLINED;
    }

    if (total >= dconf->max) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02349)
                "URL '%s' body and headers larger than limit, ignoring "
                "(%" APR_OFF_T_FMT " > %" APR_OFF_T_FMT ")",
                key, len, dconf->max);
        return DECLINED;
    }

    /* Allocate and initialize cache_object_t and cache_socache_object_t */
    h->cache_obj = obj = apr_pcalloc(r->pool, sizeof(*obj));
    obj->vobj = sobj = apr_pcalloc(r->pool, sizeof(*sobj));

    obj->key = apr_pstrdup(r->pool, key);
    sobj->key = obj->key;
    sobj->name = obj->key;

    return OK;
}

static apr_status_t sobj_body_pre_cleanup(void *baton)
{
    cache_socache_object_t *sobj = baton;
    apr_brigade_cleanup(sobj->body);
    sobj->body = NULL;
    return APR_SUCCESS;
}

static int open_entity(cache_handle_t *h, request_rec *r, const char *key)
{
    cache_socache_dir_conf *dconf =
            ap_get_module_config(r->per_dir_config, &cache_socache_module);
    cache_socache_conf *conf = ap_get_module_config(r->server->module_config,
            &cache_socache_module);
    apr_uint32_t format;
    apr_size_t slider;
    unsigned int buffer_len;
    const char *nkey;
    apr_status_t rc;
    cache_object_t *obj;
    cache_info *info;
    cache_socache_object_t *sobj;
    apr_size_t len;

    nkey = NULL;
    h->cache_obj = NULL;

    if (!conf->provider || !conf->provider->socache_instance) {
        return DECLINED;
    }

    /* Create and init the cache object */
    obj = apr_pcalloc(r->pool, sizeof(cache_object_t));
    sobj = apr_pcalloc(r->pool, sizeof(cache_socache_object_t));

    info = &(obj->info);

    /* Create a temporary pool for the buffer, and destroy it if something
     * goes wrong so we don't have large buffers of unused memory hanging
     * about for the lifetime of the response.
     */
    apr_pool_create(&sobj->pool, r->pool);
    apr_pool_tag(sobj->pool, "mod_cache_socache (open_entity)");

    sobj->buffer = apr_palloc(sobj->pool, dconf->max);
    sobj->buffer_len = dconf->max;

    /* attempt to retrieve the cached entry */
    if (socache_mutex) {
        apr_status_t status = apr_global_mutex_lock(socache_mutex);
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02350)
                    "could not acquire lock, ignoring: %s", obj->key);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return DECLINED;
        }
    }
    buffer_len = sobj->buffer_len;
    rc = conf->provider->socache_provider->retrieve(
            conf->provider->socache_instance, r->server, (unsigned char *) key,
            strlen(key), sobj->buffer, &buffer_len, r->pool);
    if (socache_mutex) {
        apr_status_t status = apr_global_mutex_unlock(socache_mutex);
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02351)
                    "could not release lock, ignoring: %s", obj->key);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return DECLINED;
        }
    }
    if (rc != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rc, r, APLOGNO(02352)
                "Key not found in cache: %s", key);
        apr_pool_destroy(sobj->pool);
        sobj->pool = NULL;
        return DECLINED;
    }
    if (buffer_len >= sobj->buffer_len) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rc, r, APLOGNO(02353)
                "Key found in cache but too big, ignoring: %s", key);
        apr_pool_destroy(sobj->pool);
        sobj->pool = NULL;
        return DECLINED;
    }

    /* read the format from the cache file */
    memcpy(&format, sobj->buffer, sizeof(format));
    slider = sizeof(format);

    if (format == CACHE_SOCACHE_VARY_FORMAT_VERSION) {
        apr_array_header_t* varray;
        apr_time_t expire;

        memcpy(&expire, sobj->buffer + slider, sizeof(expire));
        slider += sizeof(expire);

        varray = apr_array_make(r->pool, 5, sizeof(char*));
        rc = read_array(r, varray, sobj->buffer, buffer_len, &slider);
        if (rc != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(02354)
                    "Cannot parse vary entry for key: %s", key);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return DECLINED;
        }

        nkey = regen_key(r->pool, r->headers_in, varray, key, &len);

        /* attempt to retrieve the cached entry */
        if (socache_mutex) {
            apr_status_t status = apr_global_mutex_lock(socache_mutex);
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02355)
                        "could not acquire lock, ignoring: %s", obj->key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return DECLINED;
            }
        }
        buffer_len = sobj->buffer_len;
        rc = conf->provider->socache_provider->retrieve(
                conf->provider->socache_instance, r->server,
                (unsigned char *) nkey, len, sobj->buffer,
                &buffer_len, r->pool);
        if (socache_mutex) {
            apr_status_t status = apr_global_mutex_unlock(socache_mutex);
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02356)
                        "could not release lock, ignoring: %s", obj->key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return DECLINED;
            }
        }
        if (rc != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rc, r, APLOGNO(02357)
                    "Key not found in cache: %s", key);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return DECLINED;
        }
        if (buffer_len >= sobj->buffer_len) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rc, r, APLOGNO(02358)
                    "Key found in cache but too big, ignoring: %s", key);
            goto fail;
        }

    }
    else if (format != CACHE_SOCACHE_DISK_FORMAT_VERSION) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02359)
                "Key '%s' found in cache has version %d, expected %d, ignoring",
                key, format, CACHE_SOCACHE_DISK_FORMAT_VERSION);
        goto fail;
    }
    else {
        nkey = key;
    }

    obj->key = nkey;
    sobj->key = nkey;
    sobj->name = key;

    if (buffer_len >= sizeof(cache_socache_info_t)) {
        memcpy(&sobj->socache_info, sobj->buffer, sizeof(cache_socache_info_t));
    }
    else {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(02360)
                "Cache entry for key '%s' too short, removing", nkey);
        goto fail;
    }
    slider = sizeof(cache_socache_info_t);

    /* Store it away so we can get it later. */
    info->status = sobj->socache_info.status;
    info->date = sobj->socache_info.date;
    info->expire = sobj->socache_info.expire;
    info->request_time = sobj->socache_info.request_time;
    info->response_time = sobj->socache_info.response_time;

    memcpy(&info->control, &sobj->socache_info.control, sizeof(cache_control_t));

    if (sobj->socache_info.name_len <= buffer_len - slider) {
        if (strncmp((const char *) sobj->buffer + slider, sobj->name,
                sobj->socache_info.name_len)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(02361)
                    "Cache entry for key '%s' URL mismatch, ignoring", nkey);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return DECLINED;
        }
        slider += sobj->socache_info.name_len;
    }
    else {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(02362)
                "Cache entry for key '%s' too short, removing", nkey);
        goto fail;
    }

    /* Is this a cached HEAD request? */
    if (sobj->socache_info.header_only && !r->header_only) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(02363)
                "HEAD request cached, non-HEAD requested, ignoring: %s",
                sobj->key);
        apr_pool_destroy(sobj->pool);
        sobj->pool = NULL;
        return DECLINED;
    }

    h->req_hdrs = apr_table_make(r->pool, 20);
    h->resp_hdrs = apr_table_make(r->pool, 20);

    /* Call routine to read the header lines/status line */
    if (APR_SUCCESS != read_table(h, r, h->resp_hdrs, sobj->buffer, buffer_len,
            &slider)) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(02364)
                "Cache entry for key '%s' response headers unreadable, removing", nkey);
        goto fail;
    }
    if (APR_SUCCESS != read_table(h, r, h->req_hdrs, sobj->buffer, buffer_len,
            &slider)) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(02365)
                "Cache entry for key '%s' request headers unreadable, removing", nkey);
        goto fail;
    }

    /* Retrieve the body if we have one */
    len = buffer_len - slider;
    if (len > 0) {
        apr_bucket *e;
        /* Create the body brigade later concatenated to the output filters'
         * brigade by recall_body(). Since sobj->buffer (the data) point to
         * sobj->pool (a subpool of r->pool), be safe by using a pool bucket
         * which can morph to heap if sobj->pool is destroyed while the bucket
         * is still alive. But if sobj->pool gets destroyed while the bucket is
         * still in sobj->body (i.e. recall_body() was never called), we don't
         * need to morph to something just about to be freed, so a pre_cleanup
         * will take care of cleaning up sobj->body before this happens (and is
         * a noop otherwise).
         */
        sobj->body = apr_brigade_create(sobj->pool, r->connection->bucket_alloc);
        apr_pool_pre_cleanup_register(sobj->pool, sobj, sobj_body_pre_cleanup);
        e = apr_bucket_pool_create((const char *) sobj->buffer + slider, len,
                                   sobj->pool, r->connection->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(sobj->body, e);
    }

    /* make the configuration stick */
    h->cache_obj = obj;
    obj->vobj = sobj;

    return OK;

fail:
    if (socache_mutex) {
        apr_status_t status = apr_global_mutex_lock(socache_mutex);
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02366)
                    "could not acquire lock, ignoring: %s", obj->key);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return DECLINED;
        }
    }
    conf->provider->socache_provider->remove(
            conf->provider->socache_instance, r->server,
            (unsigned char *) nkey, strlen(nkey), r->pool);
    if (socache_mutex) {
        apr_status_t status = apr_global_mutex_unlock(socache_mutex);
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02367)
                    "could not release lock, ignoring: %s", obj->key);
        }
    }
    apr_pool_destroy(sobj->pool);
    sobj->pool = NULL;
    return DECLINED;
}

static int remove_entity(cache_handle_t *h)
{
    /* Null out the cache object pointer so next time we start from scratch  */
    h->cache_obj = NULL;
    return OK;
}

static int remove_url(cache_handle_t *h, request_rec *r)
{
    cache_socache_conf *conf = ap_get_module_config(r->server->module_config,
            &cache_socache_module);
    cache_socache_object_t *sobj;

    sobj = (cache_socache_object_t *) h->cache_obj->vobj;
    if (!sobj) {
        return DECLINED;
    }

    /* Remove the key from the cache */
    if (socache_mutex) {
        apr_status_t status = apr_global_mutex_lock(socache_mutex);
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02368)
                    "could not acquire lock, ignoring: %s", sobj->key);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return DECLINED;
        }
    }
    conf->provider->socache_provider->remove(conf->provider->socache_instance,
            r->server, (unsigned char *) sobj->key, strlen(sobj->key), r->pool);
    if (socache_mutex) {
        apr_status_t status = apr_global_mutex_unlock(socache_mutex);
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02369)
                    "could not release lock, ignoring: %s", sobj->key);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return DECLINED;
        }
    }

    return OK;
}

static apr_status_t recall_headers(cache_handle_t *h, request_rec *r)
{
    /* we recalled the headers during open_entity, so do nothing */
    return APR_SUCCESS;
}

static apr_status_t recall_body(cache_handle_t *h, apr_pool_t *p,
        apr_bucket_brigade *bb)
{
    cache_socache_object_t *sobj = (cache_socache_object_t*) h->cache_obj->vobj;

    if (sobj->body) {
        APR_BRIGADE_CONCAT(bb, sobj->body);
    }

    return APR_SUCCESS;
}

static apr_status_t store_headers(cache_handle_t *h, request_rec *r,
        cache_info *info)
{
    cache_socache_dir_conf *dconf =
            ap_get_module_config(r->per_dir_config, &cache_socache_module);
    cache_socache_conf *conf = ap_get_module_config(r->server->module_config,
            &cache_socache_module);
    apr_size_t slider;
    apr_status_t rv;
    cache_object_t *obj = h->cache_obj;
    cache_socache_object_t *sobj = (cache_socache_object_t*) obj->vobj;
    cache_socache_info_t *socache_info;

    memcpy(&h->cache_obj->info, info, sizeof(cache_info));

    if (r->headers_out) {
        sobj->headers_out = ap_cache_cacheable_headers_out(r);
    }

    if (r->headers_in) {
        sobj->headers_in = ap_cache_cacheable_headers_in(r);
    }

    sobj->expire
            = obj->info.expire > r->request_time + dconf->maxtime ? r->request_time
                    + dconf->maxtime
                    : obj->info.expire + dconf->mintime;

    apr_pool_create(&sobj->pool, r->pool);
    apr_pool_tag(sobj->pool, "mod_cache_socache (store_headers)");

    sobj->buffer = apr_palloc(sobj->pool, dconf->max);
    sobj->buffer_len = dconf->max;
    socache_info = (cache_socache_info_t *) sobj->buffer;

    if (sobj->headers_out) {
        const char *vary;

        vary = apr_table_get(sobj->headers_out, "Vary");

        if (vary) {
            apr_array_header_t* varray;
            apr_uint32_t format = CACHE_SOCACHE_VARY_FORMAT_VERSION;

            memcpy(sobj->buffer, &format, sizeof(format));
            slider = sizeof(format);

            memcpy(sobj->buffer + slider, &obj->info.expire,
                    sizeof(obj->info.expire));
            slider += sizeof(obj->info.expire);

            varray = apr_array_make(r->pool, 6, sizeof(char*));
            tokens_to_array(r->pool, vary, varray);

            if (APR_SUCCESS != (rv = store_array(varray, sobj->buffer,
                    sobj->buffer_len, &slider))) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02370)
                        "buffer too small for Vary array, caching aborted: %s",
                        obj->key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return rv;
            }
            if (socache_mutex) {
                apr_status_t status = apr_global_mutex_lock(socache_mutex);
                if (status != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02371)
                            "could not acquire lock, ignoring: %s", obj->key);
                    apr_pool_destroy(sobj->pool);
                    sobj->pool = NULL;
                    return status;
                }
            }
            rv = conf->provider->socache_provider->store(
                    conf->provider->socache_instance, r->server,
                    (unsigned char *) obj->key, strlen(obj->key), sobj->expire,
                    (unsigned char *) sobj->buffer, (unsigned int) slider,
                    sobj->pool);
            if (socache_mutex) {
                apr_status_t status = apr_global_mutex_unlock(socache_mutex);
                if (status != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02372)
                            "could not release lock, ignoring: %s", obj->key);
                }
            }
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(02373)
                        "Vary not written to cache, ignoring: %s", obj->key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return rv;
            }

            obj->key = sobj->key = regen_key(r->pool, sobj->headers_in, varray,
                                             sobj->name, NULL);
        }
    }

    socache_info->format = CACHE_SOCACHE_DISK_FORMAT_VERSION;
    socache_info->date = obj->info.date;
    socache_info->expire = obj->info.expire;
    socache_info->entity_version = sobj->socache_info.entity_version++;
    socache_info->request_time = obj->info.request_time;
    socache_info->response_time = obj->info.response_time;
    socache_info->status = obj->info.status;

    if (r->header_only && r->status != HTTP_NOT_MODIFIED) {
        socache_info->header_only = 1;
    }
    else {
        socache_info->header_only = sobj->socache_info.header_only;
    }

    socache_info->name_len = strlen(sobj->name);

    memcpy(&socache_info->control, &obj->info.control, sizeof(cache_control_t));
    slider = sizeof(cache_socache_info_t);

    if (slider + socache_info->name_len >= sobj->buffer_len) {
        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02374)
                "cache buffer too small for name: %s",
                sobj->name);
        apr_pool_destroy(sobj->pool);
        sobj->pool = NULL;
        return APR_EGENERAL;
    }
    memcpy(sobj->buffer + slider, sobj->name, socache_info->name_len);
    slider += socache_info->name_len;

    if (sobj->headers_out) {
        if (APR_SUCCESS != store_table(sobj->headers_out, sobj->buffer,
                sobj->buffer_len, &slider)) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02375)
                    "out-headers didn't fit in buffer: %s", sobj->name);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return APR_EGENERAL;
        }
    }

    /* Parse the vary header and dump those fields from the headers_in. */
    /* TODO: Make call to the same thing cache_select calls to crack Vary. */
    if (sobj->headers_in) {
        if (APR_SUCCESS != store_table(sobj->headers_in, sobj->buffer,
                sobj->buffer_len, &slider)) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02376)
                    "in-headers didn't fit in buffer %s",
                    sobj->key);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return APR_EGENERAL;
        }
    }

    sobj->body_offset = slider;

    return APR_SUCCESS;
}

static apr_status_t store_body(cache_handle_t *h, request_rec *r,
        apr_bucket_brigade *in, apr_bucket_brigade *out)
{
    apr_bucket *e;
    apr_status_t rv = APR_SUCCESS;
    cache_socache_object_t *sobj =
            (cache_socache_object_t *) h->cache_obj->vobj;
    cache_socache_dir_conf *dconf =
            ap_get_module_config(r->per_dir_config, &cache_socache_module);
    int seen_eos = 0;

    if (!sobj->offset) {
        sobj->offset = dconf->readsize;
    }
    if (!sobj->timeout && dconf->readtime) {
        sobj->timeout = apr_time_now() + dconf->readtime;
    }

    if (!sobj->newbody) {
        sobj->body_length = 0;
        sobj->newbody = 1;
    }
    if (sobj->offset) {
        apr_brigade_partition(in, sobj->offset, &e);
    }

    while (APR_SUCCESS == rv && !APR_BRIGADE_EMPTY(in)) {
        const char *str;
        apr_size_t length;

        e = APR_BRIGADE_FIRST(in);

        /* are we done completely? if so, pass any trailing buckets right through */
        if (sobj->done || !sobj->pool) {
            APR_BUCKET_REMOVE(e);
            APR_BRIGADE_INSERT_TAIL(out, e);
            continue;
        }

        /* have we seen eos yet? */
        if (APR_BUCKET_IS_EOS(e)) {
            seen_eos = 1;
            sobj->done = 1;
            APR_BUCKET_REMOVE(e);
            APR_BRIGADE_INSERT_TAIL(out, e);
            break;
        }

        /* honour flush buckets, we'll get called again */
        if (APR_BUCKET_IS_FLUSH(e)) {
            APR_BUCKET_REMOVE(e);
            APR_BRIGADE_INSERT_TAIL(out, e);
            break;
        }

        /* metadata buckets are preserved as is */
        if (APR_BUCKET_IS_METADATA(e)) {
            APR_BUCKET_REMOVE(e);
            APR_BRIGADE_INSERT_TAIL(out, e);
            continue;
        }

        /* read the bucket, write to the cache */
        rv = apr_bucket_read(e, &str, &length, APR_BLOCK_READ);
        APR_BUCKET_REMOVE(e);
        APR_BRIGADE_INSERT_TAIL(out, e);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02377)
                    "Error when reading bucket for URL %s",
                    h->cache_obj->key);
            /* Remove the intermediate cache file and return non-APR_SUCCESS */
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return rv;
        }

        /* don't write empty buckets to the cache */
        if (!length) {
            continue;
        }

        sobj->body_length += length;
        if (sobj->body_length >= sobj->buffer_len - sobj->body_offset) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02378)
                    "URL %s failed the buffer size check "
                    "(%" APR_OFF_T_FMT ">=%" APR_SIZE_T_FMT ")",
                    h->cache_obj->key, sobj->body_length,
                    sobj->buffer_len - sobj->body_offset);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return APR_EGENERAL;
        }
        memcpy(sobj->buffer + sobj->body_offset + sobj->body_length - length,
               str, length);

        /* have we reached the limit of how much we're prepared to write in one
         * go? If so, leave, we'll get called again. This prevents us from trying
         * to swallow too much data at once, or taking so long to write the data
         * the client times out.
         */
        sobj->offset -= length;
        if (sobj->offset <= 0) {
            sobj->offset = 0;
            break;
        }
        if ((dconf->readtime && apr_time_now() > sobj->timeout)) {
            sobj->timeout = 0;
            break;
        }

    }

    /* Was this the final bucket? If yes, perform sanity checks.
     */
    if (seen_eos) {
        const char *cl_header;
        apr_off_t cl;

        if (r->connection->aborted || r->no_cache) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02380)
                    "Discarding body for URL %s "
                    "because connection has been aborted.",
                    h->cache_obj->key);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return APR_EGENERAL;
        }

        cl_header = apr_table_get(r->headers_out, "Content-Length");
        if (cl_header && (!ap_parse_strict_length(&cl, cl_header)
                          || cl != sobj->body_length)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02381)
                    "URL %s didn't receive complete response, not caching",
                    h->cache_obj->key);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return APR_EGENERAL;
        }

        /* All checks were fine, we're good to go when the commit comes */

    }

    return APR_SUCCESS;
}

static apr_status_t commit_entity(cache_handle_t *h, request_rec *r)
{
    cache_socache_conf *conf = ap_get_module_config(r->server->module_config,
            &cache_socache_module);
    cache_object_t *obj = h->cache_obj;
    cache_socache_object_t *sobj = (cache_socache_object_t *) obj->vobj;
    apr_status_t rv;

    if (socache_mutex) {
        apr_status_t status = apr_global_mutex_lock(socache_mutex);
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02384)
                    "could not acquire lock, ignoring: %s", obj->key);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return status;
        }
    }
    rv = conf->provider->socache_provider->store(
            conf->provider->socache_instance, r->server,
            (unsigned char *) sobj->key, strlen(sobj->key), sobj->expire,
            sobj->buffer, sobj->body_offset + sobj->body_length, sobj->pool);
    if (socache_mutex) {
        apr_status_t status = apr_global_mutex_unlock(socache_mutex);
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02385)
                    "could not release lock, ignoring: %s", obj->key);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return status;
        }
    }
    if (rv != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, APLOGNO(02386)
                "could not write to cache, ignoring: %s", sobj->key);
        goto fail;
    }

    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02387)
            "commit_entity: Headers and body for URL %s cached for maximum of %d seconds.",
            sobj->name, (apr_uint32_t)apr_time_sec(sobj->expire - r->request_time));

    apr_pool_destroy(sobj->pool);
    sobj->pool = NULL;

    return APR_SUCCESS;

fail:
    /* For safety, remove any existing entry on failure, just in case it could not
     * be revalidated successfully.
     */
    if (socache_mutex) {
        apr_status_t status = apr_global_mutex_lock(socache_mutex);
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02388)
                    "could not acquire lock, ignoring: %s", obj->key);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return rv;
        }
    }
    conf->provider->socache_provider->remove(conf->provider->socache_instance,
            r->server, (unsigned char *) sobj->key, strlen(sobj->key), r->pool);
    if (socache_mutex) {
        apr_status_t status = apr_global_mutex_unlock(socache_mutex);
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02389)
                    "could not release lock, ignoring: %s", obj->key);
        }
    }

    apr_pool_destroy(sobj->pool);
    sobj->pool = NULL;
    return rv;
}

static apr_status_t invalidate_entity(cache_handle_t *h, request_rec *r)
{
    /* mark the entity as invalidated */
    h->cache_obj->info.control.invalidated = 1;

    return commit_entity(h, r);
}

static void *create_dir_config(apr_pool_t *p, char *dummy)
{
    cache_socache_dir_conf *dconf =
            apr_pcalloc(p, sizeof(cache_socache_dir_conf));

    dconf->max = DEFAULT_MAX_FILE_SIZE;
    dconf->maxtime = apr_time_from_sec(DEFAULT_MAXTIME);
    dconf->mintime = apr_time_from_sec(DEFAULT_MINTIME);
    dconf->readsize = DEFAULT_READSIZE;
    dconf->readtime = DEFAULT_READTIME;

    return dconf;
}

static void *merge_dir_config(apr_pool_t *p, void *basev, void *addv)
{
    cache_socache_dir_conf
            *new =
                    (cache_socache_dir_conf *) apr_pcalloc(p, sizeof(cache_socache_dir_conf));
    cache_socache_dir_conf *add = (cache_socache_dir_conf *) addv;
    cache_socache_dir_conf *base = (cache_socache_dir_conf *) basev;

    new->max = (add->max_set == 0) ? base->max : add->max;
    new->max_set = add->max_set || base->max_set;
    new->maxtime = (add->maxtime_set == 0) ? base->maxtime : add->maxtime;
    new->maxtime_set = add->maxtime_set || base->maxtime_set;
    new->mintime = (add->mintime_set == 0) ? base->mintime : add->mintime;
    new->mintime_set = add->mintime_set || base->mintime_set;
    new->readsize = (add->readsize_set == 0) ? base->readsize : add->readsize;
    new->readsize_set = add->readsize_set || base->readsize_set;
    new->readtime = (add->readtime_set == 0) ? base->readtime : add->readtime;
    new->readtime_set = add->readtime_set || base->readtime_set;

    return new;
}

static void *create_config(apr_pool_t *p, server_rec *s)
{
    cache_socache_conf *conf = apr_pcalloc(p, sizeof(cache_socache_conf));

    return conf;
}

static void *merge_config(apr_pool_t *p, void *basev, void *overridesv)
{
    cache_socache_conf *ps;
    cache_socache_conf *base = (cache_socache_conf *) basev;
    cache_socache_conf *overrides = (cache_socache_conf *) overridesv;

    /* socache server config only has one field */
    ps = overrides ? overrides : base;

    return ps;
}

/*
 * mod_cache_socache configuration directives handlers.
 */
static const char *set_cache_socache(cmd_parms *cmd, void *in_struct_ptr,
        const char *arg)
{
    cache_socache_conf *conf = ap_get_module_config(cmd->server->module_config,
            &cache_socache_module);
    cache_socache_provider_conf *provider = conf->provider
            = apr_pcalloc(cmd->pool, sizeof(cache_socache_provider_conf));

    const char *err = NULL, *sep, *name;

    /* Argument is of form 'name:args' or just 'name'. */
    sep = ap_strchr_c(arg, ':');
    if (sep) {
        name = apr_pstrmemdup(cmd->pool, arg, sep - arg);
        sep++;
        provider->args = sep;
    }
    else {
        name = arg;
    }

    provider->socache_provider = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP,
            name, AP_SOCACHE_PROVIDER_VERSION);
    if (provider->socache_provider == NULL) {
        err = apr_psprintf(cmd->pool,
                    "Unknown socache provider '%s'. Maybe you need "
                    "to load the appropriate socache module "
                    "(mod_socache_%s?)", name, name);
    }
    return err;
}

static const char *set_cache_max(cmd_parms *parms, void *in_struct_ptr,
        const char *arg)
{
    cache_socache_dir_conf *dconf = (cache_socache_dir_conf *) in_struct_ptr;

    if (apr_strtoff(&dconf->max, arg, NULL, 10) != APR_SUCCESS
            || dconf->max < 1024 || dconf->max > APR_UINT32_MAX) {
        return "CacheSocacheMaxSize argument must be a integer representing "
               "the max size of a cached entry (headers and body), at least 1024 "
               "and at most " APR_STRINGIFY(APR_UINT32_MAX);
    }
    dconf->max_set = 1;
    return NULL;
}

static const char *set_cache_maxtime(cmd_parms *parms, void *in_struct_ptr,
        const char *arg)
{
    cache_socache_dir_conf *dconf = (cache_socache_dir_conf *) in_struct_ptr;
    apr_off_t seconds;

    if (apr_strtoff(&seconds, arg, NULL, 10) != APR_SUCCESS || seconds < 0) {
        return "CacheSocacheMaxTime argument must be the maximum amount of time in seconds to cache an entry.";
    }
    dconf->maxtime = apr_time_from_sec(seconds);
    dconf->maxtime_set = 1;
    return NULL;
}

static const char *set_cache_mintime(cmd_parms *parms, void *in_struct_ptr,
        const char *arg)
{
    cache_socache_dir_conf *dconf = (cache_socache_dir_conf *) in_struct_ptr;
    apr_off_t seconds;

    if (apr_strtoff(&seconds, arg, NULL, 10) != APR_SUCCESS || seconds < 0) {
        return "CacheSocacheMinTime argument must be the minimum amount of time in seconds to cache an entry.";
    }
    dconf->mintime = apr_time_from_sec(seconds);
    dconf->mintime_set = 1;
    return NULL;
}

static const char *set_cache_readsize(cmd_parms *parms, void *in_struct_ptr,
        const char *arg)
{
    cache_socache_dir_conf *dconf = (cache_socache_dir_conf *) in_struct_ptr;

    if (apr_strtoff(&dconf->readsize, arg, NULL, 10) != APR_SUCCESS
            || dconf->readsize < 0) {
        return "CacheSocacheReadSize argument must be a non-negative integer representing the max amount of data to cache in go.";
    }
    dconf->readsize_set = 1;
    return NULL;
}

static const char *set_cache_readtime(cmd_parms *parms, void *in_struct_ptr,
        const char *arg)
{
    cache_socache_dir_conf *dconf = (cache_socache_dir_conf *) in_struct_ptr;
    apr_off_t milliseconds;

    if (apr_strtoff(&milliseconds, arg, NULL, 10) != APR_SUCCESS
            || milliseconds < 0) {
        return "CacheSocacheReadTime argument must be a non-negative integer representing the max amount of time taken to cache in go.";
    }
    dconf->readtime = apr_time_from_msec(milliseconds);
    dconf->readtime_set = 1;
    return NULL;
}

static apr_status_t remove_lock(void *data)
{
    if (socache_mutex) {
        apr_global_mutex_destroy(socache_mutex);
        socache_mutex = NULL;
    }
    return APR_SUCCESS;
}

static apr_status_t destroy_cache(void *data)
{
    server_rec *s = data;
    cache_socache_conf *conf =
            ap_get_module_config(s->module_config, &cache_socache_module);
    if (conf->provider && conf->provider->socache_instance) {
        conf->provider->socache_provider->destroy(
                conf->provider->socache_instance, s);
        conf->provider->socache_instance = NULL;
    }
    return APR_SUCCESS;
}

static int socache_status_hook(request_rec *r, int flags)
{
    apr_status_t status = APR_SUCCESS;
    cache_socache_conf *conf = ap_get_module_config(r->server->module_config,
                                                    &cache_socache_module);
    if (!conf->provider || !conf->provider->socache_provider ||
        !conf->provider->socache_instance) {
        return DECLINED;
    }

    if (!(flags & AP_STATUS_SHORT)) {
        ap_rputs("<hr>\n"
                 "<table cellspacing=0 cellpadding=0>\n"
                 "<tr><td bgcolor=\"#000000\">\n"
                 "<b><font color=\"#ffffff\" face=\"Arial,Helvetica\">"
                 "mod_cache_socache Status:</font></b>\n"
                 "</td></tr>\n"
                 "<tr><td bgcolor=\"#ffffff\">\n", r);
    }
    else {
        ap_rputs("ModCacheSocacheStatus\n", r);
    }

    if (socache_mutex) {
        status = apr_global_mutex_lock(socache_mutex);
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02816)
                    "could not acquire lock for cache status");
        }
    }

    if (status != APR_SUCCESS) {
        if (!(flags & AP_STATUS_SHORT)) {
            ap_rputs("No cache status data available\n", r);
        }
        else {
            ap_rputs("NotAvailable\n", r);
        }
    } else {
        conf->provider->socache_provider->status(conf->provider->socache_instance,
                                                 r, flags);
    }

    if (socache_mutex && status == APR_SUCCESS) {
        status = apr_global_mutex_unlock(socache_mutex);
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02817)
                    "could not release lock for cache status");
        }
    }

    if (!(flags & AP_STATUS_SHORT)) {
        ap_rputs("</td></tr>\n</table>\n", r);
    }
    return OK;
}

static void socache_status_register(apr_pool_t *p)
{
    APR_OPTIONAL_HOOK(ap, status_hook, socache_status_hook, NULL, NULL, APR_HOOK_MIDDLE);
}

static int socache_precfg(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptmp)
{
    apr_status_t rv = ap_mutex_register(pconf, cache_socache_id, NULL,
            APR_LOCK_DEFAULT, 0);
    if (rv != APR_SUCCESS) {
        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(02390)
                "failed to register %s mutex", cache_socache_id);
        return 500; /* An HTTP status would be a misnomer! */
    }

    /* Register to handle mod_status status page generation */
    socache_status_register(pconf);

    return OK;
}

static int socache_post_config(apr_pool_t *pconf, apr_pool_t *plog,
        apr_pool_t *ptmp, server_rec *base_server)
{
    server_rec *s;
    apr_status_t rv;
    const char *errmsg;
    static struct ap_socache_hints socache_hints =
    { 64, 2048, 60000000 };

    for (s = base_server; s; s = s->next) {
        cache_socache_conf *conf =
                ap_get_module_config(s->module_config, &cache_socache_module);

        if (!conf->provider) {
            continue;
        }

        if (!socache_mutex && conf->provider->socache_provider->flags
                & AP_SOCACHE_FLAG_NOTMPSAFE) {

            rv = ap_global_mutex_create(&socache_mutex, NULL, cache_socache_id,
                    NULL, s, pconf, 0);
            if (rv != APR_SUCCESS) {
                ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(02391)
                        "failed to create %s mutex", cache_socache_id);
                return 500; /* An HTTP status would be a misnomer! */
            }
            apr_pool_cleanup_register(pconf, NULL, remove_lock,
                    apr_pool_cleanup_null);
        }

        errmsg = conf->provider->socache_provider->create(
                &conf->provider->socache_instance, conf->provider->args, ptmp,
                pconf);
        if (errmsg) {
            ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, plog,
                    APLOGNO(02392) "%s", errmsg);
            return 500; /* An HTTP status would be a misnomer! */
        }

        rv = conf->provider->socache_provider->init(
                conf->provider->socache_instance, cache_socache_id,
                &socache_hints, s, pconf);
        if (rv != APR_SUCCESS) {
            ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(02393)
                    "failed to initialise %s cache", cache_socache_id);
            return 500; /* An HTTP status would be a misnomer! */
        }
        apr_pool_cleanup_register(pconf, (void *) s, destroy_cache,
                apr_pool_cleanup_null);

    }

    return OK;
}

static void socache_child_init(apr_pool_t *p, server_rec *s)
{
    const char *lock;
    apr_status_t rv;
    if (!socache_mutex) {
        return; /* don't waste the overhead of creating mutex & cache */
    }
    lock = apr_global_mutex_lockfile(socache_mutex);
    rv = apr_global_mutex_child_init(&socache_mutex, lock, p);
    if (rv != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(02394)
                "failed to initialise mutex in child_init");
    }
}

static const command_rec cache_socache_cmds[] =
{
    AP_INIT_TAKE1("CacheSocache", set_cache_socache, NULL, RSRC_CONF,
            "The shared object cache to store cache files"),
    AP_INIT_TAKE1("CacheSocacheMaxTime", set_cache_maxtime, NULL, RSRC_CONF | ACCESS_CONF,
            "The maximum cache expiry age to cache a document in seconds"),
    AP_INIT_TAKE1("CacheSocacheMinTime", set_cache_mintime, NULL, RSRC_CONF | ACCESS_CONF,
            "The minimum cache expiry age to cache a document in seconds"),
    AP_INIT_TAKE1("CacheSocacheMaxSize", set_cache_max, NULL, RSRC_CONF | ACCESS_CONF,
            "The maximum cache entry size (headers and body) to cache a document"),
    AP_INIT_TAKE1("CacheSocacheReadSize", set_cache_readsize, NULL, RSRC_CONF | ACCESS_CONF,
            "The maximum quantity of data to attempt to read and cache in one go"),
    AP_INIT_TAKE1("CacheSocacheReadTime", set_cache_readtime, NULL, RSRC_CONF | ACCESS_CONF,
            "The maximum time taken to attempt to read and cache in go"),
    { NULL }
};

static const cache_provider cache_socache_provider =
{
    &remove_entity, &store_headers, &store_body, &recall_headers, &recall_body,
    &create_entity, &open_entity, &remove_url, &commit_entity,
    &invalidate_entity
};

static void cache_socache_register_hook(apr_pool_t *p)
{
    /* cache initializer */
    ap_register_provider(p, CACHE_PROVIDER_GROUP, "socache", "0",
            &cache_socache_provider);
    ap_hook_pre_config(socache_precfg, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_post_config(socache_post_config, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_child_init(socache_child_init, NULL, NULL, APR_HOOK_MIDDLE);
}

AP_DECLARE_MODULE(cache_socache) = { STANDARD20_MODULE_STUFF,
    create_dir_config,  /* create per-directory config structure */
    merge_dir_config, /* merge per-directory config structures */
    create_config, /* create per-server config structure */
    merge_config, /* merge per-server config structures */
    cache_socache_cmds, /* command apr_table_t */
    cache_socache_register_hook /* register hooks */
};
