mod_alias.c revision 4d7e28c869788fb00bffda29a67f1b10e19f159d
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* ====================================================================
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * The Apache Software License, Version 1.1
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding *
bc8fd1b0b1afdf89b8d28eefa8cd74e26ba97986fielding * Copyright (c) 2000-2003 The Apache Software Foundation. All rights
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * reserved.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Redistribution and use in source and binary forms, with or without
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * modification, are permitted provided that the following conditions
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * are met:
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * 1. Redistributions of source code must retain the above copyright
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * notice, this list of conditions and the following disclaimer.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * 2. Redistributions in binary form must reproduce the above copyright
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * notice, this list of conditions and the following disclaimer in
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * the documentation and/or other materials provided with the
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * distribution.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * 3. The end-user documentation included with the redistribution,
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * if any, must include the following acknowledgment:
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * "This product includes software developed by the
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Apache Software Foundation (http://www.apache.org/)."
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Alternately, this acknowledgment may appear in the software itself,
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * if and wherever such third-party acknowledgments normally appear.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * 4. The names "Apache" and "Apache Software Foundation" must
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * not be used to endorse or promote products derived from this
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * software without prior written permission. For written
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * permission, please contact apache@apache.org.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * 5. Products derived from this software may not be called "Apache",
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * nor may "Apache" appear in their name, without prior written
64185f9824e42f21ca7b9ae6c004484215c031a7rbb * permission of the Apache Software Foundation.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * SUCH DAMAGE.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * ====================================================================
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * This software consists of voluntary contributions made by many
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * individuals on behalf of the Apache Software Foundation. For more
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * information on the Apache Software Foundation, please see
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * <http://www.apache.org/>.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Portions of this software are based upon public domain software
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * originally written at the National Center for Supercomputing Applications,
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * University of Illinois, Urbana-Champaign.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
7708bd70088b64148d7d78fd84ede43ced63c713minfrin/*
7708bd70088b64148d7d78fd84ede43ced63c713minfrin * http_alias.c: Stuff for dealing with directory aliases
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
36a72c96fc2dda27eadbae8a108fa428cc1419c1wrowe * Original by Rob McCool, rewritten in succession by David Robinson
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * and rst.
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm *
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm */
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin
6335eb31f0f0ed54628a04ed32946360b8b77684minfrin#include "apr_strings.h"
e9501b71b8a1e76384cb010b1e41e76a1e47aacctrawick#include "apr_lib.h"
e9501b71b8a1e76384cb010b1e41e76a1e47aacctrawick
e9501b71b8a1e76384cb010b1e41e76a1e47aacctrawick#define APR_WANT_STRFUNC
6335eb31f0f0ed54628a04ed32946360b8b77684minfrin#include "apr_want.h"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#include "ap_config.h"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#include "httpd.h"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#include "http_core.h"
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe#include "http_config.h"
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe#include "http_request.h"
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe#include "http_log.h"
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingtypedef struct {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *real;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *fake;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding char *handler;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding regex_t *regexp;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int redir_status; /* 301, 302, 303, 410, etc */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding} alias_entry;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingtypedef struct {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_array_header_t *aliases;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_array_header_t *redirects;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding} alias_server_conf;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingtypedef struct {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard apr_array_header_t *redirects;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard} alias_dir_conf;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddardmodule AP_MODULE_DECLARE_DATA alias_module;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddardstatic void *create_alias_config(apr_pool_t *p, server_rec *s)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard{
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard alias_server_conf *a =
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard (alias_server_conf *) apr_pcalloc(p, sizeof(alias_server_conf));
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard a->aliases = apr_array_make(p, 20, sizeof(alias_entry));
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard a->redirects = apr_array_make(p, 20, sizeof(alias_entry));
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return a;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard}
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddardstatic void *create_alias_dir_config(apr_pool_t *p, char *d)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding alias_dir_conf *a =
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding (alias_dir_conf *) apr_pcalloc(p, sizeof(alias_dir_conf));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding a->redirects = apr_array_make(p, 2, sizeof(alias_entry));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return a;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic void *merge_alias_config(apr_pool_t *p, void *basev, void *overridesv)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding alias_server_conf *a =
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding (alias_server_conf *) apr_pcalloc(p, sizeof(alias_server_conf));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding alias_server_conf *base = (alias_server_conf *) basev;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding alias_server_conf *overrides = (alias_server_conf *) overridesv;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding a->aliases = apr_array_append(p, overrides->aliases, base->aliases);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding a->redirects = apr_array_append(p, overrides->redirects, base->redirects);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return a;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic void *merge_alias_dir_config(apr_pool_t *p, void *basev, void *overridesv)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding alias_dir_conf *a =
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding (alias_dir_conf *) apr_pcalloc(p, sizeof(alias_dir_conf));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding alias_dir_conf *base = (alias_dir_conf *) basev;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding alias_dir_conf *overrides = (alias_dir_conf *) overridesv;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding a->redirects = apr_array_append(p, overrides->redirects, base->redirects);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return a;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* need prototype for overlap check */
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic int alias_matches(const char *uri, const char *alias_fakename);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *add_alias_internal(cmd_parms *cmd, void *dummy,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *f, const char *r,
16d38ac65d7e54cd44eeda7b23f84ee68b35094ewrowe int use_regex)
16d38ac65d7e54cd44eeda7b23f84ee68b35094ewrowe{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding server_rec *s = cmd->server;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard alias_server_conf *conf = ap_get_module_config(s->module_config,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard &alias_module);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard alias_entry *new = apr_array_push(conf->aliases);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard alias_entry *entries = (alias_entry *)conf->aliases->elts;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard int i;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* XX r can NOT be relative to DocumentRoot here... compat bug. */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (use_regex) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard new->regexp = ap_pregcomp(cmd->pool, f, REG_EXTENDED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (new->regexp == NULL)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return "Regular expression could not be compiled.";
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding new->real = r;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard else {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* XXX This may be optimized, but we must know that new->real
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard * exists. If so, we can dir merge later, trusing new->real
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard * and just canonicalizing the remainder. Not till I finish
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard * cleaning out the old ap_canonical stuff first.
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding new->real = r;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding new->fake = f;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding new->handler = cmd->info;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* check for overlapping (Script)Alias directives
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * and throw a warning if found one
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (!use_regex) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (i = 0; i < conf->aliases->nelts - 1; ++i) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding alias_entry *p = &entries[i];
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (!p->regexp && alias_matches(f, p->fake) > 0) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard "The %s command in line %d will probably never "
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard "match. Check previous %sAlias commands for "
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard "overlappings.", cmd->cmd->name,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding cmd->directive->line_num,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding p->handler ? "Script" : "");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break; /* one warning per alias should be sufficient */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return NULL;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard}
11c3b5180e1de6776035320b012a28bb146e7b46chuck
9e2bc52b9409a8d92ce1acd4f6127159a16cbff2ianhstatic const char *add_alias(cmd_parms *cmd, void *dummy, const char *f,
22d348febc3c258df246ac93e37945398dbf0348ianh const char *r)
22d348febc3c258df246ac93e37945398dbf0348ianh{
22d348febc3c258df246ac93e37945398dbf0348ianh return add_alias_internal(cmd, dummy, f, r, 0);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm}
759554f16128a82e3781510c480784b227843b46ianh
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *add_alias_regex(cmd_parms *cmd, void *dummy, const char *f,
1d7f1b96b49dafbd6cb414fb709cb85de2686a72chuck const char *r)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return add_alias_internal(cmd, dummy, f, r, 1);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *add_redirect_internal(cmd_parms *cmd,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding alias_dir_conf *dirconf,
9b3001f2097437c3c605d29e353fda5131b9952bminfrin const char *arg1, const char *arg2,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe const char *arg3, int use_regex)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe{
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe alias_entry *new;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe server_rec *s = cmd->server;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe alias_server_conf *serverconf = ap_get_module_config(s->module_config,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe &alias_module);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe int status = (int) (long) cmd->info;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe regex_t *r = NULL;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard const char *f = arg2;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard const char *url = arg3;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (!strcasecmp(arg1, "gone"))
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe status = HTTP_GONE;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe else if (!strcasecmp(arg1, "permanent"))
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe status = HTTP_MOVED_PERMANENTLY;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe else if (!strcasecmp(arg1, "temp"))
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe status = HTTP_MOVED_TEMPORARILY;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe else if (!strcasecmp(arg1, "seeother"))
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe status = HTTP_SEE_OTHER;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe else if (apr_isdigit(*arg1))
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe status = atoi(arg1);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe else {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe f = arg1;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe url = arg2;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (use_regex) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe r = ap_pregcomp(cmd->pool, f, REG_EXTENDED);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (r == NULL)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return "Regular expression could not be compiled.";
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (ap_is_HTTP_REDIRECT(status)) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (!url)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return "URL to redirect to is missing";
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (!use_regex && !ap_is_url(url))
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return "Redirect to non-URL";
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe else {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (url)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return "Redirect URL not valid for this status";
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (cmd->path)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe new = apr_array_push(dirconf->redirects);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe else
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe new = apr_array_push(serverconf->redirects);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe new->fake = f;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe new->real = url;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe new->regexp = r;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe new->redir_status = status;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return NULL;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe}
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic const char *add_redirect(cmd_parms *cmd, void *dirconf,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe const char *arg1, const char *arg2,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe const char *arg3)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 0);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *add_redirect2(cmd_parms *cmd, void *dirconf,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *arg1, const char *arg2)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return add_redirect_internal(cmd, dirconf, arg1, arg2, NULL, 0);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
68ce856106f153813339db8670f6cd0ab8dea484minfrin
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *add_redirect_regex(cmd_parms *cmd, void *dirconf,
d7387fcd4969206172e3a2a8bbcd25a3d7011ac5rbb const char *arg1, const char *arg2,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard const char *arg3)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 1);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
68ce856106f153813339db8670f6cd0ab8dea484minfrinstatic const command_rec alias_cmds[] =
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin{
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard AP_INIT_TAKE2("Alias", add_alias, NULL, RSRC_CONF,
68ce856106f153813339db8670f6cd0ab8dea484minfrin "a fakename and a realname"),
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding AP_INIT_TAKE2("ScriptAlias", add_alias, "cgi-script", RSRC_CONF,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "a fakename and a realname"),
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding AP_INIT_TAKE23("Redirect", add_redirect, (void *) HTTP_MOVED_TEMPORARILY,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard OR_FILEINFO,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "an optional status, then document to be redirected and "
11c3b5180e1de6776035320b012a28bb146e7b46chuck "destination URL"),
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding AP_INIT_TAKE2("AliasMatch", add_alias_regex, NULL, RSRC_CONF,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "a regular expression and a filename"),
11c3b5180e1de6776035320b012a28bb146e7b46chuck AP_INIT_TAKE2("ScriptAliasMatch", add_alias_regex, "cgi-script", RSRC_CONF,
11c3b5180e1de6776035320b012a28bb146e7b46chuck "a regular expression and a filename"),
11c3b5180e1de6776035320b012a28bb146e7b46chuck AP_INIT_TAKE23("RedirectMatch", add_redirect_regex,
11c3b5180e1de6776035320b012a28bb146e7b46chuck (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO,
11c3b5180e1de6776035320b012a28bb146e7b46chuck "an optional status, then a regular expression and "
11c3b5180e1de6776035320b012a28bb146e7b46chuck "destination URL"),
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding AP_INIT_TAKE2("RedirectTemp", add_redirect2,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "a document to be redirected, then the destination URL"),
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding AP_INIT_TAKE2("RedirectPermanent", add_redirect2,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding (void *) HTTP_MOVED_PERMANENTLY, OR_FILEINFO,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "a document to be redirected, then the destination URL"),
d7387fcd4969206172e3a2a8bbcd25a3d7011ac5rbb {NULL}
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard};
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic int alias_matches(const char *uri, const char *alias_fakename)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *aliasp = alias_fakename, *urip = uri;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding while (*aliasp) {
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm if (*aliasp == '/') {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* any number of '/' in the alias matches any number in
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * the supplied URI, but there must be at least one...
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm if (*urip != '/')
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return 0;
b999f6ba2a266bf9a92687f31bb7e76021ac5891ianh
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard do {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard ++aliasp;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding } while (*aliasp == '/');
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm do {
1cde33c7e2019830f8fb3224e01649305583916etrawick ++urip;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard } while (*urip == '/');
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard else {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* Other characters are compared literally */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (*urip++ != *aliasp++)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return 0;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* Check last alias path component matched all the way */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (aliasp[-1] != '/' && *urip != '\0' && *urip != '/')
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return 0;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb /* Return number of characters from URI which matched (may be
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * greater than length of alias, since we may have matched
5babe00918c88eda487771fa6d6d4a1a19c0ced0chuck * doubled slashes)
5babe00918c88eda487771fa6d6d4a1a19c0ced0chuck */
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return urip - uri;
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
35c9e4d2c0a6465746a98958ef756114834461e6minfrinstatic char *try_alias_list(request_rec *r, apr_array_header_t *aliases,
35c9e4d2c0a6465746a98958ef756114834461e6minfrin int doesc, int *status)
11c3b5180e1de6776035320b012a28bb146e7b46chuck{
35c9e4d2c0a6465746a98958ef756114834461e6minfrin alias_entry *entries = (alias_entry *) aliases->elts;
8a1e3e302a46f468054887a62abdbd9c98f3daa5rbb regmatch_t regm[10];
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard char *found = NULL;
11c3b5180e1de6776035320b012a28bb146e7b46chuck int i;
35c9e4d2c0a6465746a98958ef756114834461e6minfrin
35c9e4d2c0a6465746a98958ef756114834461e6minfrin for (i = 0; i < aliases->nelts; ++i) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard alias_entry *p = &entries[i];
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard int l;
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin if (p->regexp) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (!ap_regexec(p->regexp, r->uri, p->regexp->re_nsub + 1, regm,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard 0)) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (p->real) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard found = ap_pregsub(r->pool, p->real, r->uri,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard p->regexp->re_nsub + 1, regm);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (found && doesc) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard apr_uri_t uri;
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin apr_uri_parse(r->pool, found, &uri);
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin /* Do not escape the query string or fragment. */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard found = apr_uri_unparse(r->pool, &uri,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard APR_URI_UNP_OMITQUERY);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard found = ap_escape_uri(r->pool, found);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (uri.query) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard found = apr_pstrcat(r->pool, found, "?",
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard uri.query, NULL);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin if (uri.fragment) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard found = apr_pstrcat(r->pool, found, "#",
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard uri.fragment, NULL);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard else {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* need something non-null */
35c9e4d2c0a6465746a98958ef756114834461e6minfrin found = apr_pstrdup(r->pool, "");
35c9e4d2c0a6465746a98958ef756114834461e6minfrin }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else {
3d350b6e1cb11fa790a6adb428856b5dd9857fecianh l = alias_matches(r->uri, p->fake);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (l > 0) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (doesc) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding char *escurl;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding escurl = ap_os_escape_path(r->pool, r->uri + l, 1);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
5babe00918c88eda487771fa6d6d4a1a19c0ced0chuck found = apr_pstrcat(r->pool, p->real, escurl, NULL);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard found = apr_pstrcat(r->pool, p->real, r->uri + l, NULL);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (found) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (p->handler) { /* Set handler, and leave a note for mod_cgi */
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm r->handler = p->handler;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_table_setn(r->notes, "alias-forced-type", r->handler);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* XXX This is as SLOW as can be, next step, we optimize
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * and merge to whatever part of the found path was already
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * canonicalized. After I finish eliminating os canonical.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Better fail test for ap_server_root_relative needed here.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (!doesc) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard found = ap_server_root_relative(r->pool, found);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (found) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard *status = p->redir_status;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return found;
1cde33c7e2019830f8fb3224e01649305583916etrawick }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin
2e41eca72bcc4167d1871b0941ee79845540d58eminfrinstatic int translate_alias_redir(request_rec *r)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard{
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb ap_conf_vector_t *sconf = r->server->module_config;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard alias_server_conf *serverconf = ap_get_module_config(sconf, &alias_module);
9379749d811388a7d0e3410940ddd6743a33d330jim char *ret;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard int status;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (r->uri[0] != '/' && r->uri[0] != '\0') {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return DECLINED;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
1cde33c7e2019830f8fb3224e01649305583916etrawick
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if ((ret = try_alias_list(r, serverconf->redirects, 1, &status)) != NULL) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (ap_is_HTTP_REDIRECT(status)) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* include QUERY_STRING if any */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (r->args) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard apr_table_setn(r->headers_out, "Location", ret);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return status;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin if ((ret = try_alias_list(r, serverconf->aliases, 0, &status)) != NULL) {
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin r->filename = ret;
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin return OK;
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin }
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return DECLINED;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
1cde33c7e2019830f8fb3224e01649305583916etrawick
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddardstatic int fixup_redir(request_rec *r)
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin{
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin void *dconf = r->per_dir_config;
1cde33c7e2019830f8fb3224e01649305583916etrawick alias_dir_conf *dirconf =
6bdb2c094666367615890147775bb18761216c8dminfrin (alias_dir_conf *) ap_get_module_config(dconf, &alias_module);
6bdb2c094666367615890147775bb18761216c8dminfrin char *ret;
6bdb2c094666367615890147775bb18761216c8dminfrin int status;
6bdb2c094666367615890147775bb18761216c8dminfrin
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* It may have changed since last time, so try again */
9865751743e928ea0a9ad83faa04a738001932deminfrin
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin if ((ret = try_alias_list(r, dirconf->redirects, 1, &status)) != NULL) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (ap_is_HTTP_REDIRECT(status)) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (ret[0] == '/') {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding char *orig_target = ret;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ret = ap_construct_url(r->pool, ret, r);
11c3b5180e1de6776035320b012a28bb146e7b46chuck ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "incomplete redirection target of '%s' for "
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe "URI '%s' modified to '%s'",
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe orig_target, r->uri, ret);
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe }
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe if (!ap_is_url(ret)) {
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe status = HTTP_INTERNAL_SERVER_ERROR;
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe "cannot redirect '%s' to '%s'; "
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe "target is not a valid absoluteURI or abs_path",
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe r->uri, ret);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else {
af952917c05e56874069e1e5f64e6473bb478b68minfrin apr_table_setn(r->headers_out, "Location", ret);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
af952917c05e56874069e1e5f64e6473bb478b68minfrin }
af952917c05e56874069e1e5f64e6473bb478b68minfrin return status;
af952917c05e56874069e1e5f64e6473bb478b68minfrin }
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin return DECLINED;
35c9e4d2c0a6465746a98958ef756114834461e6minfrin}
35c9e4d2c0a6465746a98958ef756114834461e6minfrin
4a7df15077ff65dbf3b2cf68fa3063273ac0a547minfrinstatic void register_hooks(apr_pool_t *p)
dcc56911d2b95e73554ff8ced9f72fd456d73881minfrin{
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh static const char * const aszSucc[]={ "mod_userdir.c",
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh "mod_vhost_alias.c",NULL };
4224d5789080ea5586d49420da1e1996f5653bb5ianh
4224d5789080ea5586d49420da1e1996f5653bb5ianh ap_hook_translate_name(translate_alias_redir,NULL,aszSucc,APR_HOOK_MIDDLE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_hook_fixups(fixup_redir,NULL,NULL,APR_HOOK_MIDDLE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
af952917c05e56874069e1e5f64e6473bb478b68minfrinmodule AP_MODULE_DECLARE_DATA alias_module =
af952917c05e56874069e1e5f64e6473bb478b68minfrin{
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe STANDARD20_MODULE_STUFF,
af952917c05e56874069e1e5f64e6473bb478b68minfrin create_alias_dir_config, /* dir config creater */
af952917c05e56874069e1e5f64e6473bb478b68minfrin merge_alias_dir_config, /* dir merger --- default is to override */
af952917c05e56874069e1e5f64e6473bb478b68minfrin create_alias_config, /* server config */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe merge_alias_config, /* merge server configs */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe alias_cmds, /* command apr_table_t */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe register_hooks /* register hooks */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe};
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe