]> granicus.if.org Git - apache/blob - docs/manual/rewrite/tech.xml
Rebuild.
[apache] / docs / manual / rewrite / tech.xml
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$ -->
5
6 <!--
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
13
14      http://www.apache.org/licenses/LICENSE-2.0
15
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.
21 -->
22
23 <manualpage metafile="tech.xml.meta">
24 <parentdocument href="./">Rewrite</parentdocument>
25
26   <title>Apache mod_rewrite Technical Details</title>
27
28 <summary>
29 <p>This document discusses some of the technical details of mod_rewrite
30 and URL matching.</p>
31 </summary>
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>
41
42 <section id="InternalAPI"><title>API Phases</title>
43
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. (This is not an exhaustive list.)</p>
49
50     <p>mod_rewrite acts in two of these phases (or "hooks", as they are
51     often called) to influence how URLs may be rewritten.</p>
52
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     authorization phases, and after per-directory configuration files
57     (<code>.htaccess</code> files) have been read, but before the
58     content handler is called.</p>
59
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. (i.e., 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>
66
67     <p>A few steps later, once the final data directories have been 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>
72
73     <p>In each of these cases, mod_rewrite rewrites the
74     <code>REQUEST_URI</code> either to a new URL, or to a filename.</p>
75
76     <p>In per-directory context (i.e., within <code>.htaccess</code> files
77     and <code>Directory</code> blocks), these rules are being applied
78     after a URL has already been translated to a filename. Because of
79     this, the URL-path that mod_rewrite initially compares <directive 
80     module="mod_rewrite">RewriteRule</directive> directives against
81     is the full filesystem path to the translated filename with the current
82     directories path (including a trailing slash) removed from the front.</p>
83
84     <p> To illustrate: If rules are in /var/www/foo/.htaccess and a request
85     for /foo/bar/baz is being processed, an expression like ^bar/baz$ would
86     match.</p>
87
88     <p> If a substitution is made in per-directory context, a new internal 
89     subrequest is issued with the new URL, which restarts processing of the 
90     request phases. If the substitution is a relative path, the <directive 
91     module="mod_rewrite">RewriteBase</directive> directive 
92     determines the URL-path prefix prepended to the substitution.
93     In per-directory context, care must be taken to 
94     create rules which will eventually (in some future "round" of per-directory
95     rewrite processing) not perform a substitution to avoid looping.
96     (See <a href="http://wiki.apache.org/httpd/RewriteLooping">RewriteLooping</a>
97     for further discussion of this problem.)</p>
98
99     <p>Because of this further manipulation of the URL in per-directory
100     context, you'll need to take care to craft your rewrite rules
101     differently in that context. In particular, remember that the
102     leading directory path will be stripped off of the URL that your
103     rewrite rules will see. Consider the examples below for further
104     clarification.</p>
105
106     <table border="1">
107
108         <tr>
109             <th>Location of rule</th>
110             <th>Rule</th>
111         </tr>
112
113         <tr>
114             <td>VirtualHost section</td>
115             <td>RewriteRule "^/images/(.+)\.jpg" "/images/$1.gif"</td>
116         </tr>
117
118         <tr>
119             <td>.htaccess file in document root</td>
120             <td>RewriteRule "^images/(.+)\.jpg" "images/$1.gif"</td>
121         </tr>
122
123         <tr>
124             <td>.htaccess file in images directory</td>
125             <td>RewriteRule "^(.+)\.jpg" "$1.gif"</td>
126         </tr>
127
128     </table>
129
130     <p>For even more insight into how mod_rewrite manipulates URLs in
131     different contexts, you should consult the <a
132     href="../mod/mod_rewrite.html#logging">log entries</a> made during 
133     rewriting.</p>
134
135 </section>
136
137 <section id="InternalRuleset"><title>Ruleset Processing</title>
138
139       <p>Now when mod_rewrite is triggered in these two API phases, it
140       reads the configured rulesets from its configuration
141       structure (which itself was either created on startup for
142       per-server context or during the directory walk of the Apache
143       kernel for per-directory context). Then the URL rewriting
144       engine is started with the contained ruleset (one or more
145       rules together with their conditions). The operation of the
146       URL rewriting engine itself is exactly the same for both
147       configuration contexts. Only the final result processing is
148       different.</p>
149
150       <p>The order of rules in the ruleset is important because the
151       rewriting engine processes them in a special (and not very
152       obvious) order. The rule is this: The rewriting engine loops
153       through the ruleset rule by rule (<directive
154       module="mod_rewrite">RewriteRule</directive> directives) and
155       when a particular rule matches it optionally loops through
156       existing corresponding conditions (<code>RewriteCond</code>
157       directives). For historical reasons the conditions are given
158       first, and so the control flow is a little bit long-winded. See
159       Figure 1 for more details.</p>
160 <p class="figure">
161       <img src="../images/rewrite_process_uri.png"
162           alt="Flow of RewriteRule and RewriteCond matching" /><br />
163       <dfn>Figure 1:</dfn>The control flow through the rewriting ruleset
164 </p>
165       <p>First the URL is matched against the
166       <em>Pattern</em> of each rule. If it fails, mod_rewrite
167       immediately stops processing this rule, and continues with the
168       next rule. If the <em>Pattern</em> matches, mod_rewrite looks
169       for corresponding rule conditions (RewriteCond directives,
170       appearing immediately above the RewriteRule in the configuration).
171       If none are present, it substitutes the URL with a new value, which is
172       constructed from the string <em>Substitution</em>, and goes on
173       with its rule-looping. But if conditions exist, it starts an
174       inner loop for processing them in the order that they are
175       listed. For conditions, the logic is different: we don't match
176       a pattern against the current URL. Instead we first create a
177       string <em>TestString</em> by expanding variables,
178       back-references, map lookups, <em>etc.</em> and then we try
179       to match <em>CondPattern</em> against it. If the pattern
180       doesn't match, the complete set of conditions and the
181       corresponding rule fails. If the pattern matches, then the
182       next condition is processed until no more conditions are
183       available. If all conditions match, processing is continued
184       with the substitution of the URL with
185       <em>Substitution</em>.</p>
186
187 </section>
188
189
190 </manualpage>
191