1 <?xml version='1.0' encoding='UTF-8' ?>
2 <!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
3 <?xml-stylesheet type="text/xsl" href="../style/manual.en.xsl"?>
4 <!-- $LastChangedRevision$ -->
7 Licensed to the Apache Software Foundation (ASF) under one or more
8 contributor license agreements. See the NOTICE file distributed with
9 this work for additional information regarding copyright ownership.
10 The ASF licenses this file to You under the Apache License, Version 2.0
11 (the "License"); you may not use this file except in compliance with
12 the License. You may obtain a copy of the License at
14 http://www.apache.org/licenses/LICENSE-2.0
16 Unless required by applicable law or agreed to in writing, software
17 distributed under the License is distributed on an "AS IS" BASIS,
18 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 See the License for the specific language governing permissions and
20 limitations under the License.
23 <manualpage metafile="tech.xml.meta">
24 <parentdocument href="./">Rewrite</parentdocument>
26 <title>Apache mod_rewrite Technical Details</title>
29 <p>This document discusses some of the technical details of mod_rewrite
32 <seealso><a href="../mod/mod_rewrite.html">Module documentation</a></seealso>
33 <seealso><a href="intro.html">mod_rewrite introduction</a></seealso>
34 <seealso><a href="remapping.html">Redirection and remapping</a></seealso>
35 <seealso><a href="access.html">Controlling access</a></seealso>
36 <seealso><a href="vhosts.html">Virtual hosts</a></seealso>
37 <seealso><a href="proxy.html">Proxying</a></seealso>
38 <seealso><a href="rewritemap.html">Using RewriteMap</a></seealso>
39 <seealso><a href="advanced.html">Advanced techniques</a></seealso>
40 <seealso><a href="avoid.html">When not to use mod_rewrite</a></seealso>
42 <section id="InternalAPI"><title>API Phases</title>
44 <p>The Apache HTTP Server handles requests in several phases. At
45 each of these phases, one or more modules may be called upon to
46 handle that portion of the request lifecycle. Phases include things
47 like URL-to-filename translation, authentication, authorization,
48 content, and logging. (These is not an exhaustive list.)</p>
50 <p>mod_rewrite acts in two of these phases (or "hooks", as they are
51 sometimes called) to influence how URLs may be rewritten.</p>
53 <p>First, it uses the URL-to-filename translation hook, which occurs
54 after the HTTP request has been read, but before any authorization
55 starts. Secondly, it uses the Fixup hook, which is after the
56 authorizatin phases, and after per-directory configuration files
57 (<code>.htaccess</code> files) have been read, but before the
58 content handler is called.</p>
60 <p>So, after a request comes in and a corresponding server or
61 virtual host has been determined, the rewriting engine starts
62 processing any <code>mod_rewrite</code> directives appearing in the
63 per-server configuration. (ie, in the main server configuration file
64 and <directive module="core" type="section">Virtualhost</directive>
65 sections.) This happens in the URL-to-filename phase.</p>
67 <p>A few steps later, when the finaly data directories are found,
68 the per-directory configuration directives (<code>.htaccess</code>
69 files and <directive module="core"
70 type="section">Directory</directive> blocks) are applied. This
71 happens in the Fixup phase.</p>
73 <p>In each of these cases, mod_rewrite rewrites the
74 <code>REQUEST_URI</code> either to a new URI, or to a filename.</p>
76 <p>In per-directory context (ie, within <code>.htaccess</code> files
77 and <code>Directory</code> blocks), these rules are being applied
78 after a URI has already been translated to a filename. Because of
79 this, mod_rewrite temporarily translates the filename back into a URI,
80 by stripping off directory paty before appling the rules. (See the
81 <directive module="mod_rewrite">RewriteBase</directive> directive to
82 see how you can further manipulate how this is handled.) Then, a new
83 internal subrequest is issued with the new URI. This restarts
84 processing of the API phases.</p>
86 <p>Because of this further manipulation of the URI in per-directory
87 context, you'll need to take care to craft your rewrite rules
88 differently in that context. In particular, remember that the
89 leading directory path will be stripped off of the URI that your
90 rewrite rules will see. Consider the examples below for further
96 <th>Location of rule</th>
101 <td>VirtualHost section</td>
102 <td>RewriteRule ^/images/(.+)\.jpg /images/$1.gif</td>
106 <td>.htaccess file in document root</td>
107 <td>RewriteRule ^images/(.+)\.jpg images/$1.gif</td>
111 <td>.htaccess file in images directory</td>
112 <td>RewriteRule ^(.+)\.jpg $1.gif</td>
119 <section id="InternalRuleset"><title>Ruleset Processing</title>
121 <p>Now when mod_rewrite is triggered in these two API phases, it
122 reads the configured rulesets from its configuration
123 structure (which itself was either created on startup for
124 per-server context or during the directory walk of the Apache
125 kernel for per-directory context). Then the URL rewriting
126 engine is started with the contained ruleset (one or more
127 rules together with their conditions). The operation of the
128 URL rewriting engine itself is exactly the same for both
129 configuration contexts. Only the final result processing is
132 <p>The order of rules in the ruleset is important because the
133 rewriting engine processes them in a special (and not very
134 obvious) order. The rule is this: The rewriting engine loops
135 through the ruleset rule by rule (<directive
136 module="mod_rewrite">RewriteRule</directive> directives) and
137 when a particular rule matches it optionally loops through
138 existing corresponding conditions (<code>RewriteCond</code>
139 directives). For historical reasons the conditions are given
140 first, and so the control flow is a little bit long-winded. See
141 Figure 1 for more details.</p>
143 <img src="../images/rewrite_rule_flow.png"
144 alt="Flow of RewriteRule and RewriteCond matching" /><br />
145 <dfn>Figure 1:</dfn>The control flow through the rewriting ruleset
147 <p>As you can see, first the URL is matched against the
148 <em>Pattern</em> of each rule. When it fails mod_rewrite
149 immediately stops processing this rule and continues with the
150 next rule. If the <em>Pattern</em> matches, mod_rewrite looks
151 for corresponding rule conditions. If none are present, it
152 just substitutes the URL with a new value which is
153 constructed from the string <em>Substitution</em> and goes on
154 with its rule-looping. But if conditions exist, it starts an
155 inner loop for processing them in the order that they are
156 listed. For conditions the logic is different: we don't match
157 a pattern against the current URL. Instead we first create a
158 string <em>TestString</em> by expanding variables,
159 back-references, map lookups, <em>etc.</em> and then we try
160 to match <em>CondPattern</em> against it. If the pattern
161 doesn't match, the complete set of conditions and the
162 corresponding rule fails. If the pattern matches, then the
163 next condition is processed until no more conditions are
164 available. If all conditions match, processing is continued
165 with the substitution of the URL with
166 <em>Substitution</em>.</p>