mirror of
https://github.com/apache/httpd.git
synced 2025-05-19 02:21:09 +03:00
corrections coming up. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@80130 13f79535-47bb-0310-9956-ffa450edef68
1328 lines
48 KiB
HTML
1328 lines
48 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
|
<!--%hypertext -->
|
|
<!-- mod_rewrite.html -->
|
|
<!-- Documentation for the mod_rewrite Apache module -->
|
|
<HTML>
|
|
<HEAD>
|
|
<TITLE>Apache module mod_rewrite</TITLE>
|
|
</HEAD>
|
|
|
|
<!-- Background white, links blue (unvisited), navy (visited), red (active) -->
|
|
<BODY
|
|
BGCOLOR="#FFFFFF"
|
|
TEXT="#000000"
|
|
LINK="#0000FF"
|
|
VLINK="#000080"
|
|
ALINK="#FF0000"
|
|
>
|
|
<!--#include virtual="header.html" -->
|
|
|
|
<H1 ALIGN="CENTER">Module mod_rewrite</H1>
|
|
|
|
This module is contained in the <CODE>mod_rewrite.c</CODE> file, with Apache
|
|
1.2 and later. It provides a rule-based rewriting engine to rewrite requested
|
|
URLs on the fly. <CODE>mod_rewrite</CODE> is not compiled into the server by
|
|
default. To use <CODE>mod_rewrite</CODE> you have to enable the following line
|
|
in the server build Configuration file:
|
|
<PRE>
|
|
AddModule modules/standard/mod_rewrite.o
|
|
</PRE>
|
|
|
|
<H2>Summary</H2>
|
|
|
|
This module uses a rule-based rewriting engine (based on a
|
|
regular-expression parser) to rewrite requested URLs on the fly.
|
|
|
|
<P>
|
|
It supports an unlimited number of additional rule conditions (which can
|
|
operate on a lot of variables, including HTTP headers) for granular
|
|
matching and external database lookups (either via plain text
|
|
tables, DBM hash files or external processes) for advanced URL
|
|
substitution.
|
|
|
|
<P>
|
|
It operates on the full URLs (including the PATH_INFO part) both in per-server
|
|
context (httpd.conf) and per-dir context (.htaccess) and even can generate
|
|
QUERY_STRING parts on result. The rewritten result can lead to internal
|
|
sub-processing, external request redirection or to internal proxy throughput.
|
|
|
|
<P>
|
|
This module was originally written in April 1996 and
|
|
gifted exclusively to the The Apache Group in July 1997 by
|
|
<P>
|
|
<BLOCKQUOTE>
|
|
<EM>Ralf S. Engelschall</EM><BR>
|
|
<A HREF="mailto:rse@engelschall.com"><TT>rse@engelschall.com</TT></A><BR>
|
|
<A HREF="http://www.engelschall.com/"><TT>www.engelschall.com</TT></A>
|
|
</BLOCKQUOTE>
|
|
|
|
<!--%hypertext -->
|
|
<HR>
|
|
<!--/%hypertext -->
|
|
|
|
<P>
|
|
<H2>Directives</H2>
|
|
|
|
<UL>
|
|
<LI><A HREF="#RewriteEngine">RewriteEngine</A>
|
|
<LI><A HREF="#RewriteOptions">RewriteOptions</A>
|
|
<LI><A HREF="#RewriteLog">RewriteLog</A>
|
|
<LI><A HREF="#RewriteLogLevel">RewriteLogLevel</A>
|
|
<LI><A HREF="#RewriteMap">RewriteMap</A>
|
|
<LI><A HREF="#RewriteBase">RewriteBase</A>
|
|
<LI><A HREF="#RewriteCond">RewriteCond</A>
|
|
<LI><A HREF="#RewriteRule">RewriteRule</A>
|
|
</UL>
|
|
|
|
<!--%hypertext -->
|
|
<HR>
|
|
<!--/%hypertext -->
|
|
|
|
|
|
<CENTER>
|
|
<A name="Configuration">
|
|
<H1>Configuration Directives</H1>
|
|
</A>
|
|
</CENTER>
|
|
|
|
<A name="RewriteEngine"><H3>RewriteEngine</H3></A>
|
|
<A
|
|
HREF="directive-dict.html#Syntax"
|
|
REL="Help"
|
|
><STRONG>Syntax:</STRONG></A> <CODE>RewriteEngine</CODE> {<CODE>on,off</CODE>}<BR>
|
|
<A
|
|
HREF="directive-dict.html#Default"
|
|
REL="Help"
|
|
><STRONG>Default:</STRONG></A> <STRONG><CODE>RewriteEngine off</CODE></STRONG><BR>
|
|
<A
|
|
HREF="directive-dict.html#Context"
|
|
REL="Help"
|
|
><STRONG>Context:</STRONG></A> server config, virtual host, per-directory config<BR>
|
|
<P>
|
|
|
|
The <TT>RewriteEngine</TT> directive enables or disables the
|
|
runtime rewriting engine. If it is set to <CODE>off</CODE> this module does
|
|
no runtime processing at all. It does not even update the <TT>SCRIPT_URx</TT>
|
|
environment variables.
|
|
|
|
<P>
|
|
Use this directive to disable the module instead of commenting out
|
|
all <TT>RewriteRule</TT> directives!
|
|
|
|
<P>
|
|
Note that, by default, rewrite configurations are not inherited.
|
|
This means that you need to have a <TT>RewriteEngine on</TT>
|
|
directive for each virtual host you wish to use it in, unless <A
|
|
HREF="#RewriteOptions">RewriteOptions inherit</A> is enabled.
|
|
|
|
<P>
|
|
<hr noshade size=1>
|
|
<P>
|
|
|
|
<A name="RewriteOptions"><H3>RewriteOptions</H3></A>
|
|
<A
|
|
HREF="directive-dict.html#Syntax"
|
|
REL="Help"
|
|
><STRONG>Syntax:</STRONG></A> <CODE>RewriteOptions</CODE> <EM>Option</EM> ...<BR>
|
|
<A
|
|
HREF="directive-dict.html#Default"
|
|
REL="Help"
|
|
><STRONG>Default:</STRONG></A> -<EM>None</EM>-<BR>
|
|
<A
|
|
HREF="directive-dict.html#Context"
|
|
REL="Help"
|
|
><STRONG>Context:</STRONG></A> server config, virtual host, per-directory config<BR>
|
|
<P>
|
|
|
|
The <TT>RewriteOptions</TT> directive sets some special options for the
|
|
current per-server or per-directory configuration. The <EM>Option</EM>
|
|
strings can be one of the following:
|
|
|
|
<UL>
|
|
<LI>'<STRONG><CODE>inherit</CODE></STRONG>'<BR>
|
|
This forces the current configuration to inherit the configuration of the
|
|
parent. In per-virtual-server context this means that the maps,
|
|
conditions and rules of the main server gets inherited. In per-directory
|
|
context this means that conditions and rules of the parent directory's
|
|
<TT>.htaccess</TT> configuration gets inherited.
|
|
</UL>
|
|
|
|
<P>
|
|
<hr noshade size=1>
|
|
<P>
|
|
|
|
<A name="RewriteLog"><H3>RewriteLog</H3></A>
|
|
<A
|
|
HREF="directive-dict.html#Syntax"
|
|
REL="Help"
|
|
><STRONG>Syntax:</STRONG></A> <CODE>RewriteLog</CODE> <EM>Filename</EM><BR>
|
|
<A
|
|
HREF="directive-dict.html#Default"
|
|
REL="Help"
|
|
><STRONG>Default:</STRONG></A> -<EM>None</EM>-<BR>
|
|
<A
|
|
HREF="directive-dict.html#Context"
|
|
REL="Help"
|
|
><STRONG>Context:</STRONG></A> server config, virtual host<BR>
|
|
<P>
|
|
|
|
The <TT>RewriteLog</TT> directive sets the name of the file to which the
|
|
server logs any rewriting actions it performs. If the name does not begin
|
|
with a slash ('<TT>/</TT>') then it is assumed to be relative to the
|
|
<EM>Server Root</EM>. The directive should occur only once per server
|
|
config.
|
|
|
|
<P>
|
|
<table width="70%" border=0 bgcolor="#f0f0f0" cellspacing=0 cellpadding=10>
|
|
<TR><TD>
|
|
To disable the logging of rewriting actions it is not recommended
|
|
to set <EM>Filename</EM>
|
|
to <CODE>/dev/null</CODE>, because although the rewriting engine does
|
|
not create output to a logfile it still creates the logfile
|
|
output internally. <STRONG>This will slow down the server with no advantage to the
|
|
administrator!</STRONG>
|
|
To disable logging either remove or comment out the
|
|
<TT>RewriteLog</TT> directive or use <TT>RewriteLogLevel 0</TT>!
|
|
</TD></TR>
|
|
</TABLE>
|
|
|
|
<P>
|
|
<table width="70%" border=0 bgcolor="#fff0f0" cellspacing=0 cellpadding=10>
|
|
<TR><TD>
|
|
SECURITY: See the <A
|
|
HREF="../misc/security_tips.html">Apache Security
|
|
Tips</A> document for details on why your security could be compromised if the
|
|
directory where logfiles are stored is writable by anyone other than the user
|
|
that starts the server.
|
|
</TD></TR>
|
|
</TABLE>
|
|
|
|
<P>
|
|
<STRONG>Example:</STRONG>
|
|
<BLOCKQUOTE>
|
|
<PRE>
|
|
RewriteLog "/usr/local/var/apache/logs/rewrite.log"
|
|
</PRE>
|
|
</BLOCKQUOTE>
|
|
|
|
<P>
|
|
<hr noshade size=1>
|
|
<P>
|
|
|
|
<A name="RewriteLogLevel"><H3>RewriteLogLevel</H3></A>
|
|
<A
|
|
HREF="directive-dict.html#Syntax"
|
|
REL="Help"
|
|
><STRONG>Syntax:</STRONG></A> <CODE>RewriteLogLevel</CODE> <EM>Level</EM><BR>
|
|
<A
|
|
HREF="directive-dict.html#Default"
|
|
REL="Help"
|
|
><STRONG>Default:</STRONG></A> <STRONG><CODE>RewriteLogLevel 0</CODE></STRONG><BR>
|
|
<A
|
|
HREF="directive-dict.html#Context"
|
|
REL="Help"
|
|
><STRONG>Context:</STRONG></A> server config, virtual host<BR>
|
|
<P>
|
|
|
|
The <TT>RewriteLogLevel</TT> directive set the verbosity level of the rewriting
|
|
logfile. The default level 0 means no logging, while 9 or more means
|
|
that practically all actions are logged.
|
|
|
|
<P>
|
|
To disable the logging of rewriting actions simply set <EM>Level</EM> to 0.
|
|
This disables all rewrite action logs.
|
|
|
|
<P>
|
|
<table width="70%" border=0 bgcolor="#f0f0f0" cellspacing=0 cellpadding=10>
|
|
<TR><TD>
|
|
<STRONG>Notice:</STRONG> Using a high value for <EM>Level</EM> will slow down your Apache
|
|
server dramatically! Use the rewriting logfile only for debugging or at least
|
|
at <EM>Level</EM> not greater than 2!
|
|
</TD></TR>
|
|
</TABLE>
|
|
|
|
|
|
<P>
|
|
<STRONG>Example:</STRONG>
|
|
<BLOCKQUOTE>
|
|
<PRE>
|
|
RewriteLogLevel 3
|
|
</PRE>
|
|
</BLOCKQUOTE>
|
|
|
|
<P>
|
|
<hr noshade size=1>
|
|
<P>
|
|
|
|
<A name="RewriteMap"><H3>RewriteMap</H3></A>
|
|
<A
|
|
HREF="directive-dict.html#Syntax"
|
|
REL="Help"
|
|
><STRONG>Syntax:</STRONG></A> <CODE>RewriteMap</CODE> <EM>Mapname</EM> <CODE>{txt,dbm,prg}:</CODE><EM>Filename</EM><BR>
|
|
<A
|
|
HREF="directive-dict.html#Default"
|
|
REL="Help"
|
|
><STRONG>Default:</STRONG></A> not used per default<BR>
|
|
<A
|
|
HREF="directive-dict.html#Context"
|
|
REL="Help"
|
|
><STRONG>Context:</STRONG></A> server config, virtual host<BR>
|
|
<P>
|
|
|
|
The <TT>RewriteMap</TT> directive defines an external <EM>Rewriting Map</EM>
|
|
which can be used inside rule substitution strings by the mapping-functions
|
|
to insert/substitute fields through a key lookup.
|
|
<P>
|
|
|
|
The <A name="mapfunc"><EM>Mapname</EM></A> is the name of the map and will
|
|
be used to specify a mapping-function for the substitution strings of a
|
|
rewriting rule via
|
|
|
|
<BLOCKQUOTE><STRONG>
|
|
<CODE>${</CODE> <EM>Mapname</EM> <CODE>:</CODE> <EM>LookupKey</EM>
|
|
<CODE>|</CODE> <EM>DefaultValue</EM> <CODE>}</CODE>
|
|
</STRONG></BLOCKQUOTE>
|
|
|
|
When such a directive occurs the map <EM>Mapname</EM>
|
|
is consulted and the key <EM>LookupKey</EM> is looked-up. If the key is
|
|
found, the map-function directive is substituted by <EM>SubstValue</EM>. If
|
|
the key is not found then it is substituted by <EM>DefaultValue</EM>.
|
|
|
|
<P>
|
|
The <EM>Filename</EM> must be a valid Unix filepath, containing one
|
|
of the following formats:
|
|
|
|
<OL>
|
|
<LI><STRONG>Plain Text Format</STRONG>
|
|
<P>
|
|
This is a ASCII file which contains either blank lines, comment lines
|
|
(starting with a '#' character) or
|
|
|
|
<BLOCKQUOTE><STRONG>
|
|
<EM>MatchingKey</EM> <EM>SubstValue</EM>
|
|
</STRONG></BLOCKQUOTE>
|
|
|
|
pairs - one per line. You can create such files either manually,
|
|
using your favorite editor, or by using the programs
|
|
<TT>mapcollect</TT> and <TT>mapmerge</TT> from the <TT>support</TT>
|
|
directory of the <STRONG>mod_rewrite</STRONG> distribution.
|
|
<P>
|
|
To declare such a map prefix, <EM>Filename</EM> with a <CODE>txt:</CODE>
|
|
string as in the following example:
|
|
|
|
<P>
|
|
<table border=0 cellspacing=1 cellpadding=5 bgcolor="#f0f0f0">
|
|
<TR><TD><PRE>
|
|
#
|
|
# map.real-to-user -- maps realnames to usernames
|
|
#
|
|
|
|
Ralf.S.Engelschall rse # Bastard Operator From Hell
|
|
Dr.Fred.Klabuster fred # Mr. DAU
|
|
</PRE></TD></TR>
|
|
</TABLE>
|
|
|
|
<P>
|
|
<table border=0 cellspacing=1 cellpadding=5 bgcolor="#f0f0f0">
|
|
<TR><TD><PRE>
|
|
RewriteMap real-to-host txt:/path/to/file/map.real-to-user
|
|
</PRE></TD></TR>
|
|
</TABLE>
|
|
|
|
<P>
|
|
<LI><STRONG>DBM Hashfile Format</STRONG>
|
|
<P>
|
|
This is a binary NDBM format file containing the
|
|
same contents as the <EM>Plain Text Format</EM> files. You can create
|
|
such a file with any NDBM tool or with the <TT>dbmmanage</TT> program
|
|
from the <TT>support</TT> directory of the Apache distribution.
|
|
<P>
|
|
To declare such a map prefix <EM>Filename</EM> with a <CODE>dbm:</CODE>
|
|
string.
|
|
<P>
|
|
<LI><STRONG>Program Format</STRONG>
|
|
<P>
|
|
This is a Unix executable, not a lookup file. To create it you can use
|
|
the language of your choice, but the result has to be a run-able Unix
|
|
binary (i.e. either object-code or a script with the
|
|
magic cookie trick '<TT>#!/path/to/interpreter</TT>' as the first line).
|
|
<P>
|
|
This program gets started once at startup of the Apache servers and then
|
|
communicates with the rewriting engine over its <TT>stdin</TT> and
|
|
<TT>stdout</TT> file-handles. For each map-function lookup it will
|
|
receive the key to lookup as a newline-terminated string on
|
|
<TT>stdin</TT>. It then has to give back the looked-up value as a
|
|
newline-terminated string on <TT>stdout</TT> or the four-character string
|
|
``<TT>NULL</TT>'' if it fails (i.e. there is no corresponding value
|
|
for the given key). A trivial program which will implement a 1:1 map
|
|
(i.e. key == value) could be:
|
|
<P>
|
|
<table border=0 cellspacing=1 cellpadding=5 bgcolor="#f0f0f0">
|
|
<TR><TD><PRE>
|
|
#!/usr/bin/perl
|
|
$| = 1;
|
|
while (<STDIN>) {
|
|
# ...here any transformations
|
|
# or lookups should occur...
|
|
print $_;
|
|
}
|
|
</PRE></TD></TR>
|
|
</TABLE>
|
|
<P>
|
|
<STRONG>But be very careful:</STRONG><BR>
|
|
<OL>
|
|
<LI>``<EM>Keep the program simple, stupid</EM>'' (KISS), because
|
|
if this program hangs it will lead to a hang of the Apache server
|
|
when the rule occurs.
|
|
<LI>Avoid one common mistake: never do buffered I/O on <TT>stdout</TT>!
|
|
This will cause a deadloop! Hence the ``<TT>$|=1</TT>'' in the above
|
|
example...
|
|
</OL>
|
|
<P>
|
|
To declare such a map prefix <EM>Filename</EM> with a <CODE>prg:</CODE>
|
|
string.
|
|
</OL>
|
|
|
|
The <TT>RewriteMap</TT> directive can occur more than once. For each
|
|
mapping-function use one <TT>RewriteMap</TT> directive to declare its
|
|
rewriting mapfile. While you cannot <STRONG>declare</STRONG> a map in per-directory
|
|
context it is of course possible to <STRONG>use</STRONG> this map in per-directory
|
|
context.
|
|
|
|
<P>
|
|
<table width="70%" border=0 bgcolor="#f0f0f0" cellspacing=0 cellpadding=10>
|
|
<TR><TD>
|
|
For plain text and DBM format files the looked-up keys are cached in-core
|
|
until the <TT>mtime</TT> of the mapfile changes or the server does a
|
|
restart. This way you can have map-functions in rules which are used
|
|
for <STRONG>every</STRONG> request. This is no problem, because the external lookup
|
|
only happens once!
|
|
</TD></TR>
|
|
</TABLE>
|
|
|
|
|
|
<P>
|
|
<hr noshade size=1>
|
|
<P>
|
|
|
|
<A name="RewriteBase"><H3>RewriteBase</H3></A>
|
|
<A
|
|
HREF="directive-dict.html#Syntax"
|
|
REL="Help"
|
|
><STRONG>Syntax:</STRONG></A> <CODE>RewriteBase</CODE> <EM>BaseURL</EM><BR>
|
|
<A
|
|
HREF="directive-dict.html#Default"
|
|
REL="Help"
|
|
><STRONG>Default:</STRONG></A> <EM>default is the physical directory path</EM><BR>
|
|
<A
|
|
HREF="directive-dict.html#Context"
|
|
REL="Help"
|
|
><STRONG>Context:</STRONG></A> per-directory config<BR>
|
|
<P>
|
|
|
|
The <TT>RewriteBase</TT> directive explicitly sets the base URL for
|
|
per-directory rewrites. As you will see below, <TT>RewriteRule</TT> can be
|
|
used in per-directory config files (<TT>.htaccess</TT>). There it will act
|
|
locally, i.e. the local directory prefix is stripped at this stage of
|
|
processing and your rewriting rules act only on the remainder. At the end
|
|
it is automatically added.
|
|
|
|
<P>
|
|
When a substitution occurs for a new URL, this module has to
|
|
re-inject the URL into the server processing. To be able to do this it needs
|
|
to know what the corresponding URL-prefix or URL-base is. By default this
|
|
prefix is the corresponding filepath itself. <STRONG>But at most websites URLs are
|
|
<STRONG>NOT</STRONG> directly related to physical filename paths, so this assumption
|
|
will be usually be wrong!</STRONG> There you have to use the <TT>RewriteBase</TT>
|
|
directive to specify the correct URL-prefix.
|
|
|
|
<P>
|
|
<table width="70%" border=0 bgcolor="#fff0f0" cellspacing=0 cellpadding=10>
|
|
<TR><TD>
|
|
So, if your webserver's URLs are <STRONG>not</STRONG> directly
|
|
related to physical file paths, you have to use <TT>RewriteBase</TT> in every
|
|
<TT>.htaccess</TT> files where you want to use <TT>RewriteRule</TT>
|
|
directives.
|
|
</TD></TR>
|
|
</TABLE>
|
|
|
|
<P>
|
|
<STRONG>Example:</STRONG>
|
|
|
|
<BLOCKQUOTE>
|
|
Assume the following per-directory config file:
|
|
|
|
<P>
|
|
<table border=0 cellspacing=1 cellpadding=5 bgcolor="#f0f0f0">
|
|
<TR><TD><PRE>
|
|
#
|
|
# /abc/def/.htaccess -- per-dir config file for directory /abc/def
|
|
# Remember: /abc/def is the physical path of /xyz, i.e. the server
|
|
# has a 'Alias /xyz /abc/def' directive e.g.
|
|
#
|
|
|
|
RewriteEngine On
|
|
|
|
# let the server know that we are reached via /xyz and not
|
|
# via the physical path prefix /abc/def
|
|
RewriteBase /xyz
|
|
|
|
# now the rewriting rules
|
|
RewriteRule ^oldstuff\.html$ newstuff.html
|
|
</PRE></TD></TR>
|
|
</TABLE>
|
|
|
|
<P>
|
|
In the above example, a request to <TT>/xyz/oldstuff.html</TT> gets correctly
|
|
rewritten to the physical file <TT>/abc/def/newstuff.html</TT>.
|
|
|
|
<P>
|
|
<table width="70%" border=0 bgcolor="#fff0f0" cellspacing=0 cellpadding=10>
|
|
<TR><TD>
|
|
<font size=-1>
|
|
<STRONG>For the Apache hackers:</STRONG><BR>
|
|
The following list gives detailed information about the internal
|
|
processing steps:
|
|
|
|
<P>
|
|
<PRE>
|
|
Request:
|
|
/xyz/oldstuff.html
|
|
|
|
Internal Processing:
|
|
/xyz/oldstuff.html -> /abc/def/oldstuff.html (per-server Alias)
|
|
/abc/def/oldstuff.html -> /abc/def/newstuff.html (per-dir RewriteRule)
|
|
/abc/def/newstuff.html -> /xyz/newstuff.html (per-dir RewriteBase)
|
|
/xyz/newstuff.html -> /abc/def/newstuff.html (per-server Alias)
|
|
|
|
Result:
|
|
/abc/def/newstuff.html
|
|
</PRE>
|
|
|
|
This seems very complicated but is the correct Apache internal processing,
|
|
because the per-directory rewriting comes too late in the process. So,
|
|
when it occurs the (rewritten) request has to be re-injected into the Apache
|
|
kernel! BUT: While this seems like a serious overhead, it really isn't, because
|
|
this re-injection happens fully internal to the Apache server and the same
|
|
procedure is used by many other operations inside Apache. So, you can be
|
|
sure the design and implementation is correct.
|
|
</FONT>
|
|
</TD></TR>
|
|
</TABLE>
|
|
|
|
</BLOCKQUOTE>
|
|
|
|
|
|
<P>
|
|
<hr noshade size=1>
|
|
<P>
|
|
|
|
<A name="RewriteCond"><H3>RewriteCond</H3></A>
|
|
<A
|
|
HREF="directive-dict.html#Syntax"
|
|
REL="Help"
|
|
><STRONG>Syntax:</STRONG></A> <CODE>RewriteCond</CODE> <EM>TestString</EM> <EM>CondPattern</EM><BR>
|
|
<A
|
|
HREF="directive-dict.html#Default"
|
|
REL="Help"
|
|
><STRONG>Default:</STRONG></A> -<EM>None</EM>-<BR>
|
|
<A
|
|
HREF="directive-dict.html#Context"
|
|
REL="Help"
|
|
><STRONG>Context:</STRONG></A> server config, virtual host, per-directory config<BR>
|
|
<P>
|
|
|
|
The <TT>RewriteCond</TT> directive defines a rule condition. Precede a
|
|
<TT>RewriteRule</TT> directive with one or more <TT>RewriteCond</TT>
|
|
directives.
|
|
|
|
The following rewriting rule is only used if its pattern matches the current
|
|
state of the URI <STRONG>AND</STRONG> if these additional conditions apply, too.
|
|
|
|
<P>
|
|
<EM>TestString</EM> is a string which can contains the following
|
|
expanded constructs in addition to plain text:
|
|
|
|
<UL>
|
|
<LI><STRONG>RewriteRule backreferences</STRONG>: These are backreferences of the form
|
|
|
|
<BLOCKQUOTE><STRONG>
|
|
<TT>$N</TT>
|
|
</STRONG></BLOCKQUOTE>
|
|
|
|
(1 <= N <= 9) which provide access to the grouped parts (parenthesis!) of the
|
|
pattern from the corresponding <TT>RewriteRule</TT> directive (the one
|
|
following the current bunch of <TT>RewriteCond</TT> directives).
|
|
|
|
<P>
|
|
<LI><STRONG>RewriteCond backreferences</STRONG>: These are backreferences of the form
|
|
|
|
<BLOCKQUOTE><STRONG>
|
|
<TT>%N</TT>
|
|
</STRONG></BLOCKQUOTE>
|
|
|
|
(1 <= N <= 9) which provide access to the grouped parts (parenthesis!) of the
|
|
pattern from the last matched <TT>RewriteCond</TT> directive in the current
|
|
bunch of conditions.
|
|
|
|
<P>
|
|
<LI><STRONG>Server-Variables</STRONG>: These are variables
|
|
of the form
|
|
|
|
<BLOCKQUOTE><STRONG>
|
|
<TT>%{</TT> <EM>NAME_OF_VARIABLE</EM> <TT>}</TT>
|
|
</STRONG></BLOCKQUOTE>
|
|
|
|
where <EM>NAME_OF_VARIABLE</EM> can be a string
|
|
of the following list:
|
|
|
|
<P>
|
|
<table bgcolor="#f0f0f0" cellspacing=0 cellpadding=5>
|
|
<TR>
|
|
<td valign=top>
|
|
<STRONG>HTTP headers:</STRONG><P>
|
|
<font size=-1>
|
|
HTTP_USER_AGENT<BR>
|
|
HTTP_REFERER<BR>
|
|
HTTP_COOKIE<BR>
|
|
HTTP_FORWARDED<BR>
|
|
HTTP_HOST<BR>
|
|
HTTP_PROXY_CONNECTION<BR>
|
|
HTTP_ACCEPT<BR>
|
|
</FONT>
|
|
</TD>
|
|
|
|
<td valign=top>
|
|
<STRONG>connection & request:</STRONG><P>
|
|
<font size=-1>
|
|
REMOTE_ADDR<BR>
|
|
REMOTE_HOST<BR>
|
|
REMOTE_USER<BR>
|
|
REMOTE_IDENT<BR>
|
|
REQUEST_METHOD<BR>
|
|
SCRIPT_FILENAME<BR>
|
|
PATH_INFO<BR>
|
|
QUERY_STRING<BR>
|
|
AUTH_TYPE<BR>
|
|
</FONT>
|
|
</TD>
|
|
|
|
</TR>
|
|
<TR>
|
|
|
|
<td valign=top>
|
|
<STRONG>server internals:</STRONG><P>
|
|
<font size=-1>
|
|
DOCUMENT_ROOT<BR>
|
|
SERVER_ADMIN<BR>
|
|
SERVER_NAME<BR>
|
|
SERVER_PORT<BR>
|
|
SERVER_PROTOCOL<BR>
|
|
SERVER_SOFTWARE<BR>
|
|
SERVER_VERSION<BR>
|
|
</FONT>
|
|
</TD>
|
|
|
|
<td valign=top>
|
|
<STRONG>system stuff:</STRONG><P>
|
|
<font size=-1>
|
|
TIME_YEAR<BR>
|
|
TIME_MON<BR>
|
|
TIME_DAY<BR>
|
|
TIME_HOUR<BR>
|
|
TIME_MIN<BR>
|
|
TIME_SEC<BR>
|
|
TIME_WDAY<BR>
|
|
TIME<BR>
|
|
</FONT>
|
|
</TD>
|
|
|
|
<td valign=top>
|
|
<STRONG>specials:</STRONG><P>
|
|
<font size=-1>
|
|
API_VERSION<BR>
|
|
THE_REQUEST<BR>
|
|
REQUEST_URI<BR>
|
|
REQUEST_FILENAME<BR>
|
|
IS_SUBREQ<BR>
|
|
</FONT>
|
|
</TD>
|
|
</TR>
|
|
</TABLE>
|
|
|
|
<P>
|
|
<table width="70%" border=0 bgcolor="#f0f0f0" cellspacing=0 cellpadding=10>
|
|
<TR><TD>
|
|
These variables all correspond to the similar named HTTP MIME-headers, C
|
|
variables of the Apache server or <TT>struct tm</TT> fields of the Unix
|
|
system.
|
|
</TD></TR>
|
|
</TABLE>
|
|
|
|
</UL>
|
|
|
|
<P>
|
|
Special Notes:
|
|
<OL>
|
|
<LI>The variables SCRIPT_FILENAME and REQUEST_FILENAME contain the same
|
|
value, i.e. the value of the <TT>filename</TT> field of the internal
|
|
<TT>request_rec</TT> structure of the Apache server. The first name is just the
|
|
commonly known CGI variable name while the second is the consistent
|
|
counterpart to REQUEST_URI (which contains the value of the <TT>uri</TT>
|
|
field of <TT>request_rec</TT>).
|
|
|
|
<P>
|
|
<LI>There is the special format: <TT>%{ENV:variable}</TT> where
|
|
<EM>variable</EM> can be any environment variable. This is looked-up via
|
|
internal Apache structures and (if not found there) via <TT>getenv()</TT> from
|
|
the Apache server process.
|
|
|
|
<P>
|
|
<LI>There is the special format: <TT>%{HTTP:header}</TT> where
|
|
<EM>header</EM> can be any HTTP MIME-header name. This is looked-up
|
|
from the HTTP request. Example: <TT>%{HTTP:Proxy-Connection}</TT>
|
|
is the value of the HTTP header ``<TT>Proxy-Connection:</TT>''.
|
|
|
|
<P>
|
|
<LI>There is the special format: <TT>%{LA-U:url}</TT>
|
|
for look-aheads like <TT>-U</TT>. This performs a internal sub-request to
|
|
look-ahead for the final value of <EM>url</EM>.
|
|
|
|
<P>
|
|
<LI>There is the special format: <TT>%{LA-F:file}</TT>
|
|
for look-aheads like <TT>-F</TT>. This performs a internal sub-request to
|
|
look-ahead for the final value of <EM>file</EM>.
|
|
</OL>
|
|
|
|
<P>
|
|
<EM>CondPattern</EM> is the condition pattern, i.e. a regular expression
|
|
which gets applied to the current instance of the <EM>TestString</EM>, i.e.
|
|
<EM>TestString</EM> gets evaluated and then matched against
|
|
<EM>CondPattern</EM>.
|
|
|
|
<P>
|
|
<STRONG>Remember:</STRONG> <EM>CondPattern</EM> is a standard
|
|
<EM>Extended Regular Expression</EM> with some additions:
|
|
|
|
<OL>
|
|
<LI>You can precede the pattern string with a '<TT>!</TT>' character
|
|
(exclamation mark) to specify a <STRONG>non</STRONG>-matching pattern.
|
|
|
|
<P>
|
|
<LI>
|
|
There are some special variants of <EM>CondPatterns</EM>. Instead of real
|
|
regular expression strings you can also use one of the following:
|
|
<P>
|
|
<UL>
|
|
<LI>'<STRONG><CondPattern</STRONG>' (is lexicographically lower)<BR>
|
|
Treats the <EM>CondPattern</EM> as a plain string and compares it
|
|
lexicographically to <EM>TestString</EM> and results in a true expression if
|
|
<EM>TestString</EM> is lexicographically lower then <EM>CondPattern</EM>.
|
|
<P>
|
|
<LI>'<STRONG>>CondPattern</STRONG>' (is lexicographically greater)<BR>
|
|
Treats the <EM>CondPattern</EM> as a plain string and compares it
|
|
lexicographically to <EM>TestString</EM> and results in a true expression if
|
|
<EM>TestString</EM> is lexicographically greater then <EM>CondPattern</EM>.
|
|
<P>
|
|
<LI>'<STRONG>=CondPattern</STRONG>' (is lexicographically equal)<BR>
|
|
Treats the <EM>CondPattern</EM> as a plain string and compares it
|
|
lexicographically to <EM>TestString</EM> and results in a true expression if
|
|
<EM>TestString</EM> is lexicographically equal to <EM>CondPattern</EM>, i.e the
|
|
two strings are exactly equal (character by character).
|
|
If <EM>CondPattern</EM> is just <SAMP>""</SAMP> (two quotation marks) this
|
|
compares <EM>TestString</EM> against the empty string.
|
|
<P>
|
|
<LI>'<STRONG>-d</STRONG>' (is <STRONG>d</STRONG>irectory)<BR>
|
|
Treats the <EM>TestString</EM> as a pathname and
|
|
tests if it exists and is a directory.
|
|
<P>
|
|
<LI>'<STRONG>-f</STRONG>' (is regular <STRONG>f</STRONG>ile)<BR>
|
|
Treats the <EM>TestString</EM> as a pathname and
|
|
tests if it exists and is a regular file.
|
|
<P>
|
|
<LI>'<STRONG>-s</STRONG>' (is regular file with <STRONG>s</STRONG>ize)<BR>
|
|
Treats the <EM>TestString</EM> as a pathname and
|
|
tests if it exists and is a regular file with size greater then zero.
|
|
<P>
|
|
<LI>'<STRONG>-l</STRONG>' (is symbolic <STRONG>l</STRONG>ink)<BR>
|
|
Treats the <EM>TestString</EM> as a pathname and
|
|
tests if it exists and is a symbolic link.
|
|
<P>
|
|
<LI>'<STRONG>-F</STRONG>' (is existing file via subrequest)<BR>
|
|
Checks if <EM>TestString</EM> is a valid file and accessible via all the
|
|
server's currently-configured access controls for that path. This uses an
|
|
internal subrequest to determine the check, so use it with care because it
|
|
decreases your servers performance!
|
|
<P>
|
|
<LI>'<STRONG>-U</STRONG>' (is existing URL via subrequest)<BR>
|
|
Checks if <EM>TestString</EM> is a valid URL and accessible via all the server's
|
|
currently-configured access controls for that path. This uses an internal
|
|
subrequest to determine the check, so use it with care because it decreases
|
|
your servers performance!
|
|
</UL>
|
|
<P>
|
|
Notice: All of these tests can also be prefixed by a not ('!') character
|
|
to negate their meaning.
|
|
</OL>
|
|
|
|
<P>
|
|
Additionally you can set special flags for <EM>CondPattern</EM> by appending
|
|
|
|
<BLOCKQUOTE><STRONG>
|
|
<CODE>[</CODE><EM>flags</EM><CODE>]</CODE>
|
|
</STRONG></BLOCKQUOTE>
|
|
|
|
as the third argument to the <TT>RewriteCond</TT> directive. <EM>Flags</EM>
|
|
is a comma-separated list of the following flags:
|
|
|
|
<UL>
|
|
<LI>'<STRONG><CODE>nocase|NC</CODE></STRONG>' (<STRONG>n</STRONG>o <STRONG>c</STRONG>ase)<BR>
|
|
This makes the condition test case-insensitive, i.e. there is
|
|
no difference between 'A-Z' and 'a-z' both in the expanded
|
|
<EM>TestString</EM> and the <EM>CondPattern</EM>.
|
|
<P>
|
|
<LI>'<STRONG><CODE>ornext|OR</CODE></STRONG>' (<STRONG>or</STRONG> next condition)<BR>
|
|
Use this to combine rule conditions with a local OR instead of the
|
|
implicit AND. Typical example:
|
|
<P>
|
|
<BLOCKQUOTE><PRE>
|
|
RewriteCond %{REMOTE_HOST} ^host1.* [OR]
|
|
RewriteCond %{REMOTE_HOST} ^host2.* [OR]
|
|
RewriteCond %{REMOTE_HOST} ^host3.*
|
|
RewriteRule ...some special stuff for any of these hosts...
|
|
</PRE></BLOCKQUOTE>
|
|
Without this flag you had to write down the cond/rule three times.
|
|
</UL>
|
|
|
|
<P>
|
|
<STRONG>Example:</STRONG>
|
|
<BLOCKQUOTE>
|
|
|
|
To rewrite the Homepage of a site according to the ``<TT>User-Agent:</TT>''
|
|
header of the request, you can use the following:
|
|
|
|
<BLOCKQUOTE><PRE>
|
|
RewriteCond %{HTTP_USER_AGENT} ^Mozilla.*
|
|
RewriteRule ^/$ /homepage.max.html [L]
|
|
|
|
RewriteCond %{HTTP_USER_AGENT} ^Lynx.*
|
|
RewriteRule ^/$ /homepage.min.html [L]
|
|
|
|
RewriteRule ^/$ /homepage.std.html [L]
|
|
</PRE></BLOCKQUOTE>
|
|
|
|
Interpretation: If you use Netscape Navigator as your browser (which identifies
|
|
itself as 'Mozilla'), then you get the max homepage, which includes
|
|
Frames, etc. If you use the Lynx browser (which is Terminal-based), then you
|
|
get the min homepage, which contains no images, no tables, etc. If you
|
|
use any other browser you get the standard homepage.
|
|
</BLOCKQUOTE>
|
|
|
|
<P>
|
|
<hr noshade size=1>
|
|
<P>
|
|
|
|
<A name="RewriteRule"><H3>RewriteRule</H3></A>
|
|
<A
|
|
HREF="directive-dict.html#Syntax"
|
|
REL="Help"
|
|
><STRONG>Syntax:</STRONG></A> <CODE>RewriteRule</CODE> <EM>Pattern</EM> <EM>Substitution</EM><BR>
|
|
<A
|
|
HREF="directive-dict.html#Default"
|
|
REL="Help"
|
|
><STRONG>Default:</STRONG></A> -<EM>None</EM>-<BR>
|
|
<A
|
|
HREF="directive-dict.html#Context"
|
|
REL="Help"
|
|
><STRONG>Context:</STRONG></A> server config, virtual host, per-directory config<BR>
|
|
|
|
<P>
|
|
The <TT>RewriteRule</TT> directive is the real rewriting workhorse. The
|
|
directive can occur more than once. Each directive then defines one single
|
|
rewriting rule. The <STRONG>definition order</STRONG> of these rules is
|
|
<STRONG>important</STRONG>, because this order is used when applying the rules at
|
|
run-time.
|
|
|
|
<P>
|
|
<A name="patterns"><EM>Pattern</EM></A> can be (for Apache 1.1.x a System
|
|
V8 and for Apache 1.2.x a POSIX) <A name="regexp">regular expression</A>
|
|
which gets applied to the current URL. Here ``current'' means the value of the
|
|
URL when this rule gets applied. This may not be the original requested
|
|
URL, because there could be any number of rules before which already matched
|
|
and made alterations to it.
|
|
|
|
<P>
|
|
Some hints about the syntax of regular expressions:
|
|
|
|
<P>
|
|
<table bgcolor="#f0f0f0" cellspacing=0 cellpadding=5>
|
|
<TR>
|
|
<td valign=top>
|
|
<PRE>
|
|
<STRONG><CODE>^</CODE></STRONG> Start of line
|
|
<STRONG><CODE>$</CODE></STRONG> End of line
|
|
<STRONG><CODE>.</CODE></STRONG> Any single character
|
|
<STRONG><CODE>[</CODE></STRONG>chars<STRONG><CODE>]</CODE></STRONG> One of chars
|
|
<STRONG><CODE>[^</CODE></STRONG>chars<STRONG><CODE>]</CODE></STRONG> None of chars
|
|
|
|
<STRONG><CODE>?</CODE></STRONG> 0 or 1 of the preceding char
|
|
<STRONG><CODE>*</CODE></STRONG> 0 or N of the preceding char
|
|
<STRONG><CODE>+</CODE></STRONG> 1 or N of the preceding char
|
|
|
|
<STRONG><CODE>\</CODE></STRONG>char escape that specific char
|
|
(e.g. for specifying the chars "<CODE>.[]()</CODE>" etc.)
|
|
|
|
<STRONG><CODE>(</CODE></STRONG>string<STRONG><CODE>)</CODE></STRONG> Grouping of chars (the <STRONG>N</STRONG>th group can be used on the RHS with <CODE>$</CODE><STRONG>N</STRONG>)
|
|
</PRE>
|
|
</TD>
|
|
</TR>
|
|
</TABLE>
|
|
|
|
<P>
|
|
Additionally the NOT character ('<TT>!</TT>') is a possible pattern
|
|
prefix. This gives you the ability to negate a pattern; to say, for instance: ``<EM>if
|
|
the current URL does <STRONG>NOT</STRONG> match to this pattern</EM>''. This can be used
|
|
for special cases where it is better to match the negative pattern or as a
|
|
last default rule.
|
|
|
|
<P>
|
|
<table width="70%" border=0 bgcolor="#fff0f0" cellspacing=0 cellpadding=10>
|
|
<TR><TD>
|
|
<STRONG>Notice!</STRONG> When using the NOT character to negate a pattern you cannot
|
|
have grouped wildcard parts in the pattern. This is impossible because when
|
|
the pattern does NOT match, there are no contents for the groups. In
|
|
consequence, if negated patterns are used, you cannot use <TT>$N</TT> in the
|
|
substitution string!
|
|
</TD></TR>
|
|
</TABLE>
|
|
|
|
<P>
|
|
<A name="rhs"><EM>Substitution</EM></A> of a rewriting rule is the string
|
|
which is substituted for (or replaces) the original URL for which
|
|
<EM>Pattern</EM> matched. Beside plain text you can use
|
|
|
|
<OL>
|
|
<LI>back-references <CODE>$N</CODE> to the RewriteRule pattern
|
|
<LI>back-references <CODE>%N</CODE> to the last matched RewriteCond pattern
|
|
<LI>server-variables as in rule condition test-strings (<CODE>%{VARNAME}</CODE>)
|
|
<LI><A HREF="#mapfunc">mapping-function</A> calls (<CODE>${mapname:key|default}</CODE>)
|
|
</OL>
|
|
|
|
Back-references are <CODE>$</CODE><STRONG>N</STRONG> (<STRONG>N</STRONG>=1..9) identifiers which
|
|
will be replaced by the contents of the <STRONG>N</STRONG>th group of the matched
|
|
<EM>Pattern</EM>. The server-variables are the same as for the
|
|
<EM>TestString</EM> of a <TT>RewriteCond</TT> directive. The
|
|
mapping-functions come from the <TT>RewriteMap</TT> directive and are
|
|
explained there. These three types of variables are expanded in the order of
|
|
the above list.
|
|
|
|
<P>
|
|
As already mentioned above, all the rewriting rules are applied to the
|
|
<EM>Substitution</EM> (in the order of definition in the config file). The
|
|
URL is <STRONG>completely replaced</STRONG> by the <EM>Substitution</EM> and the
|
|
rewriting process goes on until there are no more rules (unless explicitly
|
|
terminated by a <CODE><STRONG>L</STRONG></CODE> flag - see below).
|
|
|
|
<P>
|
|
There is a special substitution string named '<TT>-</TT>' which means:
|
|
<STRONG>NO substitution</STRONG>! Sounds silly? No, it is useful to provide rewriting
|
|
rules which <STRONG>only</STRONG> match some URLs but do no substitution, e.g. in
|
|
conjunction with the <STRONG>C</STRONG> (chain) flag to be able to have more than one
|
|
pattern to be applied before a substitution occurs.
|
|
|
|
<P>
|
|
One more note: You can even create URLs in the substitution string containing
|
|
a query string part. Just use a question mark inside the substitution string
|
|
to indicate that the following stuff should be re-injected into the
|
|
QUERY_STRING. When you want to erase an existing query string, end the
|
|
substitution string with just the question mark.
|
|
|
|
<P>
|
|
<table width="70%" border=0 bgcolor="#fff0f0" cellspacing=0 cellpadding=10>
|
|
<TR><TD>
|
|
<STRONG>Notice</STRONG>: There is a special feature. When you prefix a substitution
|
|
field with <TT>http://</TT><EM>thishost</EM>[<EM>:thisport</EM>] then
|
|
<STRONG>mod_rewrite</STRONG> automatically strips it out. This auto-reduction on
|
|
implicit external redirect URLs is a useful and important feature when
|
|
used in combination with a mapping-function which generates the hostname
|
|
part. Have a look at the first example in the example section below to
|
|
understand this.
|
|
<P>
|
|
<STRONG>Remember:</STRONG> An unconditional external redirect to your own server will
|
|
not work with the prefix <TT>http://thishost</TT> because of this feature.
|
|
To achieve such a self-redirect, you have to use the <STRONG>R</STRONG>-flag (see
|
|
below).
|
|
</TD></TR>
|
|
</TABLE>
|
|
|
|
<P>
|
|
Additionally you can set special flags for <EM>Substitution</EM> by appending
|
|
|
|
<BLOCKQUOTE><STRONG>
|
|
<CODE>[</CODE><EM>flags</EM><CODE>]</CODE>
|
|
</STRONG></BLOCKQUOTE>
|
|
|
|
as the third argument to the <TT>RewriteRule</TT> directive. <EM>Flags</EM> is a
|
|
comma-separated list of the following flags:
|
|
|
|
<UL>
|
|
<LI>'<STRONG><CODE>redirect|R</CODE>[=<EM>code</EM>]</STRONG>' (force <A name="redirect"><STRONG>r</STRONG>edirect</A>)<BR>
|
|
Prefix <EM>Substitution</EM>
|
|
with <CODE>http://thishost[:thisport]/</CODE> (which makes the new URL a URI) to
|
|
force a external redirection. If no <EM>code</EM> is given a HTTP response
|
|
of 302 (MOVED TEMPORARILY) is used. If you want to use other response
|
|
codes in the range 300-400 just specify them as a number or use
|
|
one of the following symbolic names: <TT>temp</TT> (default), <TT>permanent</TT>,
|
|
<TT>seeother</TT>.
|
|
Use it for rules which should
|
|
canonicalize the URL and gives it back to the client, e.g. translate
|
|
``<CODE>/~</CODE>'' into ``<CODE>/u/</CODE>'' or always append a slash to
|
|
<CODE>/u/</CODE><EM>user</EM>, etc.<BR>
|
|
<P>
|
|
<STRONG>Notice:</STRONG> When you use this flag, make sure that the
|
|
substitution field is a valid URL! If not, you are redirecting to an
|
|
invalid location! And remember that this flag itself only prefixes the
|
|
URL with <CODE>http://thishost[:thisport]/</CODE>, but rewriting goes on.
|
|
Usually you also want to stop and do the redirection immediately. To stop
|
|
the rewriting you also have to provide the 'L' flag.
|
|
<P>
|
|
<LI>'<STRONG><CODE>forbidden|F</CODE></STRONG>' (force URL to be <STRONG>f</STRONG>orbidden)<BR>
|
|
This forces the current URL to be forbidden, i.e. it immediately sends
|
|
back a HTTP response of 403 (FORBIDDEN). Use this flag in conjunction with
|
|
appropriate RewriteConds to conditionally block some URLs.
|
|
<P>
|
|
<LI>'<STRONG><CODE>gone|G</CODE></STRONG>' (force URL to be <STRONG>g</STRONG>one)<BR>
|
|
This forces the current URL to be gone, i.e. it immediately sends back a
|
|
HTTP response of 410 (GONE). Use this flag to mark no longer existing
|
|
pages as gone.
|
|
<P>
|
|
<LI>'<STRONG><CODE>proxy|P</CODE></STRONG>' (force <STRONG>p</STRONG>roxy)<BR>
|
|
This flag forces the substitution part to be internally forced as a proxy
|
|
request and immediately (i.e. rewriting rule processing stops here) put
|
|
through the proxy module. You have to make sure that the substitution
|
|
string is a valid URI (e.g. typically <TT>http://</TT>) which can
|
|
be handled by the Apache proxy module. If not you get an error from
|
|
the proxy module. Use this flag to achieve a more powerful implementation
|
|
of the <TT>mod_proxy</TT> directive <TT>ProxyPass</TT>, to map
|
|
some remote stuff into the namespace of the local server.
|
|
<P>
|
|
Notice: <STRONG>You really have to put <TT>ProxyRequests On</TT> into your
|
|
server configuration to prevent proxy requests from leading to core-dumps
|
|
inside the Apache kernel. If you have not compiled in the proxy module,
|
|
then there is no core-dump problem, because mod_rewrite checks for
|
|
existence of the proxy module and if lost forbids proxy URLs. </STRONG>
|
|
<P>
|
|
<LI>'<STRONG><CODE>last|L</CODE></STRONG>' (<STRONG>l</STRONG>ast rule)<BR>
|
|
Stop the rewriting process here and
|
|
don't apply any more rewriting rules. This corresponds to the Perl
|
|
<CODE>last</CODE> command or the <CODE>break</CODE> command from the C
|
|
language. Use this flag to prevent the currently rewritten URL from being
|
|
rewritten further by following rules which may be wrong. For
|
|
example, use it to rewrite the root-path URL ('<CODE>/</CODE>') to a real
|
|
one, e.g. '<CODE>/e/www/</CODE>'.
|
|
<P>
|
|
<LI>'<STRONG><CODE>next|N</CODE></STRONG>' (<STRONG>n</STRONG>ext round)<BR>
|
|
Re-run the rewriting process (starting again with the first rewriting
|
|
rule). Here the URL to match is again not the original URL but the URL
|
|
from the last rewriting rule. This corresponds to the Perl
|
|
<CODE>next</CODE> command or the <CODE>continue</CODE> command from the C
|
|
language. Use this flag to restart the rewriting process, i.e. to
|
|
immediately go to the top of the loop. <BR>
|
|
<STRONG>But be careful not to create a deadloop!</STRONG>
|
|
<P>
|
|
<LI>'<STRONG><CODE>chain|C</CODE></STRONG>' (<STRONG>c</STRONG>hained with next rule)<BR>
|
|
This flag chains the current rule with the next rule (which itself can
|
|
also be chained with its following rule, etc.). This has the following
|
|
effect: if a rule matches, then processing continues as usual, i.e. the
|
|
flag has no effect. If the rule does <STRONG>not</STRONG> match, then all following
|
|
chained rules are skipped. For instance, use it to remove the
|
|
``<TT>.www</TT>'' part inside a per-directory rule set when you let an
|
|
external redirect happen (where the ``<TT>.www</TT>'' part should not to
|
|
occur!).
|
|
<P>
|
|
<LI>'<STRONG><CODE>type|T</CODE></STRONG>=<EM>mime-type</EM>' (force MIME <STRONG>t</STRONG>ype)<BR>
|
|
Force the MIME-type of the target file to be <EM>mime-type</EM>. For
|
|
instance, this can be used to simulate the old <TT>mod_alias</TT>
|
|
directive <TT>ScriptAlias</TT> which internally forces all files inside
|
|
the mapped directory to have a MIME type of
|
|
``<TT>application/x-httpd-cgi</TT>''.
|
|
<P>
|
|
<LI>'<STRONG><CODE>nosubreq|NS</CODE></STRONG>' (used only if <STRONG>n</STRONG>o internal <STRONG>s</STRONG>ub-request)<BR>
|
|
This flag forces the rewriting engine to skip a rewriting rule if the
|
|
current request is an internal sub-request. For instance, sub-requests
|
|
occur internally in Apache when <TT>mod_include</TT> tries to find out
|
|
information about possible directory default files (<TT>index.xxx</TT>).
|
|
On sub-requests it is not always useful and even sometimes causes a failure to
|
|
if the complete set of rules are applied. Use this flag to exclude some rules.<BR>
|
|
<P>
|
|
Use the following rule for your decision: whenever you prefix some URLs
|
|
with CGI-scripts to force them to be processed by the CGI-script, the
|
|
chance is high that you will run into problems (or even overhead) on sub-requests.
|
|
In these cases, use this flag.
|
|
<P>
|
|
<LI>'<STRONG><CODE>qsappend|QSA</CODE></STRONG>' (<STRONG>q</STRONG>uery <STRONG>s</STRONG>tring
|
|
<STRONG>a</STRONG>ppend)<BR>
|
|
This flag forces the rewriting engine to append a query
|
|
string part in the substitution string to the existing one instead of
|
|
replacing it. Use this when you want to add more data to the query string
|
|
via a rewrite rule.
|
|
<P>
|
|
<LI>'<STRONG><CODE>passthrough|PT</CODE></STRONG>' (<STRONG>p</STRONG>ass <STRONG>t</STRONG>hrough to next handler)<BR>
|
|
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
|
|
semantics:
|
|
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>
|
|
with <TT>mod_alias</TT>:
|
|
<PRE>
|
|
RewriteRule ^/abc(.*) /def$1 [PT]
|
|
Alias /def /ghi
|
|
</PRE>
|
|
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.
|
|
<P>
|
|
Notice: <STRONG>You have to use this flag if you want to intermix directives
|
|
of different modules which contain URL-to-filename translators</STRONG>. The
|
|
typical example is the use of <TT>mod_alias</TT> and
|
|
<TT>mod_rewrite</TT>..
|
|
<P>
|
|
<table width="70%" border=0 bgcolor="#fff0f0" cellspacing=0 cellpadding=10>
|
|
<TR><TD>
|
|
<font size=-1>
|
|
<STRONG>For the Apache hackers:</STRONG><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.
|
|
</FONT>
|
|
</TD></TR>
|
|
</TABLE>
|
|
<P>
|
|
<LI>'<STRONG><CODE>skip|S</CODE></STRONG>=<EM>num</EM>' (<STRONG>s</STRONG>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 <STRONG>not</STRONG> the same as the 'chain|C' flag!)
|
|
<P>
|
|
<LI>'<STRONG><CODE>env|E=</CODE></STRONG><EM>VAR</EM>:<EM>VAL</EM>' (set <STRONG>e</STRONG>nvironment variable)<BR>
|
|
This forces an environment variable named <EM>VAR</EM> to be set to the
|
|
value <EM>VAL</EM>, where <EM>VAL</EM> can contain regexp backreferences
|
|
<TT>$N</TT> and <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 information from URLs.
|
|
</UL>
|
|
|
|
<P>
|
|
<table width="70%" border=0 bgcolor="#fff0f0" cellspacing=0 cellpadding=10>
|
|
<TR><TD>
|
|
Remember: Never forget that <EM>Pattern</EM> gets applied to a complete URL
|
|
in per-server configuration files. <STRONG>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.</STRONG> 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.
|
|
<P>
|
|
There is one exception: If a substitution string starts with
|
|
``<TT>http://</TT>'' then the directory prefix will be <STRONG>not</STRONG> added and a
|
|
external redirect or proxy throughput (if flag <STRONG>P</STRONG> is used!) is forced!
|
|
</TD></TR>
|
|
</TABLE>
|
|
|
|
<P>
|
|
<table width="70%" border=0 bgcolor="#fff0f0" cellspacing=0 cellpadding=10>
|
|
<TR><TD>
|
|
Notice! To enable the rewriting engine for per-directory configuration files
|
|
you need to set ``<TT>RewriteEngine On</TT>'' in these files <STRONG>and</STRONG>
|
|
``<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
|
|
security reasons.
|
|
</TD></TR>
|
|
</TABLE>
|
|
|
|
<P>
|
|
Here are all possible substitution combinations and their meanings:
|
|
|
|
<P>
|
|
<STRONG>Inside per-server configuration (<TT>httpd.conf</TT>)<BR>
|
|
for request ``<TT>GET /somepath/pathinfo</TT>'':</STRONG><BR>
|
|
|
|
<P>
|
|
<table bgcolor="#f0f0f0" cellspacing=0 cellpadding=5>
|
|
<TR>
|
|
<TD>
|
|
<PRE>
|
|
<STRONG>Given Rule</STRONG> <STRONG>Resulting Substitution</STRONG>
|
|
---------------------------------------------- ----------------------------------
|
|
^/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 /otherpath/pathinfo
|
|
|
|
^/somepath(.*) /otherpath$1 [R] http://thishost/otherpath/pathinfo
|
|
via external redirection
|
|
|
|
^/somepath(.*) /otherpath$1 [P] not supported, because silly!
|
|
---------------------------------------------- ----------------------------------
|
|
^/somepath(.*) http://thishost/otherpath$1 /otherpath/pathinfo
|
|
|
|
^/somepath(.*) http://thishost/otherpath$1 [R] http://thishost/otherpath/pathinfo
|
|
via external redirection
|
|
|
|
^/somepath(.*) http://thishost/otherpath$1 [P] not supported, because silly!
|
|
---------------------------------------------- ----------------------------------
|
|
^/somepath(.*) http://otherhost/otherpath$1 http://otherhost/otherpath/pathinfo
|
|
via external redirection
|
|
|
|
^/somepath(.*) http://otherhost/otherpath$1 [R] http://otherhost/otherpath/pathinfo
|
|
via external redirection
|
|
(the [R] flag is redundant)
|
|
|
|
^/somepath(.*) http://otherhost/otherpath$1 [P] http://otherhost/otherpath/pathinfo
|
|
via internal proxy
|
|
</PRE>
|
|
</TD>
|
|
</TR>
|
|
</TABLE>
|
|
|
|
<P>
|
|
<STRONG>Inside per-directory configuration for <TT>/somepath</TT><BR>
|
|
(i.e. file <TT>.htaccess</TT> in dir <TT>/physical/path/to/somepath</TT> containing
|
|
<TT>RewriteBase /somepath</TT>)<BR> for
|
|
request ``<TT>GET /somepath/localpath/pathinfo</TT>'':</STRONG><BR>
|
|
|
|
<P>
|
|
<table bgcolor="#f0f0f0" cellspacing=0 cellpadding=5>
|
|
<TR>
|
|
<TD>
|
|
<PRE>
|
|
<STRONG>Given Rule</STRONG> <STRONG>Resulting Substitution</STRONG>
|
|
---------------------------------------------- ----------------------------------
|
|
^localpath(.*) otherpath$1 /somepath/otherpath/pathinfo
|
|
|
|
^localpath(.*) otherpath$1 [R] http://thishost/somepath/otherpath/pathinfo
|
|
via external redirection
|
|
|
|
^localpath(.*) otherpath$1 [P] not supported, because silly!
|
|
---------------------------------------------- ----------------------------------
|
|
^localpath(.*) /otherpath$1 /otherpath/pathinfo
|
|
|
|
^localpath(.*) /otherpath$1 [R] http://thishost/otherpath/pathinfo
|
|
via external redirection
|
|
|
|
^localpath(.*) /otherpath$1 [P] not supported, because silly!
|
|
---------------------------------------------- ----------------------------------
|
|
^localpath(.*) http://thishost/otherpath$1 /otherpath/pathinfo
|
|
|
|
^localpath(.*) http://thishost/otherpath$1 [R] http://thishost/otherpath/pathinfo
|
|
via external redirection
|
|
|
|
^localpath(.*) http://thishost/otherpath$1 [P] not supported, because silly!
|
|
---------------------------------------------- ----------------------------------
|
|
^localpath(.*) http://otherhost/otherpath$1 http://otherhost/otherpath/pathinfo
|
|
via external redirection
|
|
|
|
^localpath(.*) http://otherhost/otherpath$1 [R] http://otherhost/otherpath/pathinfo
|
|
via external redirection
|
|
(the [R] flag is redundant)
|
|
|
|
^localpath(.*) http://otherhost/otherpath$1 [P] http://otherhost/otherpath/pathinfo
|
|
via internal proxy
|
|
</PRE>
|
|
</TD>
|
|
</TR>
|
|
</TABLE>
|
|
|
|
|
|
<P>
|
|
<STRONG>Example:</STRONG>
|
|
<P>
|
|
<BLOCKQUOTE>
|
|
We want to rewrite URLs of the form
|
|
<BLOCKQUOTE>
|
|
<CODE>/</CODE> <EM>Language</EM>
|
|
<CODE>/~</CODE> <EM>Realname</EM>
|
|
<CODE>/.../</CODE> <EM>File</EM>
|
|
</BLOCKQUOTE>
|
|
into
|
|
<BLOCKQUOTE>
|
|
<CODE>/u/</CODE> <EM>Username</EM>
|
|
<CODE>/.../</CODE> <EM>File</EM>
|
|
<CODE>.</CODE> <EM>Language</EM>
|
|
</BLOCKQUOTE>
|
|
<P>
|
|
We take the rewrite mapfile from above and save it under
|
|
<CODE>/anywhere/map.real-to-user</CODE>. Then we only have to add the
|
|
following lines to the Apache server configuration file:
|
|
|
|
<BLOCKQUOTE>
|
|
<PRE>
|
|
RewriteLog /anywhere/rewrite.log
|
|
RewriteMap real-to-user txt:/anywhere/map.real-to-host
|
|
RewriteRule ^/([^/]+)/~([^/]+)/(.*)$ /u/${real-to-user:$2|nobody}/$3.$1
|
|
</PRE>
|
|
</BLOCKQUOTE>
|
|
</BLOCKQUOTE>
|
|
|
|
|
|
<!--%hypertext -->
|
|
<HR>
|
|
<!--/%hypertext -->
|
|
|
|
<CENTER>
|
|
<A name="Additional">
|
|
<H1>Additional Features</H1>
|
|
</A>
|
|
</CENTER>
|
|
|
|
<A name="EnvVar">
|
|
<H2>Environment Variables</H2>
|
|
</A>
|
|
|
|
This module keeps track of two additional (non-standard) CGI/SSI environment
|
|
variables named <TT>SCRIPT_URL</TT> and <TT>SCRIPT_URI</TT>. These contain
|
|
the <EM>logical</EM> Web-view to the current resource, while the standard CGI/SSI
|
|
variables <TT>SCRIPT_NAME</TT> and <TT>SCRIPT_FILENAME</TT> contain the
|
|
<EM>physical</EM> System-view.
|
|
|
|
<P>
|
|
Notice: These variables hold the URI/URL <EM>as they were initially
|
|
requested</EM>, i.e. in a state <EM>before</EM> any rewriting. This is
|
|
important because the rewriting process is primarily used to rewrite logical
|
|
URLs to physical pathnames.
|
|
|
|
<P>
|
|
<STRONG>Example:</STRONG>
|
|
|
|
<BLOCKQUOTE>
|
|
<PRE>
|
|
SCRIPT_NAME=/v/sw/free/lib/apache/global/u/rse/.www/index.html
|
|
SCRIPT_FILENAME=/u/rse/.www/index.html
|
|
SCRIPT_URL=/u/rse/
|
|
SCRIPT_URI=http://en2.en.sdm.de/u/rse/
|
|
</PRE>
|
|
</BLOCKQUOTE>
|
|
|
|
|
|
<!--#include virtual="footer.html" -->
|
|
</BODY>
|
|
</HTML>
|
|
<!--/%hypertext -->
|