39N/A<!-- Documentation for the mod_rewrite Apache module --> 39N/A<
title>Apache module mod_rewrite</
title>
39N/A<
h1>Module mod_rewrite (Version 3.0)</
h1>
39N/A1.2 and later. It provides a rule-based rewriting engine to rewrite requested
39N/AURLs on the fly. <
code>mod_rewrite</
code> is not compiled into the server by
39N/Adefault. To use <
code>mod_rewrite</
code> you have to enable the following line
39N/Ain the server build Configuration file:
39N/AThis module uses a rule-based rewriting engine (based on a
926N/Aregular-expression parser) to rewrite requested URLs on the fly.
342N/AIt supports an unlimited number of additional rule conditions (which can
1386N/Aoperate on a lot of variables, including HTTP headers) for granular
838N/Amatching and external database lookups (either via plain text
956N/Atables, DBM hash files or external processes) for advanced URL
1066N/AIt operates on the full URLs (including the PATH_INFO part) both in
1352N/Acan generate QUERY_STRING parts on result. The rewritten result can lead to internal sub-processing, external request redirection or to internal proxy throughput.
39N/AThe latest version can be found on<
br>
205N/ACopyright © 1996,1997 <
b>The Apache Group</
b>, All rights reserved.<
br>
39N/ACopyright © 1996,1997 <
i>Ralf S. Engelschall</
i>, All rights reserved.
39N/AWritten for <
b>The Apache Group</
b> by
39N/A <
i>Ralf S. Engelschall</
i><
br>
39N/A <
a href="mailto:rse@engelschall.com"><
tt>rse@engelschall.com</
tt></
a><
br>
39N/A <
li><
a href="#RewriteEngine">RewriteEngine</
a>
39N/A <
li><
a href="#RewriteOptions">RewriteOptions</
a>
39N/A <
li><
a href="#RewriteLog">RewriteLog</
a>
39N/A <
li><
a href="#RewriteLogLevel">RewriteLogLevel</
a>
39N/A <
li><
a href="#RewriteMap">RewriteMap</
a>
39N/A <
li><
a href="#RewriteBase">RewriteBase</
a>
39N/A <
li><
a href="#RewriteCond">RewriteCond</
a>
48N/A <
li><
a href="#RewriteRule">RewriteRule</
a>
39N/A<
a name="Configuration">
39N/A<
h1>Configuration Directives</
h1>
838N/A<
a name="RewriteEngine"><
h3>RewriteEngine</
h3></
a>
838N/A<
strong>Syntax:</
strong> <
code>RewriteEngine</
code> {<
code>on,off</
code>}<
br>
39N/A<
strong>Default:</
strong> <
strong><
code>RewriteEngine off</
code></
strong><
br>
39N/A<
strong>Context:</
strong> server config, virtual host, per-directory config<
br>
1431N/AThe <
tt>RewriteEngine</
tt> directive enables or disables the
39N/Aruntime rewriting engine. If it is set to <
code>off</
code> this module does
227N/Ano runtime processing at all. It does not even update the <
tt>SCRIPT_URx</
tt>
1352N/AUse this directive to disable the module instead of commenting out
1352N/Aall <
tt>RewriteRule</
tt> directives!
315N/A<
a name="RewriteOptions"><
h3>RewriteOptions</
h3></
a>
1352N/A<
strong>Syntax:</
strong> <
code>RewriteOptions</
code> <
em>Option</
em> ...<
br>
429N/A<
strong>Default:</
strong> -<
em>None</
em>-<
br>
1352N/A<
strong>Context:</
strong> server config, virtual host, per-directory config<
br>
926N/AThe <
tt>RewriteOption</
tt> directive sets some special options for the
926N/Acurrent per-server or per-directory configuration. The <
em>Option</
em>
203N/Astrings can be one of the following:
203N/A<
li>'<
strong><
code>inherit</
code></
strong>'<
br>
1045N/A This forces the current configuration to inherit the configuration of the
1045N/A parent. In per-virtual-server context this means that the maps,
72N/A conditions and rules of the main server gets inherited. In per-directory
72N/A context this means that conditions and rules of the parent directory's
59N/A <
tt>.htaccess</
tt> configuration gets inherited.
1045N/A<
a name="RewriteLog"><
h3>RewriteLog</
h3></
a>
1045N/A<
strong>Syntax:</
strong> <
code>RewriteLog</
code> <
em>Filename</
em><
br>
72N/A<
strong>Default:</
strong> -<
em>None</
em>-<
br>
72N/A<
strong>Context:</
strong> server config, virtual host<
br>
72N/AThe <
tt>RewriteLog</
tt> directive sets the name of the file to which the
72N/Aserver logs any rewriting actions it performs. If the name does not begin
838N/Awith a slash ('<
tt>/</
tt>') then it is assumed to be relative to the
72N/A<
em>Server Root</
em>. The directive should occur only once per server
59N/A<
table width=70%
border=2 bgcolor="#c0c0e0" cellspacing=0 cellpadding=10>
72N/ATo disable the logging of rewriting actions it is not recommended
307N/Ato set <
em>Filename</
em>
307N/Ato <
code>/
dev/
null</
code>, because although the rewriting engine does
307N/Anot create output to a logfile it still creates the logfile
72N/Aoutput internally. <
b>This will slow down the server with no advantage to the
72N/ATo disable logging either remove or comment out the
237N/A<
tt>RewriteLog</
tt> directive or use <
tt>RewriteLogLevel 0</
tt>!
72N/A<
table width=70%
border=2 bgcolor="#c0c0e0" cellspacing=0 cellpadding=10>
59N/ASECURITY: See the <
a 72N/ATips</
a> document for details on why your security could be compromised if the
72N/Adirectory where logfiles are stored is writable by anyone other than the user
926N/A<
a name="RewriteLogLevel"><
h3>RewriteLogLevel</
h3></
a>
838N/A<
strong>Syntax:</
strong> <
code>RewriteLogLevel</
code> <
em>Level</
em><
br>
926N/A<
strong>Default:</
strong> <
strong><
code>RewriteLogLevel 0</
code></
strong><
br>
926N/A<
strong>Context:</
strong> server config, virtual host<
br>
838N/AThe <
tt>RewriteLogLevel</
tt> directive set the verbosity level of the rewriting
838N/Alogfile. The default level 0 means no logging, while 9 or more means
838N/Athat practically all actions are logged.
838N/ATo disable the logging of rewriting actions simply set <
em>Level</
em> to 0.
838N/AThis disables all rewrite action logs.
838N/A<
table width=70%
border=2 bgcolor="#c0c0e0" cellspacing=0 cellpadding=10>
838N/A<
b>Notice:</
b> Using a high value for <
i>Level</
i> will slow down your Apache
838N/Aserver dramatically! Use the rewriting logfile only for debugging or at least
838N/Aat <
em>Level</
em> not greater than 2!
315N/A<
a name="RewriteMap"><
h3>RewriteMap</
h3></
a>
838N/A<
strong>Syntax:</
strong> <
code>RewriteMap</
code> <
em>Mapname</
em> <
code>{txt,dbm,prg}:</
code><
em>Filename</
em><
br>
203N/A<
strong>Default:</
strong> not used per default<
br>
838N/A<
strong>Context:</
strong> server config, virtual host<
br>
48N/AThe <
tt>RewriteMap</
tt> directive defines an external <
em>Rewriting Map</
em>
48N/Awhich can be used inside rule substitution strings by the mapping-functions
48N/AThe <
a name="mapfunc"><
em>Mapname</
em></
a> is the name of the map and will
203N/Abe used to specify a mapping-function for the substitution strings of a
72N/A<
blockquote><
strong>
181N/A<
code>${</
code> <
em>Mapname</
em> <
code>:</
code> <
em>LookupKey</
em>
46N/A<
code>|</
code> <
em>DefaultValue</
em> <
code>}</
code>
46N/AWhen such a directive occurs the map <
em>Mapname</
em>
838N/Ais consulted and the key <
em>LookupKey</
em> is looked-up. If the key is
838N/Afound, the map-function directive is substituted by <
em>SubstValue</
em>. If
838N/Athe key is not found then it is substituted by <
em>DefaultValue</
em>.
838N/AThe <
em>Filename</
em> must be a valid Unix filepath, containing one
838N/Aof the following formats:
926N/A<
li><
b>Plain Text Format</
b>
838N/A This is a ASCII file which contains either blank lines, comment lines
926N/A (starting with a '#' character) or
838N/A <
em>MatchingKey</
em> <
em>SubstValue</
em>
926N/A pairs - one per line. You can create such files either manually,
926N/A using your favorite editor, or by using the programs
615N/A <
tt>mapcollect</
tt> and <
tt>mapmerge</
tt> from the <
tt>support</
tt>
615N/A directory of the <
b>mod_rewrite</
b> distribution.
615N/A To declare such a map prefix, <
em>Filename</
em> with a <
code>txt:</
code>
615N/A string as in the following example:
615N/A<
table border=2 cellspacing=1 cellpadding=5 bgcolor="#d0d0d0">
838N/A<
table border=2 cellspacing=1 cellpadding=5 bgcolor="#d0d0d0">
113N/A<
li><
b>DBM Hashfile Format</
b>
113N/A This is a binary NDBM format file containing the
113N/A same contents as the <
em>Plain Text Format</
b> files. You can create
111N/A such a file with any NDBM tool or with the <
tt>dbmmanage</
tt> program
104N/A from the <
tt>support</
tt> directory of the Apache distribution.
39N/A To declare such a map prefix <
em>Filename</
em> with a <
code>dbm:</
code>
146N/A This is a Unix executable, not a lookup file. To create it you can use
1432N/A the language of your choice, but the result has to be a run-able Unix
1432N/A binary (
i.e. either object-code or a script with the
1432N/A This program gets started once at startup of the Apache servers and then
1432N/A communicates with the rewriting engine over its <
tt>stdin</
tt> and
51N/A <
tt>stdout</
tt> file-handles. For each map-function lookup it will
1432N/A receive the key to lookup as a newline-terminated string on
1432N/A <
tt>stdin</
tt>. It then has to give back the looked-up value as a
1432N/A newline-terminated string on <
tt>stdout</
tt> or the four-character string
51N/A ``<
tt>NULL</
tt>'' if it fails (
i.e. there is no corresponding value
1500N/A for the given key). A trivial program which will implement a 1:1 map
591N/A<
table border=2 cellspacing=1 cellpadding=5 bgcolor="#d0d0d0">
1500N/A # or lookups should occur...
1500N/A <
b>But be very careful:</
b><
br>
1500N/A <
li>``<
i>Keep the program simple, stupid</
i>'' (KISS), because
1500N/A if this program hangs it will lead to a hang of the Apache server
1500N/A <
li>Avoid one common mistake: never do buffered I/O on <
tt>stdout</
tt>!
1500N/A This will cause a deadloop! Hence the ``<
tt>$|=1</
tt>'' in the above
1500N/A To declare such a map prefix <
em>Filename</
em> with a <
code>prg:</
code>
1500N/AThe <
tt>RewriteMap</
tt> directive can occur more than once. For each
926N/Amapping-function use one <
tt>RewriteMap</
tt> directive to declare its
1500N/Arewriting mapfile. While you cannot <
b>declare</
b> a map in per-directory
1500N/Acontext it is of course possible to <
b>use</
b> this map in per-directory
1500N/A<
table width=70%
border=2 bgcolor="#c0c0e0" cellspacing=0 cellpadding=10>
1500N/AFor plain text and DBM format files the looked-up keys are cached in-core
1500N/Auntil the <
tt>mtime</
tt> of the mapfile changes or the server does a
1500N/Arestart. This way you can have map-functions in rules which are used
123N/Afor <
b>every</
b> request. This is no problem, because the external lookup
1500N/A<
a name="RewriteBase"><
h3>RewriteBase</
h3></
a>
1500N/A<
strong>Syntax:</
strong> <
code>RewriteBase</
code> <
em>BaseURL</
em><
br>
1500N/A<
strong>Default:</
strong> <
em>default is the physical directory path</
em><
br>
1500N/A<
strong>Context:</
strong> per-directory config<
br>
1500N/AThe <
tt>RewriteBase</
tt> directive explicitly sets the base URL for
1500N/Aper-directory rewrites. As you will see below, <
tt>RewriteRule</
tt> can be
39N/Aused in per-directory config files (<
tt>.htaccess</
tt>). There it will act
1500N/Alocally,
i.e. the local directory prefix is stripped at this stage of
1500N/Aprocessing and your rewriting rules act only on the remainder. At the end
838N/AWhen a substitution occurs for a new URL, this module has to
1500N/Are-inject the URL into the server processing. To be able to do this it needs
1500N/Ato know what the corresponding URL-prefix or URL-base is. By default this
1500N/Aprefix is the corresponding filepath itself. <
b>But at most websites URLs are
1500N/A<
b>NOT</
b> directly related to physical filename paths, so this assumption
1500N/Awill be usually be wrong!</
b> There you have to use the <
tt>RewriteBase</
tt>
1500N/Adirective to specify the correct URL-prefix.
1500N/A<
table width=70%
border=2 bgcolor="#c0c0e0" cellspacing=0 cellpadding=10>
1500N/ASo, if your webserver's URLs are <
b>not</
b> directly
1500N/Arelated to physical file paths, you have to use <
tt>RewriteBase</
tt> in every
1500N/A<
tt>.htaccess</
tt> files where you want to use <
tt>RewriteRule</
tt>
956N/A Assume the following per-directory config file:
956N/A<
table border=2 cellspacing=1 cellpadding=5 bgcolor="#d0d0d0">
1007N/A# let the server know that we are reached via /xyz and not
1100N/A<
table width=70%
border=2 bgcolor="#c0c0e0" cellspacing=0 cellpadding=10>
1100N/A<
b>For the Apache hackers:</
b><
br>
1100N/AThe following list gives detailed information about the internal
941N/AThis seems very complicated but is the correct Apache internal processing,
941N/Abecause the per-directory rewriting comes too late in the process. So,
941N/Awhen it occurs the (rewritten) request has to be re-injected into the Apache
429N/Akernel! BUT: While this seems like a serious overhead, it really isn't, because
941N/Athis re-injection happens fully internal to the Apache server and the same
941N/Aprocedure is used by many other operations inside Apache. So, you can be
941N/Asure the design and implementation is correct.
1007N/A<
a name="RewriteCond"><
h3>RewriteCond</
h3></
a>
1007N/A<
strong>Syntax:</
strong> <
code>RewriteCond</
code> <
em>TestString</
em> <
em>CondPattern</
em><
br>
1007N/A<
strong>Default:</
strong> -<
em>None</
em>-<
br>
1007N/A<
strong>Context:</
strong> server config, virtual host, per-directory config<
br>
1007N/AThe <
tt>RewriteCond</
tt> directive defines a rule condition. Precede a
1007N/A<
tt>RewriteRule</
tt> directive with one ore more <
t>RewriteCond</
tt>
1007N/AThe following rewriting rule is only used if its pattern matches the current
1007N/Astate of the URI <
b>AND</
b> if these additional conditions apply, too.
1007N/A<
em>TestString</
em> is a string which contains server-variables of the form
1007N/A<
tt>%{</
tt> <
em>NAME_OF_VARIABLE</
em> <
tt>}</
tt>
1007N/Awhere <
em>NAME_OF_VARIABLE</
em> can be a string
1007N/A<
table bgcolor="#d0d0d0" cellspacing=0 cellpadding=5>
1352N/A<
b>connection & request:</
b><
p>
1461N/A<
table width=70%
border=2 bgcolor="#c0c0e0" cellspacing=0 cellpadding=10>
1461N/AThese variables all correspond to the similar named HTTP MIME-headers, C
1461N/Avariables of the Apache server or <
tt>struct tm</
tt> fields of the Unix
1044N/A<
li>The variables SCRIPT_FILENAME and REQUEST_FILENAME contain the same
1044N/Avalue,
i.e. the value of the <
tt>filename</
tt> field of the internal
1044N/A<
tt>request_rec</
tt> structure of the Apache server. The first name is just the
1044N/Acommonly known CGI variable name while the second is the consistent
1044N/Acounterpart to REQUEST_URI (which contains the value of the <
tt>uri</
tt>
1044N/Afield of <
tt>request_rec</
tt>).
1044N/A<
li>There is the special format: <
tt>%{ENV:variable}</
tt> where
1044N/A<
i>variable</
i> can be any environment variable. This is looked-up via
1044N/Ainternal Apache structures and (if not found there) via <
tt>getenv()</
tt> from
838N/A<
li>There is the special format: <
tt>%{HTTP:header}</
tt> where
205N/A<
i>header</
i> can be any HTTP MIME-header name. This is looked-up
296N/Afrom the HTTP request. Example: <
tt>%{HTTP:Proxy-Connection}</
tt>
296N/Ais the value of the HTTP header ``<
tt>Proxy-Connection:</
tt>''.
296N/A<
li>There is the special format: <
tt>%{LA-U:url}</
tt>
296N/Afor look-aheads like <
tt>-U</
tt>. This performans a internal sub-request to
296N/Alook-ahead for the final value of <
i>url</
i>.
296N/A<
li>There is the special format: <
tt>%{LA-F:file}</
tt>
1461N/Afor look-aheads like <
tt>-F</
tt>. This performans a internal sub-request to
296N/Alook-ahead for the final value of <
i>file</
i>.
48N/A<
em>CondPattern</
em> is the condition pattern,
i.e. a regular expression
956N/Awhich gets applied to the current instance of the <
em>TestString</
em>,
i.e. 956N/A<
em>TestString</
em> gets evaluated and then matched against
956N/A<
b>Remember:</
b> <
em>CondPattern</
em> is a standard
956N/A<
em>Extended Regular Expression</
em> with some additions:
1386N/A<
li>You can precede the pattern string with a '<
tt>!</
tt>' character
1386N/A(exclamation mark) to specify a <
b>non</
b>-matching pattern.
956N/AThere are some special variants of <
em>CondPatterns</
em>. Instead of real
1352N/Aregular expression strings you can also use one of the following:
956N/A<
li>'<
b>-d</
b>' (is <
b>d</
b>irectory)<
br>
956N/ATreats the <
i>TestString</
i> as a pathname and
956N/Atests if it exists and is a directory.
956N/A<
li>'<
b>-f</
b>' (is regular <
b>f</
b>ile)<
br>
1037N/ATreats the <
i>TestString</
i> as a pathname and
1037N/Atests if it exists and is a regular file.
956N/A<
li>'<
b>-s</
b>' (is regular file with <
b>s</
b>ize)<
br>
956N/ATreats the <
i>TestString</
i> as a pathname and
956N/Atests if it exists and is a regular file with size greater then zero.
956N/A<
li>'<
b>-l</
b>' (is symbolic <
b>l</
b>ink)<
br>
956N/ATreats the <
i>TestString</
i> as a pathname and
1376N/Atests if it exists and is a symbolic link.
956N/A<
li>'<
b>-F</
b>' (is existing file via subrequest)<
br>
956N/AChecks if <
i>TestString</
i> is a valid file and accessible via all the
956N/Aserver's currently-configured access controls for that path. This uses an
956N/Ainternal subrequest to determine the check, so use it with care because it
956N/Adecreases your servers performance!
967N/A<
li>'<
b>-U</
b>' (is existing URL via subrequest)<
br>
967N/AChecks if <
i>TestString</
i> is a valid URL and accessible via all the server's
967N/Acurrently-configured access controls for that path. This uses an internal
956N/Asubrequest to determine the check, so use it with care because it decreases
956N/Ayour servers performance!
956N/ANotice: All of these tests can also be prefixed by a not ('!') character
956N/Ato negate their meaning.
956N/AAdditionally you can set special flags for <
em>CondPattern</
em> by appending
967N/A<
code>[</
code><
em>flags</
em><
code>]</
code>
956N/Aas the third argument to the <
tt>RewriteCond</
tt> directive. <
em>Flags</
em>
956N/Ais a comma-separated list of the following flags:
956N/A<
li>'<
strong><
code>nocase|NC</
code></
strong>' (<
b>n</
b>o <
b>c</
b>ase)<
br>
956N/A This makes the condition test case-insensitive,
i.e. there is
956N/A no difference between 'A-Z' and 'a-z' both in the expanded
956N/A <
em>TestString</
em> and the <
em>CondPattern</
em>.
967N/A<
li>'<
strong><
code>ornext|OR</
code></
strong>' (<
b>or</
b> next condition)<
br>
967N/A Use this to combine rule conditions with a local OR instead of the
967N/A implicit AND. Typical example:
967N/ARewriteCond %{REMOTE_HOST} ^host1.* [OR]
967N/ARewriteCond %{REMOTE_HOST} ^host2.* [OR]
967N/ARewriteCond %{REMOTE_HOST} ^host3.*
967N/ARewriteRule
...some special stuff for any of these hosts...
956N/A Without this flag you had to write down the
cond/
rule three times.
956N/ATo rewrite the Homepage of a site according to the ``<
tt>User-Agent:</
tt>''
956N/Aheader of the request, you can use the following:
967N/ARewriteCond %{HTTP_USER_AGENT} ^Mozilla.*
956N/ARewriteCond %{HTTP_USER_AGENT} ^Lynx.*
956N/AInterpretation: If you use Netscape Navigator as your browser (which identifies
956N/Aitself as 'Mozilla'), then you get the max homepage, which includes
956N/AFrames, etc. If you use the Lynx browser (which is Terminal-based), then you
956N/Aget the min homepage, which contains no images, no tables, etc. If you
956N/Ause any other browser you get the standard homepage.
1386N/A<
a name="RewriteRule"><
h3>RewriteRule</
h3></
a>
1386N/A<
strong>Syntax:</
strong> <
code>RewriteRule</
code> <
em>Pattern</
em> <
em>Substitution</
em><
br>
1386N/A<
strong>Default:</
strong> -<
em>None</
em>-<
br>
1386N/A<
strong>Context:</
strong> server config, virtual host, per-directory config<
br>
956N/AThe <
tt>RewriteRule</
tt> directive is the real rewriting workhorse. The
956N/Adirective can occur more than once. Each directive then defines one single
1386N/Arewriting rule. The <
b>definition order</
b> of these rules is
1386N/A<
b>important</
b>, because this order is used when applying the rules at
1386N/A<
a name="patterns"><
em>Pattern</
em></
a> can be (for Apache
1.1.x a System
1386N/AV8 and for Apache
1.2.x a POSIX) <
a name="regexp">regular expression</
a>
956N/Awhich gets applied to the current URL. Here ``current'' means the value of the
956N/AURL when this rule gets applied. This may not be the original requested
956N/AURL, because there could be any number of rules before which already matched
956N/Aand made alterations to it.
1386N/ASome hints about the syntax of regular expressions:
1352N/A<
table bgcolor="#d0d0d0" cellspacing=0 cellpadding=5>
956N/A<
strong><
code>^</
code></
strong> Start of line
956N/A<
strong><
code>$</
code></
strong> End of line
956N/A<
strong><
code>.</
code></
strong> Any single character
956N/A<
strong><
code>[</
code></
strong>chars<
strong><
code>]</
code></
strong> One of chars
956N/A<
strong><
code>[^</
code></
strong>chars<
strong><
code>]</
code></
strong> None of chars
956N/A<
strong><
code>?</
code></
strong> 0 or 1 of the preceding char
956N/A<
strong><
code>*</
code></
strong> 0 or N of the preceding char
956N/A<
strong><
code>+</
code></
strong> 1 or N of the preceding char
956N/A<
strong><
code>\</
code></
strong>char escape that specific char
956N/A (
e.g. for specifying the chars "<
code>.[]()</
code>" etc.)
956N/A<
strong><
code>(</
code></
strong>string<
strong><
code>)</
code></
strong> Grouping of chars (the <
b>N</
b>th group can be used on the RHS with <
code>$</
code><
b>N</
b>)
956N/AAdditionally the NOT character ('<
tt>!</
tt>') is a possible pattern
956N/Aprefix. This gives you the ability to negate a pattern; to say, for instance: ``<
i>if
956N/Athe current URL does <
b>NOT</
b> match to this pattern</
i>''. This can be used
956N/Afor special cases where it is better to match the negative pattern or as a
956N/A<
table width=70%
border=2 bgcolor="#c0c0e0" cellspacing=0 cellpadding=10>
956N/A<
b>Notice!</
b> When using the NOT character to negate a pattern you cannot
956N/Ahave grouped wildcard parts in the pattern. This is impossible because when
956N/Athe pattern does NOT match, there are no contents for the groups. In
956N/Aconsequence, if negated patterns are used, you cannot use <
tt>$N</
tt> in the
956N/A<
a name="rhs"><
em>Substitution</
em></
a> of a rewriting rule is the string
956N/Awhich is substituted for (or replaces) the original URL for which
956N/A<
em>Pattern</
em> matched. Beside plain text you can use
956N/A<
li>pattern-group back-references (<
code>$N</
code>)
956N/A<
li>server-variables as in rule condition test-strings (<
code>%{VARNAME}</
code>)
964N/A<
li><
a href="#mapfunc">mapping-function</
a> calls (<
code>${mapname:key|default}</
code>)
956N/ABack-references are <
code>$</
code><
b>N</
b> (<
b>N</
b>=1..9) identifiers which
956N/Awill be replaced by the contents of the <
b>N</
b>th group of the matched
956N/A<
em>Pattern</
em>. The server-variables are the same as for the
956N/A<
em>TestString</
em> of a <
tt>RewriteCond</
tt> directive. The
956N/Amapping-functions come from the <
tt>RewriteMap</
tt> directive and are
956N/Aexplained there. These three types of variables are expanded in the order of
956N/AAs already mentioned above, all the rewriting rules are applied to the
956N/A<
em>Substitution</
em> (in the order of definition in the config file). The
956N/AURL is <
b>completely replaced</
b> by the <
em>Substitution</
em> and the
956N/Arewriting process goes on until there are no more rules (unless explicitly
956N/Aterminated by a <
code><
b>L</
b></
code> flag - see below).
956N/AThere is a special substitution string named '<
tt>-</
tt>' which means:
956N/A<
b>NO substitution</
b>! Sounds silly? No, it is useful to provide rewriting
956N/Arules which <
b>only</
b> match some URLs but do no substitution,
e.g. in
956N/Aconjunction with the <
b>C</
b> (chain) flag to be able to have more than one
956N/Apattern to be applied before a substitution occurs.
956N/A<
table width=70%
border=2 bgcolor="#c0c0e0" cellspacing=0 cellpadding=10>
956N/A<
b>Notice</
b>: There is a special feature. When you prefix a substitution
956N/Afield with <
tt>http://</
tt><
em>thishost</
em>[<
em>:thisport</
em>] then
956N/A<
b>mod_rewrite</
b> automatically strips it out. This auto-reduction on
956N/Aimplicit external redirect URLs is a useful and important feature when
956N/Aused in combination with a mapping-function which generates the hostname
956N/Apart. Have a look at the first example in the example section below to
956N/A<
b>Remember:</
b> An unconditional external redirect to your own server will
956N/ATo achieve such a self-redirect, you have to use the <
b>R</
b>-flag (see
956N/AAdditionally you can set special flags for <
em>Substitution</
em> by appending
956N/A<
code>[</
code><
em>flags</
em><
code>]</
code>
956N/Aas the third argument to the <
tt>RewriteRule</
tt> directive. <
em>Flags</
em> is a
956N/Acomma-separated list of the following flags:
956N/A<
li>'<
strong><
code>redirect|R</
code>[=<
i>code</
i>]</
strong>' (force <
a name="redirect"><
b>r</
b>edirect</
a>)<
br>
956N/A Prefix <
em>Substitution</
em>
956N/A force a external redirection. If no <
i>code</
i> is given a HTTP response
956N/A of 302 (MOVED TEMPORARILY) is used. If you want to use other response
956N/A codes in the range 300-400 just specify them as a number or use
956N/A one of the following symbolic names: <
tt>temp</
tt> (default), <
tt>permanent</
tt>,
956N/A Use it for rules which should
956N/A canonicalize the URL and gives it back to the client,
e.g. translate
956N/A ``<
code>/~</
code>'' into ``<
code>/u/</
code>'' or always append a slash to
956N/A <
code>/u/</
code><
em>user</
em>, etc.<
br>
956N/A <
b>Notice:</
b> When you use this flag, make sure that the
956N/A substitution field is a valid URL! If not, you are redirecting to an
956N/A invalid location! And remember that this flag itself only prefixes the
956N/A Usually you also want to stop and do the redirection immediately. To stop
956N/A the rewriting you also have to provide the 'L' flag.
956N/A<
li>'<
strong><
code>forbidden|F</
code></
strong>' (force URL to be <
b>f</
b>orbidden)<
br>
956N/A This forces the current URL to be forbidden,
i.e. it immediately sends
956N/A back a HTTP response of 403 (FORBIDDEN). Use this flag in conjunction with
956N/A appropriate RewriteConds to conditionally block some URLs.
956N/A<
li>'<
strong><
code>gone|G</
code></
strong>' (force URL to be <
b>g</
b>one)<
br>
956N/A This forces the current URL to be gone,
i.e. it immediately sends back a
956N/A HTTP response of 410 (GONE). Use this flag to mark no longer existing
956N/A<
li>'<
strong><
code>proxy|P</
code></
strong>' (force <
b>p</
b>roxy)<
br>
956N/A This flag forces the substitution part to be internally forced as a proxy
956N/A request and immediately (
i.e. rewriting rule processing stops here) put
956N/A through the proxy module. You have to make sure that the substitution
956N/A string is a valid URI (
e.g. typically <
tt>http://</
tt>) which can
956N/A be handled by the Apache proxy module. If not you get an error from
956N/A the proxy module. Use this flag to achieve a more powerful implementation
956N/A of the <
tt>mod_proxy</
tt> directive <
tt>ProxyPass</
tt>, to map
956N/A some remote stuff into the namespace of the local server.
1376N/A Notice: <
b>You really have to put <
tt>ProxyRequests On</
tt> into your
1376N/A server configuration to prevent proxy requests from leading to core-dumps
1376N/A inside the Apache kernel. If you have not compiled in the proxy module,
1376N/A then there is no core-dump problem, because mod_rewrite checks for
956N/A existence of the proxy module and if lost forbids proxy URLs. </
b>
956N/A<
li>'<
strong><
code>last|L</
code></
strong>' (<
b>l</
b>ast rule)<
br>
956N/A Stop the rewriting process here and
956N/A don't apply any more rewriting rules. This corresponds to the Perl
956N/A <
code>last</
code> command or the <
code>break</
code> command from the C
956N/A language. Use this flag to prevent the currently rewritten URL from being
956N/A rewritten further by following rules which may be wrong. For
956N/A example, use it to rewrite the root-path URL ('<
code>/</
code>') to a real
956N/A<
li>'<
strong><
code>next|N</
code></
strong>' (<
b>n</
b>ext round)<
br>
956N/A Re-run the rewriting process (starting again with the first rewriting
956N/A rule). Here the URL to match is again not the original URL but the URL
956N/A from the last rewriting rule. This corresponds to the Perl
1352N/A <
code>next</
code> command or the <
code>continue</
code> command from the C
1352N/A language. Use this flag to restart the rewriting process,
i.e. to
956N/A immediately go to the top of the loop. <
br>
956N/A <
b>But be careful not to create a deadloop!</
b>
956N/A<
li>'<
strong><
code>chain|C</
code></
strong>' (<
b>c</
b>hained with next rule)<
br>
956N/A This flag chains the current rule with the next rule (which itself can
956N/A also be chained with its following rule, etc.). This has the following
956N/A effect: if a rule matches, then processing continues as usual,
i.e. the
964N/A flag has no effect. If the rule does <
b>not</
b> match, then all following
964N/A chained rules are skipped. For instance, use it to remove the
964N/A ``<
tt>.www</
tt>'' part inside a per-directory rule set when you let an
964N/A external redirect happen (where the ``<
tt>.www</
tt>'' part should not to
964N/A<
li>'<
strong><
code>type|T</
code></
strong>=<
em>mime-type</
em>' (force MIME <
b>t</
b>ype)<
br>
964N/A Force the MIME-type of the target file to be <
em>mime-type</
em>. For
1045N/A instance, this can be used to simulate the old <
tt>mod_alias</
tt>
1045N/A directive <
tt>ScriptAlias</
tt> which internally forces all files inside
1045N/A the mapped directory to have a MIME type of
1045N/A<
li>'<
strong><
code>nosubreq|NS</
code></
strong>' (used only if <
b>n</
b>o internal <
b>s</
b>ub-request)<
br>
1045N/A This flag forces the rewriting engine to skip a rewriting rule if the
1045N/A current request is an internal sub-request. For instance, sub-requests
1045N/A occur internally in Apache when <
tt>mod_include</
tt> tries to find out
1045N/A information about possible directory default files (<
tt>
index.xxx</
tt>).
1045N/A On sub-requests it is not always useful and even sometimes causes a failure to
1045N/A if the complete set of rules are applied. Use this flag to exclude some rules.<
br>
1505N/A Use the following rule for your decision: whenever you prefix some URLs
1045N/A with CGI-scripts to force them to be processed by the CGI-script, the
1352N/A chance is high that you will run into problems (or even overhead) on sub-requests.
1352N/A In these cases, use this flag.
964N/A<
li>'<
strong><
code>passthrough|PT</
code></
strong>' (<
b>p</
b>ass <
b>t</
b>hrough to next handler)<
br>
964N/A This flag forces the rewriting engine to set the <
code>uri</
code> field
of the internal <
code>request_rec</
code> structure to the value
of the <
code>filename</
code> field. This flag is just a hack to be able
to post-process the output of <
tt>RewriteRule</
tt> directives by
<
tt>Alias</
tt>, <
tt>ScriptAlias</
tt>, <
tt>Redirect</
tt>, etc. directives
from other URI-to-filename translators. A trivial example to show the
If you want to rewrite <
tt>/abc</
tt> to <
tt>/def</
tt> via the rewriting
engine of <
tt>mod_rewrite</
tt> and then <
tt>/def</
tt> to <
tt>/ghi</
tt>
RewriteRule ^/abc(.*) /def$1 [PT]
If you omit the <
tt>PT</
tt> flag then <
tt>mod_rewrite</
tt>
will do its job fine,
i.e. it rewrites <
tt>uri=/abc/...</
tt> to
<
tt>filename=/def/...</
tt> as a full API-compliant URI-to-filename
translator should do. Then <
tt>mod_alias</
tt> comes and tries to do a
URI-to-filename transition which will not work.
Notice: <
b>You have to use this flag if you want to intermix directives
of different modules which contain URL-to-filename translators</
b>. The
typical example is the use of <
tt>mod_alias</
tt> and
<
table width=70%
border=2 bgcolor="#c0c0e0" cellspacing=0 cellpadding=10>
<
b>For the Apache hackers:</
b><
br>
If the current Apache API had a
filename-to-filename hook additionally to the URI-to-filename hook then
we wouldn't need this flag! But without such a hook this flag is the
only solution. The Apache Group has discussed this problem and will
add such hooks into Apache version 2.0.
<
li>'<
strong><
code>skip|S</
code></
strong>=<
em>num</
em>' (<
b>s</
b>kip next rule(s))<
br>
This flag forces the rewriting engine to skip the next <
em>num</
em> rules
in sequence when the current rule matches. Use this to make pseudo
if-then-else constructs: The last rule of the then-clause becomes
a <
tt>skip=N</
tt> where N is the number of rules in the else-clause.
(This is <
b>not</
b> the same as the 'chain|C' flag!)
<
li>'<
strong><
code>env|E=</
code></
strong><
i>VAR</
i>:<
i>VAL</
i>' (set <
b>e</
b>nvironment variable)<
br>
This forces an environment variable named <
i>VAR</
i> to be set to the value
<
i>VAL</
i>, where <
i>VAL</
i> can contain regexp backreferences <
tt>$N</
tt>
which will be expanded. You can use this flag more than once to set more
than one variable. The variables can be later dereferenced at a lot of
situations, but the usual location will be from within XSSI (via
<
tt><!--#echo var="VAR"--></
tt>) or CGI (
e.g. <
tt>$ENV{'VAR'}</
tt>).
But additionally you can also dereference it in a following RewriteCond
pattern via <
tt>%{ENV:VAR}</
tt>. Use this to strip but remember
<
table width=70%
border=2 bgcolor="#c0c0e0" cellspacing=0 cellpadding=10>
Remember: Never forget that <
em>Pattern</
em> gets applied to a complete URL
in per-server configuration files. <
b>But in per-directory configuration
files, the per-directory prefix (which always is the same for a specific
directory!) gets automatically <
em>removed</
em> for the pattern matching and
automatically <
em>added</
em> after the substitution has been done.</
b> This feature is
essential for many sorts of rewriting, because without this prefix stripping
you have to match the parent directory which is not always possible.
There is one exception: If a substitution string starts with
``<
tt>http://</
tt>'' then the directory prefix will be <
b>not</
b> added and a
external redirect or proxy throughput (if flag <
b>P</
b> is used!) is forced!
<
table width=70%
border=2 bgcolor="#c0c0e0" cellspacing=0 cellpadding=10>
Notice! To enable the rewriting engine for per-directory configuration files
you need to set ``<
tt>RewriteEngine On</
tt>'' in these files <
b>and</
b>
``<
tt>Option FollowSymLinks</
tt>'' enabled. If your administrator has
disabled override of <
tt>FollowSymLinks</
tt> for a user's directory, then
you cannot use the rewriting engine. This restriction is needed for
Here are all possible substitution combinations and their meanings:
<
b>Inside per-server configuration (<
tt>
httpd.conf</
tt>)<
br>
<
table bgcolor="#d0d0d0" cellspacing=0 cellpadding=5>
<
b>Given Rule</
b> <
b>Resulting Substitution</
b>
---------------------------------------------- ----------------------------------
^/somepath(.*) otherpath$1 not supported, because invalid!
^/somepath(.*) otherpath$1 [R] not supported, because invalid!
^/somepath(.*) otherpath$1 [P] not supported, because invalid!
---------------------------------------------- ----------------------------------
^/somepath(.*) /otherpath$1 [P] not supported, because silly!
---------------------------------------------- ----------------------------------
---------------------------------------------- ----------------------------------
(the [R] flag is redundant)
<
b>Inside per-directory configuration for <
tt>/somepath</
tt><
br>
<
tt>RewriteBase /somepath</
tt>)<
br> for
<
table bgcolor="#d0d0d0" cellspacing=0 cellpadding=5>
<
b>Given Rule</
b> <
b>Resulting Substitution</
b>
---------------------------------------------- ----------------------------------
^localpath(.*) otherpath$1 [P] not supported, because silly!
---------------------------------------------- ----------------------------------
^localpath(.*) /otherpath$1 [P] not supported, because silly!
---------------------------------------------- ----------------------------------
---------------------------------------------- ----------------------------------
(the [R] flag is redundant)
We want to rewrite URLs of the form
<
code>/</
code> <
em>Language</
em>
<
code>/~</
code> <
em>Realname</
em>
<
code>/.../</
code> <
em>File</
em>
<
code>/u/</
code> <
em>Username</
em>
<
code>/.../</
code> <
em>File</
em>
<
code>.</
code> <
em>Language</
em>
We take the rewrite mapfile from above and save it under
following lines to the Apache server configuration file:
RewriteRule ^/([^/]+)/~([^/]+)/(.*)$ /u/${real-to-user:$2|nobody}/$3.$1