mod_alias.c revision a877b7d5d03f91d6c93076d9ccf14469c70c648d
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein/* ====================================================================
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * The Apache Software License, Version 1.1
bc8fd1b0b1afdf89b8d28eefa8cd74e26ba97986fielding * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * reserved.
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * Redistribution and use in source and binary forms, with or without
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * modification, are permitted provided that the following conditions
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * 1. Redistributions of source code must retain the above copyright
b0fb330a8581c8bfab5e523084f9f39264a52b12gstein * notice, this list of conditions and the following disclaimer.
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 * 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 * 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 * 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 * 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 * 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
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 * http_alias.c: Stuff for dealing with directory aliases
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker * Original by Rob McCool, rewritten in succession by David Robinson
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3strikertypedef struct {
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker const char *real;
f4c310fd2555c6faca1f980f00b161eadb089023gstein const char *fake;
1b21d7b3d97def358b2e923655edeb16613a1c31gsteintypedef struct {
f4c310fd2555c6faca1f980f00b161eadb089023gsteintypedef struct {
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic void *create_alias_config(apr_pool_t *p, server_rec *s)
000397350b42c6266351bd618fa07df929fa7c79gstein (alias_server_conf *) apr_pcalloc(p, sizeof(alias_server_conf));
f4c310fd2555c6faca1f980f00b161eadb089023gstein a->aliases = apr_array_make(p, 20, sizeof(alias_entry));
f4c310fd2555c6faca1f980f00b161eadb089023gstein a->redirects = apr_array_make(p, 20, sizeof(alias_entry));
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic void *create_alias_dir_config(apr_pool_t *p, char *d)
9f18c80269be35c0b5653e84b0db0a24044722c4gstein (alias_dir_conf *) apr_pcalloc(p, sizeof(alias_dir_conf));
9f18c80269be35c0b5653e84b0db0a24044722c4gstein a->redirects = apr_array_make(p, 2, sizeof(alias_entry));
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic void *merge_alias_config(apr_pool_t *p, void *basev, void *overridesv)
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;
f4c310fd2555c6faca1f980f00b161eadb089023gstein a->aliases = apr_array_append(p, overrides->aliases, base->aliases);
f4c310fd2555c6faca1f980f00b161eadb089023gstein a->redirects = apr_array_append(p, overrides->redirects, base->redirects);
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic void *merge_alias_dir_config(apr_pool_t *p, void *basev, void *overridesv)
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);
ef3c32d4a7accb38368c7b9face2ade88d987a8bgsteinstatic const char *add_alias_internal(cmd_parms *cmd, void *dummy,
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein const char *f, const char *r,
f5ec9b038bb9db933072ba2c0a8e7bb2a3cedbdagstein alias_server_conf *conf = ap_get_module_config(s->module_config,
ef3c32d4a7accb38368c7b9face2ade88d987a8bgstein /* XX r can NOT be relative to DocumentRoot here... compat bug. */
9f18c80269be35c0b5653e84b0db0a24044722c4gstein new->regexp = ap_pregcomp(cmd->pool, f, REG_EXTENDED);
9d0665da83d1e22c0ea0e5f6f940f70f75bf5237ianh return "Regular expression could not be compiled.";
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.
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic const char *add_alias(cmd_parms *cmd, void *dummy, const char *f,
b47464a901075041e800be2de098a603923fa4f9gstein const char *r)
b47464a901075041e800be2de098a603923fa4f9gsteinstatic const char *add_alias_regex(cmd_parms *cmd, void *dummy, const char *f,
f4c310fd2555c6faca1f980f00b161eadb089023gstein const char *r)
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic const char *add_redirect_internal(cmd_parms *cmd,
de18a9e85398b9c79c422f578633ed56c2747bbbgstein alias_server_conf *serverconf = ap_get_module_config(s->module_config,
de18a9e85398b9c79c422f578633ed56c2747bbbgstein const char *f = arg2;
de18a9e85398b9c79c422f578633ed56c2747bbbgstein return "Regular expression could not be compiled.";
000397350b42c6266351bd618fa07df929fa7c79gstein return "URL to redirect to is missing";
9f18c80269be35c0b5653e84b0db0a24044722c4gstein return "Redirect to non-URL";
000397350b42c6266351bd618fa07df929fa7c79gstein return "Redirect URL not valid for this status";
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic const char *add_redirect(cmd_parms *cmd, void *dirconf,
9f18c80269be35c0b5653e84b0db0a24044722c4gstein const char *arg3)
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 0);
9f18c80269be35c0b5653e84b0db0a24044722c4gsteinstatic const char *add_redirect2(cmd_parms *cmd, void *dirconf,
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein return add_redirect_internal(cmd, dirconf, arg1, arg2, NULL, 0);
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gsteinstatic const char *add_redirect_regex(cmd_parms *cmd, void *dirconf,
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein const char *arg3)
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gstein return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 1);
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 "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 "an optional status, then a regular expression and "
000397350b42c6266351bd618fa07df929fa7c79gstein "destination URL"),
000397350b42c6266351bd618fa07df929fa7c79gstein "a document to be redirected, then the destination URL"),
000397350b42c6266351bd618fa07df929fa7c79gstein "a document to be redirected, then the destination URL"),
eb2abb2d3f87f28e99bcb282b91e432822b4d9b4gsteinstatic int alias_matches(const char *uri, const char *alias_fakename)
9f18c80269be35c0b5653e84b0db0a24044722c4gstein /* any number of '/' in the alias matches any number in
9f18c80269be35c0b5653e84b0db0a24044722c4gstein * the supplied URI, but there must be at least one...
f4c310fd2555c6faca1f980f00b161eadb089023gstein /* Other characters are compared literally */
f4c310fd2555c6faca1f980f00b161eadb089023gstein /* Check last alias path component matched all the way */
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker if (aliasp[-1] != '/' && *urip != '\0' && *urip != '/')
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)
f4c310fd2555c6faca1f980f00b161eadb089023gsteinstatic char *try_alias_list(request_rec *r, apr_array_header_t *aliases, int doesc, int *status)
f4c310fd2555c6faca1f980f00b161eadb089023gstein alias_entry *entries = (alias_entry *) aliases->elts;
f4c310fd2555c6faca1f980f00b161eadb089023gstein if (!ap_regexec(p->regexp, r->uri, p->regexp->re_nsub + 1, regm, 0)) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein /* Do not escape the query string or fragment. */
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker /* need something non-null */
f5d88bab65052e00ba37a1af17e5e67a437628b5wrowe if (l > 0) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein found = apr_pstrcat(r->pool, p->real, r->uri + l, NULL);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker if (p->handler) { /* Set handler, and leave a note for mod_cgi */
5b03ba47ff7225cacb131f14b019332af27da960gstein apr_table_setn(r->notes, "alias-forced-type", r->handler);
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 alias_server_conf *serverconf = ap_get_module_config(sconf, &alias_module);
5b03ba47ff7225cacb131f14b019332af27da960gstein if ((ret = try_alias_list(r, serverconf->redirects, 1, &status)) != NULL) {
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker /* include QUERY_STRING if any */
5b03ba47ff7225cacb131f14b019332af27da960gstein if ((ret = try_alias_list(r, serverconf->aliases, 0, &status)) != NULL) {
f4c310fd2555c6faca1f980f00b161eadb089023gstein (alias_dir_conf *) ap_get_module_config(dconf, &alias_module);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker /* It may have changed since last time, so try again */
f4c310fd2555c6faca1f980f00b161eadb089023gstein if ((ret = try_alias_list(r, dirconf->redirects, 1, &status)) != NULL) {
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",
f4c310fd2555c6faca1f980f00b161eadb089023gstein static const char * const aszPre[]={ "mod_userdir.c",NULL };
f4c310fd2555c6faca1f980f00b161eadb089023gstein ap_hook_translate_name(translate_alias_redir,aszPre,NULL,APR_HOOK_MIDDLE);
72360798a27566f28e2cbee0e39a0a6e3c3bd729wrowe ap_hook_fixups(fixup_redir,NULL,NULL,APR_HOOK_MIDDLE);
49f1aab8b6762ee5b4afdb3a9cc48e7c00435dd3striker merge_alias_dir_config, /* dir merger --- default is to override */