core.c revision fc251eb7714d158c2952bc2ddbbcfb9169098212
8a77240a809197c92c0736c431b4b88947a7bac1Christian Maeder/* Licensed to the Apache Software Foundation (ASF) under one or more
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder * contributor license agreements. See the NOTICE file distributed with
e9458b1a7a19a63aa4c179f9ab20f4d50681c168Jens Elkner * this work for additional information regarding copyright ownership.
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder * The ASF licenses this file to You under the Apache License, Version 2.0
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder * (the "License"); you may not use this file except in compliance with
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder * the License. You may obtain a copy of the License at
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu Prodescu * http://www.apache.org/licenses/LICENSE-2.0
6820f0de92751e29d73d64db48e776591f529a76Christian Maeder * Unless required by applicable law or agreed to in writing, software
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder * distributed under the License is distributed on an "AS IS" BASIS,
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder * See the License for the specific language governing permissions and
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder * limitations under the License.
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder#include "apr_thread_proc.h" /* for RLIMIT stuff */
e16b3696b2c173aac14200321868ed81b8f7dc69Christian Maeder#include "http_protocol.h" /* For index_of_response(). Grump. */
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder#include "http_main.h" /* For the default_handler below... */
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder#include "mod_so.h" /* for ap_find_loaded_module_symbol */
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder#if defined(RLIMIT_CPU) || defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS) || defined (RLIMIT_NPROC)
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder/* LimitRequestBody handling */
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder#define AP_LIMIT_REQ_BODY_UNSET ((apr_off_t) -1)
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 0)
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder/* LimitXMLRequestBody handling */
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder#define AP_DEFAULT_LIMIT_XML_BODY ((apr_size_t)1000000)
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder/* maximum include nesting level */
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder/* valid in core-conf, but not in runtime r->used_path_info */
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von SchroederAP_IMPLEMENT_HOOK_RUN_ALL(int, get_mgmt_items,
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder (apr_pool_t *p, const char *val, apr_hash_t *ht),
e16b3696b2c173aac14200321868ed81b8f7dc69Christian MaederAP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, insert_network_bucket,
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder/* Server core module... This module provides support for really basic
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder * server operations, including options and commands which control the
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder * operation of other modules. Consider this the bureaucracy module.
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder * The core module also defines handlers, etc., to handle just enough
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder * to allow a server with the core module ONLY to actually serve documents.
d71447e45047d07006b4c20409fbd8ea287df01fJonathan von Schroeder * This file could almost be mod_core.c, except for the stuff which affects
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder * the http_conf_globals.
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder/* we know core's module_index is 0 */
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
d71447e45047d07006b4c20409fbd8ea287df01fJonathan von Schroeder/* Handles for core filters */
d71447e45047d07006b4c20409fbd8ea287df01fJonathan von SchroederAP_DECLARE_DATA ap_filter_rec_t *ap_subreq_core_filter_handle;
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von SchroederAP_DECLARE_DATA ap_filter_rec_t *ap_core_output_filter_handle;
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von SchroederAP_DECLARE_DATA ap_filter_rec_t *ap_content_length_filter_handle;
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von SchroederAP_DECLARE_DATA ap_filter_rec_t *ap_core_input_filter_handle;
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder/* Provide ap_document_root_check storage and default value = true */
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von SchroederAP_DECLARE_DATA int ap_document_root_check = 1;
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder/* magic pointer for ErrorDocument xxx "default" */
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroederstatic apr_array_header_t *saved_server_config_defines = NULL;
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroederstatic apr_table_t *server_config_defined_vars = NULL;
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von SchroederAP_DECLARE_DATA int ap_main_state = AP_SQ_MS_INITIAL_STARTUP;
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von SchroederAP_DECLARE_DATA int ap_run_mode = AP_SQ_RM_UNKNOWN;
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von SchroederAP_DECLARE_DATA int ap_config_generation = 0;
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroederstatic void *create_core_dir_config(apr_pool_t *a, char *dir)
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder conf = (core_dir_config *)apr_pcalloc(a, sizeof(core_dir_config));
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder /* conf->r and conf->d[_*] are initialized by dirsection() or left NULL */
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder conf->opts = dir ? OPT_UNSET : OPT_UNSET|OPT_SYM_LINKS;
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder conf->opts_add = conf->opts_remove = OPT_NONE;
80d2ec8f37d5ddec13c14b17b1bab01e9c94630aChristian Maeder conf->override_opts = OPT_UNSET | OPT_ALL | OPT_SYM_OWNER | OPT_MULTI;
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder conf->content_md5 = AP_CONTENT_MD5_UNSET;
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder conf->accept_path_info = AP_ACCEPT_PATHINFO_UNSET;
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder conf->use_canonical_name = USE_CANONICAL_NAME_UNSET;
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder conf->use_canonical_phys_port = USE_CANONICAL_PHYS_PORT_UNSET;
d71447e45047d07006b4c20409fbd8ea287df01fJonathan von Schroeder conf->hostname_lookups = HOSTNAME_LOOKUP_UNSET;
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder * left as NULL (we use apr_pcalloc):
d71447e45047d07006b4c20409fbd8ea287df01fJonathan von Schroeder * conf->limit_cpu = NULL;
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder * conf->limit_mem = NULL;
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder * conf->limit_nproc = NULL;
d71447e45047d07006b4c20409fbd8ea287df01fJonathan von Schroeder * conf->sec_file = NULL;
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder * conf->sec_if = NULL;
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder conf->limit_req_body = AP_LIMIT_REQ_BODY_UNSET;
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder conf->limit_xml_body = AP_LIMIT_UNSET;
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder conf->server_signature = srv_sig_unset;
d71447e45047d07006b4c20409fbd8ea287df01fJonathan von Schroeder conf->add_default_charset = ADD_DEFAULT_CHARSET_UNSET;
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder conf->add_default_charset_name = DEFAULT_ADD_DEFAULT_CHARSET_NAME;
d71447e45047d07006b4c20409fbd8ea287df01fJonathan von Schroeder /* Overriding all negotiation
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder * Set NULL by apr_pcalloc:
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder * conf->mime_type = NULL;
d71447e45047d07006b4c20409fbd8ea287df01fJonathan von Schroeder * conf->handler = NULL;
ece3b1a5353a9af3c966a1d5453594ed35334f7bJonathan von Schroeder * conf->output_filters = NULL;
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder * conf->input_filters = NULL;
d71447e45047d07006b4c20409fbd8ea287df01fJonathan von Schroeder * Flag for use of inodes in ETags.
d71447e45047d07006b4c20409fbd8ea287df01fJonathan von Schroeder conf->enable_mmap = ENABLE_MMAP_UNSET;
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder conf->enable_sendfile = ENABLE_SENDFILE_UNSET;
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder conf->max_ranges = AP_MAXRANGES_UNSET;
d71447e45047d07006b4c20409fbd8ea287df01fJonathan von Schroeder conf->max_overlaps = AP_MAXRANGES_UNSET;
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder conf->max_reversals = AP_MAXRANGES_UNSET;
d71447e45047d07006b4c20409fbd8ea287df01fJonathan von Schroeder return (void *)conf;
d71447e45047d07006b4c20409fbd8ea287df01fJonathan von Schroederstatic void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv)
== OPT_INCLUDES)) {
for (i = 0; i < RESPONSE_CODES; ++i) {
#ifdef RLIMIT_CPU
#ifdef RLIMIT_NPROC
conf->max_overlaps = new->max_overlaps != AP_MAXRANGES_UNSET ? new->max_overlaps : base->max_overlaps;
conf->max_reversals = new->max_reversals != AP_MAXRANGES_UNSET ? new->max_reversals : base->max_reversals;
return (void*)conf;
#ifndef ACCEPT_FILTER_NAME
#ifdef __FreeBSD_version
if (!is_virtual) {
return (void *)conf;
return conf;
void *url_config)
void **new_space;
void *if_config)
void **new_space;
int have_if = 0;
ap_conf_vector_t *);
if (!have_if)
return NULL;
struct reorder_sort_rec {
int orig_index;
int nelts;
if (!nelts) {
for (i = 0; i < nelts; ++i) {
for (i = 0; i < nelts; ++i) {
if (authn_ap_auth_type) {
return authn_ap_auth_type(r);
return NULL;
if (authn_ap_auth_name) {
return authn_ap_auth_name(r);
return NULL;
access control interacts with authentication/authorization
if (access_compat_ap_satisfies) {
return access_compat_ap_satisfies(r);
return SATISFY_NOSPEC;
return ap_document_root(r);
const char *context_document_root)
if (context_prefix)
return NULL;
return NULL;
while (sa) {
int hostname_lookups;
int ignored_str_is_ip;
*str_is_ip = 0;
if (dir_config) {
== APR_SUCCESS) {
return NULL;
return NULL;
if (ident_lookup) {
return ident_lookup(r);
return NULL;
core_dir_config *d;
const char *retval;
switch (d->use_canonical_name) {
case USE_CANONICAL_NAME_ON:
case USE_CANONICAL_NAME_DNS:
case USE_CANONICAL_NAME_OFF:
case USE_CANONICAL_NAME_UNSET:
return retval;
#if APR_HAVE_IPV6
return plain_server_name;
core_dir_config *d =
switch (d->use_canonical_name) {
case USE_CANONICAL_NAME_OFF:
case USE_CANONICAL_NAME_DNS:
case USE_CANONICAL_NAME_UNSET:
ap_default_port(r);
ap_default_port(r);
case USE_CANONICAL_NAME_ON:
ap_default_port(r);
ap_default_port(r);
return port;
request_rec *r)
core_dir_config *d =
return AP_DEFAULT_LIMIT_REQ_BODY;
return d->limit_req_body;
* Commands... this module handles almost all of the NCSA httpd.conf
* commands, but most of the old srm.conf is in the the modules.
const char *what)
return dirp;
return NULL;
unsigned forbidden)
return NULL;
return NULL;
const char *arg)
return err;
return NULL;
struct sll {
const char *string;
const char *s, *e, *ep;
unsigned spc;
return word;
spc = 0;
if (!word)
if (word) {
name);
++outlen;
word = s;
} while (result);
return res_buf;
return OK;
if (err)
return err;
if (value) {
return NULL;
const char *name)
char **defines;
if (err)
return err;
if (server_config_defined_vars) {
return NULL;
const char *arg)
return arg;
#ifdef GPROF
return err;
return NULL;
return NULL;
const char *arg)
return err;
if (!ap_document_root_check) {
return NULL;
arg);
return NULL;
const char *string)
int idx;
* http_protocol.c relies on to distinguish between
return NULL;
char *tok_state;
if (first) {
p = NULL;
first = 0;
return NULL;
const char *err;
return err;
return NULL;
const char *err;
return err;
for (i=0;i<argc;i++){
return NULL;
return NULL;
int merge = 0;
int all_none = 0;
char action;
action = *(w++);
else if (first) {
else if (merge) {
if (!first) {
if (!first) {
first = 0;
return NULL;
const char *arg)
return NULL;
const char *args_p)
char action;
char *token;
const char *args;
int valid;
int first;
int explicit;
explicit = 0;
token++;
if (first) {
first = 0;
valid = 0;
valid = 0;
if (! valid) {
NULL);
if (explicit) {
return NULL;
const char *arg)
return NULL;
const char *arg)
return NULL;
void *dummy,
const char *arg)
const char *limited_methods;
const char *errmsg;
if (!limited_methods[0]) {
while (limited_methods[0]) {
int methnum;
NULL);
return errmsg;
#ifdef WIN32
#define USE_ICASE 0
const char *errmsg;
return err;
if (!arg[0]) {
char *newpath;
return errmsg;
conf->r = r;
return NULL;
const char *errmsg;
return err;
if (!arg[0]) {
return errmsg;
conf->r = r;
return NULL;
const char *errmsg;
return err;
if (!arg[0]) {
if (!old_path) {
char *newpath;
return errmsg;
conf->r = r;
return NULL;
const char *errmsg;
const char *condition;
const char *expr_err;
return err;
if (!old_path) {
ap_assert(0);
if (arg[0])
if (!arg[0])
if (expr_err)
expr_err);
return errmsg;
return errmsg;
return NULL;
if (!found) {
if (!found) {
if (check_symbol) {
return found;
if (not) {
arg++;
if (!arg[0]) {
const char *retval;
return retval;
char **defines;
const char *endp;
int not = 0;
arg++;
if (!arg[0]) {
const char *retval;
return retval;
/* httpd.conf commands... beginning with the <VirtualHost> business */
const char *arg)
const char *errmsg;
return err;
if (!arg[0]) {
if (errmsg) {
return errmsg;
s->lookup_defaults);
return errmsg;
const char *arg)
while (*arg) {
return NULL;
char* proto;
char* accf;
return err;
return NULL;
const char *arg)
char* proto;
return err;
return NULL;
const char *arg)
return err;
return NULL;
* ServerName www.example.com
* ServerName www.example.com:80
* ServerName https://www.example.com:443
char *scheme;
int port;
return err;
if (part) {
if (portstr) {
portstr++;
port = 0;
return NULL;
const char *arg)
return NULL;
const char *arg)
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
d->allow_encoded_slashes = 0;
d->decode_encoded_slashes = 0;
d->decode_encoded_slashes = 0;
NULL);
return NULL;
const char *arg)
return NULL;
const char *arg)
return err;
return NULL;
return NULL;
return NULL;
const char *arg)
return NULL;
const char *arg)
return NULL;
const char *name)
unsigned *recursion;
void *data;
if (data) {
*recursion = 0;
*recursion = 0;
if (!conffile) {
*recursion = 0;
optional);
if (error) {
*recursion = 0;
return error;
if (*recursion) {
--*recursion;
return NULL;
char *level_str;
int level;
const char *err;
return err;
return NULL;
if (!*level_str) {
return NULL;
static int banner_locked = 0;
enum server_token_type {
banner_locked = 0;
return APR_SUCCESS;
if (! banner_locked) {
return err;
return NULL;
const char *arg)
int lim;
return err;
if (lim < 0) {
return NULL;
const char *arg)
int lim;
return err;
if (lim < 0) {
NULL);
return NULL;
const char *arg)
int lim;
return err;
if (lim < 0) {
NULL);
return NULL;
const char *arg)
char *errp;
return NULL;
const char *arg)
return NULL;
int val = 0;
if (val <= 0)
return NULL;
int val = 0;
if (val <= 0)
return NULL;
int val = 0;
if (val <= 0)
return NULL;
return AP_DEFAULT_LIMIT_XML_BODY;
#if !defined (RLIMIT_CPU) || !(defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)) || !defined (RLIMIT_NPROC)
return NULL;
#ifdef RLIMIT_CPU
return NULL;
#if defined(RLIMIT_AS)
return NULL;
#ifdef RLIMIT_NPROC
return NULL;
if (limit <= 0) {
if (arg2) {
if (limit <= 0) {
return NULL;
log_backtrace(r);
log_backtrace(r);
const char *arg1)
return NULL;
const char **sa)
char *d = scratch;
s = *sa;
at_start = 0;
*sa = s;
return NULL;
const char **sa)
const char *s = *sa;
*sa = ++s;
*sa = ++s;
return NULL;
while (apr_isdigit(*++s))
*sa = ++s;
return NULL;
if (!handler) {
dummy[0] = *s;
*sa = ++s;
return NULL;
const char **err,
int is_main_fmt)
sizeof(ap_errorlog_format_item));
char *res;
int seen_msg_fmt = 0;
if (res) {
return NULL;
if (!is_main_fmt) {
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
if (!arg2) {
sizeof(apr_array_header_t *));
if (*arg2) {
apr_array_header_t **e;
sizeof(apr_array_header_t *));
if (*arg2) {
apr_array_header_t **e;
return err_string;
int flags)
#ifdef GPROF
"Set to on or off for PATH_INFO to be accepted by handlers, or default for the per-handler preference"),
#ifdef RLIMIT_CPU
#ifdef RLIMIT_NPROC
/* scoreboard.c directives */
{ NULL }
char *path;
if (r->proxyreq) {
return HTTP_FORBIDDEN;
return HTTP_BAD_REQUEST;
/* skip all leading /'s (e.g. http://localhost///foo)
++path;
!= APR_SUCCESS) {
return HTTP_FORBIDDEN;
return OK;
int access_status;
return access_status;
return access_status;
return OK;
return OK;
apr_bucket *e;
core_dir_config *d;
int errstatus;
int bld_content_md5;
return errstatus;
return HTTP_NOT_FOUND;
return HTTP_NOT_FOUND;
return HTTP_NOT_FOUND;
r->method);
return HTTP_METHOD_NOT_ALLOWED;
#if APR_HAS_SENDFILE
return HTTP_FORBIDDEN;
ap_set_etag(r);
if (bld_content_md5) {
#if APR_HAS_MMAP
(void)apr_bucket_file_enable_mmap(e, 0);
|| c->aborted) {
return OK;
status);
return HTTP_INTERNAL_SERVER_ERROR;
if (r->the_request
"Invalid method in request %s - possible attempt to establish SSL connection on non-SSL port", r->the_request);
return HTTP_NOT_IMPLEMENTED;
return ap_send_http_options(r);
return HTTP_METHOD_NOT_ALLOWED;
static int sys_privileges = 0;
return sys_privileges;
return APR_SUCCESS;
if (s->defn_name)
return !OK;
return OK;
s = s->next;
return rv;
return OK;
if (!sys_privileges) {
return !OK;
return OK;
if (filters) {
if (filters) {
return APR_SUCCESS;
return num_request_notes++;
return NULL;
if (!req_cfg) {
return NULL;
sizeof(void *) * num_request_notes);
if (r->main) {
return OK;
!= APR_SUCCESS) {
return NULL;
!= APR_SUCCESS) {
return NULL;
c->clogging_input_filters = 0;
net->c = c;
return DONE;
switch (query) {
case AP_SQ_MAIN_STATE:
return ap_main_state;
case AP_SQ_RUN_MODE:
return ap_run_mode;
case AP_SQ_CONFIG_GEN:
return ap_config_generation;
return AP_SQ_NOT_SUPPORTED;
#if APR_HAS_THREADS
#if APR_HAS_THREADS
int threaded_mpm;
&& threaded_mpm)
goto error;
#if APR_HAS_THREADS
if (rng_mutex)
#if APR_HAS_THREADS
if (rng_mutex)
return number;
return APR_SUCCESS;
const char *tmp;
const char **defines;
if (ap_scoreboard_fname) {
if (val)
ap_expr_init(p);