blob: c31fbf09a7df0c671752e5e08d15aa786edfedeb [file] [log] [blame]
/*
** 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_strings.h"
#include "apreq_util.h"
#include "apreq_module_apache.h"
#include "apreq_version.h"
#include "httpd.h"
#include "http_log.h"
#include "http_request.h"
#include "apreq_private_apache.h"
/**
* <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_ReadLimit</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 APREQ_ERROR_GENERAL error will be reported to libapreq2 users via the return
* value of apreq_env_read().
* </TD></TR>
* <TR><TD>APREQ_BrigadeLimit</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_BrigadeLimit 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".
* XXX apreq parser registration in post_config
* </pre>
* @{
*/
static void *apreq_create_dir_config(pool *p, char *d)
{
/* d == OR_ALL */
struct dir_config *dc = ap_palloc(p, sizeof *dc);
dc->temp_dir = NULL;
dc->read_limit = (apr_uint64_t)-1;
dc->brigade_limit = APREQ_DEFAULT_BRIGADE_LIMIT;
return dc;
}
static void *apreq_merge_dir_config(pool *p, void *a_, void *b_)
{
struct dir_config *a = a_, *b = b_, *c = ap_palloc(p, sizeof *c);
c->temp_dir = (b->temp_dir != NULL) /* overrides ok */
? b->temp_dir : a->temp_dir;
c->brigade_limit = (b->brigade_limit == (apr_size_t)-1) /* overrides ok */
? a->brigade_limit : b->brigade_limit;
c->read_limit = (b->read_limit < a->read_limit) /* why min? */
? b->read_limit : a->read_limit;
return c;
}
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_read_limit(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->read_limit = apreq_atoi64f(arg);
return NULL;
}
static const char *apreq_set_brigade_limit(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->brigade_limit = apreq_atoi64f(arg);
return NULL;
}
static const command_rec apreq_cmds[] =
{
{ "APREQ_TempDir", apreq_set_temp_dir, NULL, OR_ALL, TAKE1,
"Default location of temporary directory" },
{ "APREQ_ReadLimit", apreq_set_read_limit, NULL, OR_ALL, TAKE1,
"Maximum amount of data that will be fed into a parser." },
{ "APREQ_BrigadeLimit", apreq_set_brigade_limit, NULL, OR_ALL, TAKE1,
"Maximum in-memory bytes a brigade may use." },
{ NULL }
};
static void apreq_cleanup(void *data)
{
apr_pool_t *p = data;
apr_pool_destroy(p);
apr_terminate();
}
static void apreq_init (server_rec *s, pool *sp)
{
/* APR_HOOK_FIRST because we want other modules to be able to
register parsers in their post_config hook */
apr_pool_t *p;
apr_initialize();
apr_pool_create(&p, NULL);
apreq_initialize(p);
ap_add_version_component(p, apr_psprintf(p,
"mod_apreq-%d/%s",
APREQ_APACHE_MMN,
apreq_version_string()));
ap_register_cleanup(sp, p, apreq_cleanup, apreq_cleanup);
}
/** @} */
module MODULE_VAR_EXPORT apreq_module =
{
STANDARD_MODULE_STUFF,
apreq_init, /* module initializer */
apreq_create_dir_config, /* per-directory config creator */
apreq_merge_dir_config, /* dir config merger */
NULL, /* server config creator */
NULL, /* server config merger */
apreq_cmds, /* command table */
NULL, /* [9] content handlers */
NULL, /* [2] URI-to-filename translation */
NULL, /* [5] check/validate user_id */
NULL, /* [6] check user_id is valid *here* */
NULL, /* [4] check access by host address */
NULL, /* [7] MIME type checker/setter */
NULL, /* [8] fixups */
NULL, /* [10] logger */
NULL, /* [3] header parser */
NULL, /* process initialization */
NULL, /* process exit/cleanup */
NULL /* [1] post read_request handling */
};