http_core.c revision cccd31fa4a72fe23cc3249c06db181b274a55a69
08cb74ca432a8c24e39f17dedce527e6a47b8001jerenkrantz/* ====================================================================
08cb74ca432a8c24e39f17dedce527e6a47b8001jerenkrantz * The Apache Software License, Version 1.1
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Copyright (c) 2000 The Apache Software Foundation. All rights
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * reserved.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Redistribution and use in source and binary forms, with or without
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * modification, are permitted provided that the following conditions
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * are met:
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * 1. Redistributions of source code must retain the above copyright
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * notice, this list of conditions and the following disclaimer.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * 2. Redistributions in binary form must reproduce the above copyright
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * notice, this list of conditions and the following disclaimer in
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * the documentation and/or other materials provided with the
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * distribution.
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh *
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh * 3. The end-user documentation included with the redistribution,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * if any, must include the following acknowledgment:
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh * "This product includes software developed by the
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Apache Software Foundation (http://www.apache.org/)."
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Alternately, this acknowledgment may appear in the software itself,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * if and wherever such third-party acknowledgments normally appear.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * 4. The names "Apache" and "Apache Software Foundation" must
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * not be used to endorse or promote products derived from this
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * software without prior written permission. For written
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * permission, please contact apache@apache.org.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * 5. Products derived from this software may not be called "Apache",
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * nor may "Apache" appear in their name, without prior written
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * permission of the Apache Software Foundation.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
f888346b48f5e5b5e3f0a47dedb8cefd2759a4e2gregames * SUCH DAMAGE.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * ====================================================================
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * This software consists of voluntary contributions made by many
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * individuals on behalf of the Apache Software Foundation. For more
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * information on the Apache Software Foundation, please see
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * <http://www.apache.org/>.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Portions of this software are based upon public domain software
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz * originally written at the National Center for Supercomputing Applications,
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz * University of Illinois, Urbana-Champaign.
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz */
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz#include "apr.h"
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz#include "apr_strings.h"
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz#include "apr_lib.h"
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz#include "apr_fnmatch.h"
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz#include "apr_thread_proc.h" /* for RLIMIT stuff */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#if APR_HAVE_SYS_UIO_H
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include <sys/uio.h> /* for iovec */
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#endif
a2a0abd88b19e042a3eb2a9fa1702c25ad51303dwrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#define CORE_PRIVATE
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "ap_config.h"
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#include "httpd.h"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "http_config.h"
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#include "http_core.h"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "http_protocol.h" /* For index_of_response(). Grump. */
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#include "http_request.h"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "http_vhost.h"
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#include "http_main.h" /* For the default_handler below... */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "http_log.h"
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#include "rfc1413.h"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "util_md5.h"
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#include "http_connection.h"
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#include "ap_buckets.h"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "util_filter.h"
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#include "util_ebcdic.h"
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#include "mpm.h"
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#ifdef HAVE_NETDB_H
2d399cd7535887fceaa9f8f116eb98ce68ddd602trawick#include <netdb.h>
c2cf53a40a9814eb91db2cdf820f97d943f21628coar#endif
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#ifdef HAVE_SYS_SOCKET_H
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#include <sys/socket.h>
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar#endif
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#ifdef HAVE_ARPA_INET_H
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar#include <arpa/inet.h>
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#endif
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#ifdef HAVE_STRINGS_H
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#include <strings.h>
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#endif
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe/* LimitXMLRequestBody handling */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#define AP_LIMIT_UNSET ((long) -1)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#define AP_DEFAULT_LIMIT_XML_BODY ((size_t)1000000)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
3e392a5afd51526de3cb15d57ee46d8cb160ae65gregames/* Server core module... This module provides support for really basic
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * server operations, including options and commands which control the
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * operation of other modules. Consider this the bureaucracy module.
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe *
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * The core module also defines handlers, etc., do handle just enough
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar * to allow a server with the core module ONLY to actually serve documents
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar * (though it slaps DefaultType on all of 'em); this was useful in testing,
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar * but may not be worth preserving.
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar *
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar * This file could almost be mod_core.c, except for the stuff which affects
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar * the http_conf_globals.
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar */
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantzstatic void *create_core_dir_config(apr_pool_t *a, char *dir)
2a6e98ba4ffa30ded5d8831664c5cb2a170a56b6coar{
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar core_dir_config *conf;
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar conf = (core_dir_config *)apr_pcalloc(a, sizeof(core_dir_config));
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar if (!dir || dir[strlen(dir) - 1] == '/') {
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar conf->d = dir;
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar }
2a6e98ba4ffa30ded5d8831664c5cb2a170a56b6coar else if (strncmp(dir, "proxy:", 6) == 0) {
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz conf->d = apr_pstrdup(a, dir);
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe else {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe conf->d = apr_pstrcat(a, dir, "/", NULL);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe conf->d_is_fnmatch = conf->d ? (apr_is_fnmatch(conf->d) != 0) : 0;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker conf->d_components = conf->d ? ap_count_dirs(conf->d) : 0;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
3e392a5afd51526de3cb15d57ee46d8cb160ae65gregames conf->opts = dir ? OPT_UNSET : OPT_UNSET|OPT_ALL;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf->opts_add = conf->opts_remove = OPT_NONE;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar conf->override = dir ? OR_UNSET : OR_UNSET|OR_ALL;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf->content_md5 = 2;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe conf->use_canonical_name = USE_CANONICAL_NAME_UNSET;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf->hostname_lookups = HOSTNAME_LOOKUP_UNSET;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf->do_rfc1413 = DEFAULT_RFC1413 | 2; /* set bit 1 to indicate default */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe conf->satisfy = SATISFY_NOSPEC;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#ifdef RLIMIT_CPU
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf->limit_cpu = NULL;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe#endif
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)
c2cf53a40a9814eb91db2cdf820f97d943f21628coar conf->limit_mem = NULL;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#endif
4775dfc34c90fada8c7c4d6a57ed8a3114d55c2dtrawick#ifdef RLIMIT_NPROC
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe conf->limit_nproc = NULL;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#endif
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf->limit_req_body = 0;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar conf->limit_xml_body = AP_LIMIT_UNSET;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf->sec = apr_make_array(a, 2, sizeof(void *));
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe#ifdef WIN32
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf->script_interpreter_source = INTERPRETER_SOURCE_UNSET;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe#endif
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe conf->server_signature = srv_sig_unset;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe conf->add_default_charset = ADD_DEFAULT_CHARSET_UNSET;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe conf->add_default_charset_name = DEFAULT_ADD_DEFAULT_CHARSET_NAME;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe conf->output_filters = apr_make_array(a, 2, sizeof(void *));
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe conf->input_filters = apr_make_array(a, 2, sizeof(void *));
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe return (void *)conf;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe}
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowestatic void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv)
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe{
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe core_dir_config *base = (core_dir_config *)basev;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe core_dir_config *new = (core_dir_config *)newv;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe core_dir_config *conf;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker int i;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker conf = (core_dir_config *)apr_palloc(a, sizeof(core_dir_config));
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe memcpy((char *)conf, (const char *)base, sizeof(core_dir_config));
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (base->response_code_strings) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf->response_code_strings =
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe apr_palloc(a, sizeof(*conf->response_code_strings)
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar * RESPONSE_CODES);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe memcpy(conf->response_code_strings, base->response_code_strings,
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe sizeof(*conf->response_code_strings) * RESPONSE_CODES);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf->d = new->d;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe conf->d_is_fnmatch = new->d_is_fnmatch;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker conf->d_components = new->d_components;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf->r = new->r;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
c2cf53a40a9814eb91db2cdf820f97d943f21628coar if (new->opts & OPT_UNSET) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe /* there was no explicit setting of new->opts, so we merge
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz * preserve the invariant (opts_add & opts_remove) == 0
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz */
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz conf->opts_add = (conf->opts_add & ~new->opts_remove) | new->opts_add;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf->opts_remove = (conf->opts_remove & ~new->opts_add)
4f9c22c4f27571d54197be9674e1fc0d528192aestriker | new->opts_remove;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar conf->opts = (conf->opts & ~conf->opts_remove) | conf->opts_add;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar if ((base->opts & OPT_INCNOEXEC) && (new->opts & OPT_INCLUDES)) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf->opts = (conf->opts & ~OPT_INCNOEXEC) | OPT_INCLUDES;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz }
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz }
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz else {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe /* otherwise we just copy, because an explicit opts setting
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * overrides all earlier +/- modifiers
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe */
4f9c22c4f27571d54197be9674e1fc0d528192aestriker conf->opts = new->opts;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf->opts_add = new->opts_add;
08ab23ee4e41ac8587da5a3bb8d4e9c49523b0b8nd conf->opts_remove = new->opts_remove;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
08ab23ee4e41ac8587da5a3bb8d4e9c49523b0b8nd
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (!(new->override & OR_UNSET)) {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker conf->override = new->override;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar }
c2cf53a40a9814eb91db2cdf820f97d943f21628coar if (new->ap_default_type) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf->ap_default_type = new->ap_default_type;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz }
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz if (new->ap_auth_type) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf->ap_auth_type = new->ap_auth_type;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
c2cf53a40a9814eb91db2cdf820f97d943f21628coar if (new->ap_auth_name) {
c2cf53a40a9814eb91db2cdf820f97d943f21628coar conf->ap_auth_name = new->ap_auth_name;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz if (new->ap_requires) {
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz conf->ap_requires = new->ap_requires;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (new->response_code_strings) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (conf->response_code_strings == NULL) {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe conf->response_code_strings = apr_palloc(a,
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe sizeof(*conf->response_code_strings) * RESPONSE_CODES);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe memcpy(conf->response_code_strings, new->response_code_strings,
4f9c22c4f27571d54197be9674e1fc0d528192aestriker sizeof(*conf->response_code_strings) * RESPONSE_CODES);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe else {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe for (i = 0; i < RESPONSE_CODES; ++i) {
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz if (new->response_code_strings[i] != NULL) {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe conf->response_code_strings[i]
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe = new->response_code_strings[i];
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (new->hostname_lookups != HOSTNAME_LOOKUP_UNSET) {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe conf->hostname_lookups = new->hostname_lookups;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if ((new->do_rfc1413 & 2) == 0) {
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe conf->do_rfc1413 = new->do_rfc1413;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe if ((new->content_md5 & 2) == 0) {
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe conf->content_md5 = new->content_md5;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (new->use_canonical_name != USE_CANONICAL_NAME_UNSET) {
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe conf->use_canonical_name = new->use_canonical_name;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe#ifdef RLIMIT_CPU
0540a0b469147b52e858587270dba31c2aaa9e09wrowe if (new->limit_cpu) {
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe conf->limit_cpu = new->limit_cpu;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe#endif
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe if (new->limit_mem) {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker conf->limit_mem = new->limit_mem;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#endif
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#ifdef RLIMIT_NPROC
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (new->limit_nproc) {
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe conf->limit_nproc = new->limit_nproc;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp#endif
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe if (new->limit_req_body) {
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp conf->limit_req_body = new->limit_req_body;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe if (new->limit_xml_body != AP_LIMIT_UNSET)
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe conf->limit_xml_body = new->limit_xml_body;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe else
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe conf->limit_xml_body = base->limit_xml_body;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp conf->sec = apr_append_arrays(a, base->sec, new->sec);
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp if (new->satisfy != SATISFY_NOSPEC) {
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp conf->satisfy = new->satisfy;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp#ifdef WIN32
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (new->script_interpreter_source != INTERPRETER_SOURCE_UNSET) {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker conf->script_interpreter_source = new->script_interpreter_source;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#endif
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (new->server_signature != srv_sig_unset) {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker conf->server_signature = new->server_signature;
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp }
7a2edaa0193cbb0d79a65a8461a609a9402aea49brianp
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe if (new->add_default_charset != ADD_DEFAULT_CHARSET_UNSET) {
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe conf->add_default_charset = new->add_default_charset;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe if (new->add_default_charset_name) {
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe conf->add_default_charset_name = new->add_default_charset_name;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker conf->output_filters = apr_append_arrays(a, base->output_filters,
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp new->output_filters);
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe conf->input_filters = apr_append_arrays(a, base->input_filters,
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe new->input_filters);
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe return (void*)conf;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic void *create_core_server_config(apr_pool_t *a, server_rec *s)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb core_server_config *conf;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int is_virtual = s->is_virtual;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb conf = (core_server_config *)apr_pcalloc(a, sizeof(core_server_config));
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#ifdef GPROF
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb conf->gprof_dir = NULL;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#endif
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb conf->access_name = is_virtual ? NULL : DEFAULT_ACCESS_FNAME;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb conf->ap_document_root = is_virtual ? NULL : DOCUMENT_LOCATION;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb conf->sec = apr_make_array(a, 40, sizeof(void *));
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb conf->sec_url = apr_make_array(a, 40, sizeof(void *));
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe return (void *)conf;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe}
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowestatic void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv)
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe{
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe core_server_config *base = (core_server_config *)basev;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe core_server_config *virt = (core_server_config *)virtv;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe core_server_config *conf;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe conf = (core_server_config *)apr_pcalloc(p, sizeof(core_server_config));
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe *conf = *virt;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (!conf->access_name) {
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe conf->access_name = base->access_name;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe }
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe if (!conf->ap_document_root) {
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe conf->ap_document_root = base->ap_document_root;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe }
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe conf->sec = apr_append_arrays(p, base->sec, virt->sec);
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz conf->sec_url = apr_append_arrays(p, base->sec_url, virt->sec_url);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar return conf;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe}
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe/* Add per-directory configuration entry (for <directory> section);
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz * these are part of the core server config.
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz */
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwroweAP_CORE_DECLARE(void) ap_add_per_dir_conf(server_rec *s, void *dir_config)
e8f95a682820a599fe41b22977010636be5c2717jim{
e8f95a682820a599fe41b22977010636be5c2717jim core_server_config *sconf = ap_get_module_config(s->module_config,
659ad814f714e556bdd03e1d771cba156baab92ewrowe &core_module);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe void **new_space = (void **)apr_push_array(sconf->sec);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
11fb2f3611e6ff9a541e10b13e3108934f828141gregames *new_space = dir_config;
11fb2f3611e6ff9a541e10b13e3108934f828141gregames}
11fb2f3611e6ff9a541e10b13e3108934f828141gregames
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantzAP_CORE_DECLARE(void) ap_add_per_url_conf(server_rec *s, void *url_config)
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz{
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz core_server_config *sconf = ap_get_module_config(s->module_config,
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz &core_module);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker void **new_space = (void **)apr_push_array(sconf->sec_url);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe *new_space = url_config;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe}
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwroweAP_CORE_DECLARE(void) ap_add_file_conf(core_dir_config *conf, void *url_config)
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe{
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe void **new_space = (void **)apr_push_array(conf->sec);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
e8f95a682820a599fe41b22977010636be5c2717jim *new_space = url_config;
1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9trawick}
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe/* core_reorder_directories reorders the directory sections such that the
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar * 1-component sections come first, then the 2-component, and so on, finally
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar * followed by the "special" sections. A section is "special" if it's a regex,
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe * or if it doesn't start with / -- consider proxy: matching. All movements
4f9c22c4f27571d54197be9674e1fc0d528192aestriker * are in-order to preserve the ordering of the sections from the config files.
4f9c22c4f27571d54197be9674e1fc0d528192aestriker * See directory_walk().
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe */
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe#if defined(HAVE_DRIVE_LETTERS)
1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9trawick#define IS_SPECIAL(entry_core) \
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe ((entry_core)->r != NULL \
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar || ((entry_core)->d[0] != '/' && (entry_core)->d[1] != ':'))
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe#elif defined(NETWARE)
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe/* XXX: Fairly certain this is correct... '/' must prefix the path
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe * or else in the case xyz:/ or abc/xyz:/, '/' must follow the ':'.
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz * If there is no leading '/' or embedded ':/', then we are special.
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz */
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz#define IS_SPECIAL(entry_core) \
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz ((entry_core)->r != NULL \
4f9c22c4f27571d54197be9674e1fc0d528192aestriker || ((entry_core)->d[0] != '/' \
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe && strchr((entry_core)->d, ':') \
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe && *(strchr((entry_core)->d, ':') + 1) != '/'))
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#else
8aefbd756763807188d2e3ce336a8680e4893066wrowe#define IS_SPECIAL(entry_core) \
700b96db75e7cfadb5219978c1735b710d583763wrowe ((entry_core)->r != NULL || (entry_core)->d[0] != '/')
700b96db75e7cfadb5219978c1735b710d583763wrowe#endif
700b96db75e7cfadb5219978c1735b710d583763wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowe/* We need to do a stable sort, qsort isn't stable. So to make it stable
700b96db75e7cfadb5219978c1735b710d583763wrowe * we'll be maintaining the original index into the list, and using it
700b96db75e7cfadb5219978c1735b710d583763wrowe * as the minor key during sorting. The major key is the number of
700b96db75e7cfadb5219978c1735b710d583763wrowe * components (where a "special" section has infinite components).
700b96db75e7cfadb5219978c1735b710d583763wrowe */
700b96db75e7cfadb5219978c1735b710d583763wrowestruct reorder_sort_rec {
700b96db75e7cfadb5219978c1735b710d583763wrowe void *elt;
700b96db75e7cfadb5219978c1735b710d583763wrowe int orig_index;
700b96db75e7cfadb5219978c1735b710d583763wrowe};
700b96db75e7cfadb5219978c1735b710d583763wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowestatic int reorder_sorter(const void *va, const void *vb)
700b96db75e7cfadb5219978c1735b710d583763wrowe{
700b96db75e7cfadb5219978c1735b710d583763wrowe const struct reorder_sort_rec *a = va;
103a93c625bcde1a6a7a5155b64dcda36f612180pquerna const struct reorder_sort_rec *b = vb;
700b96db75e7cfadb5219978c1735b710d583763wrowe core_dir_config *core_a;
700b96db75e7cfadb5219978c1735b710d583763wrowe core_dir_config *core_b;
6964758306167dd898baedd21048bd1515dd9d30trawick
700b96db75e7cfadb5219978c1735b710d583763wrowe core_a = (core_dir_config *)ap_get_module_config(a->elt, &core_module);
700b96db75e7cfadb5219978c1735b710d583763wrowe core_b = (core_dir_config *)ap_get_module_config(b->elt, &core_module);
700b96db75e7cfadb5219978c1735b710d583763wrowe if (IS_SPECIAL(core_a)) {
700b96db75e7cfadb5219978c1735b710d583763wrowe if (!IS_SPECIAL(core_b)) {
700b96db75e7cfadb5219978c1735b710d583763wrowe return 1;
700b96db75e7cfadb5219978c1735b710d583763wrowe }
700b96db75e7cfadb5219978c1735b710d583763wrowe }
700b96db75e7cfadb5219978c1735b710d583763wrowe else if (IS_SPECIAL(core_b)) {
700b96db75e7cfadb5219978c1735b710d583763wrowe return -1;
700b96db75e7cfadb5219978c1735b710d583763wrowe }
700b96db75e7cfadb5219978c1735b710d583763wrowe else {
700b96db75e7cfadb5219978c1735b710d583763wrowe /* we know they're both not special */
700b96db75e7cfadb5219978c1735b710d583763wrowe if (core_a->d_components < core_b->d_components) {
700b96db75e7cfadb5219978c1735b710d583763wrowe return -1;
700b96db75e7cfadb5219978c1735b710d583763wrowe }
700b96db75e7cfadb5219978c1735b710d583763wrowe else if (core_a->d_components > core_b->d_components) {
700b96db75e7cfadb5219978c1735b710d583763wrowe return 1;
700b96db75e7cfadb5219978c1735b710d583763wrowe }
700b96db75e7cfadb5219978c1735b710d583763wrowe }
700b96db75e7cfadb5219978c1735b710d583763wrowe /* Either they're both special, or they're both not special and have the
700b96db75e7cfadb5219978c1735b710d583763wrowe * same number of components. In any event, we now have to compare
700b96db75e7cfadb5219978c1735b710d583763wrowe * the minor key. */
103a93c625bcde1a6a7a5155b64dcda36f612180pquerna return a->orig_index - b->orig_index;
103a93c625bcde1a6a7a5155b64dcda36f612180pquerna}
700b96db75e7cfadb5219978c1735b710d583763wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowevoid ap_core_reorder_directories(apr_pool_t *p, server_rec *s)
700b96db75e7cfadb5219978c1735b710d583763wrowe{
8aefbd756763807188d2e3ce336a8680e4893066wrowe core_server_config *sconf;
8aefbd756763807188d2e3ce336a8680e4893066wrowe apr_array_header_t *sec;
8aefbd756763807188d2e3ce336a8680e4893066wrowe struct reorder_sort_rec *sortbin;
8aefbd756763807188d2e3ce336a8680e4893066wrowe int nelts;
8aefbd756763807188d2e3ce336a8680e4893066wrowe void **elts;
8aefbd756763807188d2e3ce336a8680e4893066wrowe int i;
8aefbd756763807188d2e3ce336a8680e4893066wrowe apr_pool_t *tmp;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe sconf = ap_get_module_config(s->module_config, &core_module);
8aefbd756763807188d2e3ce336a8680e4893066wrowe sec = sconf->sec;
8aefbd756763807188d2e3ce336a8680e4893066wrowe nelts = sec->nelts;
8aefbd756763807188d2e3ce336a8680e4893066wrowe elts = (void **)sec->elts;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* we have to allocate tmp space to do a stable sort */
8aefbd756763807188d2e3ce336a8680e4893066wrowe apr_create_pool(&tmp, p);
a2a0abd88b19e042a3eb2a9fa1702c25ad51303dwrowe sortbin = apr_palloc(tmp, sec->nelts * sizeof(*sortbin));
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (i = 0; i < nelts; ++i) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe sortbin[i].orig_index = i;
8aefbd756763807188d2e3ce336a8680e4893066wrowe sortbin[i].elt = elts[i];
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
2fa5b5878e7567e2875807c3e2a2b3b0d3ef74bewrowe
2fa5b5878e7567e2875807c3e2a2b3b0d3ef74bewrowe qsort(sortbin, nelts, sizeof(*sortbin), reorder_sorter);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* and now copy back to the original array */
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (i = 0; i < nelts; ++i) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe elts[i] = sortbin[i].elt;
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe }
a8d11d78181478da6a672f7fbc58b8d523351f49wrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker apr_destroy_pool(tmp);
23c6309e36a63b13b61c35999c978017521993d6wrowe}
23c6309e36a63b13b61c35999c978017521993d6wrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker/*****************************************************************
23c6309e36a63b13b61c35999c978017521993d6wrowe *
8aefbd756763807188d2e3ce336a8680e4893066wrowe * There are some elements of the core config structures in which
23c6309e36a63b13b61c35999c978017521993d6wrowe * other modules have a legitimate interest (this is ugly, but necessary
2d399cd7535887fceaa9f8f116eb98ce68ddd602trawick * to preserve NCSA back-compatibility). So, we have a bunch of accessors
4f9c22c4f27571d54197be9674e1fc0d528192aestriker * here...
23c6309e36a63b13b61c35999c978017521993d6wrowe */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
8aefbd756763807188d2e3ce336a8680e4893066wroweAP_DECLARE(int) ap_allow_options(request_rec *r)
8aefbd756763807188d2e3ce336a8680e4893066wrowe{
cf6ef072483172309861d06e85b1aeff4573c060wrowe core_dir_config *conf =
cf6ef072483172309861d06e85b1aeff4573c060wrowe (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module);
cf6ef072483172309861d06e85b1aeff4573c060wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe return conf->opts;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker}
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
e4a3f3c2f080cac75a15a6454cca429b8161c050wroweAP_DECLARE(int) ap_allow_overrides(request_rec *r)
2d399cd7535887fceaa9f8f116eb98ce68ddd602trawick{
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe core_dir_config *conf;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
a8d11d78181478da6a672f7fbc58b8d523351f49wrowe &core_module);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe return conf->override;
8aefbd756763807188d2e3ce336a8680e4893066wrowe}
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wroweAP_DECLARE(const char *) ap_auth_type(request_rec *r)
cf6ef072483172309861d06e85b1aeff4573c060wrowe{
8aefbd756763807188d2e3ce336a8680e4893066wrowe core_dir_config *conf;
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowe conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp &core_module);
cf6ef072483172309861d06e85b1aeff4573c060wrowe return conf->ap_auth_type;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker}
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wroweAP_DECLARE(const char *) ap_auth_name(request_rec *r)
cf6ef072483172309861d06e85b1aeff4573c060wrowe{
cf6ef072483172309861d06e85b1aeff4573c060wrowe core_dir_config *conf;
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowe conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
cf6ef072483172309861d06e85b1aeff4573c060wrowe &core_module);
cf6ef072483172309861d06e85b1aeff4573c060wrowe return conf->ap_auth_name;
cf6ef072483172309861d06e85b1aeff4573c060wrowe}
69adb3d949e3dd17c0492a01fc2cf298832c7eefwrowe
ecde48c75338ff5712f2036711f813c6dedca28ewroweAP_DECLARE(const char *) ap_default_type(request_rec *r)
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick{
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick core_dir_config *conf;
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick &core_module);
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick return conf->ap_default_type
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick ? conf->ap_default_type
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick : DEFAULT_CONTENT_TYPE;
ecde48c75338ff5712f2036711f813c6dedca28ewrowe}
ecde48c75338ff5712f2036711f813c6dedca28ewrowe
d75626f0952c6152a99acd013a4f127d46f0f9edtrawickAP_DECLARE(const char *) ap_document_root(request_rec *r) /* Don't use this! */
ecde48c75338ff5712f2036711f813c6dedca28ewrowe{
ecde48c75338ff5712f2036711f813c6dedca28ewrowe core_server_config *conf;
ecde48c75338ff5712f2036711f813c6dedca28ewrowe
ecde48c75338ff5712f2036711f813c6dedca28ewrowe conf = (core_server_config *)ap_get_module_config(r->server->module_config,
ecde48c75338ff5712f2036711f813c6dedca28ewrowe &core_module);
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick return conf->ap_document_root;
cf6ef072483172309861d06e85b1aeff4573c060wrowe}
cf6ef072483172309861d06e85b1aeff4573c060wrowe
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoarAP_DECLARE(const apr_array_header_t *) ap_requires(request_rec *r)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe{
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar core_dir_config *conf;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar &core_module);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return conf->ap_requires;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
e4a3f3c2f080cac75a15a6454cca429b8161c050wroweAP_DECLARE(int) ap_satisfies(request_rec *r)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe{
4f9c22c4f27571d54197be9674e1fc0d528192aestriker core_dir_config *conf;
23c6309e36a63b13b61c35999c978017521993d6wrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
4f9c22c4f27571d54197be9674e1fc0d528192aestriker &core_module);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
c2cf53a40a9814eb91db2cdf820f97d943f21628coar return conf->satisfy;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe/* Should probably just get rid of this... the only code that cares is
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * part of the core anyway (and in fact, it isn't publicised to other
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * modules).
a9a4544168a37b43bd180b3703ccee995f27a80awrowe */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
a9a4544168a37b43bd180b3703ccee995f27a80awrowechar *ap_response_code_string(request_rec *r, int error_index)
4f9c22c4f27571d54197be9674e1fc0d528192aestriker{
a9a4544168a37b43bd180b3703ccee995f27a80awrowe core_dir_config *conf;
a9a4544168a37b43bd180b3703ccee995f27a80awrowe
a9a4544168a37b43bd180b3703ccee995f27a80awrowe conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
a9a4544168a37b43bd180b3703ccee995f27a80awrowe &core_module);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar if (conf->response_code_strings == NULL) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return NULL;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar return conf->response_code_strings[error_index];
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe/* Code from Harald Hanche-Olsen <hanche@imf.unit.no> */
8aefbd756763807188d2e3ce336a8680e4893066wrowestatic apr_inline void do_double_reverse (conn_rec *conn)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe{
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe struct hostent *hptr;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (conn->double_reverse) {
700b96db75e7cfadb5219978c1735b710d583763wrowe /* already done */
cf6ef072483172309861d06e85b1aeff4573c060wrowe return;
cf6ef072483172309861d06e85b1aeff4573c060wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (conn->remote_host == NULL || conn->remote_host[0] == '\0') {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* single reverse failed, so don't bother */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe conn->double_reverse = -1;
8aefbd756763807188d2e3ce336a8680e4893066wrowe return;
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz }
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz hptr = gethostbyname(conn->remote_host);
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz if (hptr) {
cf6ef072483172309861d06e85b1aeff4573c060wrowe char **haddr;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe for (haddr = hptr->h_addr_list; *haddr; haddr++) {
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (((struct in_addr *)(*haddr))->s_addr
4f9c22c4f27571d54197be9674e1fc0d528192aestriker == conn->remote_addr.sin_addr.s_addr) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe conn->double_reverse = 1;
2fd8d1e14fc47762d1e01660b544d5e2a75c825dtrawick return;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe conn->double_reverse = -1;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
700b96db75e7cfadb5219978c1735b710d583763wrowe
700b96db75e7cfadb5219978c1735b710d583763wroweAP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
700b96db75e7cfadb5219978c1735b710d583763wrowe int type)
700b96db75e7cfadb5219978c1735b710d583763wrowe{
8aefbd756763807188d2e3ce336a8680e4893066wrowe int hostname_lookups;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /* If we haven't checked the host name, and we want to */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (dir_config) {
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe hostname_lookups =
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe ((core_dir_config *)ap_get_module_config(dir_config, &core_module))
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe ->hostname_lookups;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (hostname_lookups == HOSTNAME_LOOKUP_UNSET) {
59513b1275fdc2021d4949ee03ae8229469abb86wrowe hostname_lookups = HOSTNAME_LOOKUP_OFF;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker else {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /* the default */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe hostname_lookups = HOSTNAME_LOOKUP_OFF;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (type != REMOTE_NOLOOKUP
4f9c22c4f27571d54197be9674e1fc0d528192aestriker && conn->remote_host == NULL
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe && (type == REMOTE_DOUBLE_REV
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe || hostname_lookups != HOSTNAME_LOOKUP_OFF)) {
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (apr_get_hostname(&conn->remote_host, APR_REMOTE, conn->client_socket)
4f9c22c4f27571d54197be9674e1fc0d528192aestriker == APR_SUCCESS){
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe ap_str_tolower(conn->remote_host);
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe do_double_reverse(conn);
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (conn->double_reverse != 1) {
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe conn->remote_host = NULL;
cf6ef072483172309861d06e85b1aeff4573c060wrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /* if failed, set it to the NULL string to indicate error */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (conn->remote_host == NULL) {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker conn->remote_host = "";
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (type == REMOTE_DOUBLE_REV) {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker do_double_reverse(conn);
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (conn->double_reverse == -1) {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker return NULL;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe/*
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe * Return the desired information; either the remote DNS name, if found,
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe * or either NULL (if the hostname was requested) or the IP address
4f9c22c4f27571d54197be9674e1fc0d528192aestriker * (if any identifier was requested).
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (conn->remote_host != NULL && conn->remote_host[0] != '\0') {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker return conn->remote_host;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe else {
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (type == REMOTE_HOST || type == REMOTE_DOUBLE_REV) {
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe return NULL;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe else {
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe return conn->remote_ip;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe}
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwroweAP_DECLARE(const char *) ap_get_remote_logname(request_rec *r)
cf6ef072483172309861d06e85b1aeff4573c060wrowe{
4f9c22c4f27571d54197be9674e1fc0d528192aestriker core_dir_config *dir_conf;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (r->connection->remote_logname != NULL) {
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe return r->connection->remote_logname;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe/* If we haven't checked the identity, and we want to */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe dir_conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe &core_module);
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (dir_conf->do_rfc1413 & 1) {
38bcc87d9a06e8ba81165421403f275eca4e313btrawick return ap_rfc1413(r->connection, r->server);
38bcc87d9a06e8ba81165421403f275eca4e313btrawick }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe else {
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz return NULL;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe}
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe/* There are two options regarding what the "name" of a server is. The
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe * "canonical" name as defined by ServerName and Port, or the "client's
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe * name" as supplied by a possible Host: header or full URI. We never
4f9c22c4f27571d54197be9674e1fc0d528192aestriker * trust the port passed in the client's headers, we always use the
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe * port of the actual socket.
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe *
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe * The DNS option to UseCanonicalName causes this routine to do a
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe * reverse lookup on the local IP address of the connectiona and use
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe * that for the ServerName. This makes its value more reliable while
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe * at the same time allowing Demon's magic virtual hosting to work.
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz * The assumption is that DNS lookups are sufficiently quick...
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * -- fanf 1998-10-03
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz */
e4a3f3c2f080cac75a15a6454cca429b8161c050wroweAP_DECLARE(const char *) ap_get_server_name(request_rec *r)
cf6ef072483172309861d06e85b1aeff4573c060wrowe{
cf6ef072483172309861d06e85b1aeff4573c060wrowe conn_rec *conn = r->connection;
8aefbd756763807188d2e3ce336a8680e4893066wrowe core_dir_config *d;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe d = (core_dir_config *)ap_get_module_config(r->per_dir_config,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe &core_module);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
700b96db75e7cfadb5219978c1735b710d583763wrowe if (d->use_canonical_name == USE_CANONICAL_NAME_OFF) {
700b96db75e7cfadb5219978c1735b710d583763wrowe return r->hostname ? r->hostname : r->server->server_hostname;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (conn->local_host == NULL) {
cf6ef072483172309861d06e85b1aeff4573c060wrowe if (apr_get_hostname(&conn->local_host, APR_LOCAL, conn->client_socket) != APR_SUCCESS)
cf6ef072483172309861d06e85b1aeff4573c060wrowe conn->local_host = apr_pstrdup(conn->pool, r->server->server_hostname);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker else
4f9c22c4f27571d54197be9674e1fc0d528192aestriker ap_str_tolower(conn->local_host);
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz }
cf6ef072483172309861d06e85b1aeff4573c060wrowe return conn->local_host;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* default */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return r->server->server_hostname;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
4f9c22c4f27571d54197be9674e1fc0d528192aestrikerAP_DECLARE(apr_port_t) ap_get_server_port(const request_rec *r)
548b2980e83f609186a76e98fb245d02e8547bc3jerenkrantz{
548b2980e83f609186a76e98fb245d02e8547bc3jerenkrantz apr_port_t port;
4fca95918a9c0ae93593806544b425d0adc2fcc3wrowe core_dir_config *d =
548b2980e83f609186a76e98fb245d02e8547bc3jerenkrantz (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module);
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz port = r->server->port ? r->server->port : ap_default_port(r);
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar if (d->use_canonical_name == USE_CANONICAL_NAME_OFF
8aefbd756763807188d2e3ce336a8680e4893066wrowe || d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (r->hostname) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe apr_sockaddr_t *localsa;
4fca95918a9c0ae93593806544b425d0adc2fcc3wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe apr_get_sockaddr(&localsa, APR_LOCAL, r->connection->client_socket);
8aefbd756763807188d2e3ce336a8680e4893066wrowe apr_get_port(&port, localsa);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* default */
8aefbd756763807188d2e3ce336a8680e4893066wrowe return port;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker}
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wroweAP_DECLARE(char *) ap_construct_url(apr_pool_t *p, const char *uri,
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar request_rec *r)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe{
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar unsigned port = ap_get_server_port(r);
8aefbd756763807188d2e3ce336a8680e4893066wrowe const char *host = ap_get_server_name(r);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (ap_is_default_port(port, r)) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return apr_pstrcat(p, ap_http_method(r), "://", host, uri, NULL);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return apr_psprintf(p, "%s://%s:%u%s", ap_http_method(r), host, port, uri);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
f08810eff40a2bddd2bc0103453c4ae775ea62bewrowe
f08810eff40a2bddd2bc0103453c4ae775ea62bewroweAP_DECLARE(unsigned long) ap_get_limit_req_body(const request_rec *r)
f08810eff40a2bddd2bc0103453c4ae775ea62bewrowe{
1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9trawick core_dir_config *d =
f08810eff40a2bddd2bc0103453c4ae775ea62bewrowe (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return d->limit_req_body;
8aefbd756763807188d2e3ce336a8680e4893066wrowe}
700b96db75e7cfadb5219978c1735b710d583763wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowe#ifdef WIN32
700b96db75e7cfadb5219978c1735b710d583763wrowestatic apr_status_t get_win32_registry_default_value(apr_pool_t *p, HKEY hkey,
700b96db75e7cfadb5219978c1735b710d583763wrowe char* relativepath,
700b96db75e7cfadb5219978c1735b710d583763wrowe char **value)
700b96db75e7cfadb5219978c1735b710d583763wrowe{
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe HKEY hkeyOpen;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe DWORD type;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe DWORD size = 0;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe DWORD result = RegOpenKeyEx(hkey, relativepath, 0,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe KEY_QUERY_VALUE, &hkeyOpen);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (result != ERROR_SUCCESS)
700b96db75e7cfadb5219978c1735b710d583763wrowe return APR_FROM_OS_ERROR(result);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /* Read to NULL buffer to determine value size */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe result = RegQueryValueEx(hkeyOpen, "", 0, &type, NULL, &size);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (result == ERROR_SUCCESS) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if ((size < 2) || (type != REG_SZ && type != REG_EXPAND_SZ)) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe result = ERROR_INVALID_PARAMETER;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe else {
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar *value = apr_palloc(p, size);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /* Read value based on size query above */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe result = RegQueryValueEx(hkeyOpen, "", 0, &type, *value, &size);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* TODO: This might look fine, but we need to provide some warning
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar * somewhere that some environment variables may -not- be translated,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * seeing as we may have chopped the environment table down somewhat.
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if ((result == ERROR_SUCCESS) && (type == REG_EXPAND_SZ))
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe char *tmp = *value;
8aefbd756763807188d2e3ce336a8680e4893066wrowe size = ExpandEnvironmentStrings(tmp, *value, 0);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (size) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe *value = apr_palloc(p, size);
8aefbd756763807188d2e3ce336a8680e4893066wrowe size = ExpandEnvironmentStrings(tmp, *value, size);
700b96db75e7cfadb5219978c1735b710d583763wrowe }
700b96db75e7cfadb5219978c1735b710d583763wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe RegCloseKey(hkeyOpen);
e8f95a682820a599fe41b22977010636be5c2717jim return APR_FROM_OS_ERROR(result);
e8f95a682820a599fe41b22977010636be5c2717jim}
700b96db75e7cfadb5219978c1735b710d583763wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowestatic char* get_interpreter_from_win32_registry(apr_pool_t *p, const char* ext,
700b96db75e7cfadb5219978c1735b710d583763wrowe char** arguments, int strict)
700b96db75e7cfadb5219978c1735b710d583763wrowe{
700b96db75e7cfadb5219978c1735b710d583763wrowe char execcgi_path[] = "SHELL\\EXECCGI\\COMMAND";
700b96db75e7cfadb5219978c1735b710d583763wrowe char execopen_path[] = "SHELL\\OPEN\\COMMAND";
43c3e6a4b559b76b750c245ee95e2782c15b4296jim char typeName[MAX_PATH];
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe int cmdOfName = FALSE;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe HKEY hkeyName;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar HKEY hkeyType;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe DWORD type;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar int size;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe int result;
700b96db75e7cfadb5219978c1735b710d583763wrowe char *buffer;
700b96db75e7cfadb5219978c1735b710d583763wrowe char *s;
700b96db75e7cfadb5219978c1735b710d583763wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (!ext)
700b96db75e7cfadb5219978c1735b710d583763wrowe return NULL;
700b96db75e7cfadb5219978c1735b710d583763wrowe /*
700b96db75e7cfadb5219978c1735b710d583763wrowe * Future optimization:
700b96db75e7cfadb5219978c1735b710d583763wrowe * When the registry is successfully searched, store the strings for
700b96db75e7cfadb5219978c1735b710d583763wrowe * interpreter and arguments in an ext hash to speed up subsequent look-ups
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe */
700b96db75e7cfadb5219978c1735b710d583763wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowe /* Open the key associated with the script filetype extension */
700b96db75e7cfadb5219978c1735b710d583763wrowe result = RegOpenKeyEx(HKEY_CLASSES_ROOT, ext, 0, KEY_QUERY_VALUE,
700b96db75e7cfadb5219978c1735b710d583763wrowe &hkeyType);
700b96db75e7cfadb5219978c1735b710d583763wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowe if (result != ERROR_SUCCESS)
700b96db75e7cfadb5219978c1735b710d583763wrowe return NULL;
700b96db75e7cfadb5219978c1735b710d583763wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowe /* Retrieve the name of the script filetype extension */
700b96db75e7cfadb5219978c1735b710d583763wrowe size = sizeof(typeName);
700b96db75e7cfadb5219978c1735b710d583763wrowe result = RegQueryValueEx(hkeyType, "", NULL, &type, typeName, &size);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (result == ERROR_SUCCESS && type == REG_SZ && typeName[0]) {
700b96db75e7cfadb5219978c1735b710d583763wrowe /* Open the key associated with the script filetype extension */
700b96db75e7cfadb5219978c1735b710d583763wrowe result = RegOpenKeyEx(HKEY_CLASSES_ROOT, typeName, 0,
700b96db75e7cfadb5219978c1735b710d583763wrowe KEY_QUERY_VALUE, &hkeyName);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowe if (result == ERROR_SUCCESS)
700b96db75e7cfadb5219978c1735b710d583763wrowe cmdOfName = TRUE;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
700b96db75e7cfadb5219978c1735b710d583763wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowe /* Open the key for the script command path by:
700b96db75e7cfadb5219978c1735b710d583763wrowe *
700b96db75e7cfadb5219978c1735b710d583763wrowe * 1) the 'named' filetype key for ExecCGI/Command
700b96db75e7cfadb5219978c1735b710d583763wrowe * 2) the extension's type key for ExecCGI/Command
700b96db75e7cfadb5219978c1735b710d583763wrowe *
700b96db75e7cfadb5219978c1735b710d583763wrowe * and if the strict arg is false, then continue trying:
700b96db75e7cfadb5219978c1735b710d583763wrowe *
700b96db75e7cfadb5219978c1735b710d583763wrowe * 3) the 'named' filetype key for Open/Command
700b96db75e7cfadb5219978c1735b710d583763wrowe * 4) the extension's type key for Open/Command
700b96db75e7cfadb5219978c1735b710d583763wrowe */
700b96db75e7cfadb5219978c1735b710d583763wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowe if (cmdOfName) {
700b96db75e7cfadb5219978c1735b710d583763wrowe result = get_win32_registry_default_value(p, hkeyName,
700b96db75e7cfadb5219978c1735b710d583763wrowe execcgi_path, &buffer);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (!cmdOfName || (result != ERROR_SUCCESS)) {
2520f59894a3e07fefa881ef68aaded763a8d447ben result = get_win32_registry_default_value(p, hkeyType,
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz execcgi_path, &buffer);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar }
8aefbd756763807188d2e3ce336a8680e4893066wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (!strict && cmdOfName && (result != ERROR_SUCCESS)) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe result = get_win32_registry_default_value(p, hkeyName,
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar execopen_path, &buffer);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (!strict && (result != ERROR_SUCCESS)) {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker result = get_win32_registry_default_value(p, hkeyType,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe execopen_path, &buffer);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (cmdOfName)
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz RegCloseKey(hkeyName);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe RegCloseKey(hkeyType);
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (result != ERROR_SUCCESS)
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz return NULL;
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /*
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * The canonical way shell command entries are entered in the Win32
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * registry is as follows:
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * shell [options] "%1" [args]
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz * where
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz * shell - full path name to interpreter or shell to run.
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz * E.g., c:\usr\local\ntreskit\perl\bin\perl.exe
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz * options - optional switches
8aefbd756763807188d2e3ce336a8680e4893066wrowe * E.g., \C
4f9c22c4f27571d54197be9674e1fc0d528192aestriker * "%1" - Place holder for file to run the shell against.
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * Typically quoted.
4f9c22c4f27571d54197be9674e1fc0d528192aestriker * options - additional arguments
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * E.g., /silent
ecde48c75338ff5712f2036711f813c6dedca28ewrowe *
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar * If we find a %1 or a quoted %1, lop off the remainder to arguments.
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe */
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar if (buffer && *buffer) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe if ((s = strstr(buffer, "\"%1")))
cf6ef072483172309861d06e85b1aeff4573c060wrowe {
cf6ef072483172309861d06e85b1aeff4573c060wrowe *s = '\0';
cf6ef072483172309861d06e85b1aeff4573c060wrowe *arguments = s + 4;
cf6ef072483172309861d06e85b1aeff4573c060wrowe }
cf6ef072483172309861d06e85b1aeff4573c060wrowe else if ((s = strstr(buffer, "%1")))
cf6ef072483172309861d06e85b1aeff4573c060wrowe {
cf6ef072483172309861d06e85b1aeff4573c060wrowe *s = '\0';
4f9c22c4f27571d54197be9674e1fc0d528192aestriker *arguments = buffer + 2;
cf6ef072483172309861d06e85b1aeff4573c060wrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe else
cf6ef072483172309861d06e85b1aeff4573c060wrowe *arguments = strchr(buffer, '\0');
700b96db75e7cfadb5219978c1735b710d583763wrowe while (**arguments && isspace(**arguments))
69adb3d949e3dd17c0492a01fc2cf298832c7eefwrowe ++*arguments;
69adb3d949e3dd17c0492a01fc2cf298832c7eefwrowe }
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowe return buffer;
cf6ef072483172309861d06e85b1aeff4573c060wrowe}
cf6ef072483172309861d06e85b1aeff4573c060wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wroweAP_DECLARE (file_type_e) ap_get_win32_interpreter(const request_rec *r,
e8f95a682820a599fe41b22977010636be5c2717jim char** interpreter,
1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9trawick char** arguments)
e8f95a682820a599fe41b22977010636be5c2717jim{
e8f95a682820a599fe41b22977010636be5c2717jim HANDLE hFile;
e8f95a682820a599fe41b22977010636be5c2717jim DWORD nBytesRead;
1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9trawick BOOLEAN bResult;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe char buffer[1024];
1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9trawick core_dir_config *d;
e8f95a682820a599fe41b22977010636be5c2717jim int i;
1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9trawick file_type_e fileType = eFileTypeUNKNOWN;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe char *ext = NULL;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe char *exename = NULL;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
c2cf53a40a9814eb91db2cdf820f97d943f21628coar d = (core_dir_config *)ap_get_module_config(r->per_dir_config,
8aefbd756763807188d2e3ce336a8680e4893066wrowe &core_module);
cf6ef072483172309861d06e85b1aeff4573c060wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* Find the file extension */
8aefbd756763807188d2e3ce336a8680e4893066wrowe exename = strrchr(r->filename, '/');
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (!exename) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe exename = strrchr(r->filename, '\\');
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (!exename) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe exename = r->filename;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
cf6ef072483172309861d06e85b1aeff4573c060wrowe else {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker exename++;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ext = strrchr(exename, '.');
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (ext && (!strcasecmp(ext,".bat") || !strcasecmp(ext,".cmd")))
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe char *comspec = getenv("COMSPEC");
69adb3d949e3dd17c0492a01fc2cf298832c7eefwrowe if (comspec) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe *interpreter = apr_pstrcat(r->pool, "\"", comspec, "\" /c ", NULL);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return eFileTypeSCRIPT;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
cf6ef072483172309861d06e85b1aeff4573c060wrowe ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, r->server,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "Failed to start a '%s' file as a script." APR_EOL_STR
cadddb2c31d24d48f4017db4df0a29687432326cwrowe "\tCOMSPEC variable is missing from the environment.", ext);
cadddb2c31d24d48f4017db4df0a29687432326cwrowe return eFileTypeUNKNOWN;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
cf6ef072483172309861d06e85b1aeff4573c060wrowe
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz /* If the file has an extension and it is not .com and not .exe and
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * we've been instructed to search the registry, then do it!
8aefbd756763807188d2e3ce336a8680e4893066wrowe */
cf6ef072483172309861d06e85b1aeff4573c060wrowe if (ext && strcasecmp(ext,".exe") && strcasecmp(ext,".com") &&
cf6ef072483172309861d06e85b1aeff4573c060wrowe (d->script_interpreter_source == INTERPRETER_SOURCE_REGISTRY ||
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe d->script_interpreter_source == INTERPRETER_SOURCE_REGISTRY_STRICT)) {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /* Check the registry */
700b96db75e7cfadb5219978c1735b710d583763wrowe int strict = (d->script_interpreter_source
2d399cd7535887fceaa9f8f116eb98ce68ddd602trawick == INTERPRETER_SOURCE_REGISTRY_STRICT);
71fe373d064756fb261876443806ece033ee3309slive *interpreter = get_interpreter_from_win32_registry(r->pool, ext,
71fe373d064756fb261876443806ece033ee3309slive arguments, strict);
c2cf53a40a9814eb91db2cdf820f97d943f21628coar if (*interpreter)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return eFileTypeSCRIPT;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe else if (d->script_interpreter_source == INTERPRETER_SOURCE_REGISTRY_STRICT) {
ecde48c75338ff5712f2036711f813c6dedca28ewrowe ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, r->server,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "ScriptInterpreterSource config directive set to \"registry-strict\"." APR_EOL_STR
ecde48c75338ff5712f2036711f813c6dedca28ewrowe "\tInterpreter not found for files of type '%s'.", ext);
ecde48c75338ff5712f2036711f813c6dedca28ewrowe return eFileTypeUNKNOWN;
e8f95a682820a599fe41b22977010636be5c2717jim }
ecde48c75338ff5712f2036711f813c6dedca28ewrowe else
ecde48c75338ff5712f2036711f813c6dedca28ewrowe {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, r->server,
ecde48c75338ff5712f2036711f813c6dedca28ewrowe "ScriptInterpreterSource config directive set to \"registry\"." APR_EOL_STR
ecde48c75338ff5712f2036711f813c6dedca28ewrowe "\tInterpreter not found for files of type '%s', "
ecde48c75338ff5712f2036711f813c6dedca28ewrowe "trying \"script\" method...", ext);
ecde48c75338ff5712f2036711f813c6dedca28ewrowe }
ecde48c75338ff5712f2036711f813c6dedca28ewrowe }
ecde48c75338ff5712f2036711f813c6dedca28ewrowe
ecde48c75338ff5712f2036711f813c6dedca28ewrowe /* Need to peek into the file figure out what it really is... */
ecde48c75338ff5712f2036711f813c6dedca28ewrowe hFile = CreateFile(r->filename, GENERIC_READ, FILE_SHARE_READ, NULL,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (hFile == INVALID_HANDLE_VALUE) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return eFileTypeUNKNOWN;
cf6ef072483172309861d06e85b1aeff4573c060wrowe }
cf6ef072483172309861d06e85b1aeff4573c060wrowe bResult = ReadFile(hFile, (void*) &buffer, sizeof(buffer) - 1,
cf6ef072483172309861d06e85b1aeff4573c060wrowe &nBytesRead, NULL);
cf6ef072483172309861d06e85b1aeff4573c060wrowe if (!bResult || (nBytesRead == 0)) {
cf6ef072483172309861d06e85b1aeff4573c060wrowe ap_log_rerror(APLOG_MARK, APLOG_ERR, GetLastError(), r,
69adb3d949e3dd17c0492a01fc2cf298832c7eefwrowe "ReadFile(%s) failed", r->filename);
cf6ef072483172309861d06e85b1aeff4573c060wrowe CloseHandle(hFile);
cf6ef072483172309861d06e85b1aeff4573c060wrowe return eFileTypeUNKNOWN;
cf6ef072483172309861d06e85b1aeff4573c060wrowe }
cf6ef072483172309861d06e85b1aeff4573c060wrowe CloseHandle(hFile);
cf6ef072483172309861d06e85b1aeff4573c060wrowe buffer[nBytesRead] = '\0';
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowe /* Script or executable, that is the question... */
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if ((buffer[0] == '#') && (buffer[1] == '!')) {
cf6ef072483172309861d06e85b1aeff4573c060wrowe /* Assuming file is a script since it starts with a shebang */
cf6ef072483172309861d06e85b1aeff4573c060wrowe fileType = eFileTypeSCRIPT;
cf6ef072483172309861d06e85b1aeff4573c060wrowe for (i = 2; i < sizeof(buffer); i++) {
cf6ef072483172309861d06e85b1aeff4573c060wrowe if ((buffer[i] == '\r')
cf6ef072483172309861d06e85b1aeff4573c060wrowe || (buffer[i] == '\n')) {
cf6ef072483172309861d06e85b1aeff4573c060wrowe break;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe buffer[i] = '\0';
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe for (i = 2; buffer[i] == ' ' ; ++i)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe *interpreter = apr_pstrdup(r->pool, buffer + i );
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker else {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* Not a script, is it an executable? */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe IMAGE_DOS_HEADER *hdr = (IMAGE_DOS_HEADER*)buffer;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar if ((nBytesRead >= sizeof(IMAGE_DOS_HEADER)) && (hdr->e_magic == IMAGE_DOS_SIGNATURE)) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (hdr->e_lfarlc < 0x40)
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar fileType = eFileTypeEXE16;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe else
ef5650b61a8e35f3cc93ec07e73efc17ea329894jorton fileType = eFileTypeEXE32;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar else
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe fileType = eFileTypeUNKNOWN;
700b96db75e7cfadb5219978c1735b710d583763wrowe }
700b96db75e7cfadb5219978c1735b710d583763wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowe return fileType;
700b96db75e7cfadb5219978c1735b710d583763wrowe}
700b96db75e7cfadb5219978c1735b710d583763wrowe#endif
700b96db75e7cfadb5219978c1735b710d583763wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe/*****************************************************************
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe *
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * Commands... this module handles almost all of the NCSA httpd.conf
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * commands, but most of the old srm.conf is in the the modules.
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowe/* returns a parent if it matches the given directive */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowestatic const ap_directive_t * find_parent(const ap_directive_t *dirp,
4f9c22c4f27571d54197be9674e1fc0d528192aestriker const char *what)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe{
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe while (dirp->parent != NULL) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe dirp = dirp->parent;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* ### it would be nice to have atom-ized directives */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (strcasecmp(dirp->directive, what) == 0)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return dirp;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar return NULL;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker}
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wroweAP_DECLARE(const char *) ap_check_cmd_context(cmd_parms *cmd,
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar unsigned forbidden)
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar{
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe const char *gt = (cmd->cmd->name[0] == '<'
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar && cmd->cmd->name[strlen(cmd->cmd->name)-1] != '>')
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ? ">" : "";
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe const ap_directive_t *found;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if ((forbidden & NOT_IN_VIRTUALHOST) && cmd->server->is_virtual) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe return apr_pstrcat(cmd->pool, cmd->cmd->name, gt,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe " cannot occur within <VirtualHost> section", NULL);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if ((forbidden & NOT_IN_LIMIT) && cmd->limited != -1) {
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar return apr_pstrcat(cmd->pool, cmd->cmd->name, gt,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe " cannot occur within <Limit> section", NULL);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar }
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if ((forbidden & NOT_IN_DIR_LOC_FILE) == NOT_IN_DIR_LOC_FILE
c2cf53a40a9814eb91db2cdf820f97d943f21628coar && cmd->path != NULL) {
c2cf53a40a9814eb91db2cdf820f97d943f21628coar return apr_pstrcat(cmd->pool, cmd->cmd->name, gt,
c2cf53a40a9814eb91db2cdf820f97d943f21628coar " cannot occur within <Directory/Location/Files> "
c2cf53a40a9814eb91db2cdf820f97d943f21628coar "section", NULL);
0ec08ecdcb42129d147888bda504787b164da39cerikabele }
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (((forbidden & NOT_IN_DIRECTORY)
8aefbd756763807188d2e3ce336a8680e4893066wrowe && ((found = find_parent(cmd->directive, "<Directory"))
8aefbd756763807188d2e3ce336a8680e4893066wrowe || (found = find_parent(cmd->directive, "<DirectoryMatch"))))
8aefbd756763807188d2e3ce336a8680e4893066wrowe || ((forbidden & NOT_IN_LOCATION)
8aefbd756763807188d2e3ce336a8680e4893066wrowe && ((found = find_parent(cmd->directive, "<Location"))
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe || (found = find_parent(cmd->directive, "<LocationMatch"))))
8aefbd756763807188d2e3ce336a8680e4893066wrowe || ((forbidden & NOT_IN_FILES)
8aefbd756763807188d2e3ce336a8680e4893066wrowe && ((found = find_parent(cmd->directive, "<Files"))
8aefbd756763807188d2e3ce336a8680e4893066wrowe || (found = find_parent(cmd->directive, "<FilesMatch"))))) {
c2cf53a40a9814eb91db2cdf820f97d943f21628coar return apr_pstrcat(cmd->pool, cmd->cmd->name, gt,
c2cf53a40a9814eb91db2cdf820f97d943f21628coar " cannot occur within ", found->directive,
2d399cd7535887fceaa9f8f116eb98ce68ddd602trawick "> section", NULL);
c2cf53a40a9814eb91db2cdf820f97d943f21628coar }
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe return NULL;
8aefbd756763807188d2e3ce336a8680e4893066wrowe}
8aefbd756763807188d2e3ce336a8680e4893066wrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowestatic const char *set_access_name(cmd_parms *cmd, void *dummy,
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe const char *arg)
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe{
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe void *sconf = cmd->server->module_config;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe core_server_config *conf = ap_get_module_config(sconf, &core_module);
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar const char *err = ap_check_cmd_context(cmd,
0540a0b469147b52e858587270dba31c2aaa9e09wrowe NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar if (err != NULL) {
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar return err;
0540a0b469147b52e858587270dba31c2aaa9e09wrowe }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
0540a0b469147b52e858587270dba31c2aaa9e09wrowe conf->access_name = apr_pstrdup(cmd->pool, arg);
0540a0b469147b52e858587270dba31c2aaa9e09wrowe return NULL;
a9a4544168a37b43bd180b3703ccee995f27a80awrowe}
0540a0b469147b52e858587270dba31c2aaa9e09wrowe
0540a0b469147b52e858587270dba31c2aaa9e09wrowe#ifdef GPROF
0540a0b469147b52e858587270dba31c2aaa9e09wrowestatic const char *set_gprof_dir(cmd_parms *cmd, void *dummy, char *arg)
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe{
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar void *sconf = cmd->server->module_config;
0540a0b469147b52e858587270dba31c2aaa9e09wrowe core_server_config *conf = ap_get_module_config(sconf, &core_module);
0540a0b469147b52e858587270dba31c2aaa9e09wrowe
0540a0b469147b52e858587270dba31c2aaa9e09wrowe const char *err = ap_check_cmd_context(cmd,
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
0540a0b469147b52e858587270dba31c2aaa9e09wrowe if (err != NULL) {
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe return err;
0540a0b469147b52e858587270dba31c2aaa9e09wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe conf->gprof_dir = apr_pstrdup(cmd->pool, arg);
0540a0b469147b52e858587270dba31c2aaa9e09wrowe return NULL;
a2a0abd88b19e042a3eb2a9fa1702c25ad51303dwrowe}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#endif /*GPROF*/
948096a99010fccf648814fecf38f75c689172d7wrowe
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic const char *set_add_default_charset(cmd_parms *cmd,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb void *d_, const char *arg)
4f9c22c4f27571d54197be9674e1fc0d528192aestriker{
0540a0b469147b52e858587270dba31c2aaa9e09wrowe core_dir_config *d=d_;
948096a99010fccf648814fecf38f75c689172d7wrowe
948096a99010fccf648814fecf38f75c689172d7wrowe const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
948096a99010fccf648814fecf38f75c689172d7wrowe if (err != NULL) {
948096a99010fccf648814fecf38f75c689172d7wrowe return err;
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe }
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe if (!strcasecmp(arg, "Off")) {
053497224246c4dbef9af594cacf5c00ed271e6cwrowe d->add_default_charset = ADD_DEFAULT_CHARSET_OFF;
0540a0b469147b52e858587270dba31c2aaa9e09wrowe }
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz else if (!strcasecmp(arg, "On")) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb d->add_default_charset = ADD_DEFAULT_CHARSET_ON;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb d->add_default_charset_name = DEFAULT_ADD_DEFAULT_CHARSET_NAME;
42da244268b11ec661b528510f80a18b73c51727brianp }
42da244268b11ec661b528510f80a18b73c51727brianp else {
948096a99010fccf648814fecf38f75c689172d7wrowe d->add_default_charset = ADD_DEFAULT_CHARSET_ON;
948096a99010fccf648814fecf38f75c689172d7wrowe d->add_default_charset_name = arg;
948096a99010fccf648814fecf38f75c689172d7wrowe }
948096a99010fccf648814fecf38f75c689172d7wrowe return NULL;
948096a99010fccf648814fecf38f75c689172d7wrowe}
948096a99010fccf648814fecf38f75c689172d7wrowe
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantzstatic const char *set_document_root(cmd_parms *cmd, void *dummy,
948096a99010fccf648814fecf38f75c689172d7wrowe const char *arg)
948096a99010fccf648814fecf38f75c689172d7wrowe{
948096a99010fccf648814fecf38f75c689172d7wrowe void *sconf = cmd->server->module_config;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz core_server_config *conf = ap_get_module_config(sconf, &core_module);
948096a99010fccf648814fecf38f75c689172d7wrowe
948096a99010fccf648814fecf38f75c689172d7wrowe const char *err = ap_check_cmd_context(cmd,
053497224246c4dbef9af594cacf5c00ed271e6cwrowe NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
948096a99010fccf648814fecf38f75c689172d7wrowe if (err != NULL) {
948096a99010fccf648814fecf38f75c689172d7wrowe return err;
948096a99010fccf648814fecf38f75c689172d7wrowe }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
c2cf53a40a9814eb91db2cdf820f97d943f21628coar arg = ap_os_canonical_filename(cmd->pool, arg);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (/* TODO: ap_configtestonly && ap_docrootcheck && */ !ap_is_directory(arg)) {
c2cf53a40a9814eb91db2cdf820f97d943f21628coar if (cmd->server->is_virtual) {
948096a99010fccf648814fecf38f75c689172d7wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
4f9c22c4f27571d54197be9674e1fc0d528192aestriker "Warning: DocumentRoot [%s] does not exist",
948096a99010fccf648814fecf38f75c689172d7wrowe arg);
948096a99010fccf648814fecf38f75c689172d7wrowe }
053497224246c4dbef9af594cacf5c00ed271e6cwrowe else {
a9a4544168a37b43bd180b3703ccee995f27a80awrowe return "DocumentRoot must be a directory";
948096a99010fccf648814fecf38f75c689172d7wrowe }
a9a4544168a37b43bd180b3703ccee995f27a80awrowe }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
a9a4544168a37b43bd180b3703ccee995f27a80awrowe conf->ap_document_root = arg;
a9a4544168a37b43bd180b3703ccee995f27a80awrowe return NULL;
a9a4544168a37b43bd180b3703ccee995f27a80awrowe}
a9a4544168a37b43bd180b3703ccee995f27a80awrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestrikerAP_DECLARE(void) ap_custom_response(request_rec *r, int status, char *string)
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar{
948096a99010fccf648814fecf38f75c689172d7wrowe core_dir_config *conf =
948096a99010fccf648814fecf38f75c689172d7wrowe ap_get_module_config(r->per_dir_config, &core_module);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar int idx;
948096a99010fccf648814fecf38f75c689172d7wrowe
948096a99010fccf648814fecf38f75c689172d7wrowe if(conf->response_code_strings == NULL) {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker conf->response_code_strings =
948096a99010fccf648814fecf38f75c689172d7wrowe apr_pcalloc(r->pool,
948096a99010fccf648814fecf38f75c689172d7wrowe sizeof(*conf->response_code_strings) *
aecb17a45c6d3ee4729ed5f68dc4270f211ee7a8fielding RESPONSE_CODES);
948096a99010fccf648814fecf38f75c689172d7wrowe }
aa047239dedf0d26e8efecfade32e7337f35df19wrowe
948096a99010fccf648814fecf38f75c689172d7wrowe idx = ap_index_of_response(status);
948096a99010fccf648814fecf38f75c689172d7wrowe
948096a99010fccf648814fecf38f75c689172d7wrowe conf->response_code_strings[idx] =
948096a99010fccf648814fecf38f75c689172d7wrowe ((ap_is_url(string) || (*string == '/')) && (*string != '"')) ?
948096a99010fccf648814fecf38f75c689172d7wrowe apr_pstrdup(r->pool, string) : apr_pstrcat(r->pool, "\"", string, NULL);
053497224246c4dbef9af594cacf5c00ed271e6cwrowe}
0540a0b469147b52e858587270dba31c2aaa9e09wrowe
053497224246c4dbef9af594cacf5c00ed271e6cwrowestatic const char *set_error_document(cmd_parms *cmd, void *conf_,
4f9c22c4f27571d54197be9674e1fc0d528192aestriker const char *errno_str, const char *msg)
0540a0b469147b52e858587270dba31c2aaa9e09wrowe{
4f9c22c4f27571d54197be9674e1fc0d528192aestriker core_dir_config *conf=conf_;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe int error_number, index_number, idx500;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz enum { MSG, LOCAL_PATH, REMOTE_PATH } what = MSG;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
053497224246c4dbef9af594cacf5c00ed271e6cwrowe const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (err != NULL) {
053497224246c4dbef9af594cacf5c00ed271e6cwrowe return err;
053497224246c4dbef9af594cacf5c00ed271e6cwrowe }
053497224246c4dbef9af594cacf5c00ed271e6cwrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /* 1st parameter should be a 3 digit number, which we recognize;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar * convert it into an array index
c2cf53a40a9814eb91db2cdf820f97d943f21628coar */
1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9trawick error_number = atoi(errno_str);
c2cf53a40a9814eb91db2cdf820f97d943f21628coar idx500 = ap_index_of_response(HTTP_INTERNAL_SERVER_ERROR);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (error_number == HTTP_INTERNAL_SERVER_ERROR) {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker index_number = idx500;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz }
053497224246c4dbef9af594cacf5c00ed271e6cwrowe else if ((index_number = ap_index_of_response(error_number)) == idx500) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return apr_pstrcat(cmd->pool, "Unsupported HTTP response code ",
948096a99010fccf648814fecf38f75c689172d7wrowe errno_str, NULL);
948096a99010fccf648814fecf38f75c689172d7wrowe }
948096a99010fccf648814fecf38f75c689172d7wrowe
0540a0b469147b52e858587270dba31c2aaa9e09wrowe /* Heuristic to determine second argument. */
948096a99010fccf648814fecf38f75c689172d7wrowe if (ap_strchr_c(msg,' '))
948096a99010fccf648814fecf38f75c689172d7wrowe what = MSG;
948096a99010fccf648814fecf38f75c689172d7wrowe else if (msg[0] == '/')
948096a99010fccf648814fecf38f75c689172d7wrowe what = LOCAL_PATH;
948096a99010fccf648814fecf38f75c689172d7wrowe else if (ap_is_url(msg))
4f9c22c4f27571d54197be9674e1fc0d528192aestriker what = REMOTE_PATH;
948096a99010fccf648814fecf38f75c689172d7wrowe else
948096a99010fccf648814fecf38f75c689172d7wrowe what = MSG;
948096a99010fccf648814fecf38f75c689172d7wrowe
948096a99010fccf648814fecf38f75c689172d7wrowe /* The entry should be ignored if it is a full URL for a 401 error */
948096a99010fccf648814fecf38f75c689172d7wrowe
948096a99010fccf648814fecf38f75c689172d7wrowe if (error_number == 401 && what == REMOTE_PATH) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, cmd->server,
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar "cannot use a full URL in a 401 ErrorDocument "
4f9c22c4f27571d54197be9674e1fc0d528192aestriker "directive --- ignoring!");
948096a99010fccf648814fecf38f75c689172d7wrowe }
0540a0b469147b52e858587270dba31c2aaa9e09wrowe else { /* Store it... */
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar if (conf->response_code_strings == NULL) {
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar conf->response_code_strings =
0540a0b469147b52e858587270dba31c2aaa9e09wrowe apr_pcalloc(cmd->pool,
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar sizeof(*conf->response_code_strings) * RESPONSE_CODES);
696218c49632c863d18b25fa52ab63617088cb38wrowe }
948096a99010fccf648814fecf38f75c689172d7wrowe /* hack. Prefix a " if it is a msg; as that is what
0540a0b469147b52e858587270dba31c2aaa9e09wrowe * http_protocol.c relies on to distinguish between
948096a99010fccf648814fecf38f75c689172d7wrowe * a msg and a (local) path.
948096a99010fccf648814fecf38f75c689172d7wrowe */
4f9c22c4f27571d54197be9674e1fc0d528192aestriker conf->response_code_strings[index_number] = (what == MSG) ?
948096a99010fccf648814fecf38f75c689172d7wrowe apr_pstrcat(cmd->pool, "\"",msg,NULL) :
948096a99010fccf648814fecf38f75c689172d7wrowe apr_pstrdup(cmd->pool, msg);
053497224246c4dbef9af594cacf5c00ed271e6cwrowe }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
948096a99010fccf648814fecf38f75c689172d7wrowe return NULL;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar}
053497224246c4dbef9af594cacf5c00ed271e6cwrowe
053497224246c4dbef9af594cacf5c00ed271e6cwrowestatic const char *set_override(cmd_parms *cmd, void *d_, const char *l)
a9a4544168a37b43bd180b3703ccee995f27a80awrowe{
a9a4544168a37b43bd180b3703ccee995f27a80awrowe core_dir_config *d=d_;
a9a4544168a37b43bd180b3703ccee995f27a80awrowe char *w;
948096a99010fccf648814fecf38f75c689172d7wrowe
948096a99010fccf648814fecf38f75c689172d7wrowe const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
053497224246c4dbef9af594cacf5c00ed271e6cwrowe if (err != NULL) {
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar return err;
053497224246c4dbef9af594cacf5c00ed271e6cwrowe }
053497224246c4dbef9af594cacf5c00ed271e6cwrowe
948096a99010fccf648814fecf38f75c689172d7wrowe d->override = OR_NONE;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar while (l[0]) {
948096a99010fccf648814fecf38f75c689172d7wrowe w = ap_getword_conf(cmd->pool, &l);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (!strcasecmp(w, "Limit")) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb d->override |= OR_LIMIT;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else if (!strcasecmp(w, "Options")) {
a2a0abd88b19e042a3eb2a9fa1702c25ad51303dwrowe d->override |= OR_OPTIONS;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
aa047239dedf0d26e8efecfade32e7337f35df19wrowe else if (!strcasecmp(w, "FileInfo")) {
aa047239dedf0d26e8efecfade32e7337f35df19wrowe d->override |= OR_FILEINFO;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker else if (!strcasecmp(w, "AuthConfig")) {
0540a0b469147b52e858587270dba31c2aaa9e09wrowe d->override |= OR_AUTHCFG;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe }
aa047239dedf0d26e8efecfade32e7337f35df19wrowe else if (!strcasecmp(w, "Indexes")) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb d->override |= OR_INDEXES;
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker else if (!strcasecmp(w, "None")) {
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe d->override = OR_NONE;
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe }
b5bd19d82874782007a2f9bcb19341a483c1270cwrowe else if (!strcasecmp(w, "All")) {
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe d->override = OR_ALL;
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe }
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe else {
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp return apr_pstrcat(cmd->pool, "Illegal override option ", w, NULL);
aa047239dedf0d26e8efecfade32e7337f35df19wrowe }
aa047239dedf0d26e8efecfade32e7337f35df19wrowe d->override &= ~OR_UNSET;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe }
aa047239dedf0d26e8efecfade32e7337f35df19wrowe
aa047239dedf0d26e8efecfade32e7337f35df19wrowe return NULL;
0540a0b469147b52e858587270dba31c2aaa9e09wrowe}
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
aa047239dedf0d26e8efecfade32e7337f35df19wrowestatic const char *set_options(cmd_parms *cmd, void *d_, const char *l)
aa047239dedf0d26e8efecfade32e7337f35df19wrowe{
4f9c22c4f27571d54197be9674e1fc0d528192aestriker core_dir_config *d=d_;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe allow_options_t opt;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe int first = 1;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char action;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz while (l[0]) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char *w = ap_getword_conf(cmd->pool, &l);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb action = '\0';
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (*w == '+' || *w == '-') {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb action = *(w++);
aa047239dedf0d26e8efecfade32e7337f35df19wrowe }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker else if (first) {
aa047239dedf0d26e8efecfade32e7337f35df19wrowe d->opts = OPT_NONE;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe first = 0;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
c2cf53a40a9814eb91db2cdf820f97d943f21628coar if (!strcasecmp(w, "Indexes")) {
aa047239dedf0d26e8efecfade32e7337f35df19wrowe opt = OPT_INDEXES;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
aa047239dedf0d26e8efecfade32e7337f35df19wrowe else if (!strcasecmp(w, "Includes")) {
aa047239dedf0d26e8efecfade32e7337f35df19wrowe opt = OPT_INCLUDES;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe }
a9a4544168a37b43bd180b3703ccee995f27a80awrowe else if (!strcasecmp(w, "IncludesNOEXEC")) {
a9a4544168a37b43bd180b3703ccee995f27a80awrowe opt = (OPT_INCLUDES | OPT_INCNOEXEC);
a9a4544168a37b43bd180b3703ccee995f27a80awrowe }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker else if (!strcasecmp(w, "FollowSymLinks")) {
a9a4544168a37b43bd180b3703ccee995f27a80awrowe opt = OPT_SYM_LINKS;
a9a4544168a37b43bd180b3703ccee995f27a80awrowe }
aa047239dedf0d26e8efecfade32e7337f35df19wrowe else if (!strcasecmp(w, "SymLinksIfOwnerMatch")) {
a9a4544168a37b43bd180b3703ccee995f27a80awrowe opt = OPT_SYM_OWNER;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar else if (!strcasecmp(w, "execCGI")) {
aa047239dedf0d26e8efecfade32e7337f35df19wrowe opt = OPT_EXECCGI;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar else if (!strcasecmp(w, "MultiViews")) {
aa047239dedf0d26e8efecfade32e7337f35df19wrowe opt = OPT_MULTI;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker else if (!strcasecmp(w, "RunScripts")) { /* AI backcompat. Yuck */
aa047239dedf0d26e8efecfade32e7337f35df19wrowe opt = OPT_MULTI|OPT_EXECCGI;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe }
0540a0b469147b52e858587270dba31c2aaa9e09wrowe else if (!strcasecmp(w, "None")) {
aa047239dedf0d26e8efecfade32e7337f35df19wrowe opt = OPT_NONE;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe }
aa047239dedf0d26e8efecfade32e7337f35df19wrowe else if (!strcasecmp(w, "All")) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb opt = OPT_ALL;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe }
aa047239dedf0d26e8efecfade32e7337f35df19wrowe else {
aa047239dedf0d26e8efecfade32e7337f35df19wrowe return apr_pstrcat(cmd->pool, "Illegal option ", w, NULL);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
0540a0b469147b52e858587270dba31c2aaa9e09wrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /* we ensure the invariant (d->opts_add & d->opts_remove) == 0 */
0540a0b469147b52e858587270dba31c2aaa9e09wrowe if (action == '-') {
0540a0b469147b52e858587270dba31c2aaa9e09wrowe d->opts_remove |= opt;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe d->opts_add &= ~opt;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe d->opts &= ~opt;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar }
c2cf53a40a9814eb91db2cdf820f97d943f21628coar else if (action == '+') {
1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9trawick d->opts_add |= opt;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar d->opts_remove &= ~opt;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe d->opts |= opt;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
aa047239dedf0d26e8efecfade32e7337f35df19wrowe else {
aa047239dedf0d26e8efecfade32e7337f35df19wrowe d->opts |= opt;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe }
aa047239dedf0d26e8efecfade32e7337f35df19wrowe }
0540a0b469147b52e858587270dba31c2aaa9e09wrowe
aa047239dedf0d26e8efecfade32e7337f35df19wrowe return NULL;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe}
aa047239dedf0d26e8efecfade32e7337f35df19wrowe
aa047239dedf0d26e8efecfade32e7337f35df19wrowestatic const char *satisfy(cmd_parms *cmd, void *c_, const char *arg)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
4f9c22c4f27571d54197be9674e1fc0d528192aestriker core_dir_config *c=c_;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe
aa047239dedf0d26e8efecfade32e7337f35df19wrowe if (!strcasecmp(arg, "all")) {
aa047239dedf0d26e8efecfade32e7337f35df19wrowe c->satisfy = SATISFY_ALL;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe }
aa047239dedf0d26e8efecfade32e7337f35df19wrowe else if (!strcasecmp(arg, "any")) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb c->satisfy = SATISFY_ANY;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar else {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker return "Satisfy either 'any' or 'all'.";
aa047239dedf0d26e8efecfade32e7337f35df19wrowe }
0540a0b469147b52e858587270dba31c2aaa9e09wrowe return NULL;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar}
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
0540a0b469147b52e858587270dba31c2aaa9e09wrowestatic const char *require(cmd_parms *cmd, void *c_, const char *arg)
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar{
aa047239dedf0d26e8efecfade32e7337f35df19wrowe require_line *r;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe core_dir_config *c=c_;
0540a0b469147b52e858587270dba31c2aaa9e09wrowe
aa047239dedf0d26e8efecfade32e7337f35df19wrowe if (!c->ap_requires) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb c->ap_requires = apr_make_array(cmd->pool, 2, sizeof(require_line));
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
aa047239dedf0d26e8efecfade32e7337f35df19wrowe r = (require_line *)apr_push_array(c->ap_requires);
aa047239dedf0d26e8efecfade32e7337f35df19wrowe r->requirement = apr_pstrdup(cmd->pool, arg);
aa047239dedf0d26e8efecfade32e7337f35df19wrowe r->method_mask = cmd->limited;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar return NULL;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe}
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbAP_CORE_DECLARE_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, void *dummy,
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe const char *arg) {
a9a4544168a37b43bd180b3703ccee995f27a80awrowe const char *limited_methods = ap_getword(cmd->pool, &arg, '>');
a9a4544168a37b43bd180b3703ccee995f27a80awrowe void *tog = cmd->cmd->cmd_data;
a9a4544168a37b43bd180b3703ccee995f27a80awrowe int limited = 0;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe const char *errmsg;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar if (err != NULL) {
aa047239dedf0d26e8efecfade32e7337f35df19wrowe return err;
aa047239dedf0d26e8efecfade32e7337f35df19wrowe }
aa047239dedf0d26e8efecfade32e7337f35df19wrowe
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar while (limited_methods[0]) {
aa047239dedf0d26e8efecfade32e7337f35df19wrowe char *method = ap_getword_conf(cmd->pool, &limited_methods);
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe int methnum = ap_method_number_of(method);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (methnum == M_TRACE && !tog) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return "TRACE cannot be controlled by <Limit>";
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else if (methnum == M_INVALID) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char **xmethod;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb register int i, j, k;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /*
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Deal with <Limit> by adding the method to the list.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (!tog) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (cmd->limited_xmethods == NULL) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb cmd->limited_xmethods = apr_make_array(cmd->pool, 2,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb sizeof(char *));
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb xmethod = (char **) apr_push_array(cmd->limited_xmethods);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *xmethod = apr_pstrdup(cmd->pool, method);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /*
d2220a04f870f632b8cec1e6713dbb980ed5e386wrowe * <LimitExcept>, so remove any/all occurrences of the method
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * in the extension array.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
d2220a04f870f632b8cec1e6713dbb980ed5e386wrowe else if ((cmd->limited_xmethods != NULL)
4f9c22c4f27571d54197be9674e1fc0d528192aestriker && (cmd->limited_xmethods->nelts != 0)) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb xmethod = (char **) cmd->limited_xmethods->elts;
6fd5761878f22fb9a2de0835807a29784bf367abtrawick for (i = 0; i < cmd->limited_xmethods->nelts; ) {
d2220a04f870f632b8cec1e6713dbb980ed5e386wrowe if (strcmp(xmethod[i], method) == 0) {
d2220a04f870f632b8cec1e6713dbb980ed5e386wrowe for (j = i, k = i + 1;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb k < cmd->limited_xmethods->nelts;
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe ++j, ++k) {
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe xmethod[j] = xmethod[k];
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe }
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe cmd->limited_xmethods->nelts--;
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe }
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe }
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe limited |= (1 << methnum);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe /* Killing two features with one function,
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe * if (tog == NULL) <Limit>, else <LimitExcept>
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe */
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe cmd->limited = tog ? ~limited : limited;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe errmsg = ap_walk_config(cmd->directive->first_child, cmd, cmd->context);
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe cmd->limited = -1;
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe return errmsg;
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe}
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe
ebe7da316894e2b93b4a905fccd2496d0ed1bc78rbb/* We use this in <DirectoryMatch> and <FilesMatch>, to ensure that
ebe7da316894e2b93b4a905fccd2496d0ed1bc78rbb * people don't get bitten by wrong-cased regex matches
ebe7da316894e2b93b4a905fccd2496d0ed1bc78rbb */
ebe7da316894e2b93b4a905fccd2496d0ed1bc78rbb
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#ifdef WIN32
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#define USE_ICASE REG_ICASE
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe#else
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#define USE_ICASE 0
e57e920838f31508f1418aa4c25ce55b345b2cebrbb#endif
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe/*
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe * Report a missing-'>' syntax error.
e57e920838f31508f1418aa4c25ce55b345b2cebrbb */
e57e920838f31508f1418aa4c25ce55b345b2cebrbbstatic char *unclosed_directive(cmd_parms *cmd)
e57e920838f31508f1418aa4c25ce55b345b2cebrbb{
e57e920838f31508f1418aa4c25ce55b345b2cebrbb return apr_pstrcat(cmd->pool, cmd->cmd->name,
e57e920838f31508f1418aa4c25ce55b345b2cebrbb "> directive missing closing '>'", NULL);
e57e920838f31508f1418aa4c25ce55b345b2cebrbb}
e57e920838f31508f1418aa4c25ce55b345b2cebrbb
e57e920838f31508f1418aa4c25ce55b345b2cebrbbstatic const char *dirsection(cmd_parms *cmd, void *mconfig, const char *arg)
e57e920838f31508f1418aa4c25ce55b345b2cebrbb{
e57e920838f31508f1418aa4c25ce55b345b2cebrbb const char *errmsg;
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe const char *endp = ap_strrchr_c(arg, '>');
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe int old_overrides = cmd->override;
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe char *old_path = cmd->path;
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe core_dir_config *conf;
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe void *new_dir_conf = ap_create_per_dir_config(cmd->pool);
d2220a04f870f632b8cec1e6713dbb980ed5e386wrowe regex_t *r = NULL;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker const command_rec *thiscmd = cmd->cmd;
d2220a04f870f632b8cec1e6713dbb980ed5e386wrowe
d2220a04f870f632b8cec1e6713dbb980ed5e386wrowe const char *err = ap_check_cmd_context(cmd,
d2220a04f870f632b8cec1e6713dbb980ed5e386wrowe NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
d2220a04f870f632b8cec1e6713dbb980ed5e386wrowe if (err != NULL) {
098ae874f43f7a0b66be5406a7e2fb971bbbe00ewrowe return err;
098ae874f43f7a0b66be5406a7e2fb971bbbe00ewrowe }
098ae874f43f7a0b66be5406a7e2fb971bbbe00ewrowe
098ae874f43f7a0b66be5406a7e2fb971bbbe00ewrowe if (endp == NULL) {
098ae874f43f7a0b66be5406a7e2fb971bbbe00ewrowe return unclosed_directive(cmd);
d2220a04f870f632b8cec1e6713dbb980ed5e386wrowe }
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe
e68544ae924174ca227ede8e2e722cefa00ea0d3wrowe arg=apr_pstrndup(cmd->pool, arg, endp-arg);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
c2cf53a40a9814eb91db2cdf820f97d943f21628coar cmd->path = ap_getword_conf(cmd->pool, &arg);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb cmd->override = OR_ALL|ACCESS_CONF;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (thiscmd->cmd_data) { /* <DirectoryMatch> */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED|USE_ICASE);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else if (!strcmp(cmd->path, "~")) {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker cmd->path = ap_getword_conf(cmd->pool, &arg);
68b29bcadd6c46aecdc9fe14c93555a2238ad2aagregames r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED|USE_ICASE);
68b29bcadd6c46aecdc9fe14c93555a2238ad2aagregames }
68b29bcadd6c46aecdc9fe14c93555a2238ad2aagregames#if defined(HAVE_DRIVE_LETTERS) || defined(NETWARE)
4f9c22c4f27571d54197be9674e1fc0d528192aestriker else if (strcmp(cmd->path, "/") == 0) {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /* Treat 'default' path / as an inalienable root */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb cmd->path = apr_pstrdup(cmd->pool, cmd->path);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#endif
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#if defined(HAVE_UNC_PATHS)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else if (strcmp(cmd->path, "//") == 0) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* Treat UNC path // as an inalienable root */
4f9c22c4f27571d54197be9674e1fc0d528192aestriker cmd->path = apr_pstrdup(cmd->pool, cmd->path);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#endif
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /* Ensure that the pathname is canonical */
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar cmd->path = ap_os_canonical_filename(cmd->pool, cmd->path);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /* initialize our config and fetch it */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb conf = (core_dir_config *)ap_set_config_vectors(cmd, new_dir_conf,
4f9c22c4f27571d54197be9674e1fc0d528192aestriker &core_module);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_dir_conf);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (errmsg != NULL)
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar return errmsg;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
4f9c22c4f27571d54197be9674e1fc0d528192aestriker conf->r = r;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
4f9c22c4f27571d54197be9674e1fc0d528192aestriker ap_add_per_dir_conf(cmd->server, new_dir_conf);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (*arg != '\0') {
b67fb549910fa0faf4cdd8aeaf9aeab51d4b6a92wrowe return apr_pstrcat(cmd->pool, "Multiple ", thiscmd->name,
e8eee56a2ea20f673e5942fb58e1426a7561c7acstas "> arguments not (yet) supported.", NULL);
b67fb549910fa0faf4cdd8aeaf9aeab51d4b6a92wrowe }
b67fb549910fa0faf4cdd8aeaf9aeab51d4b6a92wrowe
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb cmd->path = old_path;
b67fb549910fa0faf4cdd8aeaf9aeab51d4b6a92wrowe cmd->override = old_overrides;
8011ccb9e0700e5a396e2362dab1d9386206277fcolm
e8f95a682820a599fe41b22977010636be5c2717jim return NULL;
b67fb549910fa0faf4cdd8aeaf9aeab51d4b6a92wrowe}
b67fb549910fa0faf4cdd8aeaf9aeab51d4b6a92wrowe
d2220a04f870f632b8cec1e6713dbb980ed5e386wrowestatic const char *urlsection(cmd_parms *cmd, void *mconfig, const char *arg)
b45c1c292ff1fa635004ae81fa691f8cb3cdda85rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb const char *errmsg;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb const char *endp = ap_strrchr_c(arg, '>');
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int old_overrides = cmd->override;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char *old_path = cmd->path;
e8eee56a2ea20f673e5942fb58e1426a7561c7acstas core_dir_config *conf;
e8eee56a2ea20f673e5942fb58e1426a7561c7acstas regex_t *r = NULL;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar const command_rec *thiscmd = cmd->cmd;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb void *new_url_conf = ap_create_per_dir_config(cmd->pool);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
e8eee56a2ea20f673e5942fb58e1426a7561c7acstas const char *err = ap_check_cmd_context(cmd,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd if (err != NULL) {
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd return err;
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd }
a8c55845ffa7170766e410dbd799353127b628f9nd
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd if (endp == NULL) {
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd return unclosed_directive(cmd);
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd }
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd
e8f95a682820a599fe41b22977010636be5c2717jim arg=apr_pstrndup(cmd->pool, arg, endp-arg);
30b4a330a5f651eb5198fa93dbb9f3d3594564c9stoddard
30b4a330a5f651eb5198fa93dbb9f3d3594564c9stoddard cmd->path = ap_getword_conf(cmd->pool, &arg);
6edf0ccf36ca2792b20058833680375b9256f2e0colm cmd->override = OR_ALL|ACCESS_CONF;
e8f95a682820a599fe41b22977010636be5c2717jim
e8f95a682820a599fe41b22977010636be5c2717jim if (thiscmd->cmd_data) { /* <LocationMatch> */
e8f95a682820a599fe41b22977010636be5c2717jim r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED);
e8f95a682820a599fe41b22977010636be5c2717jim }
6edf0ccf36ca2792b20058833680375b9256f2e0colm else if (!strcmp(cmd->path, "~")) {
30b4a330a5f651eb5198fa93dbb9f3d3594564c9stoddard cmd->path = ap_getword_conf(cmd->pool, &arg);
6edf0ccf36ca2792b20058833680375b9256f2e0colm r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED);
6edf0ccf36ca2792b20058833680375b9256f2e0colm }
6edf0ccf36ca2792b20058833680375b9256f2e0colm
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* initialize our config and fetch it */
6edf0ccf36ca2792b20058833680375b9256f2e0colm conf = (core_dir_config *)ap_set_config_vectors(cmd, new_url_conf,
30b4a330a5f651eb5198fa93dbb9f3d3594564c9stoddard &core_module);
30b4a330a5f651eb5198fa93dbb9f3d3594564c9stoddard
30b4a330a5f651eb5198fa93dbb9f3d3594564c9stoddard errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_url_conf);
e8f95a682820a599fe41b22977010636be5c2717jim if (errmsg != NULL)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return errmsg;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb conf->d = apr_pstrdup(cmd->pool, cmd->path); /* No mangling, please */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb conf->d_is_fnmatch = apr_is_fnmatch(conf->d) != 0;
e8eee56a2ea20f673e5942fb58e1426a7561c7acstas conf->r = r;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ap_add_per_url_conf(cmd->server, new_url_conf);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
e8eee56a2ea20f673e5942fb58e1426a7561c7acstas if (*arg != '\0') {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return apr_pstrcat(cmd->pool, "Multiple ", thiscmd->name,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb "> arguments not (yet) supported.", NULL);
efa1a34b0a7785fc72863eff175b0cfc1ecb0e38wrowe }
117026201e6d8fe7d82416b8a7324830f5a87292wrowe
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe cmd->path = old_path;
117026201e6d8fe7d82416b8a7324830f5a87292wrowe cmd->override = old_overrides;
117026201e6d8fe7d82416b8a7324830f5a87292wrowe
117026201e6d8fe7d82416b8a7324830f5a87292wrowe return NULL;
117026201e6d8fe7d82416b8a7324830f5a87292wrowe}
117026201e6d8fe7d82416b8a7324830f5a87292wrowe
6c24fd6cfe148639988d5b335185ffb215662801wrowestatic const char *filesection(cmd_parms *cmd, void *mconfig, const char *arg)
117026201e6d8fe7d82416b8a7324830f5a87292wrowe{
d2220a04f870f632b8cec1e6713dbb980ed5e386wrowe const char *errmsg;
117026201e6d8fe7d82416b8a7324830f5a87292wrowe const char *endp = ap_strrchr_c(arg, '>');
4f9c22c4f27571d54197be9674e1fc0d528192aestriker int old_overrides = cmd->override;
cadddb2c31d24d48f4017db4df0a29687432326cwrowe char *old_path = cmd->path;
117026201e6d8fe7d82416b8a7324830f5a87292wrowe core_dir_config *conf;
f888346b48f5e5b5e3f0a47dedb8cefd2759a4e2gregames regex_t *r = NULL;
f888346b48f5e5b5e3f0a47dedb8cefd2759a4e2gregames const command_rec *thiscmd = cmd->cmd;
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe core_dir_config *c=mconfig;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe void *new_file_conf = ap_create_per_dir_config(cmd->pool);
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT|NOT_IN_LOCATION);
f888346b48f5e5b5e3f0a47dedb8cefd2759a4e2gregames if (err != NULL) {
f888346b48f5e5b5e3f0a47dedb8cefd2759a4e2gregames return err;
f888346b48f5e5b5e3f0a47dedb8cefd2759a4e2gregames }
f888346b48f5e5b5e3f0a47dedb8cefd2759a4e2gregames
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe if (endp == NULL) {
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe return unclosed_directive(cmd);
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe }
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe arg=apr_pstrndup(cmd->pool, arg, endp-arg);
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe
dc3a3d949b7ef46b8385858c822267e39b665c12nd cmd->path = ap_getword_conf(cmd->pool, &arg);
f888346b48f5e5b5e3f0a47dedb8cefd2759a4e2gregames /* Only if not an .htaccess file */
f888346b48f5e5b5e3f0a47dedb8cefd2759a4e2gregames if (!old_path) {
f888346b48f5e5b5e3f0a47dedb8cefd2759a4e2gregames cmd->override = OR_ALL|ACCESS_CONF;
dc3a3d949b7ef46b8385858c822267e39b665c12nd }
dc3a3d949b7ef46b8385858c822267e39b665c12nd
dc3a3d949b7ef46b8385858c822267e39b665c12nd if (thiscmd->cmd_data) { /* <FilesMatch> */
f888346b48f5e5b5e3f0a47dedb8cefd2759a4e2gregames r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED|USE_ICASE);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
cadddb2c31d24d48f4017db4df0a29687432326cwrowe else if (!strcmp(cmd->path, "~")) {
117026201e6d8fe7d82416b8a7324830f5a87292wrowe cmd->path = ap_getword_conf(cmd->pool, &arg);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED|USE_ICASE);
e7505ba54ac56ae30e4e250f912f3dbaf92ca45fwrowe }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar else {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /* Ensure that the pathname is canonical */
cadddb2c31d24d48f4017db4df0a29687432326cwrowe cmd->path = ap_os_canonical_filename(cmd->pool, cmd->path);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
cadddb2c31d24d48f4017db4df0a29687432326cwrowe /* initialize our config and fetch it */
5b3abd2fecc712f08ad728114aa77137b9f67716wrowe conf = (core_dir_config *)ap_set_config_vectors(cmd, new_file_conf,
85bb5b92490e4f095aae394118fc588a8f4c486fwrowe &core_module);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
efa1a34b0a7785fc72863eff175b0cfc1ecb0e38wrowe errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_file_conf);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe if (errmsg != NULL)
beda1fb2f11c52ca4612460a5d5ba47398143efbwrowe return errmsg;
1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9trawick
e8f95a682820a599fe41b22977010636be5c2717jim conf->d = cmd->path;
e8f95a682820a599fe41b22977010636be5c2717jim conf->d_is_fnmatch = apr_is_fnmatch(conf->d) != 0;
1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9trawick conf->r = r;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ap_add_file_conf(c, new_file_conf);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe if (*arg != '\0') {
c2cf53a40a9814eb91db2cdf820f97d943f21628coar return apr_pstrcat(cmd->pool, "Multiple ", thiscmd->name,
c2cf53a40a9814eb91db2cdf820f97d943f21628coar "> arguments not (yet) supported.", NULL);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe }
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
117026201e6d8fe7d82416b8a7324830f5a87292wrowe cmd->path = old_path;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar cmd->override = old_overrides;
1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9trawick
e8f95a682820a599fe41b22977010636be5c2717jim return NULL;
1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9trawick}
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowestatic const char *start_ifmod(cmd_parms *cmd, void *mconfig, const char *arg)
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar{
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar const char *endp = ap_strrchr_c(arg, '>');
117026201e6d8fe7d82416b8a7324830f5a87292wrowe int not = (arg[0] == '!');
117026201e6d8fe7d82416b8a7324830f5a87292wrowe module *found;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
117026201e6d8fe7d82416b8a7324830f5a87292wrowe if (endp == NULL) {
1067418d9ed9ed9daeb3ca4f74e72db810c49833wrowe return unclosed_directive(cmd);
cadddb2c31d24d48f4017db4df0a29687432326cwrowe }
cadddb2c31d24d48f4017db4df0a29687432326cwrowe
cadddb2c31d24d48f4017db4df0a29687432326cwrowe arg=apr_pstrndup(cmd->pool, arg, endp-arg);
cadddb2c31d24d48f4017db4df0a29687432326cwrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (not) {
c2cf53a40a9814eb91db2cdf820f97d943f21628coar arg++;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar }
cadddb2c31d24d48f4017db4df0a29687432326cwrowe
cadddb2c31d24d48f4017db4df0a29687432326cwrowe found = ap_find_linked_module(arg);
cadddb2c31d24d48f4017db4df0a29687432326cwrowe
cadddb2c31d24d48f4017db4df0a29687432326cwrowe if ((!not && found) || (not && !found)) {
cadddb2c31d24d48f4017db4df0a29687432326cwrowe ap_directive_t *parent = NULL;
cadddb2c31d24d48f4017db4df0a29687432326cwrowe ap_directive_t *current = NULL;
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe const char *retval;
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe
cadddb2c31d24d48f4017db4df0a29687432326cwrowe retval = ap_build_cont_config(cmd->pool, cmd->temp_pool, cmd,
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe &current, &parent, "<IfModule");
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe *(ap_directive_t **)mconfig = current;
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe return retval;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar }
cadddb2c31d24d48f4017db4df0a29687432326cwrowe else {
cadddb2c31d24d48f4017db4df0a29687432326cwrowe *(ap_directive_t **)mconfig = NULL;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker return ap_soak_end_container(cmd, "<IfModule");
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe }
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe}
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
4f9c22c4f27571d54197be9674e1fc0d528192aestrikerAP_DECLARE(int) ap_exists_config_define(const char *name)
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe{
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe char **defines;
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe int i;
3cd826b00280881e5a2f03d8ec1f8d55802b93dewrowe
cadddb2c31d24d48f4017db4df0a29687432326cwrowe defines = (char **)ap_server_config_defines->elts;
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd for (i = 0; i < ap_server_config_defines->nelts; i++) {
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd if (strcmp(defines[i], name) == 0) {
a8c55845ffa7170766e410dbd799353127b628f9nd return 1;
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd }
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd }
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd return 0;
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd}
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
1067418d9ed9ed9daeb3ca4f74e72db810c49833wrowestatic const char *start_ifdefine(cmd_parms *cmd, void *dummy, const char *arg)
1067418d9ed9ed9daeb3ca4f74e72db810c49833wrowe{
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe const char *endp;
1067418d9ed9ed9daeb3ca4f74e72db810c49833wrowe int defined;
117026201e6d8fe7d82416b8a7324830f5a87292wrowe int not = 0;
117026201e6d8fe7d82416b8a7324830f5a87292wrowe
b67fb549910fa0faf4cdd8aeaf9aeab51d4b6a92wrowe endp = ap_strrchr_c(arg, '>');
c2cf53a40a9814eb91db2cdf820f97d943f21628coar if (endp == NULL) {
c2cf53a40a9814eb91db2cdf820f97d943f21628coar return unclosed_directive(cmd);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb arg=apr_pstrndup(cmd->pool, arg, endp-arg);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe if (arg[0] == '!') {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb not = 1;
d2220a04f870f632b8cec1e6713dbb980ed5e386wrowe arg++;
b45c1c292ff1fa635004ae81fa691f8cb3cdda85rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe defined = ap_exists_config_define(arg);
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe if ((!not && defined) || (not && !defined)) {
ecc4a080f07af3fbc1b91bbd00997ec1d592c6f9wrowe ap_directive_t *parent = NULL;
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe ap_directive_t *current = NULL;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar const char *retval;
2d2dadb81bf34e3bc9321eabcd971a738431b364wrowe
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar retval = ap_build_cont_config(cmd->pool, cmd->temp_pool, cmd,
4f9c22c4f27571d54197be9674e1fc0d528192aestriker &current, &parent, "<IfDefine");
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe *(ap_directive_t **)dummy = current;
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe return retval;
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe }
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe else {
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe *(ap_directive_t **)dummy = NULL;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker return ap_soak_end_container(cmd, "<IfDefine");
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar }
ecc4a080f07af3fbc1b91bbd00997ec1d592c6f9wrowe}
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/* httpd.conf commands... beginning with the <VirtualHost> business */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic const char *virtualhost_section(cmd_parms *cmd, void *dummy,
4f9c22c4f27571d54197be9674e1fc0d528192aestriker const char *arg)
5b3abd2fecc712f08ad728114aa77137b9f67716wrowe{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb server_rec *main_server = cmd->server, *s;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb const char *errmsg;
af7e32b660b02a378e91d40987e59b28864db954jwoolley const char *endp = ap_strrchr_c(arg, '>');
4f9c22c4f27571d54197be9674e1fc0d528192aestriker apr_pool_t *p = cmd->pool;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
0540a0b469147b52e858587270dba31c2aaa9e09wrowe const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
0540a0b469147b52e858587270dba31c2aaa9e09wrowe if (err != NULL) {
0540a0b469147b52e858587270dba31c2aaa9e09wrowe return err;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar }
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
0540a0b469147b52e858587270dba31c2aaa9e09wrowe if (endp == NULL) {
c2cf53a40a9814eb91db2cdf820f97d943f21628coar return unclosed_directive(cmd);
0540a0b469147b52e858587270dba31c2aaa9e09wrowe }
0540a0b469147b52e858587270dba31c2aaa9e09wrowe
1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9trawick arg=apr_pstrndup(cmd->pool, arg, endp-arg);
e8f95a682820a599fe41b22977010636be5c2717jim
1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9trawick /* FIXME: There's another feature waiting to happen here -- since you
c2cf53a40a9814eb91db2cdf820f97d943f21628coar can now put multiple addresses/names on a single <VirtualHost>
0540a0b469147b52e858587270dba31c2aaa9e09wrowe you might want to use it to group common definitions and then
c2cf53a40a9814eb91db2cdf820f97d943f21628coar define other "subhosts" with their individual differences. But
0540a0b469147b52e858587270dba31c2aaa9e09wrowe personally I'd rather just do it with a macro preprocessor. -djg */
7763a4beb8afca9c8f93db0cb6836124901af52awrowe if (main_server->is_virtual) {
0540a0b469147b52e858587270dba31c2aaa9e09wrowe return "<VirtualHost> doesn't nest!";
0540a0b469147b52e858587270dba31c2aaa9e09wrowe }
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
c2cf53a40a9814eb91db2cdf820f97d943f21628coar errmsg = ap_init_virtual_host(p, arg, main_server, &s);
0540a0b469147b52e858587270dba31c2aaa9e09wrowe if (errmsg) {
0540a0b469147b52e858587270dba31c2aaa9e09wrowe return errmsg;
0540a0b469147b52e858587270dba31c2aaa9e09wrowe }
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
0540a0b469147b52e858587270dba31c2aaa9e09wrowe s->next = main_server->next;
0540a0b469147b52e858587270dba31c2aaa9e09wrowe main_server->next = s;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb s->defn_name = cmd->directive->filename;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz s->defn_line_number = cmd->directive->line_num;
5b3abd2fecc712f08ad728114aa77137b9f67716wrowe
5b3abd2fecc712f08ad728114aa77137b9f67716wrowe cmd->server = s;
5b3abd2fecc712f08ad728114aa77137b9f67716wrowe
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz errmsg = ap_walk_config(cmd->directive->first_child, cmd,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb s->lookup_defaults);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb cmd->server = main_server;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return errmsg;
58097d7d8d1a394092374b9f6ddf76b7993724a4rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic const char *set_server_alias(cmd_parms *cmd, void *dummy,
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd const char *arg)
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd{
a8c55845ffa7170766e410dbd799353127b628f9nd if (!cmd->server->names) {
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd return "ServerAlias only used in <VirtualHost>";
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd }
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd while (*arg) {
c880637396a01f4acfcf7e35fe423ced2d86c3b4nd char **item, *name = ap_getword_conf(cmd->pool, &arg);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (ap_is_matchexp(name)) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb item = (char **)apr_push_array(cmd->server->wild_names);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe else {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb item = (char **)apr_push_array(cmd->server->names);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *item = name;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return NULL;
30b4a330a5f651eb5198fa93dbb9f3d3594564c9stoddard}
e8f95a682820a599fe41b22977010636be5c2717jim
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *add_filter(cmd_parms *cmd, void *dummy, const char *arg)
30b4a330a5f651eb5198fa93dbb9f3d3594564c9stoddard{
30b4a330a5f651eb5198fa93dbb9f3d3594564c9stoddard core_dir_config *conf = dummy;
30b4a330a5f651eb5198fa93dbb9f3d3594564c9stoddard char **newfilter;
30b4a330a5f651eb5198fa93dbb9f3d3594564c9stoddard
30b4a330a5f651eb5198fa93dbb9f3d3594564c9stoddard newfilter = (char **)apr_push_array(conf->output_filters);
30b4a330a5f651eb5198fa93dbb9f3d3594564c9stoddard *newfilter = apr_pstrdup(cmd->pool, arg);
66e89b91046a4d0998bcb11c8aeb39ac444ed2dfjerenkrantz return NULL;
66e89b91046a4d0998bcb11c8aeb39ac444ed2dfjerenkrantz}
66e89b91046a4d0998bcb11c8aeb39ac444ed2dfjerenkrantz
30b4a330a5f651eb5198fa93dbb9f3d3594564c9stoddardstatic const char *add_input_filter(cmd_parms *cmd, void *dummy, const char *arg)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb core_dir_config *conf = dummy;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char **newfilter;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb newfilter = (char **)apr_push_array(conf->input_filters);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *newfilter = apr_pstrdup(cmd->pool, arg);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return NULL;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic const char *add_module_command(cmd_parms *cmd, void *dummy,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb const char *arg)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (err != NULL) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return err;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz if (!ap_add_named_module(arg)) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return apr_pstrcat(cmd->pool, "Cannot add module via name '", arg,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb "': not in list of loaded modules", NULL);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *(ap_directive_t **)dummy = NULL;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return NULL;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic const char *clear_module_list_command(cmd_parms *cmd, void *dummy)
4f9c22c4f27571d54197be9674e1fc0d528192aestriker{
4f9c22c4f27571d54197be9674e1fc0d528192aestriker const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (err != NULL) {
return err;
}
ap_clear_module_list();
*(ap_directive_t **)dummy = NULL;
return NULL;
}
static const char *set_server_string_slot(cmd_parms *cmd, void *dummy,
const char *arg)
{
/* This one's pretty generic... */
int offset = (int)(long)cmd->info;
char *struct_ptr = (char *)cmd->server;
const char *err = ap_check_cmd_context(cmd,
NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
if (err != NULL) {
return err;
}
*(const char **)(struct_ptr + offset) = arg;
return NULL;
}
static const char *server_port(cmd_parms *cmd, void *dummy, const char *arg)
{
const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
int port;
if (err != NULL) {
return err;
}
port = atoi(arg);
if (port <= 0 || port >= 65536) { /* 65536 == 1<<16 */
return apr_pstrcat(cmd->temp_pool, "The port number \"", arg,
"\" is outside the appropriate range "
"(i.e., 1..65535).", NULL);
}
cmd->server->port = port;
return NULL;
}
static const char *set_signature_flag(cmd_parms *cmd, void *d_,
const char *arg)
{
core_dir_config *d=d_;
const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
if (err != NULL) {
return err;
}
if (strcasecmp(arg, "On") == 0) {
d->server_signature = srv_sig_on;
}
else if (strcasecmp(arg, "Off") == 0) {
d->server_signature = srv_sig_off;
}
else if (strcasecmp(arg, "EMail") == 0) {
d->server_signature = srv_sig_withmail;
}
else {
return "ServerSignature: use one of: off | on | email";
}
return NULL;
}
static const char *set_server_root(cmd_parms *cmd, void *dummy,
const char *arg)
{
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
if (err != NULL) {
return err;
}
arg = ap_os_canonical_filename(cmd->pool, arg);
if (!ap_is_directory(arg)) {
return "ServerRoot must be a valid directory";
}
ap_server_root = arg;
return NULL;
}
static const char *set_timeout(cmd_parms *cmd, void *dummy, const char *arg)
{
const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
if (err != NULL) {
return err;
}
cmd->server->timeout = atoi(arg);
return NULL;
}
static const char *set_keep_alive_timeout(cmd_parms *cmd, void *dummy,
const char *arg)
{
const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
if (err != NULL) {
return err;
}
cmd->server->keep_alive_timeout = atoi(arg);
return NULL;
}
static const char *set_keep_alive(cmd_parms *cmd, void *dummy,
const char *arg)
{
const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
if (err != NULL) {
return err;
}
/* We've changed it to On/Off, but used to use numbers
* so we accept anything but "Off" or "0" as "On"
*/
if (!strcasecmp(arg, "off") || !strcmp(arg, "0")) {
cmd->server->keep_alive = 0;
}
else {
cmd->server->keep_alive = 1;
}
return NULL;
}
static const char *set_keep_alive_max(cmd_parms *cmd, void *dummy,
const char *arg)
{
const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
if (err != NULL) {
return err;
}
cmd->server->keep_alive_max = atoi(arg);
return NULL;
}
static const char *set_idcheck(cmd_parms *cmd, void *d_, int arg)
{
core_dir_config *d=d_;
const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
if (err != NULL) {
return err;
}
d->do_rfc1413 = arg != 0;
return NULL;
}
static const char *set_hostname_lookups(cmd_parms *cmd, void *d_,
const char *arg)
{
core_dir_config *d=d_;
const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
if (err != NULL) {
return err;
}
if (!strcasecmp(arg, "on")) {
d->hostname_lookups = HOSTNAME_LOOKUP_ON;
}
else if (!strcasecmp(arg, "off")) {
d->hostname_lookups = HOSTNAME_LOOKUP_OFF;
}
else if (!strcasecmp(arg, "double")) {
d->hostname_lookups = HOSTNAME_LOOKUP_DOUBLE;
}
else {
return "parameter must be 'on', 'off', or 'double'";
}
return NULL;
}
static const char *set_serverpath(cmd_parms *cmd, void *dummy,
const char *arg)
{
const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
if (err != NULL) {
return err;
}
cmd->server->path = arg;
cmd->server->pathlen = strlen(arg);
return NULL;
}
static const char *set_content_md5(cmd_parms *cmd, void *d_, int arg)
{
core_dir_config *d=d_;
const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
if (err != NULL) {
return err;
}
d->content_md5 = arg != 0;
return NULL;
}
static const char *set_use_canonical_name(cmd_parms *cmd, void *d_,
const char *arg)
{
core_dir_config *d=d_;
const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
if (err != NULL) {
return err;
}
if (strcasecmp(arg, "on") == 0) {
d->use_canonical_name = USE_CANONICAL_NAME_ON;
}
else if (strcasecmp(arg, "off") == 0) {
d->use_canonical_name = USE_CANONICAL_NAME_OFF;
}
else if (strcasecmp(arg, "dns") == 0) {
d->use_canonical_name = USE_CANONICAL_NAME_DNS;
}
else {
return "parameter must be 'on', 'off', or 'dns'";
}
return NULL;
}
static const char *include_config (cmd_parms *cmd, void *dummy,
const char *name)
{
ap_directive_t *conftree = NULL;
ap_process_resource_config(cmd->server,
ap_server_root_relative(cmd->pool, name),
&conftree, cmd->pool, cmd->temp_pool);
*(ap_directive_t **)dummy = conftree;
return NULL;
}
static const char *set_loglevel(cmd_parms *cmd, void *dummy, const char *arg)
{
char *str;
const char *err = ap_check_cmd_context(cmd,
NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
if (err != NULL) {
return err;
}
if ((str = ap_getword_conf(cmd->pool, &arg))) {
if (!strcasecmp(str, "emerg")) {
cmd->server->loglevel = APLOG_EMERG;
}
else if (!strcasecmp(str, "alert")) {
cmd->server->loglevel = APLOG_ALERT;
}
else if (!strcasecmp(str, "crit")) {
cmd->server->loglevel = APLOG_CRIT;
}
else if (!strcasecmp(str, "error")) {
cmd->server->loglevel = APLOG_ERR;
}
else if (!strcasecmp(str, "warn")) {
cmd->server->loglevel = APLOG_WARNING;
}
else if (!strcasecmp(str, "notice")) {
cmd->server->loglevel = APLOG_NOTICE;
}
else if (!strcasecmp(str, "info")) {
cmd->server->loglevel = APLOG_INFO;
}
else if (!strcasecmp(str, "debug")) {
cmd->server->loglevel = APLOG_DEBUG;
}
else {
return "LogLevel requires level keyword: one of "
"emerg/alert/crit/error/warn/notice/info/debug";
}
}
else {
return "LogLevel requires level keyword";
}
return NULL;
}
AP_DECLARE(const char *) ap_psignature(const char *prefix, request_rec *r)
{
char sport[20];
core_dir_config *conf;
conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
&core_module);
if ((conf->server_signature == srv_sig_off)
|| (conf->server_signature == srv_sig_unset)) {
return "";
}
apr_snprintf(sport, sizeof sport, "%u", (unsigned) ap_get_server_port(r));
if (conf->server_signature == srv_sig_withmail) {
return apr_pstrcat(r->pool, prefix, "<ADDRESS>" AP_SERVER_BASEVERSION
" Server at <A HREF=\"mailto:",
r->server->server_admin, "\">",
ap_get_server_name(r), "</A> Port ", sport,
"</ADDRESS>\n", NULL);
}
return apr_pstrcat(r->pool, prefix, "<ADDRESS>" AP_SERVER_BASEVERSION
" Server at ", ap_get_server_name(r), " Port ", sport,
"</ADDRESS>\n", NULL);
}
/*
* Load an authorisation realm into our location configuration, applying the
* usual rules that apply to realms.
*/
static const char *set_authname(cmd_parms *cmd, void *mconfig,
const char *word1)
{
core_dir_config *aconfig = (core_dir_config *)mconfig;
aconfig->ap_auth_name = ap_escape_quotes(cmd->pool, word1);
return NULL;
}
#ifdef _OSD_POSIX /* BS2000 Logon Passwd file */
static const char *set_bs2000_account(cmd_parms *cmd, void *dummy, char *name)
{
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
if (err != NULL) {
return err;
}
return os_set_account(cmd->pool, name);
}
#endif /*_OSD_POSIX*/
/*
* Handle a request to include the server's OS platform in the Server
* response header field (the ServerTokens directive). Unfortunately
* this requires a new global in order to communicate the setting back to
* http_main so it can insert the information in the right place in the
* string.
*/
static char *server_version = NULL;
static int version_locked = 0;
enum server_token_type {
SrvTk_MIN, /* eg: Apache/1.3.0 */
SrvTk_OS, /* eg: Apache/1.3.0 (UNIX) */
SrvTk_FULL, /* eg: Apache/1.3.0 (UNIX) PHP/3.0 FooBar/1.2b */
SrvTk_PRODUCT_ONLY /* eg: Apache */
};
static enum server_token_type ap_server_tokens = SrvTk_FULL;
static apr_status_t reset_version(void *dummy)
{
version_locked = 0;
ap_server_tokens = SrvTk_FULL;
server_version = NULL;
return APR_SUCCESS;
}
AP_DECLARE(const char *) ap_get_server_version(void)
{
return (server_version ? server_version : AP_SERVER_BASEVERSION);
}
AP_DECLARE(void) ap_add_version_component(apr_pool_t *pconf, const char *component)
{
if (! version_locked) {
/*
* If the version string is null, register our cleanup to reset the
* pointer on pool destruction. We also know that, if NULL,
* we are adding the original SERVER_BASEVERSION string.
*/
if (server_version == NULL) {
apr_register_cleanup(pconf, NULL, reset_version,
apr_null_cleanup);
server_version = apr_pstrdup(pconf, component);
}
else {
/*
* Tack the given component identifier to the end of
* the existing string.
*/
server_version = apr_pstrcat(pconf, server_version, " ",
component, NULL);
}
}
}
/*
* This routine adds the real server base identity to the version string,
* and then locks out changes until the next reconfig.
*/
static void ap_set_version(apr_pool_t *pconf)
{
if (ap_server_tokens == SrvTk_PRODUCT_ONLY) {
ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT);
}
else if (ap_server_tokens == SrvTk_MIN) {
ap_add_version_component(pconf, AP_SERVER_BASEVERSION);
}
else {
ap_add_version_component(pconf, AP_SERVER_BASEVERSION " (" PLATFORM ")");
}
/*
* Lock the server_version string if we're not displaying
* the full set of tokens
*/
if (ap_server_tokens != SrvTk_FULL) {
version_locked++;
}
}
static const char *set_serv_tokens(cmd_parms *cmd, void *dummy,
const char *arg)
{
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
if (err != NULL) {
return err;
}
if (!strcasecmp(arg, "OS")) {
ap_server_tokens = SrvTk_OS;
}
else if (!strcasecmp(arg, "Min") || !strcasecmp(arg, "Minimal")) {
ap_server_tokens = SrvTk_MIN;
}
else if (!strcasecmp(arg, "Prod") || !strcasecmp(arg, "ProductOnly")) {
ap_server_tokens = SrvTk_PRODUCT_ONLY;
}
else {
ap_server_tokens = SrvTk_FULL;
}
return NULL;
}
static const char *set_limit_req_line(cmd_parms *cmd, void *dummy,
const char *arg)
{
const char *err = ap_check_cmd_context(cmd,
NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
int lim;
if (err != NULL) {
return err;
}
lim = atoi(arg);
if (lim < 0) {
return apr_pstrcat(cmd->temp_pool, "LimitRequestLine \"", arg,
"\" must be a non-negative integer", NULL);
}
if (lim > DEFAULT_LIMIT_REQUEST_LINE) {
return apr_psprintf(cmd->temp_pool, "LimitRequestLine \"%s\" "
"must not exceed the precompiled maximum of %d",
arg, DEFAULT_LIMIT_REQUEST_LINE);
}
cmd->server->limit_req_line = lim;
return NULL;
}
static const char *set_limit_req_fieldsize(cmd_parms *cmd, void *dummy,
const char *arg)
{
const char *err = ap_check_cmd_context(cmd,
NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
int lim;
if (err != NULL) {
return err;
}
lim = atoi(arg);
if (lim < 0) {
return apr_pstrcat(cmd->temp_pool, "LimitRequestFieldsize \"", arg,
"\" must be a non-negative integer (0 = no limit)",
NULL);
}
if (lim > DEFAULT_LIMIT_REQUEST_FIELDSIZE) {
return apr_psprintf(cmd->temp_pool, "LimitRequestFieldsize \"%s\" "
"must not exceed the precompiled maximum of %d",
arg, DEFAULT_LIMIT_REQUEST_FIELDSIZE);
}
cmd->server->limit_req_fieldsize = lim;
return NULL;
}
static const char *set_limit_req_fields(cmd_parms *cmd, void *dummy,
const char *arg)
{
const char *err = ap_check_cmd_context(cmd,
NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
int lim;
if (err != NULL) {
return err;
}
lim = atoi(arg);
if (lim < 0) {
return apr_pstrcat(cmd->temp_pool, "LimitRequestFields \"", arg,
"\" must be a non-negative integer (0 = no limit)",
NULL);
}
cmd->server->limit_req_fields = lim;
return NULL;
}
static const char *set_limit_req_body(cmd_parms *cmd, void *conf_,
const char *arg)
{
core_dir_config *conf=conf_;
const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
if (err != NULL) {
return err;
}
/* WTF: If strtoul is not portable, then write a replacement.
* Instead we have an idiotic define in httpd.h that prevents
* it from being used even when it is available. Sheesh.
*/
conf->limit_req_body = (unsigned long)strtol(arg, (char **)NULL, 10);
return NULL;
}
static const char *set_limit_xml_req_body(cmd_parms *cmd, void *conf_,
const char *arg)
{
core_dir_config *conf = conf_;
const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
if (err != NULL) {
return err;
}
conf->limit_xml_body = atol(arg);
if (conf->limit_xml_body < 0)
return "LimitXMLRequestBody requires a non-negative integer.";
return NULL;
}
AP_DECLARE(size_t) ap_get_limit_xml_body(const request_rec *r)
{
core_dir_config *conf;
conf = ap_get_module_config(r->per_dir_config, &core_module);
if (conf->limit_xml_body == AP_LIMIT_UNSET)
return AP_DEFAULT_LIMIT_XML_BODY;
return (size_t)conf->limit_xml_body;
}
#ifdef WIN32
static const char *set_interpreter_source(cmd_parms *cmd, core_dir_config *d,
char *arg)
{
if (!strcasecmp(arg, "registry")) {
d->script_interpreter_source = INTERPRETER_SOURCE_REGISTRY;
} else if (!strcasecmp(arg, "registry-strict")) {
d->script_interpreter_source = INTERPRETER_SOURCE_REGISTRY_STRICT;
} else if (!strcasecmp(arg, "script")) {
d->script_interpreter_source = INTERPRETER_SOURCE_SHEBANG;
} else {
return apr_pstrcat(cmd->temp_pool, "ScriptInterpreterSource \"", arg,
"\" must be \"registry\", \"registry-strict\" or "
"\"script\"", NULL);
}
return NULL;
}
#endif
#if !defined (RLIMIT_CPU) || !(defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)) || !defined (RLIMIT_NPROC)
static const char *no_set_limit(cmd_parms *cmd, void *conf_,
const char *arg, const char *arg2)
{
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, cmd->server,
"%s not supported on this platform", cmd->cmd->name);
return NULL;
}
#endif
#ifdef RLIMIT_CPU
static const char *set_limit_cpu(cmd_parms *cmd, void *conf_,
const char *arg, const char *arg2)
{
core_dir_config *conf=conf_;
unixd_set_rlimit(cmd, &conf->limit_cpu, arg, arg2, RLIMIT_CPU);
return NULL;
}
#endif
#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)
static const char *set_limit_mem(cmd_parms *cmd, void *conf_,
const char *arg, const char * arg2)
{
core_dir_config *conf=conf_;
#if defined(RLIMIT_AS)
unixd_set_rlimit(cmd, &conf->limit_mem, arg, arg2 ,RLIMIT_AS);
#elif defined(RLIMIT_DATA)
unixd_set_rlimit(cmd, &conf->limit_mem, arg, arg2, RLIMIT_DATA);
#elif defined(RLIMIT_VMEM)
unixd_set_rlimit(cmd, &conf->limit_mem, arg, arg2, RLIMIT_VMEM);
#endif
return NULL;
}
#endif
#ifdef RLIMIT_NPROC
static const char *set_limit_nproc(cmd_parms *cmd, void *conf_,
const char *arg, const char * arg2)
{
core_dir_config *conf=conf_;
unixd_set_rlimit(cmd, &conf->limit_nproc, arg, arg2, RLIMIT_NPROC);
return NULL;
}
#endif
static apr_status_t writev_it_all(apr_socket_t *s,
struct iovec *vec, int nvec,
apr_size_t len, apr_size_t *nbytes)
{
apr_size_t bytes_written = 0;
apr_status_t rv;
apr_size_t n = len;
apr_size_t i = 0;
*nbytes = 0;
/* XXX handle checking for non-blocking socket */
while (bytes_written != len) {
rv = apr_sendv(s, vec + i, nvec - i, &n);
bytes_written += n;
if (rv != APR_SUCCESS)
return rv;
*nbytes += n;
/* If the write did not complete, adjust the iovecs and issue
* apr_sendv again
*/
if (bytes_written < len) {
/* Skip over the vectors that have already been written */
apr_size_t cnt = vec[i].iov_len;
while (n >= cnt && i + 1 < nvec) {
i++;
cnt += vec[i].iov_len;
}
if (n < cnt) {
/* Handle partial write of vec i */
vec[i].iov_base = (char *) vec[i].iov_base +
(vec[i].iov_len - (cnt - n));
vec[i].iov_len = cnt -n;
}
}
n = len - bytes_written;
}
return APR_SUCCESS;
}
/* sendfile_it_all()
* send the entire file using sendfile()
* handle partial writes
* return only when all bytes have been sent or an error is encountered.
*/
#if APR_HAS_SENDFILE
static apr_status_t sendfile_it_all(conn_rec *c,
apr_file_t *fd,
apr_hdtr_t *hdtr,
apr_off_t file_offset,
apr_size_t file_bytes_left,
apr_size_t total_bytes_left,
apr_int32_t flags)
{
apr_status_t rv;
apr_int32_t timeout = 0;
AP_DEBUG_ASSERT((apr_getsocketopt(c->client_socket, APR_SO_TIMEOUT,
&timeout) == APR_SUCCESS) &&
timeout > 0); /* socket must be in timeout mode */
do {
apr_ssize_t tmplen = file_bytes_left;
rv = apr_sendfile(c->client_socket, fd, hdtr, &file_offset, &tmplen,
flags);
total_bytes_left -= tmplen;
if (!total_bytes_left || rv != APR_SUCCESS) {
return rv; /* normal case & error exit */
}
AP_DEBUG_ASSERT(total_bytes_left > 0 && tmplen > 0);
/* partial write, oooh noooo...
* Skip over any header data which was written
*/
while (tmplen && hdtr->numheaders) {
if (tmplen >= hdtr->headers[0].iov_len) {
tmplen -= hdtr->headers[0].iov_len;
--hdtr->numheaders;
++hdtr->headers;
}
else {
hdtr->headers[0].iov_len -= tmplen;
(char *) hdtr->headers[0].iov_base += tmplen;
tmplen = 0;
}
}
/* Skip over any file data which was written */
if (tmplen <= file_bytes_left) {
file_offset += tmplen;
file_bytes_left -= tmplen;
continue;
}
tmplen -= file_bytes_left;
file_bytes_left = 0;
file_offset = 0;
/* Skip over any trailer data which was written */
while (tmplen && hdtr->numtrailers) {
if (tmplen >= hdtr->trailers[0].iov_len) {
tmplen -= hdtr->trailers[0].iov_len;
--hdtr->numtrailers;
++hdtr->trailers;
}
else {
hdtr->trailers[0].iov_len -= tmplen;
(char *)hdtr->trailers[0].iov_base += tmplen;
tmplen = 0;
}
}
} while (1);
}
#endif
/*
* send_the_file()
* Sends the contents of file fd along with header/trailer bytes, if any,
* to the network. send_the_file will return only when all the bytes have been
* sent (i.e., it handles partial writes) or on a network error condition.
*/
static apr_status_t send_the_file(conn_rec *c, apr_file_t *fd,
apr_hdtr_t *hdtr, apr_off_t offset,
apr_size_t length, apr_size_t *nbytes)
{
apr_status_t rv = APR_SUCCESS;
apr_int32_t togo; /* Remaining number of bytes in the file to send */
apr_size_t sendlen = 0;
apr_size_t bytes_sent;
apr_int32_t i;
apr_off_t o; /* Track the file offset for partial writes */
char buffer[8192];
*nbytes = 0;
/* Send the headers
* writev_it_all handles partial writes.
* XXX: optimization... if headers are less than MIN_WRITE_SIZE, copy
* them into buffer
*/
if ( hdtr && hdtr->numheaders > 0 ) {
for (i = 0; i < hdtr->numheaders; i++) {
sendlen += hdtr->headers[i].iov_len;
}
rv = writev_it_all(c->client_socket, hdtr->headers, hdtr->numheaders,
sendlen, &bytes_sent);
if (rv == APR_SUCCESS)
*nbytes += bytes_sent; /* track total bytes sent */
}
/* Seek the file to 'offset' */
if (offset != 0 && rv == APR_SUCCESS) {
rv = apr_seek(fd, APR_SET, &offset);
}
/* Send the file, making sure to handle partial writes */
togo = length;
while (rv == APR_SUCCESS && togo) {
sendlen = togo > sizeof(buffer) ? sizeof(buffer) : togo;
o = 0;
rv = apr_read(fd, buffer, &sendlen);
while (rv == APR_SUCCESS && sendlen) {
bytes_sent = sendlen;
rv = apr_send(c->client_socket, &buffer[o], &bytes_sent);
if (rv == APR_SUCCESS) {
sendlen -= bytes_sent; /* sendlen != bytes_sent ==> partial write */
o += bytes_sent; /* o is where we are in the buffer */
*nbytes += bytes_sent;
togo -= bytes_sent; /* track how much of the file we've sent */
}
}
}
/* Send the trailers
* XXX: optimization... if it will fit, send this on the last send in the
* loop above
*/
sendlen = 0;
if ( rv == APR_SUCCESS && hdtr && hdtr->numtrailers > 0 ) {
for (i = 0; i < hdtr->numtrailers; i++) {
sendlen += hdtr->trailers[i].iov_len;
}
rv = writev_it_all(c->client_socket, hdtr->trailers, hdtr->numtrailers,
sendlen, &bytes_sent);
if (rv == APR_SUCCESS)
*nbytes += bytes_sent;
}
return rv;
}
/* Note --- ErrorDocument will now work from .htaccess files.
* The AllowOverride of Fileinfo allows webmasters to turn it off
*/
static const command_rec core_cmds[] = {
/* Old access config file commands */
AP_INIT_RAW_ARGS("<Directory", dirsection, NULL, RSRC_CONF,
"Container for directives affecting resources located in the specified "
"directories"),
AP_INIT_RAW_ARGS("<Location", urlsection, NULL, RSRC_CONF,
"Container for directives affecting resources accessed through the "
"specified URL paths"),
AP_INIT_RAW_ARGS("<VirtualHost", virtualhost_section, NULL, RSRC_CONF,
"Container to map directives to a particular virtual host, takes one or "
"more host addresses"),
AP_INIT_RAW_ARGS("<Files", filesection, NULL, OR_ALL,
"Container for directives affecting files matching specified patterns"),
AP_INIT_RAW_ARGS("<Limit", ap_limit_section, NULL, OR_ALL,
"Container for authentication directives when accessed using specified HTTP "
"methods"),
AP_INIT_RAW_ARGS("<LimitExcept", ap_limit_section, (void*)1, OR_ALL,
"Container for authentication directives to be applied when any HTTP "
"method other than those specified is used to access the resource"),
AP_INIT_TAKE1("<IfModule", start_ifmod, NULL, EXEC_ON_READ | OR_ALL,
"Container for directives based on existance of specified modules"),
AP_INIT_TAKE1("<IfDefine", start_ifdefine, NULL, EXEC_ON_READ | OR_ALL,
"Container for directives based on existance of command line defines"),
AP_INIT_RAW_ARGS("<DirectoryMatch", dirsection, (void*)1, RSRC_CONF,
"Container for directives affecting resources located in the "
"specified directories"),
AP_INIT_RAW_ARGS("<LocationMatch", urlsection, (void*)1, RSRC_CONF,
"Container for directives affecting resources accessed through the "
"specified URL paths"),
AP_INIT_RAW_ARGS("<FilesMatch", filesection, (void*)1, OR_ALL,
"Container for directives affecting files matching specified patterns"),
AP_INIT_TAKE1("AuthType", ap_set_string_slot,
(void*)XtOffsetOf(core_dir_config, ap_auth_type), OR_AUTHCFG,
"An HTTP authorization type (e.g., \"Basic\")"),
AP_INIT_TAKE1("AuthName", set_authname, NULL, OR_AUTHCFG,
"The authentication realm (e.g. \"Members Only\")"),
AP_INIT_RAW_ARGS("Require", require, NULL, OR_AUTHCFG,
"Selects which authenticated users or groups may access a protected space"),
AP_INIT_TAKE1("Satisfy", satisfy, NULL, OR_AUTHCFG,
"access policy if both allow and require used ('all' or 'any')"),
#ifdef GPROF
AP_INIT_TAKE1("GprofDir", set_gprof_dir, NULL, RSRC_CONF,
"Directory to plop gmon.out files"),
#endif
AP_INIT_TAKE1("AddDefaultCharset", set_add_default_charset, NULL, OR_FILEINFO,
"The name of the default charset to add to any Content-Type without one or 'Off' to disable"),
/* Old resource config file commands */
AP_INIT_RAW_ARGS("AccessFileName", set_access_name, NULL, RSRC_CONF,
"Name(s) of per-directory config files (default: .htaccess)"),
AP_INIT_TAKE1("DocumentRoot", set_document_root, NULL, RSRC_CONF,
"Root directory of the document tree"),
AP_INIT_TAKE2("ErrorDocument", set_error_document, NULL, OR_FILEINFO,
"Change responses for HTTP errors"),
AP_INIT_RAW_ARGS("AllowOverride", set_override, NULL, ACCESS_CONF,
"Controls what groups of directives can be configured by per-directory "
"config files"),
AP_INIT_RAW_ARGS("Options", set_options, NULL, OR_OPTIONS,
"Set a number of attributes for a given directory"),
AP_INIT_TAKE1("DefaultType", ap_set_string_slot,
(void*)XtOffsetOf (core_dir_config, ap_default_type),
OR_FILEINFO, "the default MIME type for untypable files"),
/* Old server config file commands */
AP_INIT_TAKE1("Port", server_port, NULL, RSRC_CONF, "A TCP port number"),
AP_INIT_TAKE1("HostnameLookups", set_hostname_lookups, NULL,
ACCESS_CONF|RSRC_CONF,
"\"on\" to enable, \"off\" to disable reverse DNS lookups, or \"double\" to "
"enable double-reverse DNS lookups"),
AP_INIT_TAKE1("ServerAdmin", set_server_string_slot,
(void *)XtOffsetOf (server_rec, server_admin), RSRC_CONF,
"The email address of the server administrator"),
AP_INIT_TAKE1("ServerName", set_server_string_slot,
(void *)XtOffsetOf (server_rec, server_hostname), RSRC_CONF,
"The hostname of the server"),
AP_INIT_TAKE1("ServerSignature", set_signature_flag, NULL, OR_ALL,
"En-/disable server signature (on|off|email)"),
AP_INIT_TAKE1("ServerRoot", set_server_root, NULL, RSRC_CONF,
"Common directory of server-related files (logs, confs, etc.)"),
AP_INIT_TAKE1("ErrorLog", set_server_string_slot,
(void *)XtOffsetOf (server_rec, error_fname), RSRC_CONF,
"The filename of the error log"),
AP_INIT_RAW_ARGS("ServerAlias", set_server_alias, NULL, RSRC_CONF,
"A name or names alternately used to access the server"),
AP_INIT_TAKE1("ServerPath", set_serverpath, NULL, RSRC_CONF,
"The pathname the server can be reached at"),
AP_INIT_TAKE1("Timeout", set_timeout, NULL, RSRC_CONF,
"Timeout duration (sec)"),
AP_INIT_TAKE1("KeepAliveTimeout", set_keep_alive_timeout, NULL, RSRC_CONF,
"Keep-Alive timeout duration (sec)"),
AP_INIT_TAKE1("MaxKeepAliveRequests", set_keep_alive_max, NULL, RSRC_CONF,
"Maximum number of Keep-Alive requests per connection, or 0 for infinite"),
AP_INIT_TAKE1("KeepAlive", set_keep_alive, NULL, RSRC_CONF,
"Whether persistent connections should be On or Off"),
AP_INIT_FLAG("IdentityCheck", set_idcheck, NULL, RSRC_CONF|ACCESS_CONF,
"Enable identd (RFC 1413) user lookups - SLOW"),
AP_INIT_FLAG("ContentDigest", set_content_md5, NULL, OR_OPTIONS,
"whether or not to send a Content-MD5 header with each request"),
AP_INIT_TAKE1("UseCanonicalName", set_use_canonical_name, NULL,
RSRC_CONF|ACCESS_CONF,
"How to work out the ServerName : Port when constructing URLs"),
/* TODO: RlimitFoo should all be part of mod_cgi, not in the core */
AP_INIT_ITERATE("AddModule", add_module_command, NULL,
RSRC_CONF, "The name of a module"),
AP_INIT_NO_ARGS("ClearModuleList", clear_module_list_command, NULL,
RSRC_CONF, NULL),
/* TODO: ListenBacklog in MPM */
AP_INIT_TAKE1("Include", include_config, NULL,
(RSRC_CONF | ACCESS_CONF | EXEC_ON_READ),
"Name of the config file to be included"),
AP_INIT_TAKE1("LogLevel", set_loglevel, NULL, RSRC_CONF,
"Level of verbosity in error logging"),
AP_INIT_TAKE1("NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF,
"A numeric IP address:port, or the name of a host"),
#ifdef _OSD_POSIX
AP_INIT_TAKE1("BS2000Account", set_bs2000_account, NULL, RSRC_CONF,
"Name of server User's bs2000 logon account name"),
#endif
#ifdef WIN32
AP_INIT_TAKE1("ScriptInterpreterSource", set_interpreter_source, NULL,
OR_FILEINFO,
"Where to find interpreter to run Win32 scripts (Registry or script shebang line)"),
#endif
AP_INIT_TAKE1("ServerTokens", set_serv_tokens, NULL, RSRC_CONF,
"Determine tokens displayed in the Server: header - Min(imal), OS or Full"),
AP_INIT_TAKE1("LimitRequestLine", set_limit_req_line, NULL, RSRC_CONF,
"Limit on maximum size of an HTTP request line"),
AP_INIT_TAKE1("LimitRequestFieldsize", set_limit_req_fieldsize, NULL,
RSRC_CONF,
"Limit on maximum size of an HTTP request header field"),
AP_INIT_TAKE1("LimitRequestFields", set_limit_req_fields, NULL, RSRC_CONF,
"Limit (0 = unlimited) on max number of header fields in a request message"),
AP_INIT_TAKE1("LimitRequestBody", set_limit_req_body,
(void*)XtOffsetOf(core_dir_config, limit_req_body), OR_ALL,
"Limit (in bytes) on maximum size of request message body"),
AP_INIT_TAKE1("LimitXMLRequestBody", set_limit_xml_req_body, NULL, OR_ALL,
"Limit (in bytes) on maximum size of an XML-based request "
"body"),
/* System Resource Controls */
#ifdef RLIMIT_CPU
AP_INIT_TAKE12("RLimitCPU", set_limit_cpu,
(void*)XtOffsetOf(core_dir_config, limit_cpu),
OR_ALL, "Soft/hard limits for max CPU usage in seconds"),
#else
AP_INIT_TAKE12("RLimitCPU", no_set_limit, NULL,
OR_ALL, "Soft/hard limits for max CPU usage in seconds"),
#endif
#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined (RLIMIT_AS)
AP_INIT_TAKE12("RLimitMEM", set_limit_mem,
(void*)XtOffsetOf(core_dir_config, limit_mem),
OR_ALL, "Soft/hard limits for max memory usage per process"),
#else
AP_INIT_TAKE12("RLimitMEM", no_set_limit, NULL,
OR_ALL, "Soft/hard limits for max memory usage per process"),
#endif
#ifdef RLIMIT_NPROC
AP_INIT_TAKE12("RLimitNPROC", set_limit_nproc,
(void*)XtOffsetOf(core_dir_config, limit_nproc),
OR_ALL, "soft/hard limits for max number of processes per uid"),
#else
AP_INIT_TAKE12("RLimitNPROC", no_set_limit, NULL,
OR_ALL, "soft/hard limits for max number of processes per uid"),
#endif
/* XXX These should be allowable in .htaccess files, but currently it won't
* play well with the Options stuff. Until that is fixed, I would prefer
* to leave it just in the conf file. Other should feel free to disagree
* with me. Rbb.
*/
AP_INIT_ITERATE("AddOutputFilter", add_filter, NULL, ACCESS_CONF,
"filters to be run"),
AP_INIT_ITERATE("AddInputFilter", add_input_filter, NULL, ACCESS_CONF,
"filters to be run on the request body"),
{ NULL }
};
/*****************************************************************
*
* Core handlers for various phases of server operation...
*/
AP_DECLARE_NONSTD(int) ap_core_translate(request_rec *r)
{
void *sconf = r->server->module_config;
core_server_config *conf = ap_get_module_config(sconf, &core_module);
if (r->proxyreq) {
return HTTP_FORBIDDEN;
}
if ((r->uri[0] != '/') && strcmp(r->uri, "*")) {
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
"Invalid URI in request %s", r->the_request);
return HTTP_BAD_REQUEST;
}
if (r->server->path
&& !strncmp(r->uri, r->server->path, r->server->pathlen)
&& (r->server->path[r->server->pathlen - 1] == '/'
|| r->uri[r->server->pathlen] == '/'
|| r->uri[r->server->pathlen] == '\0')) {
r->filename = apr_pstrcat(r->pool, conf->ap_document_root,
(r->uri + r->server->pathlen), NULL);
}
else {
/*
* Make sure that we do not mess up the translation by adding two
* /'s in a row. This happens under windows when the document
* root ends with a /
*/
if ((conf->ap_document_root[strlen(conf->ap_document_root)-1] == '/')
&& (*(r->uri) == '/')) {
r->filename = apr_pstrcat(r->pool, conf->ap_document_root, r->uri+1,
NULL);
}
else {
r->filename = apr_pstrcat(r->pool, conf->ap_document_root, r->uri,
NULL);
}
}
return OK;
}
static int do_nothing(request_rec *r) { return OK; }
static int default_handler(request_rec *r)
{
ap_bucket_brigade *bb;
ap_bucket *e;
core_dir_config *d =
(core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module);
int errstatus;
apr_file_t *fd = NULL;
apr_status_t status;
/* XXX if/when somebody writes a content-md5 filter we either need to
* remove this support or coordinate when to use the filter vs.
* when to use this code
* The current choice of when to compute the md5 here matches the 1.3
* support fairly closely (unlike 1.3, we don't handle computing md5
* when the charset is translated).
*/
int bld_content_md5 =
(d->content_md5 & 1) && r->output_filters->frec->ftype != AP_FTYPE_CONTENT;
ap_allow_methods(r, MERGE_ALLOW, "GET", "OPTIONS", "POST", NULL);
if ((errstatus = ap_discard_request_body(r)) != OK) {
return errstatus;
}
if (r->method_number == M_INVALID) {
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
"Invalid method in request %s", r->the_request);
return HTTP_NOT_IMPLEMENTED;
}
if (r->method_number == M_OPTIONS) {
return ap_send_http_options(r);
}
if (r->method_number == M_PUT) {
return HTTP_METHOD_NOT_ALLOWED;
}
if (r->finfo.protection == 0 || (r->path_info && *r->path_info)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
"File does not exist: %s",r->path_info ?
apr_pstrcat(r->pool, r->filename, r->path_info, NULL)
: r->filename);
return HTTP_NOT_FOUND;
}
if (r->method_number != M_GET && r->method_number != M_POST) {
return HTTP_METHOD_NOT_ALLOWED;
}
if ((status = apr_open(&fd, r->filename, APR_READ | APR_BINARY, 0, r->connection->pool)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
"file permissions deny server access: %s", r->filename);
return HTTP_FORBIDDEN;
}
ap_update_mtime(r, r->finfo.mtime);
ap_set_last_modified(r);
ap_set_etag(r);
apr_table_setn(r->headers_out, "Accept-Ranges", "bytes");
ap_set_content_length(r, r->finfo.size);
if ((errstatus = ap_meets_conditions(r)) != OK) {
apr_close(fd);
return errstatus;
}
if (bld_content_md5) {
apr_table_setn(r->headers_out, "Content-MD5",
ap_md5digest(r->pool, fd));
}
bb = ap_brigade_create(r->pool);
e = ap_bucket_create_file(fd, 0, r->finfo.size);
AP_BRIGADE_INSERT_HEAD(bb, e);
e = ap_bucket_create_eos();
AP_BRIGADE_INSERT_TAIL(bb, e);
return ap_pass_brigade(r->output_filters, bb);
}
/*
* coalesce_filter()
* This is a simple filter to coalesce many small buckets into one large
* bucket.
*
* Note:
* This implementation of coalesce_filter will only coalesce a single
* contiguous string of coalesable buckets. It will not coalesce multiple
* non-contiguous buckets. For example, if a brigade contains 10 small
* buckets followed by a large bucket (or a pipe or file bucket) followed
* by more small buckets, only the first 10 buckets will be coalesced.
*/
typedef struct COALESCE_FILTER_CTX {
char *buf; /* Start of buffer */
char *cur; /* Pointer to next location to write */
apr_size_t cnt; /* Number of bytes put in buf */
apr_size_t avail; /* Number of bytes available in the buf */
} coalesce_filter_ctx_t;
#define MIN_BUCKET_SIZE 200
static apr_status_t coalesce_filter(ap_filter_t *f, ap_bucket_brigade *b)
{
apr_status_t rv;
apr_pool_t *p = f->r->pool;
ap_bucket *e, *insert_before = NULL, *destroy_me = NULL;
coalesce_filter_ctx_t *ctx = f->ctx;
int pass_the_brigade = 0, insert_first = 0;
if (ctx == NULL) {
f->ctx = ctx = apr_pcalloc(p, sizeof(coalesce_filter_ctx_t));
ctx->avail = AP_MIN_BYTES_TO_WRITE;
}
if (ctx->cnt) {
insert_first = 1;
}
/* Iterate across the buckets, coalescing the small buckets into a
* single buffer
*/
AP_BRIGADE_FOREACH(e, b) {
if (destroy_me) {
ap_bucket_destroy(destroy_me);
destroy_me = NULL;
}
if (AP_BUCKET_IS_EOS(e) || AP_BUCKET_IS_FILE(e) ||
AP_BUCKET_IS_PIPE(e) || AP_BUCKET_IS_FLUSH(e)) {
pass_the_brigade = 1;
}
else {
const char *str;
apr_size_t n;
rv = ap_bucket_read(e, &str, &n, AP_BLOCK_READ);
if (rv != APR_SUCCESS) {
/* XXX: log error */
return rv;
}
if ((n < MIN_BUCKET_SIZE) && (n < ctx->avail)) {
/* Coalesce this bucket into the buffer */
if (ctx->buf == NULL) {
ctx->buf = apr_palloc(p, AP_MIN_BYTES_TO_WRITE);
ctx->cur = ctx->buf;
ctx->cnt = 0;
}
memcpy(ctx->cur, str, n);
ctx->cnt += n;
ctx->cur += n;
ctx->avail -= n;
/* If this is the first bucket to be coalesced, don't remove it
* from the brigade. Save it as a marker for where to insert
* ctx->buf into the brigade when we're done.
*/
if (insert_before || insert_first){
AP_BUCKET_REMOVE(e);
destroy_me = e;
}
else {
insert_before = e;
}
}
else if (insert_before || insert_first) {
/* This bucket was not able to be coalesced because it either
* exceeds MIN_BUCKET_SIZE or its contents will not fit into
* buf. We're done...
*/
pass_the_brigade = 1;
break;
}
else {
/* If there is even a single bucket that cannot be coalesced,
* then we must pass the brigade down to the next filter.
*/
pass_the_brigade = 1;
}
}
}
if (destroy_me) {
ap_bucket_destroy(destroy_me);
destroy_me = NULL;
}
if (pass_the_brigade) {
/* Insert ctx->buf into the correct spot in the brigade */
e = ap_bucket_create_pool(ctx->buf, ctx->cnt, p);
if (insert_first) {
AP_BRIGADE_INSERT_HEAD(b, e);
}
else if (insert_before) {
AP_BUCKET_INSERT_BEFORE(e, insert_before);
AP_BUCKET_REMOVE(insert_before);
ap_bucket_destroy(insert_before);
insert_before = NULL;
}
rv = ap_pass_brigade(f->next, b);
if (rv != APR_SUCCESS) {
/* XXX: Log the error */
return rv;
}
/* Get ctx->buf ready for the next brigade */
if (ctx) {
ctx->cur = ctx->buf;
ctx->cnt = 0;
ctx->avail = AP_MIN_BYTES_TO_WRITE;
}
}
else {
if (insert_before) {
AP_BUCKET_REMOVE(insert_before);
ap_bucket_destroy(insert_before);
}
/* The brigade should be empty now because all the buckets
* were coalesced into the coalesce_filter buf
*/
}
return APR_SUCCESS;
}
/*
* HTTP/1.1 chunked transfer encoding filter.
*/
static apr_status_t chunk_filter(ap_filter_t *f, ap_bucket_brigade *b)
{
#define ASCII_CRLF "\015\012"
#define ASCII_ZERO "\060"
ap_bucket_brigade *more = NULL;
ap_bucket *e;
apr_status_t rv;
for (more = NULL; b; b = more, more = NULL) {
apr_off_t bytes = 0;
ap_bucket *eos = NULL;
char chunk_hdr[20]; /* enough space for the snprintf below */
AP_BRIGADE_FOREACH(e, b) {
if (AP_BUCKET_IS_EOS(e)) {
/* there shouldn't be anything after the eos */
eos = e;
break;
}
else if (e->length == -1) {
/* unknown amount of data (e.g. a pipe) */
const char *data;
apr_size_t len;
rv = ap_bucket_read(e, &data, &len, AP_BLOCK_READ);
if (rv != APR_SUCCESS) {
return rv;
}
if (len > 0) {
/*
* There may be a new next bucket representing the
* rest of the data stream on which a read() may
* block so we pass down what we have so far.
*/
bytes += len;
more = ap_brigade_split(b, AP_BUCKET_NEXT(e));
break;
}
else {
/* If there was nothing in this bucket then we can
* safely move on to the next one without pausing
* to pass down what we have counted up so far.
*/
continue;
}
}
else {
bytes += e->length;
}
}
/*
* XXX: if there aren't very many bytes at this point it may
* be a good idea to set them aside and return for more,
* unless we haven't finished counting this brigade yet.
*/
/* if there are content bytes, then wrap them in a chunk */
if (bytes > 0) {
apr_size_t hdr_len;
/*
* Insert the chunk header, specifying the number of bytes in
* the chunk.
*/
/* XXX might be nice to have APR_OFF_T_FMT_HEX */
hdr_len = apr_snprintf(chunk_hdr, sizeof(chunk_hdr),
"%qx" CRLF, (apr_uint64_t)bytes);
ap_xlate_proto_to_ascii(chunk_hdr, hdr_len);
e = ap_bucket_create_transient(chunk_hdr, hdr_len);
AP_BRIGADE_INSERT_HEAD(b, e);
/*
* Insert the end-of-chunk CRLF before the EOS bucket, or
* appended to the brigade
*/
e = ap_bucket_create_immortal(ASCII_CRLF, 2);
if (eos != NULL) {
AP_BUCKET_INSERT_BEFORE(eos, e);
}
else {
AP_BRIGADE_INSERT_TAIL(b, e);
}
}
/* RFC 2616, Section 3.6.1
*
* If there is an EOS bucket, then prefix it with:
* 1) the last-chunk marker ("0" CRLF)
* 2) the trailer
* 3) the end-of-chunked body CRLF
*
* If there is no EOS bucket, then do nothing.
*
* XXX: it would be nice to combine this with the end-of-chunk
* marker above, but this is a bit more straight-forward for
* now.
*/
if (eos != NULL) {
/* XXX: (2) trailers ... does not yet exist */
e = ap_bucket_create_immortal(ASCII_ZERO ASCII_CRLF /* <trailers> */ ASCII_CRLF, 5);
AP_BUCKET_INSERT_BEFORE(eos, e);
}
/* pass the brigade to the next filter. */
rv = ap_pass_brigade(f->next, b);
if (rv != APR_SUCCESS || eos != NULL) {
return rv;
}
}
return APR_SUCCESS;
}
static int core_input_filter(ap_filter_t *f, ap_bucket_brigade *b, ap_input_mode_t mode)
{
ap_bucket *e;
if (!f->ctx) { /* If we haven't passed up the socket yet... */
f->ctx = (void *)1;
e = ap_bucket_create_socket(f->c->client_socket);
AP_BRIGADE_INSERT_TAIL(b, e);
return APR_SUCCESS;
}
else {
/* Either some code lost track of the socket
* bucket or we already found out that the
* client closed.
*/
return APR_EOF;
}
}
/* Default filter. This filter should almost always be used. Its only job
* is to send the headers if they haven't already been sent, and then send
* the actual data.
*/
typedef struct CORE_OUTPUT_FILTER_CTX {
ap_bucket_brigade *b;
} core_output_filter_ctx_t;
#define MAX_IOVEC_TO_WRITE 16
static apr_status_t core_output_filter(ap_filter_t *f, ap_bucket_brigade *b)
{
apr_status_t rv;
ap_bucket_brigade *more = NULL;
apr_size_t bytes_sent = 0, nbytes;
ap_bucket *e;
conn_rec *c = f->c;
core_output_filter_ctx_t *ctx = f->ctx;
apr_size_t nvec = 0;
apr_size_t nvec_trailers= 0;
struct iovec vec[MAX_IOVEC_TO_WRITE];
struct iovec vec_trailers[MAX_IOVEC_TO_WRITE];
apr_file_t *fd = NULL;
apr_size_t flen = 0;
apr_off_t foffset = 0;
if (ctx == NULL) {
f->ctx = ctx = apr_pcalloc(c->pool, sizeof(core_output_filter_ctx_t));
}
/* If we have a saved brigade, concatenate the new brigade to it */
if (ctx->b) {
AP_BRIGADE_CONCAT(ctx->b, b);
b = ctx->b;
ctx->b = NULL;
}
/* Iterate over the brigade collecting iovecs */
while (b) {
nbytes = 0; /* in case more points to another brigade */
more = NULL;
AP_BRIGADE_FOREACH(e, b) {
if (AP_BUCKET_IS_EOS(e) || AP_BUCKET_IS_FLUSH(e)) {
break;
}
else if (AP_BUCKET_IS_FILE(e)) {
ap_bucket_file *a = e->data;
/* Assume there is at most one AP_BUCKET_FILE in the brigade */
fd = a->fd;
flen = e->length;
foffset = a->offset;
}
else {
const char *str;
apr_size_t n;
rv = ap_bucket_read(e, &str, &n, AP_BLOCK_READ);
if (n) {
nbytes += n;
if (!fd) {
vec[nvec].iov_base = (char*) str;
vec[nvec].iov_len = n;
nvec++;
}
else {
/* The bucket is a trailer to a file bucket */
vec_trailers[nvec_trailers].iov_base = (char*) str;
vec_trailers[nvec_trailers].iov_len = n;
nvec_trailers++;
}
}
}
if ((nvec == MAX_IOVEC_TO_WRITE) || (nvec_trailers == MAX_IOVEC_TO_WRITE)) {
/* Split the brigade and break */
if (AP_BUCKET_NEXT(e) != AP_BRIGADE_SENTINEL(b)) {
more = ap_brigade_split(b, AP_BUCKET_NEXT(e));
}
break;
}
}
/* Completed iterating over the brigades, now determine if we want to
* buffer the brigade or send the brigade out on the network
*/
if ((!fd && (!more) && (nbytes < AP_MIN_BYTES_TO_WRITE) && !AP_BUCKET_IS_FLUSH(e))
|| (AP_BUCKET_IS_EOS(e) && c->keepalive)) {
/* NEVER save an EOS in here. If we are saving a brigade with an
* EOS bucket, then we are doing keepalive connections, and we want
* to process to second request fully.
*/
if (AP_BUCKET_IS_EOS(e)) {
AP_BUCKET_REMOVE(e);
ap_bucket_destroy(e);
}
ap_save_brigade(f, &ctx->b, &b);
return APR_SUCCESS;
}
if (fd) {
apr_hdtr_t hdtr;
#if APR_HAS_SENDFILE
apr_int32_t flags = 0;
#endif
memset(&hdtr, '\0', sizeof(hdtr));
if (nvec) {
hdtr.numheaders = nvec;
hdtr.headers = vec;
}
if (nvec_trailers) {
hdtr.numtrailers = nvec_trailers;
hdtr.trailers = vec_trailers;
}
#if APR_HAS_SENDFILE
if (!c->keepalive) {
/* Prepare the socket to be reused */
flags |= APR_SENDFILE_DISCONNECT_SOCKET;
}
rv = sendfile_it_all(c, /* the connection */
fd, /* the file to send */
&hdtr, /* header and trailer iovecs */
foffset, /* offset in the file to begin
sending from */
flen, /* length of file */
nbytes + flen, /* total length including
headers */
flags); /* apr_sendfile flags */
/* If apr_sendfile() returns APR_ENOTIMPL, call send_the_file() to
* loop on apr_read/apr_send to send the file. Our Windows binary
* distributions (which work on Windows 9x/NT) are compiled on
* Windows NT. TransmitFile is not available on Windows 95/98 and
* we discover this at runtime when apr_sendfile() returns
* APR_ENOTIMPL. Having apr_sendfile() return APR_ENOTIMPL seems
* the cleanest way to handle this case.
*/
if (rv == APR_ENOTIMPL) {
#endif
rv = send_the_file(c, fd, &hdtr, foffset, flen, &bytes_sent);
#if APR_HAS_SENDFILE
}
#endif
}
else {
rv = writev_it_all(c->client_socket,
vec, nvec,
nbytes, &bytes_sent);
}
ap_brigade_destroy(b);
if (rv != APR_SUCCESS) {
/* XXX: log the error */
if (more)
ap_brigade_destroy(more);
return rv;
}
nvec = 0;
nvec_trailers = 0;
b = more;
} /* end while () */
return APR_SUCCESS;
}
static const handler_rec core_handlers[] = {
{ "*/*", default_handler },
{ "default-handler", default_handler },
{ NULL, NULL }
};
static void core_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp)
{
ap_init_bucket_types(pconf);
}
static void core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
{
ap_set_version(pconf);
}
static void core_open_logs(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
{
ap_open_logs(s, pconf);
}
static const char *core_method(const request_rec *r)
{ return "http"; }
static unsigned short core_port(const request_rec *r)
{ return DEFAULT_HTTP_PORT; }
static void core_insert_filter(request_rec *r)
{
int i;
core_dir_config *conf = (core_dir_config *)
ap_get_module_config(r->per_dir_config,
&core_module);
char **items = (char **)conf->output_filters->elts;
for (i = 0; i < conf->output_filters->nelts; i++) {
char *foobar = items[i];
ap_add_output_filter(foobar, NULL, r, r->connection);
}
items = (char **)conf->input_filters->elts;
for (i = 0; i < conf->input_filters->nelts; i++) {
char *foobar = items[i];
ap_add_input_filter(foobar, NULL, r, r->connection);
}
}
static void register_hooks(void)
{
ap_hook_pre_config(core_pre_config, NULL, NULL, AP_HOOK_REALLY_FIRST);
ap_hook_post_config(core_post_config,NULL,NULL,AP_HOOK_REALLY_FIRST);
ap_hook_translate_name(ap_core_translate,NULL,NULL,AP_HOOK_REALLY_LAST);
ap_hook_pre_connection(ap_pre_http_connection,NULL,NULL,
AP_HOOK_REALLY_LAST);
ap_hook_process_connection(ap_process_http_connection,NULL,NULL,
AP_HOOK_REALLY_LAST);
ap_hook_http_method(core_method,NULL,NULL,AP_HOOK_REALLY_LAST);
ap_hook_default_port(core_port,NULL,NULL,AP_HOOK_REALLY_LAST);
ap_hook_open_logs(core_open_logs,NULL,NULL,AP_HOOK_MIDDLE);
/* FIXME: I suspect we can eliminate the need for these - Ben */
ap_hook_type_checker(do_nothing,NULL,NULL,AP_HOOK_REALLY_LAST);
ap_hook_access_checker(do_nothing,NULL,NULL,AP_HOOK_REALLY_LAST);
/* register the core's insert_filter hook and register core-provided
* filters
*/
ap_hook_insert_filter(core_insert_filter, NULL, NULL, AP_HOOK_MIDDLE);
ap_register_input_filter("HTTP_IN", ap_http_filter, AP_FTYPE_CONNECTION);
ap_register_input_filter("DECHUNK", ap_dechunk_filter, AP_FTYPE_TRANSCODE);
ap_register_input_filter("CORE_IN", core_input_filter, AP_FTYPE_NETWORK);
ap_register_output_filter("HTTP_HEADER", ap_http_header_filter,
AP_FTYPE_HTTP_HEADER);
ap_register_output_filter("CONTENT_LENGTH", ap_content_length_filter,
AP_FTYPE_HTTP_HEADER);
ap_register_output_filter("BYTERANGE", ap_byterange_filter,
AP_FTYPE_HTTP_HEADER);
ap_register_output_filter("CORE", core_output_filter, AP_FTYPE_NETWORK);
ap_register_output_filter("SUBREQ_CORE", ap_sub_req_output_filter,
AP_FTYPE_CONTENT);
ap_register_output_filter("CHUNK", chunk_filter, AP_FTYPE_TRANSCODE);
ap_register_output_filter("COALESCE", coalesce_filter, AP_FTYPE_CONTENT);
}
AP_DECLARE_DATA module core_module = {
STANDARD20_MODULE_STUFF,
create_core_dir_config, /* create per-directory config structure */
merge_core_dir_configs, /* merge per-directory config structures */
create_core_server_config, /* create per-server config structure */
merge_core_server_configs, /* merge per-server config structures */
core_cmds, /* command apr_table_t */
core_handlers, /* handlers */
register_hooks /* register hooks */
};