tech.xml revision 35b24427e6d85411ee9551d07a77cf3bb9af18a0
5693N/A<?xml version='1.0' encoding='UTF-8' ?>
5693N/A<!DOCTYPE manualpage SYSTEM "/style/manualpage.dtd">
5693N/A<?xml-stylesheet type="text/xsl" href="/style/manual.en.xsl"?>
5693N/A<!-- $LastChangedRevision$ -->
5693N/A
5693N/A<!--
5693N/A Licensed to the Apache Software Foundation (ASF) under one or more
5693N/A contributor license agreements. See the NOTICE file distributed with
5693N/A this work for additional information regarding copyright ownership.
5693N/A The ASF licenses this file to You under the Apache License, Version 2.0
5693N/A (the "License"); you may not use this file except in compliance with
5693N/A the License. You may obtain a copy of the License at
5693N/A
5693N/A http://www.apache.org/licenses/LICENSE-2.0
5693N/A
5693N/A Unless required by applicable law or agreed to in writing, software
5693N/A distributed under the License is distributed on an "AS IS" BASIS,
5693N/A WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5693N/A See the License for the specific language governing permissions and
5693N/A limitations under the License.
5693N/A-->
5693N/A
5693N/A<manualpage metafile="tech.xml.meta">
5693N/A<parentdocument href="./">Rewrite</parentdocument>
5693N/A
6350N/A <title>Apache mod_rewrite Technical Details</title>
5693N/A
5693N/A<summary>
5693N/A<p>This document discusses some of the technical details of mod_rewrite
5693N/Aand URL matching.</p>
5693N/A</summary>
5693N/A<seealso><a href="/mod/mod_rewrite.html">Module documentation</a></seealso>
5693N/A<seealso><a href="intro.html">mod_rewrite introduction</a></seealso>
5693N/A<seealso><a href="remapping.html">Redirection and remapping</a></seealso>
5693N/A<seealso><a href="access.html">Controlling access</a></seealso>
5693N/A<seealso><a href="vhosts.html">Virtual hosts</a></seealso>
5693N/A<seealso><a href="proxy.html">Proxying</a></seealso>
5693N/A<seealso><a href="rewritemap.html">Using RewriteMap</a></seealso>
5693N/A<seealso><a href="advanced.html">Advanced techniques</a></seealso>
5693N/A<seealso><a href="avoid.html">When not to use mod_rewrite</a></seealso>
5693N/A
5693N/A<section id="InternalAPI"><title>API Phases</title>
5693N/A
5693N/A <p>The Apache HTTP Server handles requests in several phases. At
5693N/A each of these phases, one or more modules may be called upon to
5693N/A handle that portion of the request lifecycle. Phases include things
5693N/A like URL-to-filename translation, authentication, authorization,
5693N/A content, and logging. (This is not an exhaustive list.)</p>
5693N/A
5693N/A <p>mod_rewrite acts in two of these phases (or "hooks", as they are
5693N/A often called) to influence how URLs may be rewritten.</p>
5693N/A
5693N/A <p>First, it uses the URL-to-filename translation hook, which occurs
5693N/A after the HTTP request has been read, but before any authorization
5693N/A starts. Secondly, it uses the Fixup hook, which is after the
5693N/A authorization phases, and after per-directory configuration files
5693N/A (<code>.htaccess</code> files) have been read, but before the
5693N/A content handler is called.</p>
5693N/A
6350N/A <p>So, after a request comes in and a corresponding server or
5693N/A virtual host has been determined, the rewriting engine starts
5693N/A processing any <code>mod_rewrite</code> directives appearing in the
5693N/A per-server configuration. (i.e., in the main server configuration file
5693N/A and <directive module="core" type="section">Virtualhost</directive>
5693N/A sections.) This happens in the URL-to-filename phase.</p>
5693N/A
5693N/A <p>A few steps later, once the final data directories have been found,
5693N/A the per-directory configuration directives (<code>.htaccess</code>
5693N/A files and <directive module="core"
5693N/A type="section">Directory</directive> blocks) are applied. This
5693N/A happens in the Fixup phase.</p>
5693N/A
5693N/A <p>In each of these cases, mod_rewrite rewrites the
5693N/A <code>REQUEST_URI</code> either to a new URL, or to a filename.</p>
5693N/A
5693N/A <p>In per-directory context (i.e., within <code>.htaccess</code> files
6350N/A and <code>Directory</code> blocks), these rules are being applied
6350N/A after a URL has already been translated to a filename. Because of
6350N/A this, mod_rewrite temporarily translates the filename back into a URL,
6350N/A by stripping off the directory path (including a trailing slash)
6350N/A before applying the rules. ) If a substitution is made, a new internal
6350N/A subrequest is issued with the new URL, which restarts processing of the
6350N/A request phases. If the substution is a relative path, the <directive
5693N/A module="mod_rewrite">RewriteBase</directive> directive
5693N/A determines the URL-path prefix appended to the substitution.
5693N/A In per-directory context, care must be taken to
6350N/A create rules which will eventually (in some future "round" of per-directory
5693N/A rewrite processing) not perform a substitution to avoid looping.
5693N/A (See <a href="http://wiki.apache.org/httpd/RewriteLooping">RewriteLooping</a>
5693N/A for further discussion of this problem.)</p>
6350N/A
5693N/A <p>Because of this further manipulation of the URL in per-directory
5693N/A context, you'll need to take care to craft your rewrite rules
5693N/A differently in that context. In particular, remember that the
5693N/A leading directory path will be stripped off of the URL that your
5693N/A rewrite rules will see. Consider the examples below for further
5693N/A clarification.</p>
5693N/A
5693N/A <table border="1">
5693N/A
5693N/A <tr>
5693N/A <th>Location of rule</th>
5693N/A <th>Rule</th>
5693N/A </tr>
5693N/A
5693N/A <tr>
5693N/A <td>VirtualHost section</td>
5693N/A <td>RewriteRule ^/images/(.+)\.jpg /images/$1.gif</td>
5693N/A </tr>
5693N/A
5693N/A <tr>
5693N/A <td>.htaccess file in document root</td>
5693N/A <td>RewriteRule ^images/(.+)\.jpg images/$1.gif</td>
5693N/A </tr>
5693N/A
5693N/A <tr>
5693N/A <td>.htaccess file in images directory</td>
5693N/A <td>RewriteRule ^(.+)\.jpg $1.gif</td>
5693N/A </tr>
5693N/A
5693N/A </table>
5821N/A
5693N/A <p>For even more insight into how mod_rewrite manipulates URLs in
6350N/A different contexts, you should consult the <a
6350N/A href="/mod/mod_rewrite.html#logging">log entries</a> made during
5693N/A rewriting.</p>
5693N/A
5693N/A</section>
5693N/A
5693N/A<section id="InternalRuleset"><title>Ruleset Processing</title>
5693N/A
5693N/A <p>Now when mod_rewrite is triggered in these two API phases, it
5693N/A reads the configured rulesets from its configuration
5693N/A structure (which itself was either created on startup for
5693N/A per-server context or during the directory walk of the Apache
5693N/A kernel for per-directory context). Then the URL rewriting
5693N/A engine is started with the contained ruleset (one or more
5693N/A rules together with their conditions). The operation of the
5693N/A URL rewriting engine itself is exactly the same for both
5693N/A configuration contexts. Only the final result processing is
5693N/A different.</p>
5693N/A
<p>The order of rules in the ruleset is important because the
rewriting engine processes them in a special (and not very
obvious) order. The rule is this: The rewriting engine loops
through the ruleset rule by rule (<directive
module="mod_rewrite">RewriteRule</directive> directives) and
when a particular rule matches it optionally loops through
existing corresponding conditions (<code>RewriteCond</code>
directives). For historical reasons the conditions are given
first, and so the control flow is a little bit long-winded. See
Figure 1 for more details.</p>
<p class="figure">
<img src="/images/rewrite_rule_flow.png"
alt="Flow of RewriteRule and RewriteCond matching" /><br />
<dfn>Figure 1:</dfn>The control flow through the rewriting ruleset
</p>
<p>First the URL is matched against the
<em>Pattern</em> of each rule. If it fails, mod_rewrite
immediately stops processing this rule, and continues with the
next rule. If the <em>Pattern</em> matches, mod_rewrite looks
for corresponding rule conditions (RewriteCond directives,
appearing immediately above the RewriteRule in the configuration).
If none are present, it 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 exist, it starts an
inner loop for processing them in the order that 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, <em>etc.</em> and then we try
to match <em>CondPattern</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 conditions are
available. If all conditions match, processing is continued
with the substitution of the URL with
<em>Substitution</em>.</p>
</section>
</manualpage>