mod_vhost_alias.c revision c5e78f582d171e8e06830ee721e94ba13005b159
1a38107941725211e7c3f051f7a8f5e12199f03acmaeder/* ====================================================================
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * The Apache Software License, Version 1.1
e9458b1a7a19a63aa4c179f9ab20f4d50681c168Jens Elkner *
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
431571057e88a650a974adec93ea4bb5173b6213Felix Gabriel Mance * reserved.
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu *
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * Redistribution and use in source and binary forms, with or without
431571057e88a650a974adec93ea4bb5173b6213Felix Gabriel Mance * modification, are permitted provided that the following conditions
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * are met:
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu *
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * 1. Redistributions of source code must retain the above copyright
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * notice, this list of conditions and the following disclaimer.
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu *
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * 2. Redistributions in binary form must reproduce the above copyright
19e01e1a7e319063434bd86c8ecbc5f241ef9993Felix Gabriel Mance * notice, this list of conditions and the following disclaimer in
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * the documentation and/or other materials provided with the
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski * distribution.
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu *
a604cbad8e2202147b5c6bb9f2e06ae61162d654Felix Gabriel Mance * 3. The end-user documentation included with the redistribution,
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * if any, must include the following acknowledgment:
be2439588008221e691321fdf4f75432cfb72878Felix Gabriel Mance * "This product includes software developed by the
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * Apache Software Foundation (http://www.apache.org/)."
fc05327b875b5723b6c17849b83477f29ec12c90Felix Gabriel Mance * Alternately, this acknowledgment may appear in the software itself,
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * if and wherever such third-party acknowledgments normally appear.
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu *
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * 4. The names "Apache" and "Apache Software Foundation" must
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * not be used to endorse or promote products derived from this
0dd6e7830de0887c9a12356447975a826b3b3db2Christian Maeder * software without prior written permission. For written
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * permission, please contact apache@apache.org.
e0f1794e365dd347e97b37d7d22b2fce27296fa1Christian Maeder *
424860079d47bf490fa98d5d7498096a0447c569mcodescu * 5. Products derived from this software may not be called "Apache",
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * nor may "Apache" appear in their name, without prior written
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * permission of the Apache Software Foundation.
1a38107941725211e7c3f051f7a8f5e12199f03acmaeder *
1a38107941725211e7c3f051f7a8f5e12199f03acmaeder * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
32bbac77828be0233953f8fe476edb0a9585408dChristian Maeder * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27fdf879983dd28e211b41f3be6c0e930b7c816bFelix Gabriel Mance * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
431571057e88a650a974adec93ea4bb5173b6213Felix Gabriel Mance * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1a38107941725211e7c3f051f7a8f5e12199f03acmaeder * SUCH DAMAGE.
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * ====================================================================
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu *
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * This software consists of voluntary contributions made by many
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * individuals on behalf of the Apache Software Foundation. For more
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * information on the Apache Software Foundation, please see
b84c87f199dc287d235d7dad6ea344f6912ef531Christian Maeder * <http://www.apache.org/>.
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu *
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * Portions of this software are based upon public domain software
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * originally written at the National Center for Supercomputing Applications,
be00381168b3f10192afabbba136fb06d3a9f358Christian Maeder * University of Illinois, Urbana-Champaign.
be00381168b3f10192afabbba136fb06d3a9f358Christian Maeder */
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu
27fdf879983dd28e211b41f3be6c0e930b7c816bFelix Gabriel Mance/*
7852de3551fc797566ee71165bafe05b6d81728cnotanartist * mod_vhost_alias.c: support for dynamically configured mass virtual hosting
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu *
27fdf879983dd28e211b41f3be6c0e930b7c816bFelix Gabriel Mance * Copyright (c) 1998-1999 Demon Internet Ltd.
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu *
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * This software was submitted by Demon Internet to the Apache Software Foundation
27fdf879983dd28e211b41f3be6c0e930b7c816bFelix Gabriel Mance * in May 1999. Future revisions and derivatives of this source code
d0f58d27c2536eba454d8f77de8617bc6a2c99cdFelix Gabriel Mance * must acknowledge Demon Internet as the original contributor of
d0f58d27c2536eba454d8f77de8617bc6a2c99cdFelix Gabriel Mance * this module. All other licensing and usage conditions are those
d0f58d27c2536eba454d8f77de8617bc6a2c99cdFelix Gabriel Mance * of the Apache Software Foundation.
d0f58d27c2536eba454d8f77de8617bc6a2c99cdFelix Gabriel Mance *
431571057e88a650a974adec93ea4bb5173b6213Felix Gabriel Mance * Originally written by Tony Finch <fanf@demon.net> <dot@dotat.at>.
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu *
27fdf879983dd28e211b41f3be6c0e930b7c816bFelix Gabriel Mance * Implementation ideas were taken from mod_alias.c. The overall
424860079d47bf490fa98d5d7498096a0447c569mcodescu * concept is derived from the OVERRIDE_DOC_ROOT/OVERRIDE_CGIDIR
60f30f0eeeacdfc1e0dfe39664373ddf5a0675adFelix Gabriel Mance * patch to Apache 1.3b3 and a similar feature in Demon's thttpd,
60f30f0eeeacdfc1e0dfe39664373ddf5a0675adFelix Gabriel Mance * both written by James Grinter <jrg@blodwen.demon.co.uk>.
0dd6e7830de0887c9a12356447975a826b3b3db2Christian Maeder */
424860079d47bf490fa98d5d7498096a0447c569mcodescu
424860079d47bf490fa98d5d7498096a0447c569mcodescu#include "apr.h"
424860079d47bf490fa98d5d7498096a0447c569mcodescu#include "apr_strings.h"
60f30f0eeeacdfc1e0dfe39664373ddf5a0675adFelix Gabriel Mance#include "apr_hooks.h"
d6d81ead61a5f9fb7d047e623f7898e730c258camcodescu#include "apr_lib.h"
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu#define APR_WANT_STRFUNC
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu#include "apr_want.h"
60f30f0eeeacdfc1e0dfe39664373ddf5a0675adFelix Gabriel Mance
7852de3551fc797566ee71165bafe05b6d81728cnotanartist#include "httpd.h"
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu#include "http_config.h"
60f30f0eeeacdfc1e0dfe39664373ddf5a0675adFelix Gabriel Mance#include "http_core.h"
9475501a6acf48434052d9e6f4a05ed6681eaaabFrancisc Nicolae Bungiu#include "http_request.h" /* for ap_hook_translate_name */
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu
7852de3551fc797566ee71165bafe05b6d81728cnotanartist
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowskimodule AP_MODULE_DECLARE_DATA vhost_alias_module;
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski
424860079d47bf490fa98d5d7498096a0447c569mcodescu
0dd6e7830de0887c9a12356447975a826b3b3db2Christian Maeder/*
0dd6e7830de0887c9a12356447975a826b3b3db2Christian Maeder * basic configuration things
424860079d47bf490fa98d5d7498096a0447c569mcodescu * we abbreviate "mod_vhost_alias" to "mva" for shorter names
0dd6e7830de0887c9a12356447975a826b3b3db2Christian Maeder */
0dd6e7830de0887c9a12356447975a826b3b3db2Christian Maeder
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiutypedef enum {
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu VHOST_ALIAS_UNSET, VHOST_ALIAS_NONE, VHOST_ALIAS_NAME, VHOST_ALIAS_IP
d0f58d27c2536eba454d8f77de8617bc6a2c99cdFelix Gabriel Mance} mva_mode_e;
60f30f0eeeacdfc1e0dfe39664373ddf5a0675adFelix Gabriel Mance
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu/*
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * Per-server module config record.
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu */
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiutypedef struct mva_sconf_t {
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu const char *doc_root;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu const char *cgi_root;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu mva_mode_e doc_root_mode;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu mva_mode_e cgi_root_mode;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu} mva_sconf_t;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroederstatic void *mva_create_server_config(apr_pool_t *p, server_rec *s)
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu{
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder mva_sconf_t *conf;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu conf = (mva_sconf_t *) apr_pcalloc(p, sizeof(mva_sconf_t));
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu conf->doc_root = NULL;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu conf->cgi_root = NULL;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu conf->doc_root_mode = VHOST_ALIAS_UNSET;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder conf->cgi_root_mode = VHOST_ALIAS_UNSET;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu return conf;
31e9d2a02e15b7dbc157e0d3fb3b84f6c8666482Christian Maeder}
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiustatic void *mva_merge_server_config(apr_pool_t *p, void *parentv, void *childv)
656f17ae9b7610ff2de1b6eedeeadea0c3bcdc8dChristian Maeder{
d3cb3401882f6956de016f8eecbec1cd3b868acbFelix Gabriel Mance mva_sconf_t *parent = (mva_sconf_t *) parentv;
d3cb3401882f6956de016f8eecbec1cd3b868acbFelix Gabriel Mance mva_sconf_t *child = (mva_sconf_t *) childv;
d3cb3401882f6956de016f8eecbec1cd3b868acbFelix Gabriel Mance mva_sconf_t *conf;
d3cb3401882f6956de016f8eecbec1cd3b868acbFelix Gabriel Mance
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu conf = (mva_sconf_t *) apr_pcalloc(p, sizeof(*conf));
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu if (child->doc_root_mode == VHOST_ALIAS_UNSET) {
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu conf->doc_root_mode = parent->doc_root_mode;
7852de3551fc797566ee71165bafe05b6d81728cnotanartist conf->doc_root = parent->doc_root;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu }
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu else {
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu conf->doc_root_mode = child->doc_root_mode;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu conf->doc_root = child->doc_root;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu }
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu if (child->cgi_root_mode == VHOST_ALIAS_UNSET) {
0dd6e7830de0887c9a12356447975a826b3b3db2Christian Maeder conf->cgi_root_mode = parent->cgi_root_mode;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu conf->cgi_root = parent->cgi_root;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu }
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu else {
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu conf->cgi_root_mode = child->cgi_root_mode;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu conf->cgi_root = child->cgi_root;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu }
06acd8a23b2f06e7b2373d53f738cf56c7f03223Francisc Nicolae Bungiu return conf;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu}
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu/*
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu * These are just here to tell us what vhost_alias_set should do.
7852de3551fc797566ee71165bafe05b6d81728cnotanartist * We don't put anything into them; we just use the cell addresses.
32bbac77828be0233953f8fe476edb0a9585408dChristian Maeder */
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowskistatic int vhost_alias_set_doc_root_ip,
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski vhost_alias_set_cgi_root_ip,
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski vhost_alias_set_doc_root_name,
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski vhost_alias_set_cgi_root_name;
32bbac77828be0233953f8fe476edb0a9585408dChristian Maeder
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowskistatic const char *vhost_alias_set(cmd_parms *cmd, void *dummy, const char *map)
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu{
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder mva_sconf_t *conf;
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder mva_mode_e mode, *pmode;
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder const char **pmap;
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder const char *p;
b84c87f199dc287d235d7dad6ea344f6912ef531Christian Maeder
7852de3551fc797566ee71165bafe05b6d81728cnotanartist conf = (mva_sconf_t *) ap_get_module_config(cmd->server->module_config,
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski &vhost_alias_module);
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder /* there ought to be a better way of doing this */
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder if (&vhost_alias_set_doc_root_ip == cmd->info) {
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder mode = VHOST_ALIAS_IP;
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder pmap = &conf->doc_root;
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder pmode = &conf->doc_root_mode;
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder }
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder else if (&vhost_alias_set_cgi_root_ip == cmd->info) {
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder mode = VHOST_ALIAS_IP;
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder pmap = &conf->cgi_root;
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder pmode = &conf->cgi_root_mode;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu }
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu else if (&vhost_alias_set_doc_root_name == cmd->info) {
7852de3551fc797566ee71165bafe05b6d81728cnotanartist mode = VHOST_ALIAS_NAME;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu pmap = &conf->doc_root;
7852de3551fc797566ee71165bafe05b6d81728cnotanartist pmode = &conf->doc_root_mode;
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski }
624f8c31bd8d6746b93f4b5966aa6fc7680fefc5Felix Gabriel Mance else if (&vhost_alias_set_cgi_root_name == cmd->info) {
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski mode = VHOST_ALIAS_NAME;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu pmap = &conf->cgi_root;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu pmode = &conf->cgi_root_mode;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu }
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu else {
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu return "INTERNAL ERROR: unknown command info";
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu }
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu
b84c87f199dc287d235d7dad6ea344f6912ef531Christian Maeder if (!ap_os_is_path_absolute(cmd->pool, map)) {
624f8c31bd8d6746b93f4b5966aa6fc7680fefc5Felix Gabriel Mance if (strcasecmp(map, "none")) {
7852de3551fc797566ee71165bafe05b6d81728cnotanartist return "format string must be an absolute path, or 'none'";
624f8c31bd8d6746b93f4b5966aa6fc7680fefc5Felix Gabriel Mance }
1a38107941725211e7c3f051f7a8f5e12199f03acmaeder *pmap = NULL;
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski *pmode = VHOST_ALIAS_NONE;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu return NULL;
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu }
d0f58d27c2536eba454d8f77de8617bc6a2c99cdFelix Gabriel Mance
431571057e88a650a974adec93ea4bb5173b6213Felix Gabriel Mance /* sanity check */
431571057e88a650a974adec93ea4bb5173b6213Felix Gabriel Mance p = map;
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu while (*p != '\0') {
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu if (*p++ != '%') {
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu continue;
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu }
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu /* we just found a '%' */
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu if (*p == 'p' || *p == '%') {
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu ++p;
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu continue;
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu }
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu /* optional dash */
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu if (*p == '-') {
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu ++p;
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu }
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu /* digit N */
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu if (apr_isdigit(*p)) {
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu ++p;
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu }
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu else {
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu return "syntax error in format string";
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu }
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu /* optional plus */
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu if (*p == '+') {
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu ++p;
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu }
/* do we end here? */
if (*p != '.') {
continue;
}
++p;
/* optional dash */
if (*p == '-') {
++p;
}
/* digit M */
if (apr_isdigit(*p)) {
++p;
}
else {
return "syntax error in format string";
}
/* optional plus */
if (*p == '+') {
++p;
}
}
*pmap = map;
*pmode = mode;
return NULL;
}
static const command_rec mva_commands[] =
{
AP_INIT_TAKE1("VirtualScriptAlias", vhost_alias_set,
&vhost_alias_set_cgi_root_name, RSRC_CONF,
"how to create a ScriptAlias based on the host"),
AP_INIT_TAKE1("VirtualDocumentRoot", vhost_alias_set,
&vhost_alias_set_doc_root_name, RSRC_CONF,
"how to create the DocumentRoot based on the host"),
AP_INIT_TAKE1("VirtualScriptAliasIP", vhost_alias_set,
&vhost_alias_set_cgi_root_ip, RSRC_CONF,
"how to create a ScriptAlias based on the host"),
AP_INIT_TAKE1("VirtualDocumentRootIP", vhost_alias_set,
&vhost_alias_set_doc_root_ip, RSRC_CONF,
"how to create the DocumentRoot based on the host"),
{ NULL }
};
/*
* This really wants to be a nested function
* but C is too feeble to support them.
*/
static APR_INLINE void vhost_alias_checkspace(request_rec *r, char *buf,
char **pdest, int size)
{
/* XXX: what if size > HUGE_STRING_LEN? */
if (*pdest + size > buf + HUGE_STRING_LEN) {
**pdest = '\0';
if (r->filename) {
r->filename = apr_pstrcat(r->pool, r->filename, buf, NULL);
}
else {
r->filename = apr_pstrdup(r->pool, buf);
}
*pdest = buf;
}
}
static void vhost_alias_interpolate(request_rec *r, const char *name,
const char *map, const char *uri)
{
/* 0..9 9..0 */
enum { MAXDOTS = 19 };
const char *dots[MAXDOTS+1];
int ndots;
char buf[HUGE_STRING_LEN];
char *dest, last;
int N, M, Np, Mp, Nd, Md;
const char *start, *end;
const char *p;
ndots = 0;
dots[ndots++] = name-1; /* slightly naughty */
for (p = name; *p; ++p){
if (*p == '.' && ndots < MAXDOTS) {
dots[ndots++] = p;
}
}
dots[ndots] = p;
r->filename = NULL;
dest = buf;
last = '\0';
while (*map) {
if (*map != '%') {
/* normal characters */
vhost_alias_checkspace(r, buf, &dest, 1);
last = *dest++ = *map++;
continue;
}
/* we are in a format specifier */
++map;
/* can't be a slash */
last = '\0';
/* %% -> % */
if (*map == '%') {
++map;
vhost_alias_checkspace(r, buf, &dest, 1);
*dest++ = '%';
continue;
}
/* port number */
if (*map == 'p') {
++map;
/* no. of decimal digits in a short plus one */
vhost_alias_checkspace(r, buf, &dest, 7);
dest += apr_snprintf(dest, 7, "%d", ap_get_server_port(r));
continue;
}
/* deal with %-N+.-M+ -- syntax is already checked */
N = M = 0; /* value */
Np = Mp = 0; /* is there a plus? */
Nd = Md = 0; /* is there a dash? */
if (*map == '-') ++map, Nd = 1;
N = *map++ - '0';
if (*map == '+') ++map, Np = 1;
if (*map == '.') {
++map;
if (*map == '-') {
++map, Md = 1;
}
M = *map++ - '0';
if (*map == '+') {
++map, Mp = 1;
}
}
/* note that N and M are one-based indices, not zero-based */
start = dots[0]+1; /* ptr to the first character */
end = dots[ndots]; /* ptr to the character after the last one */
if (N != 0) {
if (N > ndots) {
start = "_";
end = start+1;
}
else if (!Nd) {
start = dots[N-1]+1;
if (!Np) {
end = dots[N];
}
}
else {
if (!Np) {
start = dots[ndots-N]+1;
}
end = dots[ndots-N+1];
}
}
if (M != 0) {
if (M > end - start) {
start = "_";
end = start+1;
}
else if (!Md) {
start = start+M-1;
if (!Mp) {
end = start+1;
}
}
else {
if (!Mp) {
start = end-M;
}
end = end-M+1;
}
}
vhost_alias_checkspace(r, buf, &dest, end - start);
for (p = start; p < end; ++p) {
*dest++ = apr_tolower(*p);
}
}
*dest = '\0';
/* no double slashes */
if (last == '/') {
++uri;
}
if (r->filename) {
r->filename = apr_pstrcat(r->pool, r->filename, buf, uri, NULL);
}
else {
r->filename = apr_pstrcat(r->pool, buf, uri, NULL);
}
}
static int mva_translate(request_rec *r)
{
mva_sconf_t *conf;
const char *name, *map, *uri;
mva_mode_e mode;
const char *cgi;
conf = (mva_sconf_t *) ap_get_module_config(r->server->module_config,
&vhost_alias_module);
cgi = NULL;
if (conf->cgi_root) {
cgi = strstr(r->uri, "cgi-bin/");
if (cgi && (cgi != r->uri + strspn(r->uri, "/"))) {
cgi = NULL;
}
}
if (cgi) {
mode = conf->cgi_root_mode;
map = conf->cgi_root;
uri = cgi + strlen("cgi-bin");
}
else if (r->uri[0] == '/') {
mode = conf->doc_root_mode;
map = conf->doc_root;
uri = r->uri;
}
else {
return DECLINED;
}
if (mode == VHOST_ALIAS_NAME) {
name = ap_get_server_name(r);
}
else if (mode == VHOST_ALIAS_IP) {
name = r->connection->local_ip;
}
else {
return DECLINED;
}
/* ### There is an optimization available here to determine the
* absolute portion of the path from the server config phase,
* through the first % segment, and note that portion of the path
* canonical_path buffer.
*/
r->canonical_filename = "";
vhost_alias_interpolate(r, name, map, uri);
if (cgi) {
/* see is_scriptaliased() in mod_cgi */
r->handler = "cgi-script";
apr_table_setn(r->notes, "alias-forced-type", r->handler);
}
return OK;
}
static void register_hooks(apr_pool_t *p)
{
ap_hook_translate_name(mva_translate, NULL, NULL, APR_HOOK_MIDDLE);
}
module AP_MODULE_DECLARE_DATA vhost_alias_module =
{
STANDARD20_MODULE_STUFF,
NULL, /* dir config creater */
NULL, /* dir merger --- default is to override */
mva_create_server_config, /* server config */
mva_merge_server_config, /* merge server configs */
mva_commands, /* command apr_table_t */
register_hooks /* register hooks */
};