core.c revision 82d2a5debc5a6ed2118ac5916d9ba36ad0b5d78b
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * applicable.
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * Licensed under the Apache License, Version 2.0 (the "License");
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * you may not use this file except in compliance with the License.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * You may obtain a copy of the License at
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Unless required by applicable law or agreed to in writing, software
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * distributed under the License is distributed on an "AS IS" BASIS,
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * See the License for the specific language governing permissions and
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * limitations under the License.
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding#include "http_protocol.h" /* For index_of_response(). Grump. */
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding#include "http_main.h" /* For the default_handler below... */
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding#include "mod_so.h" /* for ap_find_loaded_module_symbol */
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding/* LimitRequestBody handling */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* LimitXMLRequestBody handling */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* maximum include nesting level */
48d7c43629323c8d5ee9f7bd0d194de0a376b391rbb/* Server core module... This module provides support for really basic
d4f1d9c1ff112a8ab9bee31f196973761329b236rbb * server operations, including options and commands which control the
48d7c43629323c8d5ee9f7bd0d194de0a376b391rbb * operation of other modules. Consider this the bureaucracy module.
fdeba8dafd227781a897c772905bb32197e92797trawick * The core module also defines handlers, etc., do handle just enough
fdeba8dafd227781a897c772905bb32197e92797trawick * to allow a server with the core module ONLY to actually serve documents
48d7c43629323c8d5ee9f7bd0d194de0a376b391rbb * (though it slaps DefaultType on all of 'em); this was useful in testing,
d4f1d9c1ff112a8ab9bee31f196973761329b236rbb * but may not be worth preserving.
d41217398f0e1031adbb6f5bd37f45737c805deftrawick * This file could almost be mod_core.c, except for the stuff which affects
d41217398f0e1031adbb6f5bd37f45737c805deftrawick * the http_conf_globals.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* Handles for core filters */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingAP_DECLARE_DATA ap_filter_rec_t *ap_subreq_core_filter_handle;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingAP_DECLARE_DATA ap_filter_rec_t *ap_core_output_filter_handle;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingAP_DECLARE_DATA ap_filter_rec_t *ap_content_length_filter_handle;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingAP_DECLARE_DATA ap_filter_rec_t *ap_net_time_filter_handle;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingAP_DECLARE_DATA ap_filter_rec_t *ap_core_input_filter_handle;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* magic pointer for ErrorDocument xxx "default" */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic void *create_core_dir_config(apr_pool_t *a, char *dir)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf = (core_dir_config *)apr_pcalloc(a, sizeof(core_dir_config));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* conf->r and conf->d[_*] are initialized by dirsection() or left NULL */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->override_opts = OPT_UNSET | OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->use_canonical_name = USE_CANONICAL_NAME_UNSET;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->satisfy = apr_palloc(a, sizeof(*conf->satisfy) * METHODS);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding for (i = 0; i < METHODS; ++i) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->sec_file = apr_array_make(a, 2, sizeof(ap_conf_vector_t *));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->add_default_charset = ADD_DEFAULT_CHARSET_UNSET;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->add_default_charset_name = DEFAULT_ADD_DEFAULT_CHARSET_NAME;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* Overriding all negotiation
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Flag for use of inodes in ETags.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return (void *)conf;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Overlay one hash table of ct_output_filters onto another
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm const void *key,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const void *base_val,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const void *data)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const ap_filter_rec_t *overlay_info = (const ap_filter_rec_t *)overlay_val;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const ap_filter_rec_t *base_info = (const ap_filter_rec_t *)base_val;
66d349e02d1a5a599a01c977d2c5b0009181f7deben /* We can't have dups. */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding while (f) {
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawickstatic void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv)
74b39333600dee3260355ad3a06e36ef6c61c8f1dreid /* Create this conf by duplicating the base, replacing elements
d17890657bc529b3f9db20e5546511182b829565dreid * (or creating copies for merging) where new-> values exist.
d17890657bc529b3f9db20e5546511182b829565dreid conf = (core_dir_config *)apr_palloc(a, sizeof(core_dir_config));
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm /* there was no explicit setting of new->opts, so we merge
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * preserve the invariant (opts_add & opts_remove) == 0
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->opts_add = (conf->opts_add & ~new->opts_remove) | new->opts_add;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->opts_remove = (conf->opts_remove & ~new->opts_add)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->opts = (conf->opts & ~conf->opts_remove) | conf->opts_add;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if ((base->opts & OPT_INCNOEXEC) && (new->opts & OPT_INCLUDES)) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->opts = (conf->opts & ~OPT_INCNOEXEC) | OPT_INCLUDES;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* otherwise we just copy, because an explicit opts setting
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * overrides all earlier +/- modifiers
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->response_code_strings = new->response_code_strings;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* If we merge, the merge-result must have it's own array
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding sizeof(*conf->response_code_strings) * RESPONSE_CODES);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding memcpy(conf->response_code_strings, base->response_code_strings,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding sizeof(*conf->response_code_strings) * RESPONSE_CODES);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding for (i = 0; i < RESPONSE_CODES; ++i) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->response_code_strings[i] = new->response_code_strings[i];
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* Otherwise we simply use the base->response_code_strings array
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (new->hostname_lookups != HOSTNAME_LOOKUP_UNSET) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (new->use_canonical_name != USE_CANONICAL_NAME_UNSET) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->use_canonical_name = new->use_canonical_name;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm /* If we merge, the merge-result must have it's own array
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->sec_file = apr_array_append(a, base->sec_file, new->sec_file);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* Otherwise we simply use the base->sec_file array
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* use a separate ->satisfy[] array either way */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->satisfy = apr_palloc(a, sizeof(*conf->satisfy) * METHODS);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm for (i = 0; i < METHODS; ++i) {
35ecf536dec58844b65e1edfd1633d36ea091acbdreid if (new->add_default_charset != ADD_DEFAULT_CHARSET_UNSET) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->add_default_charset_name = new->add_default_charset_name;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* Overriding all negotiation
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (conf->ct_output_filters && new->ct_output_filters) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->ct_output_filters = apr_hash_copy(a, new->ct_output_filters);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* That memcpy above isn't enough. */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->ct_output_filters = apr_hash_copy(a, base->ct_output_filters);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Now merge the setting of the FileETag directive.
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick (conf->etag_add & (~ new->etag_remove)) | new->etag_add;
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf (conf->opts_remove & (~ new->etag_add)) | new->etag_remove;
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick (conf->etag_bits & (~ conf->etag_remove)) | conf->etag_add;
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf conf->allow_encoded_slashes = new->allow_encoded_slashes;
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf return (void*)conf;
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanfstatic void *create_core_server_config(apr_pool_t *a, server_rec *s)
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf conf = (core_server_config *)apr_pcalloc(a, sizeof(core_server_config));
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf conf->access_name = is_virtual ? NULL : DEFAULT_ACCESS_FNAME;
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm conf->ap_document_root = is_virtual ? NULL : DOCUMENT_LOCATION;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->sec_dir = apr_array_make(a, 40, sizeof(ap_conf_vector_t *));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf->sec_url = apr_array_make(a, 40, sizeof(ap_conf_vector_t *));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* recursion stopper */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return (void *)conf;
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanfstatic void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv)
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf core_server_config *base = (core_server_config *)basev;
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf core_server_config *virt = (core_server_config *)virtv;
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf conf = (core_server_config *)apr_palloc(p, sizeof(core_server_config));
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf conf->sec_dir = apr_array_append(p, base->sec_dir, virt->sec_dir);
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf conf->sec_url = apr_array_append(p, base->sec_url, virt->sec_url);
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf/* Add per-directory configuration entry (for <directory> section);
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf * these are part of the core server config.
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanfAP_CORE_DECLARE(void) ap_add_per_dir_conf(server_rec *s, void *dir_config)
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf core_server_config *sconf = ap_get_module_config(s->module_config,
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf void **new_space = (void **)apr_array_push(sconf->sec_dir);
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanfAP_CORE_DECLARE(void) ap_add_per_url_conf(server_rec *s, void *url_config)
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf core_server_config *sconf = ap_get_module_config(s->module_config,
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf void **new_space = (void **)apr_array_push(sconf->sec_url);
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanfAP_CORE_DECLARE(void) ap_add_file_conf(core_dir_config *conf, void *url_config)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding void **new_space = (void **)apr_array_push(conf->sec_file);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* We need to do a stable sort, qsort isn't stable. So to make it stable
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * we'll be maintaining the original index into the list, and using it
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * as the minor key during sorting. The major key is the number of
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * components (where the root component is zero).
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic int reorder_sorter(const void *va, const void *vb)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding core_a = ap_get_module_config(a->elt, &core_module);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding core_b = ap_get_module_config(b->elt, &core_module);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* a regex always sorts after a non-regex
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* we always sort next by the number of components
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf return -1;
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf else if (core_a->d_components > core_b->d_components) {
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf /* They have the same number of components, we now have to compare
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf * the minor key to maintain the original order (from the config.)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingvoid ap_core_reorder_directories(apr_pool_t *p, server_rec *s)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding sconf = ap_get_module_config(s->module_config, &core_module);
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf /* simple case of already being sorted... */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf /* We're not checking this condition to be fast... we're checking
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf * it to avoid trying to palloc zero bytes, which can trigger some
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf * memory debuggers to barf
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf /* we have to allocate tmp space to do a stable sort */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding sortbin = apr_palloc(tmp, sec_dir->nelts * sizeof(*sortbin));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding for (i = 0; i < nelts; ++i) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding qsort(sortbin, nelts, sizeof(*sortbin), reorder_sorter);
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick /* and now copy back to the original array */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf for (i = 0; i < nelts; ++i) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/*****************************************************************
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * There are some elements of the core config structures in which
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * other modules have a legitimate interest (this is ugly, but necessary
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * to preserve NCSA back-compatibility). So, we have a bunch of accessors
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingAP_DECLARE(const char *) ap_auth_name(request_rec *r)
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawickAP_DECLARE(const char *) ap_default_type(request_rec *r)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanfAP_DECLARE(const char *) ap_document_root(request_rec *r) /* Don't use this! */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf = (core_server_config *)ap_get_module_config(r->server->module_config,
93b653492fb3b4b65006e95a435629d806a9e589rbbAP_DECLARE(const apr_array_header_t *) ap_requires(request_rec *r)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
91583d2e9c0550f539ea6f4dedf051979ad1ad88fanf conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
91583d2e9c0550f539ea6f4dedf051979ad1ad88fanf/* Should probably just get rid of this... the only code that cares is
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * part of the core anyway (and in fact, it isn't publicised to other
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * modules).
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanfchar *ap_response_code_string(request_rec *r, int error_index)
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf /* check for string registered via ap_custom_response() first */
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf reqconf = (core_request_config *)ap_get_module_config(r->request_config,
45e5168aee4720a335af59306e297c1f58a82138fanf /* check for string specified via ErrorDocument */
45e5168aee4720a335af59306e297c1f58a82138fanf dirconf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf if (dirconf->response_code_strings[error_index] == &errordocument_default) {
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf/* Code from Harald Hanche-Olsen <hanche@imf.unit.no> */
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanfstatic APR_INLINE void do_double_reverse (conn_rec *conn)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* already done */
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf if (conn->remote_host == NULL || conn->remote_host[0] == '\0') {
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf /* single reverse failed, so don't bother */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding rv = apr_sockaddr_info_get(&sa, conn->remote_host, APR_UNSPEC, 0, 0, conn->pool);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingAP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!str_is_ip) { /* caller doesn't want to know */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* If we haven't checked the host name, and we want to */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ((core_dir_config *)ap_get_module_config(dir_config, &core_module))
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* the default */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (apr_getnameinfo(&conn->remote_host, conn->remote_addr, 0)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* if failed, set it to the NULL string to indicate error */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Return the desired information; either the remote DNS name, if found,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * or either NULL (if the hostname was requested) or the IP address
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * (if any identifier was requested).
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (conn->remote_host != NULL && conn->remote_host[0] != '\0') {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (type == REMOTE_HOST || type == REMOTE_DOUBLE_REV) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Optional function coming from mod_ident, used for looking up ident user
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic APR_OPTIONAL_FN_TYPE(ap_ident_lookup) *ident_lookup;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingAP_DECLARE(const char *) ap_get_remote_logname(request_rec *r)
382fa07a63096c4a1aabfed36433ea5ac9c40ad0trawick/* There are two options regarding what the "name" of a server is. The
382fa07a63096c4a1aabfed36433ea5ac9c40ad0trawick * "canonical" name as defined by ServerName and Port, or the "client's
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * name" as supplied by a possible Host: header or full URI. We never
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * trust the port passed in the client's headers, we always use the
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * port of the actual socket.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * The DNS option to UseCanonicalName causes this routine to do a
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * reverse lookup on the local IP address of the connection and use
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * that for the ServerName. This makes its value more reliable while
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * at the same time allowing Demon's magic virtual hosting to work.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * The assumption is that DNS lookups are sufficiently quick...
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * -- fanf 1998-10-03
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingAP_DECLARE(const char *) ap_get_server_name(request_rec *r)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding d = (core_dir_config *)ap_get_module_config(r->per_dir_config,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (d->use_canonical_name == USE_CANONICAL_NAME_ON) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* default */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return r->hostname ? r->hostname : r->server->server_hostname;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Get the current server name from the request for the purposes
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * of using in a URL. If the server name is an IPv6 literal
51af95bb51b5084e883bad250b2afa2838e9ceebfielding * address, it will be returned in URL format (e.g., "[fe80::1]").
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic const char *get_server_name_for_url(request_rec *r)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const char *plain_server_name = ap_get_server_name(r);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (ap_strchr_c(plain_server_name, ':')) { /* IPv6 literal? */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return apr_psprintf(r->pool, "[%s]", plain_server_name);
e93ddd15fd44e7542b9ace8567852ab2b7604bc7dreidAP_DECLARE(apr_port_t) ap_get_server_port(const request_rec *r)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (d->use_canonical_name == USE_CANONICAL_NAME_OFF
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding || d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* With UseCanonicalName off Apache will form self-referential
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * URLs using the hostname and port supplied by the client if
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * any are supplied (otherwise it will use the canonical name).
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding port = r->parsed_uri.port_str ? r->parsed_uri.port :
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding r->connection->local_addr->port ? r->connection->local_addr->port :
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding else { /* d->use_canonical_name == USE_CANONICAL_NAME_ON */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* With UseCanonicalName on (and in all versions prior to 1.3)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Apache will use the hostname and port specified in the
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * ServerName directive to construct a canonical name for the
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * server. (If no port was specified in the ServerName
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * directive, Apache uses the port supplied by the client if
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * any is supplied, and finally the default port for the protocol
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding r->connection->local_addr->port ? r->connection->local_addr->port :
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* default */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingAP_DECLARE(char *) ap_construct_url(apr_pool_t *p, const char *uri,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return apr_pstrcat(p, ap_http_scheme(r), "://", host, uri, NULL);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return apr_psprintf(p, "%s://%s:%u%s", ap_http_scheme(r), host, port, uri);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingAP_DECLARE(apr_off_t) ap_get_limit_req_body(const request_rec *r)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (d->limit_req_body == AP_LIMIT_REQ_BODY_UNSET) {
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm/*****************************************************************
91644a5f4d3e992dc208304b50e80bbb236fca89trawick * Commands... this module handles almost all of the NCSA httpd.conf
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * commands, but most of the old srm.conf is in the the modules.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* returns a parent if it matches the given directive */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic const ap_directive_t * find_parent(const ap_directive_t *dirp,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const char *what)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* ### it would be nice to have atom-ized directives */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanfAP_DECLARE(const char *) ap_check_cmd_context(cmd_parms *cmd,
return NULL;
return NULL;
const char *arg)
return err;
return NULL;
#ifdef GPROF
return err;
return NULL;
return err;
return NULL;
const char *arg)
return err;
arg);
return NULL;
const char *string)
int idx;
return err;
* http_protocol.c relies on to distinguish between
return NULL;
char *tok_state;
if (first) {
p = NULL;
first = 0;
return NULL;
return err;
return NULL;
char action;
action = *(w++);
else if (first) {
first = 0;
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 err;
return NULL;
const char *arg)
return err;
return NULL;
for (i = 0; i < METHODS; ++i) {
return NULL;
require_line *r;
if (!c->ap_requires) {
return NULL;
void *dummy,
const char *arg)
const char *limited_methods;
const char *errmsg;
return err;
if (!limited_methods[0]) {
while (limited_methods[0]) {
int methnum;
return errmsg;
#ifdef WIN32
#define USE_ICASE 0
const char *errmsg;
return err;
if (!arg[0]) {
if (!arg) {
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;
if (not) {
arg++;
if (!arg[0]) {
if (!found) {
if (!found) {
if (check_symbol) {
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;
const char *arg)
return err;
return NULL;
const char *portstr;
int port;
return err;
if (portstr) {
portstr++;
port = 0;
return NULL;
const char *arg)
return err;
return NULL;
const char *arg)
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
const char *arg)
return err;
return NULL;
const char *arg)
return err;
return NULL;
return err;
return NULL;
return NULL;
const char *arg)
return err;
return NULL;
const char *name)
unsigned *recursion;
void *data;
if (data) {
*recursion = 0;
*recursion = 0;
if (!conffile) {
*recursion = 0;
if (error) {
*recursion = 0;
return error;
if (*recursion) {
--*recursion;
return NULL;
char *str;
return err;
return NULL;
&core_module);
const char *word1)
return NULL;
static int version_locked = 0;
enum server_token_type {
version_locked = 0;
return APR_SUCCESS;
if (! version_locked) {
const char *arg)
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 err;
return NULL;
const char *arg)
return err;
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;
&core_module);
if (limit <= 0) {
if (arg2) {
if (limit <= 0) {
return NULL;
&core_module);
log_backtrace(r);
log_backtrace(r);
const char *filter_name;
if (old) {
while (*arg &&
if (old) {
if (!new) {
return NULL;
const char *ctype;
&core_module);
if (ctype) {
while (ct_filter) {
#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
* #defined them in mpm.h.
#ifdef AP_MPM_WANT_SET_PIDFILE
#ifdef AP_MPM_WANT_SET_SCOREBOARD
#ifdef AP_MPM_WANT_SET_LOCKFILE
#ifdef AP_MPM_WANT_SET_MAX_REQUESTS
#ifdef AP_MPM_WANT_SET_COREDUMPDIR
#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE
#ifdef AP_MPM_WANT_SET_STACKSIZE
{ NULL }
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;
/* 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;
&core_module);
return OK;
apr_bucket *e;
core_dir_config *d;
int errstatus;
int bld_content_md5;
&core_module);
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
? 0 : APR_SENDFILE_ENABLED)
return HTTP_FORBIDDEN;
ap_set_etag(r);
return errstatus;
if (bld_content_md5) {
c->bucket_alloc);
#if APR_HAS_MMAP
(void)apr_bucket_file_enable_mmap(e, 0);
return HTTP_NOT_IMPLEMENTED;
return ap_send_http_options(r);
return HTTP_METHOD_NOT_ALLOWED;
return OK;
&core_module);
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) {
if (!r->prev) {
return OK;
!= APR_SUCCESS) {
return NULL;
!= APR_SUCCESS) {
return NULL;
net->c = c;
return DONE;