/*
**  Copyright 2003-2004  The Apache Software Foundation
**
**  Licensed 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 "httpd.h"
#include "http_config.h"
#include "http_log.h"
#include "util_filter.h"
#include "apr_tables.h"
#include "apr_buckets.h"
#include "http_request.h"
#include "apr_strings.h"

#include "apreq.h"
#include "apreq_env.h"
#include "apreq_params.h"
#include "apreq_cookie.h"

#define dR  request_rec *r = (request_rec *)env

struct dir_config {
    const char         *temp_dir;
    apr_off_t           max_body;
    apr_ssize_t         max_brigade;
};


static void *apreq_create_dir_config(apr_pool_t *p, char *d)
{
    /* d == OR_ALL */
    struct dir_config *dc = apr_palloc(p, sizeof *dc);
    dc->temp_dir    = NULL;
    dc->max_body    = -1;
    dc->max_brigade = APREQ_MAX_BRIGADE_LEN;
    return dc;
}

static void *apreq_merge_dir_config(apr_pool_t *p, void *a_, void *b_)
{
    struct dir_config *a = a_, *b = b_, *c = apr_palloc(p, sizeof *c);
    c->temp_dir    = (b->temp_dir != NULL)    ? b->temp_dir    : a->temp_dir;
    c->max_body    = (b->max_body >= 0)       ? b->max_body    : a->max_body;
    c->max_brigade = (b->max_brigade >= 0)    ? b->max_brigade : a->max_brigade;
    return c;
}


/* The "warehouse", stored in r->request_config */
struct env_config {
    apreq_jar_t        *jar;    /* Active jar for the current request_rec */
    apreq_request_t    *req;    /* Active request for current request_rec */
    ap_filter_t        *f;      /* Active apreq filter for this request_rec */
    const char         *temp_dir; /* Temporary directory for spool files */
    apr_off_t           max_body; /* Maximum bytes the parser may see */
    apr_ssize_t         max_brigade; /* Maximum heap space for brigades */
};

/* Tracks the apreq filter state */
struct filter_ctx {
    request_rec        *r;     /* request that originally created this filter */
    apr_bucket_brigade *bb;    /* input brigade that's passed to the parser */
    apr_bucket_brigade *spool; /* copied prefetch data for downstream filters */
    apr_status_t        status;/* APR_SUCCESS, APR_INCOMPLETE, or parse error */
    unsigned            saw_eos;      /* Has EOS bucket appeared in filter? */
    apr_off_t           bytes_read;   /* Total bytes read into this filter. */
};

static const char filter_name[] = "APREQ";
module AP_MODULE_DECLARE_DATA apreq_module;

/**
 * @defgroup mod_apreq Apache 2.X Filter Module
 * @ingroup apreq_env
 * @brief mod_apreq - DSO that ties libapreq2 to Apache 2.X.
 *
 * mod_apreq provides the "APREQ" input filter for using libapreq2
 * (and allow its parsed data structures to be shared) within
 * the Apache 2.X webserver.  Using it, libapreq2 works properly
 * in every phase of the HTTP request, from translation handlers 
 * to output filters, and even for subrequests / internal redirects.
 *
 * <hr>
 *
 * <h2>Activating mod_apreq in Apache 2.X</h2>
 *
 * Normally the installation process triggered by
 * <code>% make install</code>
 * will make the necessary changes to httpd.conf for you. In any case,
 * after installing the mod_apreq.so module, be sure your webserver's
 * httpd.conf activates it on startup with a LoadModule directive, e.g.
 * @code
 *
 *     LoadModule    modules/mod_apreq.so
 *
 * @endcode
 *
 * The mod_apreq filter is named "APREQ", and may be used in Apache's
 * input filter directives, e.g.
 * @code
 *
 *     AddInputFilter APREQ         # or
 *     SetInputFilter APREQ
 *
 * @endcode
 *
 * However, this is not required because libapreq2 will add the filter (only)
 * if it's necessary.  You just need to ensure that your module instantiates
 * an apreq_request_t using apreq_request() <em>before the content handler
 * ultimately reads from the input filter chain</em>.  It is important to
 * recognize that no matter how the input filters are initially arranged,
 * the APREQ filter will attempt to reposition itself to be the last input filter
 * to read the data.
 *
 * If you want to use other input filters to transform the incoming HTTP
 * request data, is important to register those filters with Apache
 * as having type AP_FTYPE_CONTENT_SET or AP_FTYPE_RESOURCE.  Due to the 
 * limitations of Apache's current input filter design, types higher than 
 * AP_FTYPE_CONTENT_SET may not work properly whenever the apreq filter is active.
 *
 * This is especially true when a content handler uses libapreq2 to parse 
 * some of the post data before doing an internal redirect.  Any input filter
 * subsequently added to the redirected request will bypass the original apreq 
 * filter (and therefore lose access to some of the original post data), unless 
 * its type is less than the type of the apreq filter (currently AP_FTYPE_PROTOCOL-1).
 *
 *
 * <h2>Server Configuration Directives</h2>
 *
 * <TABLE class="qref"><CAPTION>Per-directory commands for mod_apreq</CAPTION>
 * <TR><TH>Directive</TH><TH>Context</TH><TH>Default</TH><TH>Description</TH></TR>
 * <TR class="odd"><TD>APREQ_MaxBody</TD><TD>directory</TD><TD>-1 (Unlimited)</TD><TD>
 * Maximum number of bytes mod_apreq will send off to libapreq for parsing.  
 * mod_apreq will log this event and remove itself from the filter chain.
 * The APR_EGENERAL error will be reported to libapreq2 users via the return 
 * value of apreq_env_read().
 * </TD></TR>
 * <TR><TD>APREQ_MaxBrigade</TD><TD>directory</TD><TD> #APREQ_MAX_BRIGADE_LEN </TD><TD>
 * Maximum number of bytes apreq will allow to accumulate
 * within a brigade.  Excess data will be spooled to a
 * file bucket appended to the brigade.
 * </TD></TR>
 * <TR class="odd"><TD>APREQ_TempDir</TD><TD>directory</TD><TD>NULL</TD><TD>
 * Sets the location of the temporary directory apreq will use to spool
 * overflow brigade data (based on the APREQ_MaxBrigade setting).
 * If left unset, libapreq2 will select a platform-specific location via apr_temp_dir_get().
 * </TD></TR>
 * </TABLE>
 *
 * <h2>Implementation Details</h2>
 * <pre>
 * XXX apreq as a normal input filter
 * XXX apreq as a "virtual" content handler.
 * XXX apreq as a transparent "tee".
 * </pre>
 * @{
 */


#define APREQ_MODULE_NAME               "APACHE2"
#define APREQ_MODULE_MAGIC_NUMBER       20050105

static void apache2_log(const char *file, int line, int level, 
                        apr_status_t status, void *env, const char *fmt,
                        va_list vp)
{
    dR;
    ap_log_rerror(file, line, level, status, r, 
                  "%s", apr_pvsprintf(r->pool, fmt, vp));
}


static const char *apache2_query_string(void *env)
{
    dR;
    return r->args;
}

static apr_pool_t *apache2_pool(void *env)
{
    dR;
    return r->pool;
}

static apr_bucket_alloc_t *apache2_bucket_alloc(void *env)
{
    dR;
    return r->connection->bucket_alloc;
}

static const char *apache2_header_in(void *env, const char *name)
{
    dR;
    return apr_table_get(r->headers_in, name);
}

/*
 * r->headers_out ~> r->err_headers_out ?
 * @bug Sending a Set-Cookie header on a 304
 * requires err_headers_out table.
 */
static apr_status_t apache2_header_out(void *env, const char *name, 
                                       char *value)
{
    dR;
    apr_table_add(r->err_headers_out, name, value);
    return APR_SUCCESS;
}


APR_INLINE
static struct env_config *get_cfg(request_rec *r)
{
    struct env_config *cfg = 
        ap_get_module_config(r->request_config, &apreq_module);
    if (cfg == NULL) {
        struct dir_config *d = ap_get_module_config(r->per_dir_config, 
                                                    &apreq_module);
        cfg = apr_pcalloc(r->pool, sizeof *cfg);
        ap_set_module_config(r->request_config, &apreq_module, cfg);

        if (d) {
            cfg->temp_dir    = d->temp_dir;
            cfg->max_body    = d->max_body;
            cfg->max_brigade = d->max_brigade;
        } 
        else {
            cfg->max_body    = -1;
            cfg->max_brigade = APREQ_MAX_BRIGADE_LEN;
        }
    }
    return cfg;
}

static apreq_jar_t *apache2_jar(void *env, apreq_jar_t *jar)
{
    dR;
    struct env_config *c = get_cfg(r);
    if (jar != NULL) {
        apreq_jar_t *old = c->jar;
        c->jar = jar;
        return old;
    }
    return c->jar;
}

APR_INLINE
static void apreq_filter_relocate(ap_filter_t *f)
{
    request_rec *r = f->r;
    if (f != r->input_filters) {
        ap_filter_t *top = r->input_filters;
        ap_remove_input_filter(f);
        r->input_filters = f;
        f->next = top;
    }
}

static ap_filter_t *get_apreq_filter(request_rec *r)
{
    struct env_config *cfg = get_cfg(r);

    if (cfg->f != NULL)
       return cfg->f;

    cfg->f = ap_add_input_filter(filter_name, NULL, r, r->connection);

/* ap_add_input_filter does not guarantee cfg->f == r->input_filters,
 * so we reposition the new filter there as necessary.
 */

    apreq_filter_relocate(cfg->f); 
    return cfg->f;
}

static apreq_request_t *apache2_request(void *env, 
                                        apreq_request_t *req)
{
    dR;
    struct env_config *c = get_cfg(r);

    if (c->f == NULL)
        get_apreq_filter(r);

    if (req != NULL) {
        apreq_request_t *old = c->req;
        c->req = req;
        return old;
    }

    return c->req;
}

APR_INLINE
static void apreq_filter_make_context(ap_filter_t *f)
{
    request_rec *r = f->r;
    struct env_config *cfg = get_cfg(r);
    apreq_request_t *req = cfg->req;
    struct filter_ctx *ctx;
    apr_bucket_alloc_t *alloc;

    if (f == r->input_filters 
        && r->proto_input_filters == f->next
        && strcasecmp(f->next->frec->name, filter_name) == 0) 
    {
        /* Try to steal the context and parse data of the 
           upstream apreq filter. */
        ctx = f->next->ctx;

        switch (ctx->status) {
        case APR_SUCCESS:
        case APR_INCOMPLETE:
            break;
        default:
            apreq_log(APREQ_DEBUG ctx->status, r, 
                      "cannot steal context: bad filter status");
            goto make_new_context;
        }

        if (ctx->r != r) {
            /* r is a new request (subrequest or internal redirect) */
            apreq_request_t *old_req;

            if (req != NULL) {
                if (req->parser != NULL) {
                    apreq_log(APREQ_DEBUG ctx->status, r, 
                              "cannot steal context: new parser detected");
                    goto make_new_context;
                }
            }
            else {
                req = apreq_request(r, NULL);
            }

            /* steal the parser output */
            apreq_log(APREQ_DEBUG 0, r, "stealing parser output");
            old_req = apreq_request(ctx->r, NULL);
            req->parser = old_req->parser;
            req->body = old_req->body;
            req->body_status = old_req->body_status;
            ctx->r = r;
        }

        /* steal the filter context */
        apreq_log(APREQ_DEBUG 0, r, "stealing filter context");
        f->ctx = f->next->ctx;
        r->proto_input_filters = f;
        ap_remove_input_filter(f->next);
        return;
    }

 make_new_context:
    if (req != NULL && f == r->input_filters) {
        if (req->body_status != APR_EINIT) {
            req->body = NULL;
            req->parser = NULL;
            req->body_status = APR_EINIT;
        }
    }

    alloc = r->connection->bucket_alloc;
    ctx = apr_palloc(r->pool, sizeof *ctx);

    f->ctx       = ctx;
    ctx->r       = r;
    ctx->bb      = apr_brigade_create(r->pool, alloc);
    ctx->spool   = apr_brigade_create(r->pool, alloc);
    ctx->status  = APR_INCOMPLETE;
    ctx->saw_eos = 0;
    ctx->bytes_read = 0;

    if (cfg->max_body >= 0) {
        const char *cl = apr_table_get(r->headers_in, "Content-Length");
        if (cl != NULL) {
            char *dummy;
            apr_int64_t content_length = apr_strtoi64(cl,&dummy,0);

            if (dummy == NULL || *dummy != 0) {
                apreq_log(APREQ_ERROR APR_EGENERAL, r, 
                      "Invalid Content-Length header (%s)", cl);
                ctx->status = APR_EGENERAL;
                apreq_request(r, NULL)->body_status = APR_EGENERAL;
            }
            else if (content_length > (apr_int64_t)cfg->max_body) {
                apreq_log(APREQ_ERROR APR_EGENERAL, r,
                          "Content-Length header (%s) exceeds configured "
                          "max_body limit (%" APR_OFF_T_FMT ")", 
                          cl, cfg->max_body);
                ctx->status = APR_EGENERAL;
                apreq_request(r, NULL)->body_status = APR_EGENERAL;
            }
        }
    }
}

/*
 * Reads data directly into the parser.
 */

static apr_status_t apache2_read(void *env, 
                                 apr_read_type_e block,
                                 apr_off_t bytes)
{
    dR;
    ap_filter_t *f = get_apreq_filter(r); /*ensures correct filter for prefetch */
    struct filter_ctx *ctx;
    apr_status_t s;

    if (f->ctx == NULL)
        apreq_filter_make_context(f);
    ctx = f->ctx;
    if (ctx->status != APR_INCOMPLETE || bytes == 0)
        return ctx->status;

    apreq_log(APREQ_DEBUG 0, r, "prefetching %" APR_OFF_T_FMT " bytes", bytes);
    s = ap_get_brigade(f, NULL, AP_MODE_READBYTES, block, bytes);
    if (s != APR_SUCCESS)
        return s;
    return ctx->status;
}


static const char *apache2_temp_dir(void *env, const char *path)
{
    dR;
    struct env_config *c = get_cfg(r);

    if (path != NULL) {
        const char *rv = c->temp_dir;
        c->temp_dir = apr_pstrdup(r->pool, path);
        return rv;
    }
    if (c->temp_dir == NULL) {
        if (apr_temp_dir_get(&c->temp_dir, r->pool) != APR_SUCCESS)
            c->temp_dir = NULL;
    }

    return c->temp_dir;
}


static apr_off_t apache2_max_body(void *env, apr_off_t bytes)
{
    dR;
    struct env_config *c = get_cfg(r);

    if (bytes >= 0) {
        apr_off_t rv = c->max_body;
        c->max_body = bytes;
        return rv;
    }
    return c->max_body;
}


static apr_ssize_t apache2_max_brigade(void *env, apr_ssize_t bytes)
{
    dR;
    struct env_config *c = get_cfg(r);

    if (bytes >= 0) {
        apr_ssize_t rv = c->max_brigade;
        c->max_brigade = bytes;
        return rv;
    }
    return c->max_brigade;
}


/*
 * Situations to contend with:
 *
 * 1) Often the filter will be added by the content handler itself,
 *    so the apreq_filter_init hook will not be run.
 * 2) If an auth handler uses apreq, the apreq_filter will ensure
 *    it's part of the protocol filters.  apreq_filter_init does NOT need
 *    to notify the protocol filter that it must not continue parsing,
 *    the apreq filter can perform this check itself.  apreq_filter_init
 *    just needs to ensure cfg->f does not point at it.
 * 3) If req->proto_input_filters and req->input_filters are apreq
 *    filters, and req->input_filters->next == req->proto_input_filters,
 *    it is safe for apreq_filter to "steal" the proto filter's context 
 *    and subsequently drop it from the chain.
 */


/* Examines the input_filter chain and moves the apreq filter(s) around
 * before the filter chain is stacked by ap_get_brigade.
 */

static apr_status_t apreq_filter_init(ap_filter_t *f)
{
    request_rec *r = f->r;
    struct env_config *cfg = get_cfg(r);
    ap_filter_t *in;

    if (f != r->proto_input_filters) {
        if (f == r->input_filters) {
            cfg->f = f;
            return APR_SUCCESS;
        }
        for (in = r->input_filters; in != r->proto_input_filters; 
             in = in->next)
        {
            if (f == in) {
                if (strcasecmp(r->input_filters->frec->name, filter_name) == 0) {
                    apreq_log(APREQ_DEBUG 0, r, 
                              "removing intermediate apreq filter");
                    if (cfg->f == f)
                        cfg->f = r->input_filters;
                    ap_remove_input_filter(f);
                }
                else {
                    apreq_log(APREQ_DEBUG 0, r, 
                              "relocating intermediate apreq filter");
                    apreq_filter_relocate(f);
                    cfg->f = f;
                }
                return APR_SUCCESS;
            }
        }
    }

    /* else this is a protocol filter which may still be active.
     * if it is, we must deregister it now.
     */
    if (cfg->f == f) {
        apreq_log(APREQ_DEBUG 0, r, "disabling stale protocol filter");
        cfg->f = NULL;
    }
    return APR_SUCCESS;
}

static apr_status_t apreq_filter(ap_filter_t *f,
                                 apr_bucket_brigade *bb,
                                 ap_input_mode_t mode,
                                 apr_read_type_e block,
                                 apr_off_t readbytes)
{
    request_rec *r = f->r;
    struct filter_ctx *ctx;
    struct env_config *cfg;
    apreq_request_t *req;
    apr_status_t rv;

    switch (mode) {
    case AP_MODE_READBYTES:
    case AP_MODE_EXHAUSTIVE:
        /* only the modes above are supported */
        break;
    case AP_MODE_GETLINE: /* punt- chunks are b0rked in ap_http_filter */
        return ap_get_brigade(f->next, bb, mode, block, readbytes);
    default:
        return APR_ENOTIMPL;
    }

    cfg = get_cfg(r);
    req = cfg->req;

    if (f->ctx == NULL)
        apreq_filter_make_context(f);

    ctx = f->ctx;

    if (cfg->f != f)
        ctx->status = APR_SUCCESS;

    if (bb != NULL) {

        if (!ctx->saw_eos) {
 
            if (ctx->status == APR_INCOMPLETE) {
                apr_off_t len;
                rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
            
                if (rv != APR_SUCCESS) {
                    apreq_log(APREQ_ERROR rv, r, "ap_get_brigade failed");
                    return rv;
                }

                APREQ_BRIGADE_COPY(ctx->bb, bb);
                apr_brigade_length(bb, 1, &len);
                ctx->bytes_read += len;

                if (cfg->max_body >= 0 && ctx->bytes_read > cfg->max_body) {
                    ctx->status = APR_EGENERAL;
                    apreq_request(r, NULL)->body_status = APR_EGENERAL;
                    apreq_log(APREQ_ERROR ctx->status, r, "Bytes read (" APR_OFF_T_FMT
                              ") exceeds configured max_body limit (" APR_OFF_T_FMT ")",
                              ctx->bytes_read, cfg->max_body);
                }

            }
            if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(ctx->bb)))
                ctx->saw_eos = 1;
        }

        if (!APR_BRIGADE_EMPTY(ctx->spool)) {
            APR_BRIGADE_PREPEND(bb, ctx->spool);
            if (mode == AP_MODE_READBYTES) {
                apr_bucket *e;
                rv = apr_brigade_partition(bb, readbytes, &e);
                if (rv != APR_SUCCESS && rv != APR_INCOMPLETE) {
                    apreq_log(APREQ_ERROR rv, r, "partition failed");
                    return rv;
                }
                if (APR_BUCKET_IS_EOS(e))
                    e = APR_BUCKET_NEXT(e);
                ctx->spool = apr_brigade_split(bb, e);
                APREQ_BRIGADE_SETASIDE(ctx->spool,r->pool);
            }
        }

        if (ctx->status != APR_INCOMPLETE) {
            if (APR_BRIGADE_EMPTY(ctx->spool)) {
                ap_filter_t *next = f->next;

                if (cfg->f != f) {
                    apreq_log(APREQ_DEBUG ctx->status, r,
                              "removing inactive filter (%d)",
                              r->input_filters == f);

                    ap_remove_input_filter(f);
                }
                if (APR_BRIGADE_EMPTY(bb))
                    return ap_get_brigade(next, bb, mode, block, readbytes);
            }
            return APR_SUCCESS;
        }
    }
    else if (!ctx->saw_eos) {
        /* bb == NULL, so this is a prefetch read! */
        apr_off_t total_read = 0;

        bb = apr_brigade_create(ctx->bb->p, ctx->bb->bucket_alloc);

        while (total_read < readbytes) {
            apr_off_t len;
            apr_bucket *last = APR_BRIGADE_LAST(ctx->spool);

            if (APR_BUCKET_IS_EOS(last)) {
                ctx->saw_eos = 1;
                break;
            }

            rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
            if (rv != APR_SUCCESS) {
                apreq_log(APREQ_ERROR rv, r, "ap_get_brigade failed");
                return rv;
            }
            APREQ_BRIGADE_SETASIDE(bb, r->pool);
            APREQ_BRIGADE_COPY(ctx->bb, bb);

            apr_brigade_length(bb, 1, &len);
            total_read += len;

            rv = apreq_brigade_concat(r, ctx->spool, bb);
            if (rv != APR_SUCCESS && rv != APR_EOF) {
                apreq_log(APREQ_ERROR rv, r,
                          "apreq_brigade_concat failed; APREQ_TempDir problem?");
                return rv;
            }
        }

        ctx->bytes_read += total_read;

        if (cfg->max_body >= 0 && ctx->bytes_read > cfg->max_body) {
            ctx->status = APR_EGENERAL;
            apreq_request(r, NULL)->body_status = APR_EGENERAL;
            apreq_log(APREQ_ERROR ctx->status, r, "Bytes read (%" APR_OFF_T_FMT
                      ") exceeds configured max_body limit (%" APR_OFF_T_FMT ")",
                      ctx->bytes_read, cfg->max_body);
        }

        /* Adding "f" to the protocol filter chain ensures the 
         * spooled data is preserved across internal redirects.
         */
        if (f != r->proto_input_filters) {
            ap_filter_t *in;
            for (in = r->input_filters; in != r->proto_input_filters; 
                 in = in->next)
            {
                if (f == in) {
                    r->proto_input_filters = f;
                    break;
                }
            }
        }
    }
    else
        return APR_SUCCESS;

    if (ctx->status == APR_INCOMPLETE) {
        if (req == NULL)
            req = apreq_request(r, NULL);

        ctx->status = apreq_parse_request(req, ctx->bb);
        apr_brigade_cleanup(ctx->bb);
    }

    return APR_SUCCESS;
}

static APREQ_ENV_MODULE(apache2, APREQ_MODULE_NAME,
                        APREQ_MODULE_MAGIC_NUMBER);

static void register_hooks (apr_pool_t *p)
{
    const apreq_env_t *old_env;
    old_env = apreq_env_module(&apache2_module);
    ap_register_input_filter(filter_name, apreq_filter, apreq_filter_init,
                             AP_FTYPE_PROTOCOL-1);
}


/* Configuration directives */


static const char *apreq_set_temp_dir(cmd_parms *cmd, void *data,
                                      const char *arg)
{
    struct dir_config *conf = data;
    const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);

    if (err != NULL)
        return err;

    conf->temp_dir = arg;
    return NULL;
}

static const char *apreq_set_max_body(cmd_parms *cmd, void *data,
                                      const char *arg)
{
    struct dir_config *conf = data;
    const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);

    if (err != NULL)
        return err;

    conf->max_body = apreq_atoi64f(arg);

    if (conf->max_body < 0)
        return "APREQ_MaxBody requires a non-negative integer.";

    return NULL;
}

static const char *apreq_set_max_brigade(cmd_parms *cmd, void *data,
                                          const char *arg)
{
    struct dir_config *conf = data;
    const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);

    if (err != NULL)
        return err;

    conf->max_brigade = apreq_atoi64f(arg);

    if (conf->max_brigade < 0)
        return "APREQ_MaxBrigade requires a non-negative integer.";

    return NULL;
}

static const command_rec apreq_cmds[] =
{
    AP_INIT_TAKE1("APREQ_TempDir", apreq_set_temp_dir, NULL, OR_ALL,
                  "Default location of temporary directory"),
    AP_INIT_TAKE1("APREQ_MaxBody", apreq_set_max_body, NULL, OR_ALL,
                  "Maximum amount of data that will be fed into a parser."),
    AP_INIT_TAKE1("APREQ_MaxBrigade", apreq_set_max_brigade, NULL, OR_ALL,
                  "Maximum in-memory bytes a brigade may use."),
    {NULL}
};

/** @} */

module AP_MODULE_DECLARE_DATA apreq_module =
{
	STANDARD20_MODULE_STUFF,
	apreq_create_dir_config,
	apreq_merge_dir_config,
	NULL,
	NULL,
	apreq_cmds,
	register_hooks,
};
