mod_alias.c revision bbe046d7cbb950ab3e372e4119ae001a5fe52ed4
842ae4bd224140319ae7feec1872b93dfd491143fielding/* ====================================================================
842ae4bd224140319ae7feec1872b93dfd491143fielding * The Apache Software License, Version 1.1
842ae4bd224140319ae7feec1872b93dfd491143fielding *
842ae4bd224140319ae7feec1872b93dfd491143fielding * Copyright (c) 2000-2003 The Apache Software Foundation. All rights
842ae4bd224140319ae7feec1872b93dfd491143fielding * reserved.
842ae4bd224140319ae7feec1872b93dfd491143fielding *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Redistribution and use in source and binary forms, with or without
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * modification, are permitted provided that the following conditions
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * 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
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * notice, this list of conditions and the following disclaimer in
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * the documentation and/or other materials provided with the
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh * distribution.
e8f95a682820a599fe41b22977010636be5c2717jim *
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh * 3. The end-user documentation included with the redistribution,
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh * if any, must include the following acknowledgment:
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * "This product includes software developed by the
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Apache Software Foundation (http://www.apache.org/)."
1b21d7b3d97def358b2e923655edeb16613a1c31gstein * Alternately, this acknowledgment may appear in the software itself,
1b21d7b3d97def358b2e923655edeb16613a1c31gstein * if and wherever such third-party acknowledgments normally appear.
1b21d7b3d97def358b2e923655edeb16613a1c31gstein *
1b21d7b3d97def358b2e923655edeb16613a1c31gstein * 4. The names "Apache" and "Apache Software Foundation" must
1b21d7b3d97def358b2e923655edeb16613a1c31gstein * not be used to endorse or promote products derived from this
1b21d7b3d97def358b2e923655edeb16613a1c31gstein * software without prior written permission. For written
1b21d7b3d97def358b2e923655edeb16613a1c31gstein * permission, please contact apache@apache.org.
2d71630471d1c23f0137309e3c3957c633ecbfd6rbb *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * 5. Products derived from this software may not be called "Apache",
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * nor may "Apache" appear in their name, without prior written
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * permission of the Apache Software Foundation.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
51af95bb51b5084e883bad250b2afa2838e9ceebfielding * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
d4f1d9c1ff112a8ab9bee31f196973761329b236rbb * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7fae9cc4639013f3c04c085547256c68814aee8ftrawick * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
7fae9cc4639013f3c04c085547256c68814aee8ftrawick * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
7fae9cc4639013f3c04c085547256c68814aee8ftrawick * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
7fae9cc4639013f3c04c085547256c68814aee8ftrawick * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
7184de27ec1d62a83c41cdeac0953ca9fd661e8csf * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
7184de27ec1d62a83c41cdeac0953ca9fd661e8csf * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
7184de27ec1d62a83c41cdeac0953ca9fd661e8csf * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
36ef8f77bffe75d1aa327882be1b5bdbe2ff567asf * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * SUCH DAMAGE.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * ====================================================================
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * This software consists of voluntary contributions made by many
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * individuals on behalf of the Apache Software Foundation. For more
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * information on the Apache Software Foundation, please see
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * <http://www.apache.org/>.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Portions of this software are based upon public domain software
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * originally written at the National Center for Supercomputing Applications,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * University of Illinois, Urbana-Champaign.
785be1b6298010956622771c870ab3cd8ca57a2faaron */
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron/*
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * http_alias.c: Stuff for dealing with directory aliases
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Original by Rob McCool, rewritten in succession by David Robinson
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * and rst.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "apr_strings.h"
785be1b6298010956622771c870ab3cd8ca57a2faaron#include "apr_lib.h"
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron#define APR_WANT_STRFUNC
785be1b6298010956622771c870ab3cd8ca57a2faaron#include "apr_want.h"
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron#include "ap_config.h"
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim#include "httpd.h"
7697b1b7376a532163c621e050b70c90dcb15d66covener#include "http_core.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "http_config.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "http_request.h"
f4b96a996afbc46872f57ad1450e6ee1c8f13707jorton#include "http_log.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingtypedef struct {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const char *real;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const char *fake;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding char *handler;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding regex_t *regexp;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding int redir_status; /* 301, 302, 303, 410, etc */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding} alias_entry;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingtypedef struct {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding apr_array_header_t *aliases;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding apr_array_header_t *redirects;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding} alias_server_conf;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingtypedef struct {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding apr_array_header_t *redirects;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding} alias_dir_conf;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingmodule AP_MODULE_DECLARE_DATA alias_module;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
e08076ca56e6cb68b30846b9e9339061058aae6dpoirierstatic void *create_alias_config(apr_pool_t *p, server_rec *s)
e08076ca56e6cb68b30846b9e9339061058aae6dpoirier{
e08076ca56e6cb68b30846b9e9339061058aae6dpoirier alias_server_conf *a =
e08076ca56e6cb68b30846b9e9339061058aae6dpoirier (alias_server_conf *) apr_pcalloc(p, sizeof(alias_server_conf));
e08076ca56e6cb68b30846b9e9339061058aae6dpoirier
e08076ca56e6cb68b30846b9e9339061058aae6dpoirier a->aliases = apr_array_make(p, 20, sizeof(alias_entry));
e08076ca56e6cb68b30846b9e9339061058aae6dpoirier a->redirects = apr_array_make(p, 20, sizeof(alias_entry));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return a;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic void *create_alias_dir_config(apr_pool_t *p, char *d)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding alias_dir_conf *a =
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding (alias_dir_conf *) apr_pcalloc(p, sizeof(alias_dir_conf));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding a->redirects = apr_array_make(p, 2, sizeof(alias_entry));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return a;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic void *merge_alias_config(apr_pool_t *p, void *basev, void *overridesv)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding alias_server_conf *a =
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding (alias_server_conf *) apr_pcalloc(p, sizeof(alias_server_conf));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding alias_server_conf *base = (alias_server_conf *) basev;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding alias_server_conf *overrides = (alias_server_conf *) overridesv;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding a->aliases = apr_array_append(p, overrides->aliases, base->aliases);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding a->redirects = apr_array_append(p, overrides->redirects, base->redirects);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return a;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic void *merge_alias_dir_config(apr_pool_t *p, void *basev, void *overridesv)
45acd673a68181802b112e97e84fa3813ddd3ec1stoddard{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding alias_dir_conf *a =
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding (alias_dir_conf *) apr_pcalloc(p, sizeof(alias_dir_conf));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding alias_dir_conf *base = (alias_dir_conf *) basev;
e08076ca56e6cb68b30846b9e9339061058aae6dpoirier alias_dir_conf *overrides = (alias_dir_conf *) overridesv;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding a->redirects = apr_array_append(p, overrides->redirects, base->redirects);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return a;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* need prototype for overlap check */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic int alias_matches(const char *uri, const char *alias_fakename);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic const char *add_alias_internal(cmd_parms *cmd, void *dummy,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const char *f, const char *r,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding int use_regex)
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm{
e8f95a682820a599fe41b22977010636be5c2717jim server_rec *s = cmd->server;
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick alias_server_conf *conf = ap_get_module_config(s->module_config,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding &alias_module);
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick alias_entry *new = apr_array_push(conf->aliases);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding alias_entry *entries = (alias_entry *)conf->aliases->elts;
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick int i;
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick
58fd79b56eb624bf011772994e9761d3c2e228c1orlikowski /* XX r can NOT be relative to DocumentRoot here... compat bug. */
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick if (use_regex) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding new->regexp = ap_pregcomp(cmd->pool, f, REG_EXTENDED);
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick if (new->regexp == NULL)
785be1b6298010956622771c870ab3cd8ca57a2faaron return "Regular expression could not be compiled.";
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding new->real = r;
3c290fd0361d6d9d84d97725eaf299456bddd6cfsf }
3c290fd0361d6d9d84d97725eaf299456bddd6cfsf else {
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick /* XXX This may be optimized, but we must know that new->real
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames * exists. If so, we can dir merge later, trusing new->real
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames * and just canonicalizing the remainder. Not till I finish
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames * cleaning out the old ap_canonical stuff first.
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames */
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames new->real = r;
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames }
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames new->fake = f;
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames new->handler = cmd->info;
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick /* check for overlapping (Script)Alias directives
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick * and throw a warning if found one
560f6ac786d611b858b2bad932713d9e971f0716trawick */
560f6ac786d611b858b2bad932713d9e971f0716trawick if (!use_regex) {
560f6ac786d611b858b2bad932713d9e971f0716trawick for (i = 0; i < conf->aliases->nelts - 1; ++i) {
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick alias_entry *p = &entries[i];
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick if ( (!p->regexp && alias_matches(f, p->fake) > 0)
7bf77d70b6830636bc36e6b76a228c301be23ff7brianp || (p->regexp && !ap_regexec(p->regexp, f, 0, NULL, 0))) {
7bf77d70b6830636bc36e6b76a228c301be23ff7brianp ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server,
7bf77d70b6830636bc36e6b76a228c301be23ff7brianp "The %s directive at line %d will probably never "
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick "match because it overlaps an earlier %sAlias%s.",
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick cmd->cmd->name, cmd->directive->line_num,
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick p->handler ? "Script" : "",
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick p->regexp ? "Match" : "");
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding break; /* one warning per alias should be sufficient */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
7697b1b7376a532163c621e050b70c90dcb15d66covener }
7c6f514f2ef9b98f58b8f8a5f534eb78a75f29f2jorton }
de00ec7378227d05be63ecd2053ebbb01b940023jorton
7c6f514f2ef9b98f58b8f8a5f534eb78a75f29f2jorton return NULL;
de00ec7378227d05be63ecd2053ebbb01b940023jorton}
de00ec7378227d05be63ecd2053ebbb01b940023jorton
785be1b6298010956622771c870ab3cd8ca57a2faaronstatic const char *add_alias(cmd_parms *cmd, void *dummy, const char *f,
785be1b6298010956622771c870ab3cd8ca57a2faaron const char *r)
066877f1a045103acfdd376d48cdd473c33f409bdougm{
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick return add_alias_internal(cmd, dummy, f, r, 0);
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick}
f3aa436e29aa30e29695a18b7f469dd66b39b7e4jorton
74b39333600dee3260355ad3a06e36ef6c61c8f1dreidstatic const char *add_alias_regex(cmd_parms *cmd, void *dummy, const char *f,
74b39333600dee3260355ad3a06e36ef6c61c8f1dreid const char *r)
74b39333600dee3260355ad3a06e36ef6c61c8f1dreid{
74b39333600dee3260355ad3a06e36ef6c61c8f1dreid return add_alias_internal(cmd, dummy, f, r, 1);
97c78987224dcd037076d393aad1867c26b2c8cftrawick}
97c78987224dcd037076d393aad1867c26b2c8cftrawick
97c78987224dcd037076d393aad1867c26b2c8cftrawickstatic const char *add_redirect_internal(cmd_parms *cmd,
97c78987224dcd037076d393aad1867c26b2c8cftrawick alias_dir_conf *dirconf,
97c78987224dcd037076d393aad1867c26b2c8cftrawick const char *arg1, const char *arg2,
97c78987224dcd037076d393aad1867c26b2c8cftrawick const char *arg3, int use_regex)
97c78987224dcd037076d393aad1867c26b2c8cftrawick{
97c78987224dcd037076d393aad1867c26b2c8cftrawick alias_entry *new;
97c78987224dcd037076d393aad1867c26b2c8cftrawick server_rec *s = cmd->server;
97c78987224dcd037076d393aad1867c26b2c8cftrawick alias_server_conf *serverconf = ap_get_module_config(s->module_config,
97c78987224dcd037076d393aad1867c26b2c8cftrawick &alias_module);
97c78987224dcd037076d393aad1867c26b2c8cftrawick int status = (int) (long) cmd->info;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding regex_t *r = NULL;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const char *f = arg2;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const char *url = arg3;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!strcasecmp(arg1, "gone"))
785be1b6298010956622771c870ab3cd8ca57a2faaron status = HTTP_GONE;
785be1b6298010956622771c870ab3cd8ca57a2faaron else if (!strcasecmp(arg1, "permanent"))
785be1b6298010956622771c870ab3cd8ca57a2faaron status = HTTP_MOVED_PERMANENTLY;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding else if (!strcasecmp(arg1, "temp"))
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding status = HTTP_MOVED_TEMPORARILY;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding else if (!strcasecmp(arg1, "seeother"))
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding status = HTTP_SEE_OTHER;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding else if (apr_isdigit(*arg1))
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding status = atoi(arg1);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding else {
785be1b6298010956622771c870ab3cd8ca57a2faaron f = arg1;
785be1b6298010956622771c870ab3cd8ca57a2faaron url = arg2;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron if (use_regex) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding r = ap_pregcomp(cmd->pool, f, REG_EXTENDED);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (r == NULL)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return "Regular expression could not be compiled.";
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron if (ap_is_HTTP_REDIRECT(status)) {
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!url)
785be1b6298010956622771c870ab3cd8ca57a2faaron return "URL to redirect to is missing";
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!use_regex && !ap_is_url(url))
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return "Redirect to non-URL";
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding else {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (url)
c5d006b2861d49c61bcf79316163e30611c6fd08trawick return "Redirect URL not valid for this status";
c5d006b2861d49c61bcf79316163e30611c6fd08trawick }
c5d006b2861d49c61bcf79316163e30611c6fd08trawick
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (cmd->path)
7697b1b7376a532163c621e050b70c90dcb15d66covener new = apr_array_push(dirconf->redirects);
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim else
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim new = apr_array_push(serverconf->redirects);
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim new->fake = f;
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim new->real = url;
7697b1b7376a532163c621e050b70c90dcb15d66covener new->regexp = r;
e08076ca56e6cb68b30846b9e9339061058aae6dpoirier new->redir_status = status;
e08076ca56e6cb68b30846b9e9339061058aae6dpoirier return NULL;
7697b1b7376a532163c621e050b70c90dcb15d66covener}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic const char *add_redirect(cmd_parms *cmd, void *dirconf,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const char *arg1, const char *arg2,
f4b96a996afbc46872f57ad1450e6ee1c8f13707jorton const char *arg3)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 0);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic const char *add_redirect2(cmd_parms *cmd, void *dirconf,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const char *arg1, const char *arg2)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return add_redirect_internal(cmd, dirconf, arg1, arg2, NULL, 0);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic const char *add_redirect_regex(cmd_parms *cmd, void *dirconf,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const char *arg1, const char *arg2,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const char *arg3)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 1);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic const command_rec alias_cmds[] =
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding AP_INIT_TAKE2("Alias", add_alias, NULL, RSRC_CONF,
785be1b6298010956622771c870ab3cd8ca57a2faaron "a fakename and a realname"),
785be1b6298010956622771c870ab3cd8ca57a2faaron AP_INIT_TAKE2("ScriptAlias", add_alias, "cgi-script", RSRC_CONF,
785be1b6298010956622771c870ab3cd8ca57a2faaron "a fakename and a realname"),
785be1b6298010956622771c870ab3cd8ca57a2faaron AP_INIT_TAKE23("Redirect", add_redirect, (void *) HTTP_MOVED_TEMPORARILY,
785be1b6298010956622771c870ab3cd8ca57a2faaron OR_FILEINFO,
785be1b6298010956622771c870ab3cd8ca57a2faaron "an optional status, then document to be redirected and "
785be1b6298010956622771c870ab3cd8ca57a2faaron "destination URL"),
785be1b6298010956622771c870ab3cd8ca57a2faaron AP_INIT_TAKE2("AliasMatch", add_alias_regex, NULL, RSRC_CONF,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding "a regular expression and a filename"),
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding AP_INIT_TAKE2("ScriptAliasMatch", add_alias_regex, "cgi-script", RSRC_CONF,
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm "a regular expression and a filename"),
785be1b6298010956622771c870ab3cd8ca57a2faaron AP_INIT_TAKE23("RedirectMatch", add_redirect_regex,
785be1b6298010956622771c870ab3cd8ca57a2faaron (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO,
785be1b6298010956622771c870ab3cd8ca57a2faaron "an optional status, then a regular expression and "
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding "destination URL"),
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding AP_INIT_TAKE2("RedirectTemp", add_redirect2,
785be1b6298010956622771c870ab3cd8ca57a2faaron (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO,
785be1b6298010956622771c870ab3cd8ca57a2faaron "a document to be redirected, then the destination URL"),
785be1b6298010956622771c870ab3cd8ca57a2faaron AP_INIT_TAKE2("RedirectPermanent", add_redirect2,
785be1b6298010956622771c870ab3cd8ca57a2faaron (void *) HTTP_MOVED_PERMANENTLY, OR_FILEINFO,
785be1b6298010956622771c870ab3cd8ca57a2faaron "a document to be redirected, then the destination URL"),
785be1b6298010956622771c870ab3cd8ca57a2faaron {NULL}
785be1b6298010956622771c870ab3cd8ca57a2faaron};
785be1b6298010956622771c870ab3cd8ca57a2faaron
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic int alias_matches(const char *uri, const char *alias_fakename)
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm{
785be1b6298010956622771c870ab3cd8ca57a2faaron const char *aliasp = alias_fakename, *urip = uri;
2d399cd7535887fceaa9f8f116eb98ce68ddd602trawick
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding while (*aliasp) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (*aliasp == '/') {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* any number of '/' in the alias matches any number in
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * the supplied URI, but there must be at least one...
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (*urip != '/')
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return 0;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding do {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ++aliasp;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding } while (*aliasp == '/');
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding do {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ++urip;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding } while (*urip == '/');
a7ed9c525f9460187f327cea953bf90ecf1bdc51gstein }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding else {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* Other characters are compared literally */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (*urip++ != *aliasp++)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return 0;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
a7ed9c525f9460187f327cea953bf90ecf1bdc51gstein }
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick /* Check last alias path component matched all the way */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick if (aliasp[-1] != '/' && *urip != '\0' && *urip != '/')
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick return 0;
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick /* Return number of characters from URI which matched (may be
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick * greater than length of alias, since we may have matched
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick * doubled slashes)
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm return urip - uri;
785be1b6298010956622771c870ab3cd8ca57a2faaron}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic char *try_alias_list(request_rec *r, apr_array_header_t *aliases,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding int doesc, int *status)
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding alias_entry *entries = (alias_entry *) aliases->elts;
7697b1b7376a532163c621e050b70c90dcb15d66covener regmatch_t regm[AP_MAX_REG_MATCH];
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding char *found = NULL;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding int i;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding for (i = 0; i < aliases->nelts; ++i) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding alias_entry *p = &entries[i];
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding int l;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
785be1b6298010956622771c870ab3cd8ca57a2faaron if (p->regexp) {
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!ap_regexec(p->regexp, r->uri, AP_MAX_REG_MATCH, regm, 0)) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (p->real) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding found = ap_pregsub(r->pool, p->real, r->uri,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding AP_MAX_REG_MATCH, regm);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm if (found && doesc) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding apr_uri_t uri;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding apr_uri_parse(r->pool, found, &uri);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* Do not escape the query string or fragment. */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding found = apr_uri_unparse(r->pool, &uri,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding APR_URI_UNP_OMITQUERY);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding found = ap_escape_uri(r->pool, found);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (uri.query) {
a7ed9c525f9460187f327cea953bf90ecf1bdc51gstein found = apr_pstrcat(r->pool, found, "?",
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding uri.query, NULL);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
27c5ebb7d411a214f5b6b55a881086ce086d3dd3covener if (uri.fragment) {
27c5ebb7d411a214f5b6b55a881086ce086d3dd3covener found = apr_pstrcat(r->pool, found, "#",
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding uri.fragment, NULL);
f4b96a996afbc46872f57ad1450e6ee1c8f13707jorton }
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
785be1b6298010956622771c870ab3cd8ca57a2faaron else {
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick /* need something non-null */
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick found = apr_pstrdup(r->pool, "");
27c5ebb7d411a214f5b6b55a881086ce086d3dd3covener }
8fd7c5046d164fb0959222497e5925dfc6a52ff3trawick }
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick }
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick else {
e8f95a682820a599fe41b22977010636be5c2717jim l = alias_matches(r->uri, p->fake);
27c5ebb7d411a214f5b6b55a881086ce086d3dd3covener
27c5ebb7d411a214f5b6b55a881086ce086d3dd3covener if (l > 0) {
27c5ebb7d411a214f5b6b55a881086ce086d3dd3covener if (doesc) {
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim char *escurl;
27c5ebb7d411a214f5b6b55a881086ce086d3dd3covener escurl = ap_os_escape_path(r->pool, r->uri + l, 1);
27c5ebb7d411a214f5b6b55a881086ce086d3dd3covener
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding found = apr_pstrcat(r->pool, p->real, escurl, NULL);
27c5ebb7d411a214f5b6b55a881086ce086d3dd3covener }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding else
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding found = apr_pstrcat(r->pool, p->real, r->uri + l, NULL);
8f8ec0957334f50b7ac11359f90490ee467258eedreid }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
27c5ebb7d411a214f5b6b55a881086ce086d3dd3covener if (found) {
27c5ebb7d411a214f5b6b55a881086ce086d3dd3covener if (p->handler) { /* Set handler, and leave a note for mod_cgi */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding r->handler = p->handler;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding apr_table_setn(r->notes, "alias-forced-type", r->handler);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
27c5ebb7d411a214f5b6b55a881086ce086d3dd3covener /* XXX This is as SLOW as can be, next step, we optimize
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * and merge to whatever part of the found path was already
785be1b6298010956622771c870ab3cd8ca57a2faaron * canonicalized. After I finish eliminating os canonical.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Better fail test for ap_server_root_relative needed here.
27c5ebb7d411a214f5b6b55a881086ce086d3dd3covener */
27c5ebb7d411a214f5b6b55a881086ce086d3dd3covener if (!doesc) {
27c5ebb7d411a214f5b6b55a881086ce086d3dd3covener found = ap_server_root_relative(r->pool, found);
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (found) {
27c5ebb7d411a214f5b6b55a881086ce086d3dd3covener *status = p->redir_status;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return found;
7c6f514f2ef9b98f58b8f8a5f534eb78a75f29f2jorton }
7c6f514f2ef9b98f58b8f8a5f534eb78a75f29f2jorton
7c6f514f2ef9b98f58b8f8a5f534eb78a75f29f2jorton }
7c6f514f2ef9b98f58b8f8a5f534eb78a75f29f2jorton
7c6f514f2ef9b98f58b8f8a5f534eb78a75f29f2jorton return NULL;
7c6f514f2ef9b98f58b8f8a5f534eb78a75f29f2jorton}
7c6f514f2ef9b98f58b8f8a5f534eb78a75f29f2jorton
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanfstatic int translate_alias_redir(request_rec *r)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_conf_vector_t *sconf = r->server->module_config;
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf alias_server_conf *serverconf = ap_get_module_config(sconf, &alias_module);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding char *ret;
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick int status;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
7c6f514f2ef9b98f58b8f8a5f534eb78a75f29f2jorton if (r->uri[0] != '/' && r->uri[0] != '\0') {
7c6f514f2ef9b98f58b8f8a5f534eb78a75f29f2jorton return DECLINED;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf if ((ret = try_alias_list(r, serverconf->redirects, 1, &status)) != NULL) {
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf if (ap_is_HTTP_REDIRECT(status)) {
785be1b6298010956622771c870ab3cd8ca57a2faaron /* include QUERY_STRING if any */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf if (r->args) {
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL);
785be1b6298010956622771c870ab3cd8ca57a2faaron }
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf apr_table_setn(r->headers_out, "Location", ret);
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf }
785be1b6298010956622771c870ab3cd8ca57a2faaron return status;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron if ((ret = try_alias_list(r, serverconf->aliases, 0, &status)) != NULL) {
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf r->filename = ret;
066877f1a045103acfdd376d48cdd473c33f409bdougm return OK;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron return DECLINED;
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf}
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaronstatic int fixup_redir(request_rec *r)
785be1b6298010956622771c870ab3cd8ca57a2faaron{
785be1b6298010956622771c870ab3cd8ca57a2faaron void *dconf = r->per_dir_config;
785be1b6298010956622771c870ab3cd8ca57a2faaron alias_dir_conf *dirconf =
785be1b6298010956622771c870ab3cd8ca57a2faaron (alias_dir_conf *) ap_get_module_config(dconf, &alias_module);
785be1b6298010956622771c870ab3cd8ca57a2faaron char *ret;
785be1b6298010956622771c870ab3cd8ca57a2faaron int status;
785be1b6298010956622771c870ab3cd8ca57a2faaron
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier /* It may have changed since last time, so try again */
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier if ((ret = try_alias_list(r, dirconf->redirects, 1, &status)) != NULL) {
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier if (ap_is_HTTP_REDIRECT(status)) {
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier if (ret[0] == '/') {
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier char *orig_target = ret;
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier ret = ap_construct_url(r->pool, ret, r);
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier "incomplete redirection target of '%s' for "
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier "URI '%s' modified to '%s'",
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier orig_target, r->uri, ret);
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier }
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier if (!ap_is_url(ret)) {
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier status = HTTP_INTERNAL_SERVER_ERROR;
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier "cannot redirect '%s' to '%s'; "
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier "target is not a valid absoluteURI or abs_path",
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier r->uri, ret);
b6d9e9d6421b9cebfc74f9c1a870b8b85473f1c1poirier }
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf else {
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf /* append requested query only, if the config didn't
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf * supply its own.
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf if (r->args && !ap_strchr(ret, '?')) {
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL);
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf }
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf apr_table_setn(r->headers_out, "Location", ret);
066877f1a045103acfdd376d48cdd473c33f409bdougm }
7697b1b7376a532163c621e050b70c90dcb15d66covener }
7697b1b7376a532163c621e050b70c90dcb15d66covener return status;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron return DECLINED;
785be1b6298010956622771c870ab3cd8ca57a2faaron}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
7697b1b7376a532163c621e050b70c90dcb15d66covenerstatic void register_hooks(apr_pool_t *p)
7697b1b7376a532163c621e050b70c90dcb15d66covener{
7697b1b7376a532163c621e050b70c90dcb15d66covener static const char * const aszSucc[]={ "mod_userdir.c",
7697b1b7376a532163c621e050b70c90dcb15d66covener "mod_vhost_alias.c",NULL };
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf ap_hook_translate_name(translate_alias_redir,NULL,aszSucc,APR_HOOK_MIDDLE);
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf ap_hook_fixups(fixup_redir,NULL,NULL,APR_HOOK_MIDDLE);
7697b1b7376a532163c621e050b70c90dcb15d66covener}
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf
7697b1b7376a532163c621e050b70c90dcb15d66covenermodule AP_MODULE_DECLARE_DATA alias_module =
7697b1b7376a532163c621e050b70c90dcb15d66covener{
7697b1b7376a532163c621e050b70c90dcb15d66covener STANDARD20_MODULE_STUFF,
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf create_alias_dir_config, /* dir config creater */
7697b1b7376a532163c621e050b70c90dcb15d66covener merge_alias_dir_config, /* dir merger --- default is to override */
785be1b6298010956622771c870ab3cd8ca57a2faaron create_alias_config, /* server config */
785be1b6298010956622771c870ab3cd8ca57a2faaron merge_alias_config, /* merge server configs */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf alias_cmds, /* command apr_table_t */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf register_hooks /* register hooks */
7697b1b7376a532163c621e050b70c90dcb15d66covener};
7697b1b7376a532163c621e050b70c90dcb15d66covener