mod_alias.c revision a877b7d5d03f91d6c93076d9ccf14469c70c648d
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein/* ====================================================================
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * The Apache Software License, Version 1.1
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein *
bc8fd1b0b1afdf89b8d28eefa8cd74e26ba97986fielding * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * reserved.
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein *
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * Redistribution and use in source and binary forms, with or without
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * modification, are permitted provided that the following conditions
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * are met:
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein *
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * 1. Redistributions of source code must retain the above copyright
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * notice, this list of conditions and the following disclaimer.
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein *
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * 2. Redistributions in binary form must reproduce the above copyright
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * notice, this list of conditions and the following disclaimer in
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * the documentation and/or other materials provided with the
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * distribution.
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein *
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * 3. The end-user documentation included with the redistribution,
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * if any, must include the following acknowledgment:
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * "This product includes software developed by the
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * Apache Software Foundation (http://www.apache.org/)."
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * Alternately, this acknowledgment may appear in the software itself,
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * if and wherever such third-party acknowledgments normally appear.
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein *
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * 4. The names "Apache" and "Apache Software Foundation" must
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * not be used to endorse or promote products derived from this
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * software without prior written permission. For written
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * permission, please contact apache@apache.org.
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein *
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * 5. Products derived from this software may not be called "Apache",
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * nor may "Apache" appear in their name, without prior written
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * permission of the Apache Software Foundation.
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein *
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * SUCH DAMAGE.
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * ====================================================================
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein *
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * This software consists of voluntary contributions made by many
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * individuals on behalf of the Apache Software Foundation. For more
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * information on the Apache Software Foundation, please see
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * <http://www.apache.org/>.
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein *
f4c310fd2555c6faca1f980f00b161eadb089023gstein * Portions of this software are based upon public domain software
f4c310fd2555c6faca1f980f00b161eadb089023gstein * originally written at the National Center for Supercomputing Applications,
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker * University of Illinois, Urbana-Champaign.
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker */
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker/*
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker * http_alias.c: Stuff for dealing with directory aliases
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker *
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker * Original by Rob McCool, rewritten in succession by David Robinson
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker * and rst.
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker *
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker */
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#include "apr_strings.h"
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#include "apr_lib.h"
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#define APR_WANT_STRFUNC
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#include "apr_want.h"
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#include "ap_config.h"
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#include "httpd.h"
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#include "http_config.h"
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#include "http_request.h"
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker#include "http_log.h"
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3strikertypedef struct {
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker const char *real;
f4c310fd2555c6faca1f980f00b161eadb089023gstein const char *fake;
1b21d7b3d97def358b2e923655edeb16613a1c31gstein char *handler;
1327b173ab33ae5bec795b798d5c54c16a7b5c05gstein regex_t *regexp;
1b21d7b3d97def358b2e923655edeb16613a1c31gstein int redir_status; /* 301, 302, 303, 410, etc */
1b21d7b3d97def358b2e923655edeb16613a1c31gstein} alias_entry;
1b21d7b3d97def358b2e923655edeb16613a1c31gstein
1b21d7b3d97def358b2e923655edeb16613a1c31gsteintypedef struct {
f4c310fd2555c6faca1f980f00b161eadb089023gstein apr_array_header_t *aliases;
f4c310fd2555c6faca1f980f00b161eadb089023gstein apr_array_header_t *redirects;
f4c310fd2555c6faca1f980f00b161eadb089023gstein} alias_server_conf;
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gsteintypedef struct {
f4c310fd2555c6faca1f980f00b161eadb089023gstein apr_array_header_t *redirects;
f4c310fd2555c6faca1f980f00b161eadb089023gstein} alias_dir_conf;
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gsteinmodule AP_MODULE_DECLARE_DATA alias_module;
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic void *create_alias_config(apr_pool_t *p, server_rec *s)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
000397350b42c6266351bd618fa07df929fa7c79gstein alias_server_conf *a =
000397350b42c6266351bd618fa07df929fa7c79gstein (alias_server_conf *) apr_pcalloc(p, sizeof(alias_server_conf));
000397350b42c6266351bd618fa07df929fa7c79gstein
f4c310fd2555c6faca1f980f00b161eadb089023gstein a->aliases = apr_array_make(p, 20, sizeof(alias_entry));
f4c310fd2555c6faca1f980f00b161eadb089023gstein a->redirects = apr_array_make(p, 20, sizeof(alias_entry));
f4c310fd2555c6faca1f980f00b161eadb089023gstein return a;
f4c310fd2555c6faca1f980f00b161eadb089023gstein}
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic void *create_alias_dir_config(apr_pool_t *p, char *d)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
f4c310fd2555c6faca1f980f00b161eadb089023gstein alias_dir_conf *a =
9f18c80269be35c0b5653e84b0db0a24044722c4gstein (alias_dir_conf *) apr_pcalloc(p, sizeof(alias_dir_conf));
9f18c80269be35c0b5653e84b0db0a24044722c4gstein a->redirects = apr_array_make(p, 2, sizeof(alias_entry));
f4c310fd2555c6faca1f980f00b161eadb089023gstein return a;
f4c310fd2555c6faca1f980f00b161eadb089023gstein}
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic void *merge_alias_config(apr_pool_t *p, void *basev, void *overridesv)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
f4c310fd2555c6faca1f980f00b161eadb089023gstein alias_server_conf *a =
f4c310fd2555c6faca1f980f00b161eadb089023gstein (alias_server_conf *) apr_pcalloc(p, sizeof(alias_server_conf));
f4c310fd2555c6faca1f980f00b161eadb089023gstein alias_server_conf *base = (alias_server_conf *) basev, *overrides = (alias_server_conf *) overridesv;
b47464a901075041e800be2de098a603923fa4f9gstein
f4c310fd2555c6faca1f980f00b161eadb089023gstein a->aliases = apr_array_append(p, overrides->aliases, base->aliases);
f4c310fd2555c6faca1f980f00b161eadb089023gstein a->redirects = apr_array_append(p, overrides->redirects, base->redirects);
f4c310fd2555c6faca1f980f00b161eadb089023gstein return a;
f4c310fd2555c6faca1f980f00b161eadb089023gstein}
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic void *merge_alias_dir_config(apr_pool_t *p, void *basev, void *overridesv)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
f4c310fd2555c6faca1f980f00b161eadb089023gstein alias_dir_conf *a =
98e9c4a310bb623ff788680f88b6bd200ff36a24wrowe (alias_dir_conf *) apr_pcalloc(p, sizeof(alias_dir_conf));
f4c310fd2555c6faca1f980f00b161eadb089023gstein alias_dir_conf *base = (alias_dir_conf *) basev, *overrides = (alias_dir_conf *) overridesv;
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein a->redirects = apr_array_append(p, overrides->redirects, base->redirects);
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein return a;
5a9667916c79d8c699b069068e5570aa1c331c80gstein}
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein
ef3c32d4a7accb38368c7b9face2ade88d987a8bgsteinstatic const char *add_alias_internal(cmd_parms *cmd, void *dummy,
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein const char *f, const char *r,
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein int use_regex)
5a9667916c79d8c699b069068e5570aa1c331c80gstein{
9d0665da83d1e22c0ea0e5f6f940f70f75bf5237ianh server_rec *s = cmd->server;
f5ec9b038bb9db933072ba2c0a8e7bb2a3cedbdagstein alias_server_conf *conf = ap_get_module_config(s->module_config,
f4c310fd2555c6faca1f980f00b161eadb089023gstein &alias_module);
f4c310fd2555c6faca1f980f00b161eadb089023gstein alias_entry *new = apr_array_push(conf->aliases);
f4c310fd2555c6faca1f980f00b161eadb089023gstein
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein /* XX r can NOT be relative to DocumentRoot here... compat bug. */
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein if (use_regex) {
9f18c80269be35c0b5653e84b0db0a24044722c4gstein new->regexp = ap_pregcomp(cmd->pool, f, REG_EXTENDED);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker if (new->regexp == NULL)
9d0665da83d1e22c0ea0e5f6f940f70f75bf5237ianh return "Regular expression could not be compiled.";
f4c310fd2555c6faca1f980f00b161eadb089023gstein new->real = r;
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm else {
f4c310fd2555c6faca1f980f00b161eadb089023gstein /* XXX This may be optimized, but we must know that new->real
f4c310fd2555c6faca1f980f00b161eadb089023gstein * exists. If so, we can dir merge later, trusing new->real
f4c310fd2555c6faca1f980f00b161eadb089023gstein * and just canonicalizing the remainder. Not till I finish
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker * cleaning out the old ap_canonical stuff first.
f4c310fd2555c6faca1f980f00b161eadb089023gstein */
b47464a901075041e800be2de098a603923fa4f9gstein new->real = r;
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein new->fake = f;
f4c310fd2555c6faca1f980f00b161eadb089023gstein new->handler = cmd->info;
f4c310fd2555c6faca1f980f00b161eadb089023gstein
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm return NULL;
f4c310fd2555c6faca1f980f00b161eadb089023gstein}
b47464a901075041e800be2de098a603923fa4f9gstein
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic const char *add_alias(cmd_parms *cmd, void *dummy, const char *f,
b47464a901075041e800be2de098a603923fa4f9gstein const char *r)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
f4c310fd2555c6faca1f980f00b161eadb089023gstein return add_alias_internal(cmd, dummy, f, r, 0);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker}
f4c310fd2555c6faca1f980f00b161eadb089023gstein
b47464a901075041e800be2de098a603923fa4f9gsteinstatic const char *add_alias_regex(cmd_parms *cmd, void *dummy, const char *f,
f4c310fd2555c6faca1f980f00b161eadb089023gstein const char *r)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
f4c310fd2555c6faca1f980f00b161eadb089023gstein return add_alias_internal(cmd, dummy, f, r, 1);
f4c310fd2555c6faca1f980f00b161eadb089023gstein}
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic const char *add_redirect_internal(cmd_parms *cmd,
f4c310fd2555c6faca1f980f00b161eadb089023gstein alias_dir_conf *dirconf,
f4c310fd2555c6faca1f980f00b161eadb089023gstein const char *arg1, const char *arg2,
f4c310fd2555c6faca1f980f00b161eadb089023gstein const char *arg3, int use_regex)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker alias_entry *new;
de18a9e85398b9c79c422f578633ed56c2747bbbgstein server_rec *s = cmd->server;
de18a9e85398b9c79c422f578633ed56c2747bbbgstein alias_server_conf *serverconf = ap_get_module_config(s->module_config,
de18a9e85398b9c79c422f578633ed56c2747bbbgstein &alias_module);
de18a9e85398b9c79c422f578633ed56c2747bbbgstein int status = (int) (long) cmd->info;
de18a9e85398b9c79c422f578633ed56c2747bbbgstein regex_t *r = NULL;
de18a9e85398b9c79c422f578633ed56c2747bbbgstein const char *f = arg2;
de18a9e85398b9c79c422f578633ed56c2747bbbgstein const char *url = arg3;
de18a9e85398b9c79c422f578633ed56c2747bbbgstein
de18a9e85398b9c79c422f578633ed56c2747bbbgstein if (!strcasecmp(arg1, "gone"))
de18a9e85398b9c79c422f578633ed56c2747bbbgstein status = HTTP_GONE;
de18a9e85398b9c79c422f578633ed56c2747bbbgstein else if (!strcasecmp(arg1, "permanent"))
de18a9e85398b9c79c422f578633ed56c2747bbbgstein status = HTTP_MOVED_PERMANENTLY;
de18a9e85398b9c79c422f578633ed56c2747bbbgstein else if (!strcasecmp(arg1, "temp"))
f4c310fd2555c6faca1f980f00b161eadb089023gstein status = HTTP_MOVED_TEMPORARILY;
f4c310fd2555c6faca1f980f00b161eadb089023gstein else if (!strcasecmp(arg1, "seeother"))
f4c310fd2555c6faca1f980f00b161eadb089023gstein status = HTTP_SEE_OTHER;
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm else if (apr_isdigit(*arg1))
f4c310fd2555c6faca1f980f00b161eadb089023gstein status = atoi(arg1);
f4c310fd2555c6faca1f980f00b161eadb089023gstein else {
f4c310fd2555c6faca1f980f00b161eadb089023gstein f = arg1;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker url = arg2;
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gstein if (use_regex) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein r = ap_pregcomp(cmd->pool, f, REG_EXTENDED);
de18a9e85398b9c79c422f578633ed56c2747bbbgstein if (r == NULL)
de18a9e85398b9c79c422f578633ed56c2747bbbgstein return "Regular expression could not be compiled.";
9f18c80269be35c0b5653e84b0db0a24044722c4gstein }
9f18c80269be35c0b5653e84b0db0a24044722c4gstein
000397350b42c6266351bd618fa07df929fa7c79gstein if (ap_is_HTTP_REDIRECT(status)) {
000397350b42c6266351bd618fa07df929fa7c79gstein if (!url)
000397350b42c6266351bd618fa07df929fa7c79gstein return "URL to redirect to is missing";
000397350b42c6266351bd618fa07df929fa7c79gstein if (!use_regex && !ap_is_url(url))
9f18c80269be35c0b5653e84b0db0a24044722c4gstein return "Redirect to non-URL";
9f18c80269be35c0b5653e84b0db0a24044722c4gstein }
000397350b42c6266351bd618fa07df929fa7c79gstein else {
000397350b42c6266351bd618fa07df929fa7c79gstein if (url)
000397350b42c6266351bd618fa07df929fa7c79gstein return "Redirect URL not valid for this status";
000397350b42c6266351bd618fa07df929fa7c79gstein }
000397350b42c6266351bd618fa07df929fa7c79gstein
000397350b42c6266351bd618fa07df929fa7c79gstein if (cmd->path)
f4c310fd2555c6faca1f980f00b161eadb089023gstein new = apr_array_push(dirconf->redirects);
f4c310fd2555c6faca1f980f00b161eadb089023gstein else
f4c310fd2555c6faca1f980f00b161eadb089023gstein new = apr_array_push(serverconf->redirects);
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gstein new->fake = f;
f4c310fd2555c6faca1f980f00b161eadb089023gstein new->real = url;
f4c310fd2555c6faca1f980f00b161eadb089023gstein new->regexp = r;
f4c310fd2555c6faca1f980f00b161eadb089023gstein new->redir_status = status;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker return NULL;
f4c310fd2555c6faca1f980f00b161eadb089023gstein}
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic const char *add_redirect(cmd_parms *cmd, void *dirconf,
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein const char *arg1, const char *arg2,
9f18c80269be35c0b5653e84b0db0a24044722c4gstein const char *arg3)
9f18c80269be35c0b5653e84b0db0a24044722c4gstein{
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 0);
9f18c80269be35c0b5653e84b0db0a24044722c4gstein}
9f18c80269be35c0b5653e84b0db0a24044722c4gstein
9f18c80269be35c0b5653e84b0db0a24044722c4gsteinstatic const char *add_redirect2(cmd_parms *cmd, void *dirconf,
709df1e1c2e1710570f8cb4209497e88662829c3gstein const char *arg1, const char *arg2)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein return add_redirect_internal(cmd, dirconf, arg1, arg2, NULL, 0);
709df1e1c2e1710570f8cb4209497e88662829c3gstein}
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gsteinstatic const char *add_redirect_regex(cmd_parms *cmd, void *dirconf,
f4c310fd2555c6faca1f980f00b161eadb089023gstein const char *arg1, const char *arg2,
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein const char *arg3)
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein{
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 1);
709df1e1c2e1710570f8cb4209497e88662829c3gstein}
f4c310fd2555c6faca1f980f00b161eadb089023gstein
709df1e1c2e1710570f8cb4209497e88662829c3gsteinstatic const command_rec alias_cmds[] =
709df1e1c2e1710570f8cb4209497e88662829c3gstein{
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein AP_INIT_TAKE2("Alias", add_alias, NULL, RSRC_CONF,
f4c310fd2555c6faca1f980f00b161eadb089023gstein "a fakename and a realname"),
f4c310fd2555c6faca1f980f00b161eadb089023gstein AP_INIT_TAKE2("ScriptAlias", add_alias, "cgi-script", RSRC_CONF,
7281ea331999debdc337b02ce37a3169e0e033a2gstein "a fakename and a realname"),
7281ea331999debdc337b02ce37a3169e0e033a2gstein AP_INIT_TAKE23("Redirect", add_redirect, (void *) HTTP_MOVED_TEMPORARILY,
7281ea331999debdc337b02ce37a3169e0e033a2gstein OR_FILEINFO,
7281ea331999debdc337b02ce37a3169e0e033a2gstein "an optional status, then document to be redirected and "
7281ea331999debdc337b02ce37a3169e0e033a2gstein "destination URL"),
f4c310fd2555c6faca1f980f00b161eadb089023gstein AP_INIT_TAKE2("AliasMatch", add_alias_regex, NULL, RSRC_CONF,
000397350b42c6266351bd618fa07df929fa7c79gstein "a regular expression and a filename"),
f4c310fd2555c6faca1f980f00b161eadb089023gstein AP_INIT_TAKE2("ScriptAliasMatch", add_alias_regex, "cgi-script", RSRC_CONF,
000397350b42c6266351bd618fa07df929fa7c79gstein "a regular expression and a filename"),
f4c310fd2555c6faca1f980f00b161eadb089023gstein AP_INIT_TAKE23("RedirectMatch", add_redirect_regex,
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO,
f4c310fd2555c6faca1f980f00b161eadb089023gstein "an optional status, then a regular expression and "
000397350b42c6266351bd618fa07df929fa7c79gstein "destination URL"),
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker AP_INIT_TAKE2("RedirectTemp", add_redirect2,
000397350b42c6266351bd618fa07df929fa7c79gstein (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO,
000397350b42c6266351bd618fa07df929fa7c79gstein "a document to be redirected, then the destination URL"),
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker AP_INIT_TAKE2("RedirectPermanent", add_redirect2,
9f18c80269be35c0b5653e84b0db0a24044722c4gstein (void *) HTTP_MOVED_PERMANENTLY, OR_FILEINFO,
000397350b42c6266351bd618fa07df929fa7c79gstein "a document to be redirected, then the destination URL"),
000397350b42c6266351bd618fa07df929fa7c79gstein {NULL}
9f18c80269be35c0b5653e84b0db0a24044722c4gstein};
000397350b42c6266351bd618fa07df929fa7c79gstein
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gsteinstatic int alias_matches(const char *uri, const char *alias_fakename)
9f18c80269be35c0b5653e84b0db0a24044722c4gstein{
9f18c80269be35c0b5653e84b0db0a24044722c4gstein const char *aliasp = alias_fakename, *urip = uri;
9f18c80269be35c0b5653e84b0db0a24044722c4gstein
9f18c80269be35c0b5653e84b0db0a24044722c4gstein while (*aliasp) {
9f18c80269be35c0b5653e84b0db0a24044722c4gstein if (*aliasp == '/') {
9f18c80269be35c0b5653e84b0db0a24044722c4gstein /* any number of '/' in the alias matches any number in
9f18c80269be35c0b5653e84b0db0a24044722c4gstein * the supplied URI, but there must be at least one...
9f18c80269be35c0b5653e84b0db0a24044722c4gstein */
9f18c80269be35c0b5653e84b0db0a24044722c4gstein if (*urip != '/')
9f18c80269be35c0b5653e84b0db0a24044722c4gstein return 0;
9f18c80269be35c0b5653e84b0db0a24044722c4gstein
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein while (*aliasp == '/')
000397350b42c6266351bd618fa07df929fa7c79gstein ++aliasp;
f4c310fd2555c6faca1f980f00b161eadb089023gstein while (*urip == '/')
f4c310fd2555c6faca1f980f00b161eadb089023gstein ++urip;
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein else {
f4c310fd2555c6faca1f980f00b161eadb089023gstein /* Other characters are compared literally */
f4c310fd2555c6faca1f980f00b161eadb089023gstein if (*urip++ != *aliasp++)
f4c310fd2555c6faca1f980f00b161eadb089023gstein return 0;
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
f4c310fd2555c6faca1f980f00b161eadb089023gstein /* Check last alias path component matched all the way */
f4c310fd2555c6faca1f980f00b161eadb089023gstein
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker if (aliasp[-1] != '/' && *urip != '\0' && *urip != '/')
f4c310fd2555c6faca1f980f00b161eadb089023gstein return 0;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
f4c310fd2555c6faca1f980f00b161eadb089023gstein /* Return number of characters from URI which matched (may be
f4c310fd2555c6faca1f980f00b161eadb089023gstein * greater than length of alias, since we may have matched
f4c310fd2555c6faca1f980f00b161eadb089023gstein * doubled slashes)
f4c310fd2555c6faca1f980f00b161eadb089023gstein */
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gstein return urip - uri;
f4c310fd2555c6faca1f980f00b161eadb089023gstein}
26250b0077972bf21b6d8a8d23772a4cf53f9477gstein
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic char *try_alias_list(request_rec *r, apr_array_header_t *aliases, int doesc, int *status)
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker{
f4c310fd2555c6faca1f980f00b161eadb089023gstein alias_entry *entries = (alias_entry *) aliases->elts;
f4c310fd2555c6faca1f980f00b161eadb089023gstein regmatch_t regm[10];
f4c310fd2555c6faca1f980f00b161eadb089023gstein char *found = NULL;
f4c310fd2555c6faca1f980f00b161eadb089023gstein int i;
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gstein for (i = 0; i < aliases->nelts; ++i) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein alias_entry *p = &entries[i];
f4c310fd2555c6faca1f980f00b161eadb089023gstein int l;
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gstein if (p->regexp) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein if (!ap_regexec(p->regexp, r->uri, p->regexp->re_nsub + 1, regm, 0)) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein if (p->real) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein found = ap_pregsub(r->pool, p->real, r->uri,
f4c310fd2555c6faca1f980f00b161eadb089023gstein p->regexp->re_nsub + 1, regm);
f39230a531b23d94f86a087963299bbe2e431a4agstein if (found && doesc) {
f39230a531b23d94f86a087963299bbe2e431a4agstein apr_uri_t uri;
f4c310fd2555c6faca1f980f00b161eadb089023gstein apr_uri_parse(r->pool, found, &uri);
f4c310fd2555c6faca1f980f00b161eadb089023gstein /* Do not escape the query string or fragment. */
f4c310fd2555c6faca1f980f00b161eadb089023gstein found = apr_uri_unparse(r->pool, &uri,
f4c310fd2555c6faca1f980f00b161eadb089023gstein APR_URI_UNP_OMITQUERY);
5b03ba47ff7225cacb131f14b019332af27da960gstein found = ap_escape_uri(r->pool, found);
5b03ba47ff7225cacb131f14b019332af27da960gstein if (uri.query) {
5b03ba47ff7225cacb131f14b019332af27da960gstein found = apr_pstrcat(r->pool, found, "?",
5b03ba47ff7225cacb131f14b019332af27da960gstein uri.query, NULL);
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein if (uri.fragment) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein found = apr_pstrcat(r->pool, found, "#",
f4c310fd2555c6faca1f980f00b161eadb089023gstein uri.fragment, NULL);
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker else {
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker /* need something non-null */
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker found = apr_pstrdup(r->pool, "");
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker }
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker }
f5d88bab65052e00ba37a1af17e5e67a437628b5wrowe }
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker else {
f5d88bab65052e00ba37a1af17e5e67a437628b5wrowe l = alias_matches(r->uri, p->fake);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
f5d88bab65052e00ba37a1af17e5e67a437628b5wrowe if (l > 0) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein if (doesc) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein char *escurl;
f4c310fd2555c6faca1f980f00b161eadb089023gstein escurl = ap_os_escape_path(r->pool, r->uri + l, 1);
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gstein found = apr_pstrcat(r->pool, p->real, escurl, NULL);
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein else
f4c310fd2555c6faca1f980f00b161eadb089023gstein found = apr_pstrcat(r->pool, p->real, r->uri + l, NULL);
5b03ba47ff7225cacb131f14b019332af27da960gstein }
5b03ba47ff7225cacb131f14b019332af27da960gstein }
5b03ba47ff7225cacb131f14b019332af27da960gstein
5b03ba47ff7225cacb131f14b019332af27da960gstein if (found) {
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker if (p->handler) { /* Set handler, and leave a note for mod_cgi */
5b03ba47ff7225cacb131f14b019332af27da960gstein r->handler = p->handler;
5b03ba47ff7225cacb131f14b019332af27da960gstein apr_table_setn(r->notes, "alias-forced-type", r->handler);
5b03ba47ff7225cacb131f14b019332af27da960gstein }
5b03ba47ff7225cacb131f14b019332af27da960gstein /* XXX This is as SLOW as can be, next step, we optimize
5b03ba47ff7225cacb131f14b019332af27da960gstein * and merge to whatever part of the found path was already
5b03ba47ff7225cacb131f14b019332af27da960gstein * canonicalized. After I finish eliminating os canonical.
5b03ba47ff7225cacb131f14b019332af27da960gstein */
5b03ba47ff7225cacb131f14b019332af27da960gstein if (!doesc)
5b03ba47ff7225cacb131f14b019332af27da960gstein found = ap_server_root_relative(r->pool, found);
5b03ba47ff7225cacb131f14b019332af27da960gstein *status = p->redir_status;
5b03ba47ff7225cacb131f14b019332af27da960gstein
5b03ba47ff7225cacb131f14b019332af27da960gstein return found;
5b03ba47ff7225cacb131f14b019332af27da960gstein }
5b03ba47ff7225cacb131f14b019332af27da960gstein
5b03ba47ff7225cacb131f14b019332af27da960gstein }
5b03ba47ff7225cacb131f14b019332af27da960gstein
5b03ba47ff7225cacb131f14b019332af27da960gstein return NULL;
5b03ba47ff7225cacb131f14b019332af27da960gstein}
5b03ba47ff7225cacb131f14b019332af27da960gstein
5b03ba47ff7225cacb131f14b019332af27da960gsteinstatic int translate_alias_redir(request_rec *r)
5b03ba47ff7225cacb131f14b019332af27da960gstein{
5b03ba47ff7225cacb131f14b019332af27da960gstein ap_conf_vector_t *sconf = r->server->module_config;
5b03ba47ff7225cacb131f14b019332af27da960gstein alias_server_conf *serverconf = ap_get_module_config(sconf, &alias_module);
5b03ba47ff7225cacb131f14b019332af27da960gstein char *ret;
5b03ba47ff7225cacb131f14b019332af27da960gstein int status;
5b03ba47ff7225cacb131f14b019332af27da960gstein
5b03ba47ff7225cacb131f14b019332af27da960gstein if (r->uri[0] != '/' && r->uri[0] != '\0')
5b03ba47ff7225cacb131f14b019332af27da960gstein return DECLINED;
5b03ba47ff7225cacb131f14b019332af27da960gstein
5b03ba47ff7225cacb131f14b019332af27da960gstein if ((ret = try_alias_list(r, serverconf->redirects, 1, &status)) != NULL) {
5b03ba47ff7225cacb131f14b019332af27da960gstein if (ap_is_HTTP_REDIRECT(status)) {
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker /* include QUERY_STRING if any */
5b03ba47ff7225cacb131f14b019332af27da960gstein if (r->args) {
5b03ba47ff7225cacb131f14b019332af27da960gstein ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker }
5b03ba47ff7225cacb131f14b019332af27da960gstein apr_table_setn(r->headers_out, "Location", ret);
5b03ba47ff7225cacb131f14b019332af27da960gstein }
5b03ba47ff7225cacb131f14b019332af27da960gstein return status;
5b03ba47ff7225cacb131f14b019332af27da960gstein }
5b03ba47ff7225cacb131f14b019332af27da960gstein
5b03ba47ff7225cacb131f14b019332af27da960gstein if ((ret = try_alias_list(r, serverconf->aliases, 0, &status)) != NULL) {
5b03ba47ff7225cacb131f14b019332af27da960gstein r->filename = ret;
5b03ba47ff7225cacb131f14b019332af27da960gstein return OK;
5b03ba47ff7225cacb131f14b019332af27da960gstein }
5b03ba47ff7225cacb131f14b019332af27da960gstein
5b03ba47ff7225cacb131f14b019332af27da960gstein return DECLINED;
5b03ba47ff7225cacb131f14b019332af27da960gstein}
5b03ba47ff7225cacb131f14b019332af27da960gstein
5b03ba47ff7225cacb131f14b019332af27da960gsteinstatic int fixup_redir(request_rec *r)
5b03ba47ff7225cacb131f14b019332af27da960gstein{
5b03ba47ff7225cacb131f14b019332af27da960gstein void *dconf = r->per_dir_config;
5b03ba47ff7225cacb131f14b019332af27da960gstein alias_dir_conf *dirconf =
f4c310fd2555c6faca1f980f00b161eadb089023gstein (alias_dir_conf *) ap_get_module_config(dconf, &alias_module);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker char *ret;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker int status;
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker /* It may have changed since last time, so try again */
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm
f4c310fd2555c6faca1f980f00b161eadb089023gstein if ((ret = try_alias_list(r, dirconf->redirects, 1, &status)) != NULL) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein if (ap_is_HTTP_REDIRECT(status)) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein if (!ap_is_url(ret)) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein status = HTTP_INTERNAL_SERVER_ERROR;
26250b0077972bf21b6d8a8d23772a4cf53f9477gstein ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker "cannot redirect '%s' to '%s'; "
f4c310fd2555c6faca1f980f00b161eadb089023gstein "target is not a valid absoluteURI",
9a1d0e3184c65f510dbef5e83ba5b9f27f961b44gstein r->uri, ret);
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein else {
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker apr_table_setn(r->headers_out, "Location", ret);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker }
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker }
252e2478cb56afb5ca8585b50bc2ffb780d2efb6gstein return status;
f4c310fd2555c6faca1f980f00b161eadb089023gstein }
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gstein return DECLINED;
f4c310fd2555c6faca1f980f00b161eadb089023gstein}
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic void register_hooks(apr_pool_t *p)
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
f4c310fd2555c6faca1f980f00b161eadb089023gstein static const char * const aszPre[]={ "mod_userdir.c",NULL };
f4c310fd2555c6faca1f980f00b161eadb089023gstein
f4c310fd2555c6faca1f980f00b161eadb089023gstein ap_hook_translate_name(translate_alias_redir,aszPre,NULL,APR_HOOK_MIDDLE);
72360798a27566f28e2cbee0e39a0a6e3c3bd729wrowe ap_hook_fixups(fixup_redir,NULL,NULL,APR_HOOK_MIDDLE);
f4c310fd2555c6faca1f980f00b161eadb089023gstein}
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker
f4c310fd2555c6faca1f980f00b161eadb089023gsteinmodule AP_MODULE_DECLARE_DATA alias_module =
f4c310fd2555c6faca1f980f00b161eadb089023gstein{
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker STANDARD20_MODULE_STUFF,
f4c310fd2555c6faca1f980f00b161eadb089023gstein create_alias_dir_config, /* dir config creater */
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker merge_alias_dir_config, /* dir merger --- default is to override */
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker create_alias_config, /* server config */
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker merge_alias_config, /* merge server configs */
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker alias_cmds, /* command apr_table_t */
f4c310fd2555c6faca1f980f00b161eadb089023gstein register_hooks /* register hooks */
f4c310fd2555c6faca1f980f00b161eadb089023gstein};
f4c310fd2555c6faca1f980f00b161eadb089023gstein