mirror of
				https://github.com/apache/httpd.git
				synced 2025-10-30 08:05:39 +03:00 
			
		
		
		
	Submitted by: Youichirou Koga <y-koga@jp.FreeBSD.ORG> Reviewed by: Ralf S. Engelschall PR: 2895 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@81954 13f79535-47bb-0310-9956-ffa450edef68
		
			
				
	
	
		
			1835 lines
		
	
	
		
			67 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			1835 lines
		
	
	
		
			67 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"
 | |
| >
 | |
| <BLOCKQUOTE><!-- page indentation -->
 | |
| <!--#include virtual="header.html" -->
 | |
| 
 | |
| <BR>
 | |
| <H1 ALIGN="CENTER">Module mod_rewrite<BR>URL Rewriting Engine</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. It 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 <CODE>Configuration</CODE> file:
 | |
| <PRE>
 | |
|     AddModule  modules/standard/mod_rewrite.o
 | |
| </PRE>
 | |
| 
 | |
| <P>
 | |
| <HR NOSHADE SIZE=1>
 | |
| 
 | |
| <BR>
 | |
| <H2>Summary</H2>
 | |
| 
 | |
| <BLOCKQUOTE>
 | |
| <BLOCKQUOTE>
 | |
| <BLOCKQUOTE>
 | |
| <EM>``The great thing about mod_rewrite is it gives you all the
 | |
| configurability and flexibility of Sendmail. The downside to
 | |
| mod_rewrite is that it gives you all the configurability and
 | |
| flexibility of Sendmail.''</EM>
 | |
| <DIV ALIGN=RIGHT>
 | |
| -- Brian Behlendorf<BR>
 | |
| Apache Group
 | |
| </DIV>
 | |
| </BLOCKQUOTE>
 | |
| </BLOCKQUOTE>
 | |
| </BLOCKQUOTE>
 | |
| 
 | |
| <BLOCKQUOTE>
 | |
| <BLOCKQUOTE>
 | |
| <BLOCKQUOTE>
 | |
| <EM>``
 | |
| Despite the tons of examples and docs, mod_rewrite
 | |
| is voodoo. Damned cool voodoo, but still voodoo.
 | |
| ''</EM>
 | |
| <DIV ALIGN=RIGHT>
 | |
| -- Brian Moore<BR>
 | |
| bem@news.cmc.net
 | |
| </DIV>
 | |
| </BLOCKQUOTE>
 | |
| </BLOCKQUOTE>
 | |
| </BLOCKQUOTE>
 | |
| 
 | |
| Welcome to mod_rewrite, the Swiss Army Knife of URL manipulation!
 | |
| 
 | |
| <P>
 | |
| This module uses a rule-based rewriting engine (based on a regular-expression
 | |
| parser) to rewrite requested URLs on the fly. It supports an unlimited number
 | |
| of rules and an unlimited number of attached rule conditions for each rule to
 | |
| provide a really flexible and powerful URL manipulation mechanism.  The URL
 | |
| manipulations can depend on various tests, for instance server variables,
 | |
| environment variables, HTTP headers, time stamps and even external database
 | |
| lookups in various formats can be used to achieve a really granular URL
 | |
| matching. 
 | |
| 
 | |
| <P>
 | |
| This module operates on the full URLs (including the path-info part) both in
 | |
| per-server context (<CODE>httpd.conf</CODE>) and per-directory context
 | |
| (<CODE>.htaccess</CODE>) and even can generate query-string parts on result.
 | |
| The rewritten result can lead to internal sub-processing, external request
 | |
| redirection or even to an internal proxy throughput.
 | |
| 
 | |
| <P>
 | |
| But all this functionality and flexibility has its drawback: complexity. So
 | |
| don't expect to understand this module in it's whole in just one day.
 | |
| 
 | |
| <P>
 | |
| This module was invented and originally written in April 1996<BR>
 | |
| and gifted exclusively to the The Apache Group in July 1997 by
 | |
| 
 | |
| <P>
 | |
| <BLOCKQUOTE>
 | |
| <A HREF="http://www.engelschall.com/"><CODE>Ralf S. Engelschall</CODE></A><BR>
 | |
| <A HREF="mailto:rse@engelschall.com"><CODE>rse@engelschall.com</CODE></A><BR>
 | |
| <A HREF="http://www.engelschall.com/"><CODE>www.engelschall.com</CODE></A>
 | |
| </BLOCKQUOTE>
 | |
| 
 | |
| <P>
 | |
| <HR NOSHADE SIZE=1>
 | |
| 
 | |
| <H2>Table Of Contents</H2>
 | |
| 
 | |
| <P>
 | |
| <STRONG>Internal Processing</STRONG>
 | |
| <UL>
 | |
|     <LI><A HREF="#InternalAPI">API Phases</A>
 | |
|     <LI><A HREF="#InternalRuleset">Ruleset Processing</A>
 | |
|     <LI><A HREF="#InternalBackRefs">Regex Back-Reference Availability</A>
 | |
| </UL>
 | |
| <P>
 | |
| <STRONG>Configuration Directives</STRONG>
 | |
| <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="#RewriteLock">RewriteLock</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>
 | |
| <STRONG>Miscellaneous</STRONG>
 | |
| <UL>
 | |
|     <LI><A HREF="#EnvVar">Environment Variables</A>
 | |
|     <LI><A HREF="#Solutions">Practical Solutions</A>
 | |
| </UL>
 | |
| 
 | |
| <P>
 | |
| <HR NOSHADE SIZE=1>
 | |
| 
 | |
| <CENTER>
 | |
| <H1><A NAME="Internal">Internal Processing</A></H1>
 | |
| </CENTER>
 | |
| 
 | |
| <P>
 | |
| <HR NOSHADE SIZE=1>
 | |
| 
 | |
| <P>
 | |
| The internal processing of this module is very complex but needs to be
 | |
| explained once even to the average user to avoid common mistakes and to let
 | |
| you exploit its full functionality. 
 | |
| 
 | |
| <H2><A NAME="InternalAPI">API Phases</A></H2>
 | |
| 
 | |
| <P>
 | |
| First you have to understand that when Apache processes a HTTP request it does
 | |
| this in phases. A hook for each of these phases is provided by the Apache API.
 | |
| Mod_rewrite uses two of these hooks: the URL-to-filename translation hook
 | |
| which is used after the HTTP request was read and before any authorization
 | |
| starts and the Fixup hook which is triggered after the authorization phases
 | |
| and after the per-directory config files (<CODE>.htaccess</CODE>) where read,
 | |
| but before the content handler is activated.
 | |
| 
 | |
| <P>
 | |
| So, after a request comes in and Apache has determined the corresponding
 | |
| server (or virtual server) the rewriting engine start processing of all
 | |
| mod_rewrite directives from the per-server configuration in the
 | |
| URL-to-filename phase. A few steps later when the final data directories are
 | |
| found, the per-directory configuration directives of mod_rewrite are triggered
 | |
| in the Fixup phase. In both situations mod_rewrite either rewrites URLs to new
 | |
| URLs or to filenames, although there is no obvious distinction between them.
 | |
| This is a usage of the API which was not intended this way when the API
 | |
| was designed, but as of Apache 1.x this is the only way mod_rewrite can
 | |
| operate. To make this point more clear remember the following two points:
 | |
| 
 | |
| <OL>
 | |
| <LI>The API currently provides only a URL-to-filename hook. Although
 | |
|     mod_rewrite rewrites URLs to URLs, URLs to filenames and even
 | |
|     filenames to filenames. In Apache 2.0 the two missing hooks 
 | |
|     will be added to make the processing more clear. But this
 | |
|     point has no drawbacks for the user, it is just a fact which
 | |
|     should be remembered: Apache does more in the URL-to-filename hook
 | |
|     then the API intends for it.
 | |
| <P>
 | |
| <LI>Unbelievably mod_rewrite provides URL manipulations in per-directory
 | |
|     context, i.e. within <CODE>.htaccess</CODE> files, although these are
 | |
|     reached a very long time after the URLs were translated to filenames (this
 | |
|     has to be this way, because <CODE>.htaccess</CODE> files stay in the
 | |
|     filesystem, so processing has already been reached this stage of
 | |
|     processing). In other words: According to the API phases at this time it
 | |
|     is too late for any URL manipulations.  To overcome this chicken and egg
 | |
|     problem mod_rewrite uses a trick: When you manipulate a URL/filename in
 | |
|     per-directory context mod_rewrite first rewrites the filename back to its
 | |
|     corresponding URL (which it usually impossible, but see the
 | |
|     <CODE>RewriteBase</CODE> directive below for the trick to achieve this)
 | |
|     and then initiates a new internal sub-request with the new URL. This leads
 | |
|     to a new processing of the API phases from the beginning. 
 | |
|     <P>
 | |
|     Again mod_rewrite tries hard to make this complicated step totally
 | |
|     transparent to the user, but you should remember here: While URL
 | |
|     manipulations in per-server context are really fast and efficient,
 | |
|     per-directory rewrites are slow and inefficient due to this chicken and
 | |
|     egg problem. But on the other hand this is the only way mod_rewrite can
 | |
|     provide (locally restricted) URL manipulations to the average user.
 | |
| </OL>
 | |
| 
 | |
| <P>
 | |
| Don't forget these two points!
 | |
| 
 | |
| <H2><A NAME="InternalRuleset">Ruleset Processing</A></H2>
 | |
| 
 | |
| Now when mod_rewrite is triggered in these two API phases, it reads the
 | |
| configured rulesets from its configuration structure (which itself was either
 | |
| created on startup for per-server context or while the directory walk of the
 | |
| Apache kernel for per-directory context).  Then the URL rewriting engine is
 | |
| started with the contained ruleset (one or more rules together with their
 | |
| conditions). The operation of the URL rewriting engine itself is exactly the
 | |
| same for both configuration contexts. Just the final result processing is
 | |
| different.
 | |
| 
 | |
| <P>
 | |
| The order of rules in the ruleset is important because the rewriting engine
 | |
| processes them in a special order. And this order is not very obvious. The
 | |
| rule is this: The rewriting engine loops through the ruleset rule by rule
 | |
| (<CODE>RewriteRule</CODE> directives!) and when a particular rule matched it
 | |
| optionally loops through existing corresponding conditions
 | |
| (<CODE>RewriteCond</CODE> directives). Because of historical reasons the 
 | |
| conditions are given first, the control flow is a little bit winded. See
 | |
| Figure 1 for more details.
 | |
| 
 | |
| <P>
 | |
| <DIV ALIGN=CENTER>
 | |
| <TABLE CELLSPACING=0 CELLPADDING=2 BORDER=0>
 | |
| <TR>
 | |
| <TD BGCOLOR="#CCCCCC"><IMG 
 | |
|     SRC="../images/mod_rewrite_fig1.gif"
 | |
|     WIDTH="428" HEIGHT="385"
 | |
|     ALT="[Needs graphics capability to display]"></TD>
 | |
| </TR>
 | |
| <TR>
 | |
| <TD ALIGN=CENTER>
 | |
| <STRONG>Figure 1:</STRONG> The control flow through the rewriting ruleset
 | |
| </TD>
 | |
| </TR>
 | |
| </TABLE>
 | |
| </DIV>
 | |
| 
 | |
| <P>
 | |
| As you can see, first the URL is matched against the <EM>Pattern</EM> of each
 | |
| rule. When it fails mod_rewrite immediately stops processing this rule and
 | |
| continues with the next rule. If the <EM>Pattern</EM> matched, mod_rewrite
 | |
| looks for corresponding rule conditions. If none are present, it just
 | |
| substitutes the URL with a new value which is constructed from the string
 | |
| <EM>Substitution</EM> and goes on with its rule-looping. But if conditions But
 | |
| if conditions exists, it starts an inner loop for processing them in order
 | |
| they are listed. For conditions the logic is different: We don't match a
 | |
| pattern against the current URL. Instead we first create a string
 | |
| <EM>TestString</EM> by expanding variables, back-references, map lookups, etc.
 | |
| and then we try to match <EM>TestPattern</EM> against it. If the pattern
 | |
| doesn't match, the complete set of conditions and the corresponding rule fails.
 | |
| If the pattern matches, then the next condition is processed until no more
 | |
| condition is available. If all conditions matched processing is continued with
 | |
| the substitution of the URL with <EM>Substitution</EM>.
 | |
| 
 | |
| <H2><A NAME="InternalBackRefs">Regex Back-Reference Availability</A></H2>
 | |
| 
 | |
| One important thing here has to be remembered: Whenever you
 | |
| use parenthesis in <EM>Pattern</EM> or in one of the <EM>TestPattern</EM>
 | |
| back-reference are internally created which can be used with the
 | |
| strings <CODE>$N</CODE> and <CODE>%N</CODE> (see below). And these
 | |
| are available for creating the strings <EM>Substitution</EM> and
 | |
| <EM>TestCond</EM>. Figure 2 shows at which locations the back-references are
 | |
| transfered to for expansion.
 | |
| 
 | |
| <P>
 | |
| <DIV ALIGN=CENTER>
 | |
| <TABLE  CELLSPACING=0 CELLPADDING=2 BORDER=0>
 | |
| <TR>
 | |
| <TD BGCOLOR="#CCCCCC"><IMG 
 | |
|     SRC="../images/mod_rewrite_fig2.gif"
 | |
|     WIDTH="381" HEIGHT="179"
 | |
|     ALT="[Needs graphics capability to display]"></TD>
 | |
| </TR>
 | |
| <TR>
 | |
| <TD ALIGN=CENTER>
 | |
| <STRONG>Figure 2:</STRONG> The back-reference flow through a rule
 | |
| </TD>
 | |
| </TR>
 | |
| </TABLE>
 | |
| </DIV>
 | |
| 
 | |
| <P>
 | |
| We know, this was a crash course of mod_rewrite's internal processing.  But
 | |
| you will benefit from this knowledge when reading the following documentation
 | |
| of the available directives.
 | |
| 
 | |
| <P>
 | |
| <HR NOSHADE SIZE=1>
 | |
| 
 | |
| <CENTER>
 | |
| <H1><A NAME="Configuration">Configuration Directives</A></H1>
 | |
| </CENTER>
 | |
| 
 | |
| <P>
 | |
| <HR NOSHADE SIZE=1>
 | |
| 
 | |
| <H3><A NAME="RewriteEngine">RewriteEngine</A></H3>
 | |
| <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, directory, .htaccess<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Override"
 | |
|  REL="Help"
 | |
| ><STRONG>Override:</STRONG></A> FileInfo<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Status"
 | |
|  REL="Help"
 | |
| ><STRONG>Status:</STRONG></A> Extension<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Module"
 | |
|  REL="Help"
 | |
| ><STRONG>Module:</STRONG></A> mod_rewrite.c<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Compatibility"
 | |
|  REL="Help"
 | |
| ><STRONG>Compatibility:</STRONG></A> Apache 1.2<BR>
 | |
| 
 | |
| <P>
 | |
| The <CODE>RewriteEngine</CODE> 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 <CODE>SCRIPT_URx</CODE>
 | |
| environment variables.
 | |
| 
 | |
| <P>
 | |
| Use this directive to disable the module instead of commenting out
 | |
| all <CODE>RewriteRule</CODE> directives!
 | |
| 
 | |
| <P>
 | |
| Note that, by default, rewrite configurations are not inherited.
 | |
| This means that you need to have a <CODE>RewriteEngine on</CODE>
 | |
| directive for each virtual host you wish to use it in.
 | |
| 
 | |
| <P>
 | |
| <HR NOSHADE SIZE=1>
 | |
| <P>
 | |
| 
 | |
| <H3><A NAME="RewriteOptions">RewriteOptions</A></H3>
 | |
| <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, directory, .htaccess<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Override"
 | |
|  REL="Help"
 | |
| ><STRONG>Override:</STRONG></A> FileInfo<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Status"
 | |
|  REL="Help"
 | |
| ><STRONG>Status:</STRONG></A> Extension<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Module"
 | |
|  REL="Help"
 | |
| ><STRONG>Module:</STRONG></A> mod_rewrite.c<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Compatibility"
 | |
|  REL="Help"
 | |
| ><STRONG>Compatibility:</STRONG></A> Apache 1.2<BR>
 | |
| 
 | |
| <P>
 | |
| The <CODE>RewriteOptions</CODE> 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
 | |
|     <CODE>.htaccess</CODE> configuration gets inherited.
 | |
| </UL>
 | |
| 
 | |
| <P>
 | |
| <HR NOSHADE SIZE=1>
 | |
| <P>
 | |
| 
 | |
| <H3><A NAME="RewriteLog">RewriteLog</A></H3>
 | |
| <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>
 | |
| <A
 | |
|  HREF="directive-dict.html#Override"
 | |
|  REL="Help"
 | |
| ><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Status"
 | |
|  REL="Help"
 | |
| ><STRONG>Status:</STRONG></A> Extension<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Module"
 | |
|  REL="Help"
 | |
| ><STRONG>Module:</STRONG></A> mod_rewrite.c<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Compatibility"
 | |
|  REL="Help"
 | |
| ><STRONG>Compatibility:</STRONG></A> Apache 1.2<BR>
 | |
| 
 | |
| <P>
 | |
| The <CODE>RewriteLog</CODE> 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 ('<CODE>/</CODE>') 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="#E0E0F0" CELLSPACING=0 CELLPADDING=10>
 | |
| <TR><TD>
 | |
| <STRONG>Notice</STRONG>: 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
 | |
| <CODE>RewriteLog</CODE> directive or use <CODE>RewriteLogLevel 0</CODE>!
 | |
| </TD></TR>
 | |
| </TABLE>
 | |
| 
 | |
| <P>
 | |
| <TABLE WIDTH="70%" BORDER=0 BGCOLOR="#E0E0F0" CELLSPACING=0 CELLPADDING=10>
 | |
| <TR><TD>
 | |
| <STRONG>Security</STRONG>: 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>
 | |
| 
 | |
| <H3><A NAME="RewriteLogLevel">RewriteLogLevel</A></H3>
 | |
| <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>
 | |
| <A
 | |
|  HREF="directive-dict.html#Override"
 | |
|  REL="Help"
 | |
| ><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Status"
 | |
|  REL="Help"
 | |
| ><STRONG>Status:</STRONG></A> Extension<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Module"
 | |
|  REL="Help"
 | |
| ><STRONG>Module:</STRONG></A> mod_rewrite.c<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Compatibility"
 | |
|  REL="Help"
 | |
| ><STRONG>Compatibility:</STRONG></A> Apache 1.2<BR>
 | |
| 
 | |
| <P>
 | |
| The <CODE>RewriteLogLevel</CODE> 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="#E0E0F0" 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>
 | |
| 
 | |
| <H3><A NAME="RewriteLock">RewriteLock</A></H3>
 | |
| <A
 | |
|  HREF="directive-dict.html#Syntax"
 | |
|  REL="Help"
 | |
| ><STRONG>Syntax:</STRONG></A> <CODE>RewriteLock</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>
 | |
| <A
 | |
|  HREF="directive-dict.html#Override"
 | |
|  REL="Help"
 | |
| ><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Status"
 | |
|  REL="Help"
 | |
| ><STRONG>Status:</STRONG></A> Extension<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Module"
 | |
|  REL="Help"
 | |
| ><STRONG>Module:</STRONG></A> mod_rewrite.c<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Compatibility"
 | |
|  REL="Help"
 | |
| ><STRONG>Compatibility:</STRONG></A> Apache 1.3<BR>
 | |
| 
 | |
| <P>
 | |
| This directive sets the filename for a synchronization lockfile which
 | |
| mod_rewrite needs to communicate with <SAMP>RewriteMap</SAMP>
 | |
| <EM>programs</EM>. Set this lockfile to a local path (not on a NFS-mounted
 | |
| device) when you want to use a rewriting map-program. It is not required for
 | |
| SAMP using all other types of rewriting maps.
 | |
| 
 | |
| <P>
 | |
| <HR NOSHADE SIZE=1>
 | |
| <P>
 | |
| 
 | |
| <H3><A NAME="RewriteMap">RewriteMap</A></H3>
 | |
| <A
 | |
|  HREF="directive-dict.html#Syntax"
 | |
|  REL="Help"
 | |
| ><STRONG>Syntax:</STRONG></A> <CODE>RewriteMap</CODE> <EM>MapName</EM> <EM>MapType</EM><CODE>:</CODE><EM>MapSource</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>
 | |
| <A
 | |
|  HREF="directive-dict.html#Override"
 | |
|  REL="Help"
 | |
| ><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Status"
 | |
|  REL="Help"
 | |
| ><STRONG>Status:</STRONG></A> Extension<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Module"
 | |
|  REL="Help"
 | |
| ><STRONG>Module:</STRONG></A> mod_rewrite.c<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Compatibility"
 | |
|  REL="Help"
 | |
| ><STRONG>Compatibility:</STRONG></A> Apache 1.2 (partially), Apache 1.3<BR>
 | |
| 
 | |
| <P>
 | |
| The <CODE>RewriteMap</CODE> directive defines a <EM>Rewriting Map</EM>
 | |
| which can be used inside rule substitution strings by the mapping-functions
 | |
| to insert/substitute fields through a key lookup. The source of this
 | |
| lookup can be of various types.
 | |
| <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 one of the following constructs:
 | |
| 
 | |
| <BLOCKQUOTE><STRONG>
 | |
| <CODE>${</CODE> <EM>MapName</EM> <CODE>:</CODE> <EM>LookupKey</EM>
 | |
| <CODE>}</CODE><BR>
 | |
| <CODE>${</CODE> <EM>MapName</EM> <CODE>:</CODE> <EM>LookupKey</EM>
 | |
| <CODE>|</CODE> <EM>DefaultValue</EM> <CODE>}</CODE>
 | |
| </STRONG></BLOCKQUOTE>
 | |
| 
 | |
| When such a construct 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 construct is substituted by <EM>SubstValue</EM>. If
 | |
| the key is not found then it is substituted by <EM>DefaultValue</EM> or
 | |
| the empty string if no <EM>DefaultValue</EM> was specified.
 | |
| 
 | |
| <P>
 | |
| The following combinations for <EM>MapType</EM> and <EM>MapSource</EM>
 | |
| can be used:
 | |
| 
 | |
| <UL>
 | |
| <LI><STRONG>Standard Plain Text</STRONG><BR>
 | |
|     MapType: <CODE>txt</CODE>, MapSource: Unix filesystem path to valid regular file
 | |
|     <P>
 | |
|     This is the standard rewriting map feature where the <EM>MapSource</EM> is
 | |
|     a plain ASCII file containing either blank lines, comment lines (starting
 | |
|     with a '#' character) or pairs like the following - one per line.
 | |
| 
 | |
|     <BLOCKQUOTE><STRONG>
 | |
|     <EM>MatchingKey</EM>  <EM>SubstValue</EM>
 | |
|     </STRONG></BLOCKQUOTE>
 | |
| 
 | |
|     <P>
 | |
|     Example:
 | |
| <P>
 | |
| <TABLE BORDER=0 CELLSPACING=1 CELLPADDING=5 BGCOLOR="#F0F0F0">
 | |
| <TR><TD><PRE>
 | |
| ##
 | |
| ##  map.txt -- rewriting map
 | |
| ##
 | |
| 
 | |
| Ralf.S.Engelschall    rse   # Bastard Operator From Hell
 | |
| Mr.Joe.Average        joe   # Mr. Average
 | |
| </PRE></TD></TR>
 | |
| </TABLE>
 | |
| 
 | |
| <P>
 | |
| <TABLE BORDER=0 CELLSPACING=1 CELLPADDING=5 BGCOLOR="#F0F0F0">
 | |
| <TR><TD><PRE>
 | |
| RewriteMap real-to-user txt:/path/to/file/map.txt
 | |
| </PRE></TD></TR>
 | |
| </TABLE>
 | |
| 
 | |
| <P>
 | |
| <LI><STRONG>Randomized Plain Text</STRONG><BR>
 | |
|     MapType: <CODE>rnd</CODE>, MapSource: Unix filesystem path to valid regular file
 | |
|     <P>
 | |
|     This is identical to the Standard Plain Text variant above but with a special
 | |
|     post-processing feature: After looking up a value it is parsed according
 | |
|     to contained ``<CODE>|</CODE>'' characters which have the meaning of ``or''.  Or
 | |
|     in other words: they indicate a set of alternatives from which the actual
 | |
|     returned value is chosen randomly. Although this sounds crazy and useless, it
 | |
|     was actually designed for load balancing in a reverse proxy situation where
 | |
|     the looked up values are server names.
 | |
|     Example:
 | |
| <P>
 | |
| <TABLE BORDER=0 CELLSPACING=1 CELLPADDING=5 BGCOLOR="#F0F0F0">
 | |
| <TR><TD><PRE>
 | |
| ##
 | |
| ##  map.txt -- rewriting map
 | |
| ##
 | |
| 
 | |
| static   www1|www2|www3|www4
 | |
| dynamic  www5|www6
 | |
| </PRE></TD></TR>
 | |
| </TABLE>
 | |
| 
 | |
| <P>
 | |
| <TABLE BORDER=0 CELLSPACING=1 CELLPADDING=5 BGCOLOR="#F0F0F0">
 | |
| <TR><TD><PRE>
 | |
| RewriteMap servers rnd:/path/to/file/map.txt
 | |
| </PRE></TD></TR>
 | |
| </TABLE>
 | |
| 
 | |
| <P>
 | |
| <LI><STRONG>Hash File</STRONG><BR>
 | |
|     MapType: <CODE>dbm</CODE>, MapSource: Unix filesystem path to valid regular file
 | |
|     <P>
 | |
|     Here the source is a binary NDBM format file containing the same contents
 | |
|     as a <EM>Plain Text</EM> format file, but in a special representation
 | |
|     which is optimized for really fast lookups. You can create such a file with
 | |
|     any NDBM tool or with the following Perl script:
 | |
|     <P>
 | |
|     <TABLE BORDER=0 CELLSPACING=1 CELLPADDING=5 BGCOLOR="#F0F0F0">
 | |
|     <TR><TD><PRE>
 | |
| #!/path/to/bin/perl
 | |
| ##
 | |
| ##  txt2dbm -- convert txt map to dbm format
 | |
| ##
 | |
| 
 | |
| ($txtmap, $dbmmap) = @ARGV;
 | |
| open(TXT, "<$txtmap");
 | |
| dbmopen(%DB, $dbmmap, 0644);
 | |
| while (<TXT>) {
 | |
|     next if (m|^s*#.*| or m|^s*$|);
 | |
|     $DB{$1} = $2 if (m|^\s*(\S+)\s+(\S+)$|);
 | |
| }
 | |
| dbmclose(%DB);
 | |
| close(TXT)</PRE></TD></TR>
 | |
|     </TABLE>
 | |
|     <P>
 | |
|     <TABLE BORDER=0 CELLSPACING=1 CELLPADDING=5 BGCOLOR="#F0F0F0">
 | |
|     <TR><TD><PRE>$ txt2dbm map.txt map.db </PRE></TD></TR>
 | |
|     </TABLE>
 | |
| <P>
 | |
| <LI><STRONG>Internal Function</STRONG><BR>
 | |
|     MapType: <CODE>int</CODE>, MapSource: Internal Apache function
 | |
|     <P>
 | |
|     Here the source is an internal Apache function. Currently you cannot
 | |
|     create your own, but the following functions already exists:
 | |
|     <UL> 
 | |
|     <LI><STRONG>toupper</STRONG>:<BR>
 | |
|         Converts the looked up key to all upper case.
 | |
|     <LI><STRONG>tolower</STRONG>:<BR>
 | |
|         Converts the looked up key to all lower case.
 | |
|     </UL>
 | |
| <P>
 | |
| <LI><STRONG>External Rewriting Program</STRONG><BR>
 | |
|     MapType: <CODE>prg</CODE>, MapSource: Unix filesystem path to valid regular file
 | |
|     <P>
 | |
|     Here the source is a Unix program, not a map file. To create it you can use
 | |
|     the language of your choice, but the result has to be a run-able Unix
 | |
|     executable (i.e. either object-code or a script with the
 | |
|     magic cookie trick '<CODE>#!/path/to/interpreter</CODE>' 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 <CODE>stdin</CODE> and
 | |
|     <CODE>stdout</CODE> file-handles.  For each map-function lookup it will
 | |
|     receive the key to lookup as a newline-terminated string on
 | |
|     <CODE>stdin</CODE>. It then has to give back the looked-up value as a
 | |
|     newline-terminated string on <CODE>stdout</CODE> or the four-character string
 | |
|     ``<CODE>NULL</CODE>'' 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>
 | |
|     But be very careful:<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 <CODE>stdout</CODE>!
 | |
|         This will cause a deadloop! Hence the ``<CODE>$|=1</CODE>'' in the above
 | |
|         example...
 | |
|     <LI>Use the <SAMP>RewriteLock</SAMP> directive to define a lockfile
 | |
|         mod_rewrite can use to synchronize the communication to the program.
 | |
|         Per default no such synchronization takes place.
 | |
|     </OL>
 | |
| </UL>
 | |
| 
 | |
| The <CODE>RewriteMap</CODE> directive can occur more than once. For each
 | |
| mapping-function use one <CODE>RewriteMap</CODE> 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="#E0E0F0" CELLSPACING=0 CELLPADDING=10>
 | |
| <TR><TD>
 | |
| <STRONG>Notice:</STRONG> For plain text and DBM format files the looked-up keys are cached in-core
 | |
| until the <CODE>mtime</CODE> 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>
 | |
| 
 | |
| <H3><A NAME="RewriteBase">RewriteBase</A></H3>
 | |
| <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> directory, .htaccess<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Override"
 | |
|  REL="Help"
 | |
| ><STRONG>Override:</STRONG></A> <EM>FileInfo</EM><BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Status"
 | |
|  REL="Help"
 | |
| ><STRONG>Status:</STRONG></A> Extension<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Module"
 | |
|  REL="Help"
 | |
| ><STRONG>Module:</STRONG></A> mod_rewrite.c<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Compatibility"
 | |
|  REL="Help"
 | |
| ><STRONG>Compatibility:</STRONG></A> Apache 1.2<BR>
 | |
| 
 | |
| <P>
 | |
| The <CODE>RewriteBase</CODE> directive explicitly sets the base URL for
 | |
| per-directory rewrites. As you will see below, <CODE>RewriteRule</CODE> can be
 | |
| used in per-directory config files (<CODE>.htaccess</CODE>). 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
 | |
| <CODE>RewriteBase</CODE> directive to specify the correct URL-prefix.
 | |
| 
 | |
| <P>
 | |
| <TABLE WIDTH="70%" BORDER=0 BGCOLOR="#E0E0F0" CELLSPACING=0 CELLPADDING=10>
 | |
| <TR><TD>
 | |
| <STRONG>Notice:</STRONG> If your webserver's URLs are <STRONG>not</STRONG> directly
 | |
| related to physical file paths, you have to use <CODE>RewriteBase</CODE> in every
 | |
| <CODE>.htaccess</CODE> files where you want to use <CODE>RewriteRule</CODE>
 | |
| 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 <CODE>/xyz/oldstuff.html</CODE> gets correctly
 | |
| rewritten to the physical file <CODE>/abc/def/newstuff.html</CODE>.
 | |
| 
 | |
| <P>
 | |
| <TABLE WIDTH="70%" BORDER=0 BGCOLOR="#E0E0F0" CELLSPACING=0 CELLPADDING=10>
 | |
| <TR><TD>
 | |
| <FONT SIZE=-1>
 | |
| <STRONG>Notice - 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>
 | |
| 
 | |
| <H3><A NAME="RewriteCond">RewriteCond</A></H3>
 | |
| <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, directory, .htaccess<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Override"
 | |
|  REL="Help"
 | |
| ><STRONG>Override:</STRONG></A> <EM>FileInfo</EM><BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Status"
 | |
|  REL="Help"
 | |
| ><STRONG>Status:</STRONG></A> Extension<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Module"
 | |
|  REL="Help"
 | |
| ><STRONG>Module:</STRONG></A> mod_rewrite.c<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Compatibility"
 | |
|  REL="Help"
 | |
| ><STRONG>Compatibility:</STRONG></A> Apache 1.2 (partially), Apache 1.3<BR>
 | |
| 
 | |
| <P>
 | |
| The <CODE>RewriteCond</CODE> directive defines a rule condition. Precede a
 | |
| <CODE>RewriteRule</CODE> directive with one or more <CODE>RewriteCond</CODE>
 | |
| 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>
 | |
| <CODE>$N</CODE>
 | |
| </STRONG></BLOCKQUOTE>
 | |
| 
 | |
| (1 <= N <= 9) which provide access to the grouped parts (parenthesis!)
 | |
| of the
 | |
| pattern from the corresponding <CODE>RewriteRule</CODE> directive (the one
 | |
| following the current bunch of <CODE>RewriteCond</CODE> directives).
 | |
| 
 | |
| <P>
 | |
| <LI><STRONG>RewriteCond backreferences</STRONG>: These are backreferences of
 | |
| the form
 | |
| 
 | |
| <BLOCKQUOTE><STRONG>
 | |
| <CODE>%N</CODE>
 | |
| </STRONG></BLOCKQUOTE>
 | |
| 
 | |
| (1 <= N <= 9) which provide access to the grouped parts (parenthesis!) of the
 | |
| pattern from the last matched <CODE>RewriteCond</CODE> directive in the current
 | |
| bunch of conditions.
 | |
| 
 | |
| <P>
 | |
| <LI><STRONG>Server-Variables</STRONG>: These are variables
 | |
|     of the form
 | |
| 
 | |
| <BLOCKQUOTE><STRONG>
 | |
| <CODE>%{</CODE> <EM>NAME_OF_VARIABLE</EM> <CODE>}</CODE>
 | |
| </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>
 | |
| </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="#E0E0F0" CELLSPACING=0 CELLPADDING=10>
 | |
| <TR><TD>
 | |
| <STRONG>Notice:</STRONG> These variables all correspond to the similar named
 | |
| HTTP MIME-headers, C variables of the Apache server or <CODE>struct tm</CODE>
 | |
| 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 <CODE>filename</CODE> field of the internal
 | |
| <CODE>request_rec</CODE> 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 <CODE>uri</CODE>
 | |
| field of <CODE>request_rec</CODE>).
 | |
| 
 | |
| <P>
 | |
| <LI>There is the special format: <CODE>%{ENV:variable}</CODE> where
 | |
| <EM>variable</EM> can be any environment variable. This is looked-up via
 | |
| internal Apache structures and (if not found there) via <CODE>getenv()</CODE> from
 | |
| the Apache server process.
 | |
| 
 | |
| <P>
 | |
| <LI>There is the special format: <CODE>%{HTTP:header}</CODE> where
 | |
| <EM>header</EM> can be any HTTP MIME-header name. This is looked-up
 | |
| from the HTTP request. Example: <CODE>%{HTTP:Proxy-Connection}</CODE>
 | |
| is the value of the HTTP header ``<CODE>Proxy-Connection:</CODE>''.
 | |
| 
 | |
| <P>
 | |
| <LI>There is the special format <CODE>%{LA-U:variable}</CODE> for look-aheads
 | |
| which perform an internal (URL-based) sub-request to determine the final value
 | |
| of <EM>variable</EM>. Use this when you want to use a variable for rewriting
 | |
| which actually is set later in an API phase and thus is not available at the
 | |
| current stage. For instance when you want to rewrite according to the
 | |
| <CODE>REMOTE_USER</CODE> variable from within the per-server context
 | |
| (<CODE>httpd.conf</CODE> file) you have to use <CODE>%{LA-U:REMOTE_USER}</CODE>
 | |
| because this variable is set by the authorization phases which come
 | |
| <EM>after</EM> the URL translation phase where mod_rewrite operates. On the
 | |
| other hand, because mod_rewrite implements its per-directory context
 | |
| (<CODE>.htaccess</CODE> file) via the Fixup phase of the API and because the
 | |
| authorization phases come <EM>before</EM> this phase, you just can use
 | |
| <CODE>%{REMOTE_USER}</CODE> there.
 | |
| 
 | |
| <P>
 | |
| <LI>There is the special format: <CODE>%{LA-F:variable}</CODE> which perform an
 | |
| internal (filename-based) sub-request to determine the final value of
 | |
| <EM>variable</EM>. This is the most of the time the same as LA-U above.
 | |
| </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 '<CODE>!</CODE>' 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 than <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 than <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 than 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>
 | |
| <TABLE WIDTH="70%" BORDER=0 BGCOLOR="#E0E0F0" CELLSPACING=0 CELLPADDING=10>
 | |
| <TR><TD>
 | |
| <STRONG>Notice:</STRONG>
 | |
| All of these tests can also be prefixed by a not ('!') character
 | |
| to negate their meaning.
 | |
| </TD></TR>
 | |
| </TABLE>
 | |
| </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 <CODE>RewriteCond</CODE> 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 ``<CODE>User-Agent:</CODE>''
 | |
| 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>
 | |
| 
 | |
| <H3><A NAME="RewriteRule">RewriteRule</A></H3>
 | |
| <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, directory, .htaccess<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Override"
 | |
|  REL="Help"
 | |
| ><STRONG>Override:</STRONG></A> <EM>FileInfo</EM><BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Status"
 | |
|  REL="Help"
 | |
| ><STRONG>Status:</STRONG></A> Extension<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Module"
 | |
|  REL="Help"
 | |
| ><STRONG>Module:</STRONG></A> mod_rewrite.c<BR>
 | |
| <A
 | |
|  HREF="directive-dict.html#Compatibility"
 | |
|  REL="Help"
 | |
| ><STRONG>Compatibility:</STRONG></A> Apache 1.2 (partially), Apache 1.3<BR>
 | |
| 
 | |
| <P>
 | |
| The <CODE>RewriteRule</CODE> 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>Text:</STRONG>
 | |
|   <STRONG><CODE>.</CODE></STRONG>           Any single character
 | |
|   <STRONG><CODE>[</CODE></STRONG>chars<STRONG><CODE>]</CODE></STRONG>     Character class: One  of chars
 | |
|   <STRONG><CODE>[^</CODE></STRONG>chars<STRONG><CODE>]</CODE></STRONG>    Character class: None of chars
 | |
|   text1<STRONG><CODE>|</CODE></STRONG>text2 Alternative: text1 or text2
 | |
| 
 | |
| <STRONG>Quantifiers:</STRONG>
 | |
|   <STRONG><CODE>?</CODE></STRONG>           0 or 1 of the preceding text
 | |
|   <STRONG><CODE>*</CODE></STRONG>           0 or N of the preceding text (N > 1)
 | |
|   <STRONG><CODE>+</CODE></STRONG>           1 or N of the preceding text (N > 1)
 | |
| 
 | |
| <STRONG>Grouping:</STRONG>
 | |
|   <STRONG><CODE>(</CODE></STRONG>text<STRONG><CODE>)</CODE></STRONG>      Grouping of text
 | |
|               (either to set the borders of an alternative or
 | |
|               for making backreferences where the <STRONG>N</STRONG>th group can 
 | |
|               be used on the RHS of a RewriteRule with <CODE>$</CODE><STRONG>N</STRONG>)
 | |
| 
 | |
| <STRONG>Anchors:</STRONG>
 | |
|   <STRONG><CODE>^</CODE></STRONG>           Start of line anchor
 | |
|   <STRONG><CODE>$</CODE></STRONG>           End   of line anchor
 | |
| 
 | |
| <STRONG>Escaping:</STRONG>
 | |
|   <STRONG><CODE>\</CODE></STRONG>char       escape that particular char
 | |
|               (for instance to specify the chars "<CODE>.[]()</CODE>" etc.)
 | |
| </PRE>
 | |
| </TD>
 | |
| </TR>
 | |
| </TABLE>
 | |
| 
 | |
| <P>
 | |
| For more information about regular expressions either have a look at your
 | |
| local regex(3) manpage or its <CODE>src/regex/regex.3</CODE> copy in the
 | |
| Apache 1.3 distribution.  When you are interested in more detailed and deeper
 | |
| information about regular expressions and its variants (POSIX regex, Perl
 | |
| regex, etc.) have a look at the following dedicated book on this topic: 
 | |
| 
 | |
| <BLOCKQUOTE>
 | |
| <EM>Mastering Regular Expressions</EM><BR>
 | |
| Jeffrey E.F. Friedl<BR>
 | |
| Nutshell Handbook Series<BR>
 | |
| O'Reilly & Associates, Inc. 1997<BR>
 | |
| ISBN 1-56592-257-3<BR>
 | |
| </BLOCKQUOTE>
 | |
| 
 | |
| <P>
 | |
| Additionally in mod_rewrite the NOT character ('<CODE>!</CODE>') 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="#E0E0F0" 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 <CODE>$N</CODE> 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 <CODE>RewriteCond</CODE> directive. The
 | |
| mapping-functions come from the <CODE>RewriteMap</CODE> 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 '<CODE>-</CODE>' 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="#E0E0F0" CELLSPACING=0 CELLPADDING=10>
 | |
| <TR><TD>
 | |
| <STRONG>Notice</STRONG>: There is a special feature. When you prefix a substitution
 | |
| field with <CODE>http://</CODE><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.
 | |
| </TD></TR>
 | |
| </TABLE>
 | |
| 
 | |
| <P>
 | |
| <TABLE WIDTH="70%" BORDER=0 BGCOLOR="#E0E0F0" CELLSPACING=0 CELLPADDING=10>
 | |
| <TR><TD>
 | |
| <STRONG>Remember:</STRONG> An unconditional external redirect to your own server will
 | |
| not work with the prefix <CODE>http://thishost</CODE> 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 <CODE>RewriteRule</CODE> 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: <CODE>temp</CODE> (default), <CODE>permanent</CODE>,
 | |
|     <CODE>seeother</CODE>.
 | |
|     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 <A HREF="mod_proxy.html">proxy module</A>. You have to make
 | |
|     sure that the substitution string is a valid URI (e.g.  typically starting
 | |
|     with <CODE>http://</CODE><EM>hostname</EM>) 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 <A
 | |
|     HREF="mod_proxy.html#proxypass">ProxyPass</A> directive, to map some
 | |
|     remote stuff into the namespace of the local server.
 | |
|     <P>
 | |
|     Notice: To use this functionality make sure you have the proxy module
 | |
|     compiled into your Apache server program.  If you don't know please check
 | |
|     whether <CODE>mod_proxy.c</CODE> is part of the ``<CODE>httpd -l</CODE>''
 | |
|     output. If yes, this functionality is available to mod_rewrite. If not,
 | |
|     then you first have to rebuild the ``<CODE>httpd</CODE>'' program with
 | |
|     mod_proxy enabled.
 | |
| <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
 | |
|     ``<CODE>.www</CODE>'' part inside a per-directory rule set when you let an
 | |
|     external redirect happen (where the ``<CODE>.www</CODE>'' 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 <CODE>mod_alias</CODE>
 | |
|     directive <CODE>ScriptAlias</CODE> which internally forces all files inside
 | |
|     the mapped directory to have a MIME type of
 | |
|     ``<CODE>application/x-httpd-cgi</CODE>''.
 | |
| <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 <CODE>mod_include</CODE> tries to find out
 | |
|     information about possible directory default files (<CODE>index.xxx</CODE>).
 | |
|     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 <CODE>RewriteRule</CODE> directives by
 | |
|     <CODE>Alias</CODE>, <CODE>ScriptAlias</CODE>, <CODE>Redirect</CODE>, etc. directives
 | |
|     from other URI-to-filename translators. A trivial example to show the
 | |
|     semantics:
 | |
|     If you want to rewrite <CODE>/abc</CODE> to <CODE>/def</CODE> via the rewriting
 | |
|     engine of <CODE>mod_rewrite</CODE> and then <CODE>/def</CODE> to <CODE>/ghi</CODE>
 | |
|     with <CODE>mod_alias</CODE>:
 | |
|     <PRE>
 | |
|     RewriteRule ^/abc(.*)  /def$1 [PT]
 | |
|     Alias       /def       /ghi
 | |
|     </PRE>
 | |
|     If you omit the <CODE>PT</CODE> flag then <CODE>mod_rewrite</CODE>
 | |
|     will do its job fine, i.e. it rewrites <CODE>uri=/abc/...</CODE> to
 | |
|     <CODE>filename=/def/...</CODE> as a full API-compliant URI-to-filename
 | |
|     translator should do. Then <CODE>mod_alias</CODE> 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 <CODE>mod_alias</CODE> and
 | |
|     <CODE>mod_rewrite</CODE>..
 | |
| <P>
 | |
| <TABLE WIDTH="70%" BORDER=0 BGCOLOR="#E0E0F0" CELLSPACING=0 CELLPADDING=10>
 | |
| <TR><TD>
 | |
| <font size=-1>
 | |
|     <STRONG>Notice - 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 <CODE>skip=N</CODE> 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
 | |
|     <CODE>$N</CODE> and <CODE>%N</CODE> 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 <CODE><!--#echo var="VAR"--></CODE>) or CGI (e.g.
 | |
|     <CODE>$ENV{'VAR'}</CODE>).  But additionally you can also dereference it in a
 | |
|     following RewriteCond pattern via <CODE>%{ENV:VAR}</CODE>. Use this to strip
 | |
|     but remember information from URLs.
 | |
| </UL>
 | |
| 
 | |
| <P>
 | |
| <TABLE WIDTH="70%" BORDER=0 BGCOLOR="#E0E0F0" CELLSPACING=0 CELLPADDING=10>
 | |
| <TR><TD>
 | |
| <STRONG>Notice:</STRONG> 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
 | |
| ``<CODE>http://</CODE>'' 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="#E0E0F0" CELLSPACING=0 CELLPADDING=10>
 | |
| <TR><TD>
 | |
| <STRONG>Notice:</STRONG> To enable the rewriting engine for per-directory configuration files
 | |
| you need to set ``<CODE>RewriteEngine On</CODE>'' in these files <STRONG>and</STRONG>
 | |
| ``<CODE>Option FollowSymLinks</CODE>'' enabled. If your administrator has
 | |
| disabled override of <CODE>FollowSymLinks</CODE> 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 (<CODE>httpd.conf</CODE>)<BR>
 | |
| for request ``<CODE>GET /somepath/pathinfo</CODE>'':</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 <CODE>/somepath</CODE><BR>
 | |
| (i.e. file <CODE>.htaccess</CODE> in dir <CODE>/physical/path/to/somepath</CODE> containing
 | |
| <CODE>RewriteBase /somepath</CODE>)<BR> for
 | |
| request ``<CODE>GET /somepath/localpath/pathinfo</CODE>'':</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>/path/to/file/map.txt</CODE>. Then we only have to add the
 | |
| following lines to the Apache server configuration file:
 | |
| 
 | |
| <BLOCKQUOTE>
 | |
| <PRE>
 | |
| RewriteLog   /path/to/file/rewrite.log
 | |
| RewriteMap   real-to-user               txt:/path/to/file/map.txt
 | |
| RewriteRule  ^/([^/]+)/~([^/]+)/(.*)$   /u/${real-to-user:$2|nobody}/$3.$1
 | |
| </PRE>
 | |
| </BLOCKQUOTE>
 | |
| 
 | |
| </BLOCKQUOTE>
 | |
| 
 | |
| <P>
 | |
| <HR NOSHADE SIZE=1>
 | |
| 
 | |
| <CENTER>
 | |
| <H1><A NAME="Miscelleneous">Miscellaneous</A></H1>
 | |
| </CENTER>
 | |
| 
 | |
| <P>
 | |
| <HR NOSHADE SIZE=1>
 | |
| 
 | |
| <H2><A NAME="EnvVar">Environment Variables</A></H2>
 | |
| 
 | |
| This module keeps track of two additional (non-standard) CGI/SSI environment
 | |
| variables named <CODE>SCRIPT_URL</CODE> and <CODE>SCRIPT_URI</CODE>. These contain
 | |
| the <EM>logical</EM> Web-view to the current resource, while the standard CGI/SSI
 | |
| variables <CODE>SCRIPT_NAME</CODE> and <CODE>SCRIPT_FILENAME</CODE> 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=/sw/lib/w3s/tree/global/u/rse/.www/index.html
 | |
| SCRIPT_FILENAME=/u/rse/.www/index.html
 | |
| SCRIPT_URL=/u/rse/
 | |
| SCRIPT_URI=http://en1.engelschall.com/u/rse/
 | |
| </PRE>
 | |
| </BLOCKQUOTE>
 | |
| 
 | |
| <P>
 | |
| <HR NOSHADE SIZE=1>
 | |
| 
 | |
| <H2><A NAME="Solutions">Practical Solutions</A></H2>
 | |
| 
 | |
| There is a comprehensive collection of practical solutions for URL-based
 | |
| problems available by the author of mod_rewrite.  Here you will find real-life
 | |
| rulesets and additional information.
 | |
| 
 | |
| <BLOCKQUOTE>
 | |
| <STRONG>Apache URL Rewriting Guide</STRONG><BR>
 | |
| <STRONG><A HREF="http://www.engelschall.com/pw/apache/rewriteguide/"
 | |
|         >http://www.engelschall.com/pw/apache/rewriteguide/</A></STRONG>
 | |
| </BLOCKQUOTE>
 | |
| 
 | |
| <!--#include virtual="footer.html" -->
 | |
| </BLOCKQUOTE><!-- page indentation -->
 | |
| </BODY>
 | |
| </HTML>
 | |
| <!--/%hypertext -->
 |