mod_rewrite.c revision c6edcf04010c354eef81d0b9c02aa917965637a2
beaad6ac31022179c44d88536811e9ccd9425696nd/* ====================================================================
beaad6ac31022179c44d88536811e9ccd9425696nd * The Apache Software License, Version 1.1
db878466c5e95073429dda0bdd001f45e9486e16fielding * Copyright (c) 2000-2002 The Apache Software Foundation. All rights
db878466c5e95073429dda0bdd001f45e9486e16fielding * reserved.
db878466c5e95073429dda0bdd001f45e9486e16fielding * Redistribution and use in source and binary forms, with or without
db878466c5e95073429dda0bdd001f45e9486e16fielding * modification, are permitted provided that the following conditions
beaad6ac31022179c44d88536811e9ccd9425696nd * 1. Redistributions of source code must retain the above copyright
beaad6ac31022179c44d88536811e9ccd9425696nd * notice, this list of conditions and the following disclaimer.
beaad6ac31022179c44d88536811e9ccd9425696nd * 2. Redistributions in binary form must reproduce the above copyright
beaad6ac31022179c44d88536811e9ccd9425696nd * notice, this list of conditions and the following disclaimer in
beaad6ac31022179c44d88536811e9ccd9425696nd * the documentation and/or other materials provided with the
beaad6ac31022179c44d88536811e9ccd9425696nd * distribution.
beaad6ac31022179c44d88536811e9ccd9425696nd * 3. The end-user documentation included with the redistribution,
01c674544bd4c211141bcd9fb09b96ffc18c6c3dnd * if any, must include the following acknowledgment:
01c674544bd4c211141bcd9fb09b96ffc18c6c3dnd * "This product includes software developed by the
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * Apache Software Foundation (http://www.apache.org/)."
01c674544bd4c211141bcd9fb09b96ffc18c6c3dnd * Alternately, this acknowledgment may appear in the software itself,
3726777f47ac4bba3e21b075905959bbea47e72eerikabele * if and wherever such third-party acknowledgments normally appear.
3726777f47ac4bba3e21b075905959bbea47e72eerikabele * 4. The names "Apache" and "Apache Software Foundation" must
3726777f47ac4bba3e21b075905959bbea47e72eerikabele * not be used to endorse or promote products derived from this
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * software without prior written permission. For written
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * permission, please contact apache@apache.org.
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * 5. Products derived from this software may not be called "Apache",
3726777f47ac4bba3e21b075905959bbea47e72eerikabele * nor may "Apache" appear in their name, without prior written
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * permission of the Apache Software Foundation.
e5343521634b71f10f0e88374d88bd5a45f75f68nd * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
66e48875fca2df6669dab4f2690ee36c6913c0ffnd * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
66e48875fca2df6669dab4f2690ee36c6913c0ffnd * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3726777f47ac4bba3e21b075905959bbea47e72eerikabele * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
bdbf46e4950b6f633073f803486962e82c2f086and * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * SUCH DAMAGE.
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * ====================================================================
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * This software consists of voluntary contributions made by many
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * individuals on behalf of the Apache Software Foundation. For more
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * information on the Apache Software Foundation, please see
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * Portions of this software are based upon public domain software
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * originally written at the National Center for Supercomputing Applications,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * University of Illinois, Urbana-Champaign.
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** _ __ ___ ___ __| | _ __ _____ ___ __(_) |_ ___
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** | '_ ` _ \ / _ \ / _` | | '__/ _ \ \ /\ / / '__| | __/ _ \
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** | | | | | | (_) | (_| | | | | __/\ V V /| | | | || __/
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** |_| |_| |_|\___/ \__,_|___|_| \___| \_/\_/ |_| |_|\__\___|
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** URL Rewriting Module
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** This module uses a rule-based rewriting engine (based on a
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** regular-expression parser) to rewrite requested URLs on the fly.
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** It supports an unlimited number of additional rule conditions (which can
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** operate on a lot of variables, even on HTTP headers) for granular
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** matching and even external database lookups (either via plain text
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** tables, DBM hash files or even external processes) for advanced URL
e5343521634b71f10f0e88374d88bd5a45f75f68nd** substitution.
bdbf46e4950b6f633073f803486962e82c2f086and** It operates on the full URLs (including the PATH_INFO part) both in
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** per-server context (httpd.conf) and per-dir context (.htaccess) and even
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** can generate QUERY_STRING parts on result. The rewriting result finally
3726777f47ac4bba3e21b075905959bbea47e72eerikabele** can lead to internal subprocessing, external request redirection or even
11c3b428f0fc9b03f353ed9b66347c5deb567052nd** to internal proxy throughput.
11c3b428f0fc9b03f353ed9b66347c5deb567052nd** This module was originally written in April 1996 and
11c3b428f0fc9b03f353ed9b66347c5deb567052nd** gifted exclusively to the The Apache Software Foundation in July 1997 by
11c3b428f0fc9b03f353ed9b66347c5deb567052nd** Ralf S. Engelschall
11c3b428f0fc9b03f353ed9b66347c5deb567052nd** rse@engelschall.com
fd46b0fed4351924170b4db5859dc35b771ee16dnd#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** +-------------------------------------------------------+
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** | static module configuration
3726777f47ac4bba3e21b075905959bbea47e72eerikabele** +-------------------------------------------------------+
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** Our interface to the Apache server kernel:
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** o Runtime logic of a request is as following:
3726777f47ac4bba3e21b075905959bbea47e72eerikabele** while(request or subrequest)
3726777f47ac4bba3e21b075905959bbea47e72eerikabele** foreach(stage #0...#9)
3726777f47ac4bba3e21b075905959bbea47e72eerikabele** foreach(module) (**)
66e48875fca2df6669dab4f2690ee36c6913c0ffnd** try to run hook
d3cd98e7839dd1c737c18d42a916ed20860a50e1nd** o the order of modules at (**) is the inverted order as
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** given in the "Configuration" file, i.e. the last module
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** specified is the first one called for each hook!
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** The core module is always the last!
bdbf46e4950b6f633073f803486962e82c2f086and** o there are two different types of result checking and
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** continue processing:
e5343521634b71f10f0e88374d88bd5a45f75f68nd** for hook #0,#1,#4,#5,#6,#8:
e5343521634b71f10f0e88374d88bd5a45f75f68nd** hook run loop stops on first modules which gives
e5343521634b71f10f0e88374d88bd5a45f75f68nd** back a result != DECLINED, i.e. it usually returns OK
e5343521634b71f10f0e88374d88bd5a45f75f68nd** which says "OK, module has handled this _stage_" and for #1
e5343521634b71f10f0e88374d88bd5a45f75f68nd** this have not to mean "Ok, the filename is now valid".
e5343521634b71f10f0e88374d88bd5a45f75f68nd** for hook #2,#3,#7,#9:
e5343521634b71f10f0e88374d88bd5a45f75f68nd** all hooks are run, independend of result
e5343521634b71f10f0e88374d88bd5a45f75f68nd** o at the last stage, the core module always
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** - says "HTTP_BAD_REQUEST" if r->filename does not begin with "/"
bdbf46e4950b6f633073f803486962e82c2f086and** - prefix URL with document_root or replaced server_root
bdbf46e4950b6f633073f803486962e82c2f086and** with document_root and sets r->filename
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** - always return a "OK" independed if the file really exists
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* The section for the Configure script:
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * XXX: this needs updating for apache-2.0 configuration method
d177004a74b061338daf7f2603197d673ed76d36kess * MODULE-DEFINITION-START
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * Name: rewrite_module
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * ConfigStart
d3cd98e7839dd1c737c18d42a916ed20860a50e1nd if [ "x$found_dbm" = "x1" ]; then
7e68fce3cbd2246164e045a51ecd77f9f26680ednd echo " enabling DBM support for mod_rewrite"
bdbf46e4950b6f633073f803486962e82c2f086and echo " disabling DBM support for mod_rewrite"
7e68fce3cbd2246164e045a51ecd77f9f26680ednd echo " (perhaps you need to add -ldbm, -lndbm or -lgdbm to EXTRA_LIBS)"
7e68fce3cbd2246164e045a51ecd77f9f26680ednd CFLAGS="$CFLAGS -DNO_DBM_REWRITEMAP"
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * ConfigEnd
d3cd98e7839dd1c737c18d42a916ed20860a50e1nd * MODULE-DEFINITION-END
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* the module (predeclaration) */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* rewritemap int: handler function registry */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* the cache */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* whether proxy module is available or not */
7e68fce3cbd2246164e045a51ecd77f9f26680edndstatic const char *lockname;
3726777f47ac4bba3e21b075905959bbea47e72eerikabelestatic apr_global_mutex_t *rewrite_mapr_lock_acquire = NULL;
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** +-------------------------------------------------------+
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** | configuration directive handling
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** +-------------------------------------------------------+
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** per-server configuration structure handling
7e68fce3cbd2246164e045a51ecd77f9f26680edndstatic void *config_server_create(apr_pool_t *p, server_rec *s)
7e68fce3cbd2246164e045a51ecd77f9f26680ednd a = (rewrite_server_conf *)apr_pcalloc(p, sizeof(rewrite_server_conf));
7e68fce3cbd2246164e045a51ecd77f9f26680ednd a->rewritemaps = apr_array_make(p, 2, sizeof(rewritemap_entry));
7e68fce3cbd2246164e045a51ecd77f9f26680ednd a->rewriteconds = apr_array_make(p, 2, sizeof(rewritecond_entry));
7e68fce3cbd2246164e045a51ecd77f9f26680ednd a->rewriterules = apr_array_make(p, 2, sizeof(rewriterule_entry));
d3cd98e7839dd1c737c18d42a916ed20860a50e1nd return (void *)a;
ba5874d287f4d19d1a336e9195c73de9ab34fa50slivestatic void *config_server_merge(apr_pool_t *p, void *basev, void *overridesv)
66e48875fca2df6669dab4f2690ee36c6913c0ffnd a = (rewrite_server_conf *)apr_pcalloc(p, sizeof(rewrite_server_conf));
3726777f47ac4bba3e21b075905959bbea47e72eerikabele * local directives override
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * and anything else is inherited
3726777f47ac4bba3e21b075905959bbea47e72eerikabele a->rewriteloglevel = overrides->rewriteloglevel != 0
7e68fce3cbd2246164e045a51ecd77f9f26680ednd a->rewritemaps = apr_array_append(p, overrides->rewritemaps,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd a->rewriteconds = apr_array_append(p, overrides->rewriteconds,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd a->rewriterules = apr_array_append(p, overrides->rewriterules,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * local directives override
d3cd98e7839dd1c737c18d42a916ed20860a50e1nd * and anything else gets defaults
f4a6ce7d0d0311e4da2d4df6812263c562a05a3end return (void *)a;
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** per-directory configuration structure handling
8cfbcde8e416fd60132dd4324c42a5098da156cfndstatic void *config_perdir_create(apr_pool_t *p, char *path)
7e68fce3cbd2246164e045a51ecd77f9f26680ednd a = (rewrite_perdir_conf *)apr_pcalloc(p, sizeof(rewrite_perdir_conf));
4930be147adf9e3f6d3ca9313a6524f9bf654b2dnd a->rewriteconds = apr_array_make(p, 2, sizeof(rewritecond_entry));
21041d71aa640dca78abab65ea293171b668bc20nd a->rewriterules = apr_array_make(p, 2, sizeof(rewriterule_entry));
21041d71aa640dca78abab65ea293171b668bc20nd /* make sure it has a trailing slash */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd return (void *)a;
7e68fce3cbd2246164e045a51ecd77f9f26680edndstatic void *config_perdir_merge(apr_pool_t *p, void *basev, void *overridesv)
8cfbcde8e416fd60132dd4324c42a5098da156cfnd a->rewriteconds = apr_array_append(p, overrides->rewriteconds,
8cfbcde8e416fd60132dd4324c42a5098da156cfnd a->rewriterules = apr_array_append(p, overrides->rewriterules,
8cfbcde8e416fd60132dd4324c42a5098da156cfnd return (void *)a;
99e4eb246ec234156eb878835d4e1b4e2f48c499nd** the configuration commands
61d237f7e3a54089a7514227d663fac296d7d8f0bnicholesstatic const char *cmd_rewriteengine(cmd_parms *cmd,
8cfbcde8e416fd60132dd4324c42a5098da156cfnd sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module);
8cfbcde8e416fd60132dd4324c42a5098da156cfnd sconf->state = (flag ? ENGINE_ENABLED : ENGINE_DISABLED);
99e4eb246ec234156eb878835d4e1b4e2f48c499nd else /* is per-directory command */ {
99e4eb246ec234156eb878835d4e1b4e2f48c499nd dconf->state = (flag ? ENGINE_ENABLED : ENGINE_DISABLED);
8cfbcde8e416fd60132dd4324c42a5098da156cfnd const char *err;
8cfbcde8e416fd60132dd4324c42a5098da156cfnd sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module);
7e68fce3cbd2246164e045a51ecd77f9f26680ednd else { /* is per-directory command */
7e68fce3cbd2246164e045a51ecd77f9f26680edndstatic const char *cmd_rewriteoptions_setoption(apr_pool_t *p, int *options,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd const char *name)
7e68fce3cbd2246164e045a51ecd77f9f26680ednd return apr_pstrcat(p, "RewriteOptions: unknown option '",
7e68fce3cbd2246164e045a51ecd77f9f26680edndstatic const char *cmd_rewritelog(cmd_parms *cmd, void *dconf, const char *a1)
7e68fce3cbd2246164e045a51ecd77f9f26680ednd sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module);
65241490e40aa0c831988073eed0633dad10c6f2ndstatic const char *cmd_rewriteloglevel(cmd_parms *cmd, void *dconf, const char *a1)
65241490e40aa0c831988073eed0633dad10c6f2nd sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module);
7e68fce3cbd2246164e045a51ecd77f9f26680edndstatic const char *cmd_rewritemap(cmd_parms *cmd, void *dconf, const char *a1,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd const char *a2)
7e68fce3cbd2246164e045a51ecd77f9f26680ednd sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module);
7e68fce3cbd2246164e045a51ecd77f9f26680ednd newmap->checkfile = apr_pstrcat(cmd->pool, a2+4, NDBM_FILE_SUFFIX, NULL);
7e68fce3cbd2246164e045a51ecd77f9f26680ednd return apr_pstrdup(cmd->pool, "RewriteMap: cannot use NDBM mapfile, "
7e68fce3cbd2246164e045a51ecd77f9f26680ednd "because no NDBM support is compiled in");
7e68fce3cbd2246164e045a51ecd77f9f26680ednd if ((sconf->state == ENGINE_ENABLED) && (newmap->func == NULL)) {
7e68fce3cbd2246164e045a51ecd77f9f26680ednd return apr_pstrcat(cmd->pool, "RewriteMap: internal map not found:",
7e68fce3cbd2246164e045a51ecd77f9f26680ednd if (newmap->checkfile && (sconf->state == ENGINE_ENABLED)
7e68fce3cbd2246164e045a51ecd77f9f26680ednd "RewriteMap: map file not found:",
7e68fce3cbd2246164e045a51ecd77f9f26680edndstatic const char *cmd_rewritelock(cmd_parms *cmd, void *dconf, const char *a1)
7e68fce3cbd2246164e045a51ecd77f9f26680ednd const char *error;
7e68fce3cbd2246164e045a51ecd77f9f26680ednd if ((error = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL)
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* fixup the path, especially for rewritelock_remove() */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd return apr_pstrcat(cmd->pool, "Invalid RewriteLock path ", a1);
7e68fce3cbd2246164e045a51ecd77f9f26680edndstatic const char *cmd_rewritebase(cmd_parms *cmd, void *in_dconf,
66e48875fca2df6669dab4f2690ee36c6913c0ffnd const char *a1)
7e68fce3cbd2246164e045a51ecd77f9f26680ednd return "RewriteBase: only valid in per-directory config files";
65241490e40aa0c831988073eed0633dad10c6f2nd return "RewriteBase: empty URL not allowed";
7e68fce3cbd2246164e045a51ecd77f9f26680ednd return "RewriteBase: argument is not a valid URL";
7e68fce3cbd2246164e045a51ecd77f9f26680edndstatic const char *cmd_rewritecond(cmd_parms *cmd, void *in_dconf,
3726777f47ac4bba3e21b075905959bbea47e72eerikabele const char *in_str)
7e68fce3cbd2246164e045a51ecd77f9f26680ednd const char *err;
7e68fce3cbd2246164e045a51ecd77f9f26680ednd sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module);
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* make a new entry in the internal temporary rewrite rule list */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd else { /* is per-directory command */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* parse the argument line ourself */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd return apr_pstrcat(cmd->pool, "RewriteCond: bad argument line '", str,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* arg1: the input string */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* arg3: optional flags field
7e68fce3cbd2246164e045a51ecd77f9f26680ednd (this have to be first parsed, because we need to
7e68fce3cbd2246164e045a51ecd77f9f26680ednd know if the regex should be compiled with ICASE!) */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd if ((err = cmd_rewritecond_parseflagfield(cmd->pool, newcond,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* arg2: the pattern
7e68fce3cbd2246164e045a51ecd77f9f26680ednd try to compile the regexp to test if is ok */
d3cd98e7839dd1c737c18d42a916ed20860a50e1nd /* now be careful: Under the POSIX regex library
7e68fce3cbd2246164e045a51ecd77f9f26680ednd we can compile the pattern for case insensitive matching,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd under the old V8 library we have to do it self via a hack */
b09970a14a3280b9e4e449dea6e53968fc206731nd rc = ((regexp = ap_pregcomp(cmd->pool, cp, REG_EXTENDED|REG_ICASE))
b09970a14a3280b9e4e449dea6e53968fc206731nd rc = ((regexp = ap_pregcomp(cmd->pool, cp, REG_EXTENDED)) == NULL);
b09970a14a3280b9e4e449dea6e53968fc206731nd "RewriteCond: cannot compile regular expression '",
7e68fce3cbd2246164e045a51ecd77f9f26680edndstatic const char *cmd_rewritecond_parseflagfield(apr_pool_t *p,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd const char *err;
7e68fce3cbd2246164e045a51ecd77f9f26680ednd return "RewriteCond: bad flag delimiters";
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* skip whitespaces */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd for ( ; (*cp == ' ' || *cp == '\t') && *cp != '\0'; cp++)
3726777f47ac4bba3e21b075905959bbea47e72eerikabele for ( ; (*(cp2-1) == ' ' || *(cp2-1) == '\t'); cp2--)
7e68fce3cbd2246164e045a51ecd77f9f26680ednd if ((err = cmd_rewritecond_setflag(p, cfg, key, val)) != NULL) {
7e68fce3cbd2246164e045a51ecd77f9f26680edndstatic const char *cmd_rewritecond_setflag(apr_pool_t *p, rewritecond_entry *cfg,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd return apr_pstrcat(p, "RewriteCond: unknown flag '", key, "'", NULL);
3726777f47ac4bba3e21b075905959bbea47e72eerikabelestatic const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd const char *in_str)
7e68fce3cbd2246164e045a51ecd77f9f26680ednd const char *err;
3726777f47ac4bba3e21b075905959bbea47e72eerikabele sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module);
3726777f47ac4bba3e21b075905959bbea47e72eerikabele /* make a new entry in the internal rewrite rule list */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd else { /* is per-directory command */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* parse the argument line ourself */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd return apr_pstrcat(cmd->pool, "RewriteRule: bad argument line '", str,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* arg3: optional flags field */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd if ((err = cmd_rewriterule_parseflagfield(cmd->pool, newrule,
8fff30d106ca02816827b4bfb01a93995665f54end /* arg1: the pattern
8fff30d106ca02816827b4bfb01a93995665f54end * try to compile the regexp to test if is ok
7e68fce3cbd2246164e045a51ecd77f9f26680ednd if ((regexp = ap_pregcomp(cmd->pool, cp, mode)) == NULL) {
7e68fce3cbd2246164e045a51ecd77f9f26680ednd "RewriteRule: cannot compile regular expression '",
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* arg2: the output string
66e48875fca2df6669dab4f2690ee36c6913c0ffnd * replace the $<N> by \<n> which is needed by the currently
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * used Regular Expression library
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * TODO: Is this still required for PCRE? If not, does it *work* with PCRE?
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* now, if the server or per-dir config holds an
3726777f47ac4bba3e21b075905959bbea47e72eerikabele * array of RewriteCond entries, we take it for us
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * and clear the array
7e68fce3cbd2246164e045a51ecd77f9f26680ednd else { /* is per-directory command */
7e68fce3cbd2246164e045a51ecd77f9f26680edndstatic const char *cmd_rewriterule_parseflagfield(apr_pool_t *p,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd const char *err;
7e68fce3cbd2246164e045a51ecd77f9f26680ednd return "RewriteRule: bad flag delimiters";
3726777f47ac4bba3e21b075905959bbea47e72eerikabele str[strlen(str)-1] = ','; /* for simpler parsing */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* skip whitespaces */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd for ( ; (*cp == ' ' || *cp == '\t') && *cp != '\0'; cp++)
7e68fce3cbd2246164e045a51ecd77f9f26680ednd if ((err = cmd_rewriterule_setflag(p, cfg, key, val)) != NULL) {
fd46b0fed4351924170b4db5859dc35b771ee16dndstatic const char *cmd_rewriterule_setflag(apr_pool_t *p, rewriterule_entry *cfg,
fd46b0fed4351924170b4db5859dc35b771ee16dnd return "RewriteRule: invalid HTTP response code "
fd46b0fed4351924170b4db5859dc35b771ee16dnd "for flag 'R'";
7e68fce3cbd2246164e045a51ecd77f9f26680ednd for (i = 0; (cfg->env[i] != NULL) && (i < MAX_ENV_FLAGS); i++)
acc36ab93565d2880447d535da6ca6e5feac7a70nd return "RewriteRule: too many environment flags 'E'";
bdbf46e4950b6f633073f803486962e82c2f086and return apr_pstrcat(p, "RewriteRule: unknown flag '", key, "'", NULL);
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** Global Module Initialization
7e68fce3cbd2246164e045a51ecd77f9f26680ednd APR_OPTIONAL_FN_TYPE(ap_register_rewrite_mapfunc) *map_pfn_register;
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* register int: rewritemap handlers */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd map_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_rewrite_mapfunc);
7e68fce3cbd2246164e045a51ecd77f9f26680ednd apr_pool_userdata_get(&data, userdata_key, s->process->pool);
3c185a8e451791a511a1ad5e36ee0fd863f47e6ckess /* check if proxy module is available */
3c185a8e451791a511a1ad5e36ee0fd863f47e6ckess proxy_available = (ap_find_linked_module("mod_proxy.c") != NULL);
3c185a8e451791a511a1ad5e36ee0fd863f47e6ckess /* create the rewriting lockfiles in the parent */
3c185a8e451791a511a1ad5e36ee0fd863f47e6ckess if ((rv = apr_global_mutex_create(&rewrite_log_lock, NULL,
3c185a8e451791a511a1ad5e36ee0fd863f47e6ckess "mod_rewrite: could not create rewrite_log_lock");
72615c84d57d1f03b8ca2bc8aa3d2e82d3b30eb0slive "mod_rewrite: Could not set permissions on "
72615c84d57d1f03b8ca2bc8aa3d2e82d3b30eb0slive "rewrite_log_lock; check User and Group directives");
72615c84d57d1f03b8ca2bc8aa3d2e82d3b30eb0slive apr_pool_cleanup_register(p, (void *)s, rewritelock_remove, apr_pool_cleanup_null);
72615c84d57d1f03b8ca2bc8aa3d2e82d3b30eb0slive /* step through the servers and
72615c84d57d1f03b8ca2bc8aa3d2e82d3b30eb0slive * - open each rewriting logfile
72615c84d57d1f03b8ca2bc8aa3d2e82d3b30eb0slive * - open the RewriteMap prg:xxx programs
3c185a8e451791a511a1ad5e36ee0fd863f47e6ckess for (; s; s = s->next) {
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** Per-Child Module Initialization
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** [called after a child process is spawned]
7e68fce3cbd2246164e045a51ecd77f9f26680ednd rv = apr_global_mutex_child_init(&rewrite_mapr_lock_acquire,
ab3f278fbf670b521b2e7fd6fe93732059e2bf24nd "mod_rewrite: could not init rewrite_mapr_lock_acquire "
ab3f278fbf670b521b2e7fd6fe93732059e2bf24nd "in child");
ab3f278fbf670b521b2e7fd6fe93732059e2bf24nd /* create the lookup cache */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd** +-------------------------------------------------------+
ab3f278fbf670b521b2e7fd6fe93732059e2bf24nd** | runtime hooks
ab3f278fbf670b521b2e7fd6fe93732059e2bf24nd** +-------------------------------------------------------+
ab3f278fbf670b521b2e7fd6fe93732059e2bf24nd** URI-to-filename hook
ab3f278fbf670b521b2e7fd6fe93732059e2bf24nd** [used for the rewriting engine triggered by
ab3f278fbf670b521b2e7fd6fe93732059e2bf24nd** the per-server 'RewriteRule' directives]
ab3f278fbf670b521b2e7fd6fe93732059e2bf24nd const char *var;
ab3f278fbf670b521b2e7fd6fe93732059e2bf24nd const char *thisserver;
7e68fce3cbd2246164e045a51ecd77f9f26680ednd const char *thisurl;
7e68fce3cbd2246164e045a51ecd77f9f26680ednd const char *ccp;
7e68fce3cbd2246164e045a51ecd77f9f26680ednd unsigned int port;
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * retrieve the config structures
7e68fce3cbd2246164e045a51ecd77f9f26680ednd conf = ap_get_module_config(r->server->module_config, &rewrite_module);
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * only do something under runtime if the engine is really enabled,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * else return immediately!
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * check for the ugly API case of a virtual host section where no
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * mod_rewrite directives exists. In this situation we became no chance
4e5d76cd516a36223b6e73a8000c879a5675e436nd * by the API to setup our default per-server config so we have to
4e5d76cd516a36223b6e73a8000c879a5675e436nd * on-the-fly assume we have the default config. But because the default
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * config has a disabled rewriting engine we are lucky because can
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * just stop operating now.
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * add the SCRIPT_URL variable to the env. this is a bit complicated
8a72c24379e10c3f3d0dfe352bf15e45ee65c179nd * due to the fact that apache uses subrequests and internal redirects
7e68fce3cbd2246164e045a51ecd77f9f26680ednd var = apr_pstrcat(r->pool, "REDIRECT_", ENVVAR_SCRIPT_URL, NULL);
7e68fce3cbd2246164e045a51ecd77f9f26680ednd apr_table_setn(r->subprocess_env, ENVVAR_SCRIPT_URL, r->uri);
4e5d76cd516a36223b6e73a8000c879a5675e436nd apr_table_setn(r->subprocess_env, ENVVAR_SCRIPT_URL, var);
7e68fce3cbd2246164e045a51ecd77f9f26680ednd var = apr_table_get(r->main->subprocess_env, ENVVAR_SCRIPT_URL);
7e68fce3cbd2246164e045a51ecd77f9f26680ednd apr_table_setn(r->subprocess_env, ENVVAR_SCRIPT_URL, var);
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * create the SCRIPT_URI variable for the env
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* add the canonical URI of this URL */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd thisurl = apr_table_get(r->subprocess_env, ENVVAR_SCRIPT_URL);
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* set the variable */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd var = apr_pstrcat(r->pool, ap_http_method(r), "://", thisserver, thisport,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd apr_table_setn(r->subprocess_env, ENVVAR_SCRIPT_URI, var);
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* if filename was not initially set,
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * we start with the requested URI
7e68fce3cbd2246164e045a51ecd77f9f26680ednd rewritelog(r, 2, "init rewrite engine with requested uri %s",
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * now apply the rules ...
7e68fce3cbd2246164e045a51ecd77f9f26680ednd rulestatus = apply_rewrite_list(r, conf->rewriterules, NULL);
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* it should be go on as an internal proxy request */
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* check if the proxy module is enabled, so
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * we can actually use it!
7e68fce3cbd2246164e045a51ecd77f9f26680ednd "attempt to make remote request from mod_rewrite "
7e68fce3cbd2246164e045a51ecd77f9f26680ednd /* make sure the QUERY_STRING and
7e68fce3cbd2246164e045a51ecd77f9f26680ednd * PATH_INFO parts get incorporated
04ff03c2d7e0ff45ee181eb1fa5bf7649ffcf6bfslive /* see proxy_http:proxy_http_canon() */
04ff03c2d7e0ff45ee181eb1fa5bf7649ffcf6bfslive /* now make sure the request gets handled by the proxy handler */
r->filename);
return OK;
char *args;
n = r->status;
return HTTP_FORBIDDEN;
return HTTP_GONE;
return DECLINED;
#if APR_HAS_USER
return HTTP_BAD_REQUEST;
(r->filename +
r->filename);
return OK;
return DECLINED;
if (t == NULL) {
return DECLINED;
r->filename, t);
ap_set_content_type(r, t);
return OK;
char *cp;
char *cp2;
const char *ccp;
char *prefix;
int rulestatus;
char *ofilename;
return DECLINED;
return DECLINED;
return DECLINED;
return HTTP_FORBIDDEN;
return DECLINED;
if (rulestatus) {
return OK;
char *args;
n = r->status;
return HTTP_FORBIDDEN;
return HTTP_GONE;
return HTTP_BAD_REQUEST;
return OK;
r->filename+l);
return OK;
return DECLINED;
return DECLINED;
return DECLINED;
return OK;
char *perdir)
int changed;
int rc;
changed = 0;
loop:
p = &entries[i];
if (rc) {
goto loop;
if (p->skip > 0) {
s = p->skip;
p = &entries[i];
p = &entries[i];
return changed;
char *perdir)
char *uri;
char *output;
const char *vary;
int prefixstrip;
int failed;
int rc;
prefixstrip = 0;
sizeof(regmatch));
failed = 0;
c = &conds[i];
if (rc == 0) {
c = &conds[i];
if (rc == 0) {
if (failed) {
p->forced_mimetype);
reduce_uri(r);
r->filename);
p->forced_mimetype);
int rc;
rc = 0;
#if !defined(OS2)
sizeof(regmatch));
return rc;
inp++;
goto skip;
char *endp;
goto skip;
goto skip;
if (result) {
char *var;
span = 0;
skip:
space--;
char *olduri;
if (q != NULL) {
if (qsappend) {
r->filename);
char *cp;
unsigned short port;
char *portp;
char *hostp;
char *url;
char *olduri;
apr_size_t l;
c = *cp;
*cp = c;
const char *thisserver;
char *thisport;
int port;
#if APR_HAS_USER
char *newuri;
char *homedir;
return newuri;
rewritemap_entry *s;
char *value;
s = &entries[i];
return NULL;
if ((value =
return value;
return NULL;
#ifndef NO_DBM_REWRITEMAP
return NULL;
if ((value =
return value;
return NULL;
return NULL;
if ((value =
return value;
return value;
return NULL;
if ((value =
return NULL;
return value;
return NULL;
char *cpT;
char *curkey;
char *curval;
return NULL;
if (skip == 0)
++cpT;
if (skip == 0)
return value;
#ifndef NO_DBM_REWRITEMAP
return value;
#ifndef NO_WRITEV
return NULL;
if (rewrite_mapr_lock_acquire) {
#ifdef NO_WRITEV
buf[i++] = c;
if (rewrite_mapr_lock_acquire) {
return NULL;
cp++) {
return value;
cp++) {
return value;
char *value;
return value;
char *value;
return value;
static int rewrite_rand_init_done = 0;
static void rewrite_rand_init(void)
if (!rewrite_rand_init_done) {
static int rewrite_rand(int l, int h)
char *buf;
return value;
return buf;
const char *fname;
if (!fname) {
!= APR_SUCCESS) {
char *str1;
const char *type;
char *ruser;
const char *rhost;
(unsigned long)(r->server), (unsigned long)r,
return APR_SUCCESS;
APR_LOCK_DEFAULT, p);
return rc;
return rc;
return APR_SUCCESS;
return APR_SUCCESS;
return APR_SUCCESS;
return rc;
return APR_SUCCESS;
char **argv;
!= APR_SUCCESS) ||
procattr, p);
if (fpin) {
if (fpout) {
if (fperr) {
return (rc);
const char *result;
/* XXX: wow this has gotta be slow if you actually use it for a lot, recalculates exploded time for each variable */
return (char *)result; \
return NULL;
cache *c;
return NULL;
#if APR_HAS_THREADS
return NULL;
return NULL;
return NULL;
return n % CACHE_TLB_ROWS;
char *key)
for (i=0; i < CACHE_TLB_COLS; ++i) {
return NULL;
return &elt[j];
return NULL;
cacheentry *e)
cachelist *l;
cacheentry *e;
cachetlbentry *t;
int found_list;
#if APR_HAS_THREADS
found_list = 0;
if (e != NULL) {
#if APR_HAS_THREADS
#if APR_HAS_THREADS
if (!found_list) {
sizeof(cachetlbentry));
for (i=0; i<CACHE_TLB_ROWS; ++i) {
for (j=0; j<CACHE_TLB_COLS; ++j)
#if APR_HAS_THREADS
#if APR_HAS_THREADS
cachelist *l;
cacheentry *e;
#if APR_HAS_THREADS
if (e != NULL) {
#if APR_HAS_THREADS
#if APR_HAS_THREADS
#if APR_HAS_THREADS
return NULL;
const char *subst)
char *output;
return output;
char *cp;
int isquoted;
cp++; \
isquoted = 0; \
cp++; \
cp++; \
char *cp;
char *cp;
for (i = 0; i < n1; i++) {
int depth;
else if (*s == left) {
++depth;
return NULL;
int depth;
return NULL;
else if (*s == left) {
++depth;
return NULL;
{ NULL }