]> granicus.if.org Git - apache/blob - docs/manual/rewrite/rewritemap.xml
Missing space.
[apache] / docs / manual / rewrite / rewritemap.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: 882992 $ -->
5 <!--
6  Licensed to the Apache Software Foundation (ASF) under one or more
7  contributor license agreements.  See the NOTICE file distributed with
8  this work for additional information regarding copyright ownership.
9  The ASF licenses this file to You under the Apache License, Version 2.0
10  (the "License"); you may not use this file except in compliance with
11  the License.  You may obtain a copy of the License at
12
13      http://www.apache.org/licenses/LICENSE-2.0
14
15  Unless required by applicable law or agreed to in writing, software
16  distributed under the License is distributed on an "AS IS" BASIS,
17  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  See the License for the specific language governing permissions and
19  limitations under the License.
20 -->
21 <manualpage metafile="rewritemap.xml.meta">
22   <parentdocument href="./">Rewrite</parentdocument>
23   <title>Using RewriteMap</title>
24   <summary>
25
26     <p>This document supplements the <module>mod_rewrite</module> 
27 <a href="../mod/mod_rewrite.html">reference documentation</a>. It describes
28 the use of the <directive module="mod_rewrite">RewriteMap</directive> directive,
29 and provides examples of each of the various <code>RewriteMap</code> types.</p>
30
31     <note type="warning">Note that many of these examples won't work unchanged in your
32 particular server configuration, so it's important that you understand
33 them, rather than merely cutting and pasting the examples into your
34 configuration.</note>
35
36   </summary>
37   <seealso><a href="../mod/mod_rewrite.html">Module documentation</a></seealso>
38   <seealso><a href="intro.html">mod_rewrite introduction</a></seealso>
39   <seealso><a href="remapping.html">Redirection and remapping</a></seealso>
40   <seealso><a href="access.html">Controlling access</a></seealso>
41   <seealso><a href="vhosts.html">Virtual hosts</a></seealso>
42   <seealso><a href="proxy.html">Proxying</a></seealso>
43   <seealso><a href="advanced.html">Advanced techniques and tricks</a></seealso>
44   <seealso><a href="avoid.html">When not to use mod_rewrite</a></seealso>
45
46   <section id="introduction">
47     <title>Introduction</title>
48
49    <p>
50    The <directive module="mod_rewrite">RewriteMap</directive> directive
51    defines an external function which can be called in the context of
52    <directive module="mod_rewrite">RewriteRule</directive> or
53    <directive module="mod_rewrite">RewriteCond</directive> directives to
54    perform rewriting that is too complicated, or too specialized to be
55    performed just by regular expressions. The source of this lookup can
56    be any of the types listed in the sections below, and enumerated in
57    the <directive module="mod_rewrite">RewriteMap</directive> reference
58    documentation.</p>
59
60    <p>The syntax of the <code>RewriteMap</code> directive is as
61    follows:</p>
62
63 <example>
64 RewriteMap <em>MapName</em> <em>MapType</em>:<em>MapSource</em>
65 </example>
66     
67     <p>The <a id="mapfunc" name="mapfunc"><em>MapName</em></a> is an
68     arbitray name that you assign to the map, and which you will use in
69     directives later on. Arguments are passed to the map via the
70     following syntax:</p>
71
72     <p class="indent">
73       <strong>
74         <code>${</code> <em>MapName</em> <code>:</code> <em>LookupKey</em>
75         <code>}</code> <br/> <code>${</code> <em>MapName</em> <code>:</code>
76         <em>LookupKey</em> <code>|</code> <em>DefaultValue</em> <code>}</code>
77       </strong>
78     </p>
79
80     <p>When such a construct occurs, the map <em>MapName</em> is
81       consulted and the key <em>LookupKey</em> is looked-up. If the
82       key is found, the map-function construct is substituted by
83       <em>SubstValue</em>. If the key is not found then it is
84       substituted by <em>DefaultValue</em> or by the empty string
85       if no <em>DefaultValue</em> was specified.</p>
86
87     <p>For example, you might define a
88       <directive>RewriteMap</directive> as:</p>
89     <example>
90       RewriteMap examplemap txt:/path/to/file/map.txt
91       </example>
92     <p>You would then be able to use this map in a
93       <directive>RewriteRule</directive> as follows:</p>
94 <example>
95   RewriteRule ^/ex/(.*) ${examplemap:$1}
96 </example>
97
98 <p>A default value can be specified in the event that nothing is found
99 in the map:</p>
100
101 <example>
102 RewriteRule ^/ex/(.*) ${examplemap:$1|/not_found.html}
103 </example>
104
105 <note><title>Per-directory and .htaccess context</title>
106 <p>
107 The <code>RewriteMap</code> directive  may not be used in
108 &lt;Directory&gt; sections or <code>.htaccess</code> files. You must
109 declare the map in server or virtualhost context. You may use the map,
110 once created, in your <code>RewriteRule</code> and
111 <code>RewriteCond</code> directives in those scopes. You just can't
112 <strong>declare</strong> it in those scopes.
113 </p>
114 </note>
115
116 <p>The sections that follow describe the various <em>MapType</em>s that
117 may be used, and give examples of each.</p>
118   </section>
119
120   <section id="txt">
121     <title>txt: Plain text maps</title>
122
123     <p>When a MapType of <code>txt</code> is used, the MapSource is a filesystem path to a
124     plain-text mapping file, containing space-separated key/value pair
125     per line. Optionally, a line may be contain a comment, starting with
126     a '#' character.</p>
127
128     <p>For example, the following might be valid entries in a map
129     file.</p>
130
131     <p class="indent">
132       # Comment line<br />
133       <strong><em>MatchingKey</em> <em>SubstValue</em></strong><br />
134       <strong><em>MatchingKey</em> <em>SubstValue</em></strong> # comment<br />
135     </p>
136
137     <p>When the RewriteMap is invoked the argument is looked for in the
138     first argument of a line, and, if found, the substitution value is
139     returned.</p>
140
141     <p>For example, we might use a mapfile to translate product names to
142     product IDs for easier-to-remember URLs, using the following
143     recipe:</p>
144
145     <example><title>Product to ID configuration</title>
146     RewriteMap product2id txt:/etc/apache2/productmap.txt<br />
147     RewriteRule ^/product/(.*) /prods.php?id=${product2id:$1|NOTFOUND} [PT]
148     </example>
149
150     <p>We assume here that the <code>prods.php</code> script knows what
151     to do when it received an argument of <code>id=NOTFOUND</code> when
152     a product is not found in the lookup map.</p>
153
154     <p>The file <code>/etc/apache2/productmap.txt</code> then contains
155     the following:</p>
156
157     <example><title>Product to ID map</title>
158 ##<br />
159 ##  productmap.txt - Product to ID map file<br />
160 ##<br />
161 <br />
162 television 993<br />
163 stereo     198<br />
164 fishingrod 043<br />
165 basketball 418<br />
166 telephone  328
167     </example>
168
169     <p>Thus, when <code>http://example.com/product/television</code> is
170     requested, the <code>RewriteRule</code> is applied, and the request
171     is internally mapped to <code>/prods.php?id=993</code>.</p>
172
173     <note><title>Note: .htaccess files</title>
174     The example given is crafted to be used in server or virtualhost
175     scope. If you're planning to use this in a <code>.htaccess</code>
176     file, you'll need to remove the leading slash from the rewrite
177     pattern in order for it to match anything:
178     <example>
179     RewriteRule ^product/(.*) /prods.php?id=${product2id:$1|NOTFOUND} [PT]
180     </example>
181     </note>
182
183     <note><title>Cached lookups</title>
184     <p>
185     The looked-up keys are cached by httpd until the <code>mtime</code>
186     (modified time) of the mapfile changes, or the httpd server is
187     restarted. This ensures better performance on maps that are called
188     by many requests.
189     </p>
190     </note>
191
192   </section>
193   <section id="rnd">
194     <title>rnd: Randomized Plain Text</title>
195
196     <p>When a MapType of <code>rnd</code> is used, the MapSource is a
197     filesystem path to a plain-text mapping file, each line of which
198     contains a key, and one or more values separated by <code>|</code>.
199     One of these values will be chosen at random if the key is
200     matched.</p>
201
202     <p>For example, you might use the following map
203     file and directives to provide a random load balancing between
204     several back-end server, via a reverse-proxy. Images are sent
205     to one of the servers in the 'static' pool, while everything
206     else is sent to one of the 'dynamic' pool.</p>
207
208     <example><title>Rewrite map file</title>
209 ##<br />
210 ##  map.txt -- rewriting map<br />
211 ##<br />
212 <br />
213 static   www1|www2|www3|www4<br />
214 dynamic  www5|www6
215     </example>
216
217     <example><title>Configuration directives</title>
218     RewriteMap servers rnd:/path/to/file/map.txt<br/>
219     <br/>
220     RewriteRule ^/(.*\.(png|gif|jpg)) http://${servers:static}/$1 [NC,P,L]<br/>
221     RewriteRule ^/(.*) http://${servers:dynamic}/$1 [P,L]
222     </example>
223
224     <p>So, when an image is requested and the first of these rules is
225     matched, <code>RewriteMap</code> looks up the string
226     <code>static</code> in the map file, which returns one of the
227     specified hostnames at random, which is then used in the
228     <code>RewriteRule</code> target.</p>
229
230     <p>If you wanted to have one of the servers more likely to be chosen
231     (for example, if one of the server has more memory than the others,
232     and so can handle more requests) simply list it more times in the
233     map file.</p>
234
235     <example>
236 static   www1|www1|www2|www3|www4
237     </example>
238
239   </section>
240
241   <section id="dbm">
242     <title>dbm: DBM Hash File</title>
243
244     <p>When a MapType of <code>dbm</code> is used, the MapSource is a
245     filesystem path to a DBM database file containing key/value pairs to
246     be used in the mapping. This works exactly the same way as the
247     <code>txt</code> map, but is much faster, because a DBM is indexed,
248     whereas a text file is not. This allows more rapid access to the
249     desired key.</p>
250
251     <p>You may optionally specify a particular dbm type:</p>
252
253  <example>
254  RewriteMap examplemap dbm=sdbm:/etc/apache/mapfile.dbm
255  </example>
256
257     <p>The type can be sdbm, gdbm, ndbm or db.
258     However, it is recommended that you just use the <a
259     href="../programs/httxt2dbm.html">httxt2dbm</a> utility that is
260     provided with Apache HTTP Server, as it will use the correct DBM library,
261     matching the one that was used when httpd itself was built.</p>
262
263     <p>To create a dbm file, first create a text map file as described
264     in the <a href="#txt">txt</a> section. Then run
265     <code>httxt2dbm</code>:</p>
266
267 <example>
268 $ httxt2dbm -i mapfile.txt -o mapfile.map
269 </example>
270
271 <p>You can then reference the resulting file in your
272 <code>RewriteMap</code> directive:</p>
273
274 <example>
275 RewriteMap mapname dbm:/etc/apache/mapfile.map
276 </example>
277
278 <note>
279 <p>Note that with some dbm types, more than one file is generated, with
280 a common base name. For example, you may have two files named
281 <code>mapfile.map.dir</code> and <code>mapfiile.map.pag</code>. This is
282 normal, and you need only use the base name <code>mapfile.map</code> in
283 your <code>RewriteMap</code> directive.</p>
284 </note>
285
286 <note><title>Cached lookups</title>
287 <p>
288 The looked-up keys are cached by httpd until the <code>mtime</code>
289 (modified time) of the mapfile changes, or the httpd server is
290 restarted. This ensures better performance on maps that are called
291 by many requests.
292 </p>
293 </note>
294
295   </section>
296
297   <section id="int">
298     <title>int: Internal Function</title>
299
300     <p>When a MapType of <code>int</code> is used, the MapSource is one
301     of the available internal RewriteMap functions.  Module authors can provide 
302     additional internal functions by registering them with the
303     <code>ap_register_rewrite_mapfunc</code> API. 
304     The functions that are provided by default are:
305     </p>
306
307     <ul>
308       <li><strong>toupper</strong>:<br/>
309              Converts the key to all upper case.</li>
310       <li><strong>tolower</strong>:<br/>
311              Converts the key to all lower case.</li>
312       <li><strong>escape</strong>:<br/>
313              Translates special characters in the key to
314             hex-encodings.</li>
315       <li><strong>unescape</strong>:<br/>
316              Translates hex-encodings in the key back to
317             special characters.</li>
318     </ul>
319
320     <p>
321     To use one of these functions, create a <code>RewriteMap</code> referencing
322     the int function, and then use that in your <code>RewriteRule</code>:
323     </p>
324
325     <example><title>Redirect a URI to an all-lowercase version of itself</title>
326     RewriteMap lc int:tolower<br />
327     RewriteRule (.*[A-Z]+.*) ${lc:$1} [R]
328     </example>
329
330     <note>
331     <p>Please note that the example offered here is for
332     illustration purposes only, and is not a recommendation. If you want
333     to make URLs case-insensitive, consider using
334     <module>mod_speling</module> instead.
335     </p>
336     </note>
337
338   </section>
339
340   <section id="prg"><title>prg: External Rewriting Program</title>
341
342     <p>When a MapType of <code>prg</code> is used, the MapSource is a
343     filesystem path to an executable program which will providing the
344     mapping behavior. This can be a compiled binary file, or a program
345     in an interpreted language such as Perl or Python.</p>
346
347     <p>This program is started once, when the Apache HTTP Server is
348     started, and then communicates with the rewriting engine via
349     <code>STDIN</code> and <code>STDOUT</code>. That is, for each map
350     function lookup, it expects one argument via <code>STDIN</code>, and
351     should return one new-line terminated response string on
352     <code>STDOUT</code>. If there is no corresponding lookup value, the
353     map program should return the four-character string
354     "<code>NULL</code>" to indicate this.</p>
355
356     <p>External rewriting programs are not started if they're defined in
357     a context that does not have <directive
358     module="mod_rewrite">RewriteEngine</directive> set to
359     <code>on</code>.</p>
360
361     <p>This feature utilizes the <code>rewrite-map</code> mutex,
362     which is required for reliable communication with the program.
363     The mutex mechanism and lock file can be configured with the
364     <directive module="core">Mutex</directive> directive.</p>
365
366     <p>A simple example is shown here which will replace all dashes with
367     underscores in a request URI.</p>
368
369     <example><title>Rewrite configuration</title>
370     RewriteMap d2u prg:/www/bin/dash2under.pl<br />
371     RewriteRule - ${d2u:%{REQUEST_URI}}
372     </example>
373
374     <example><title>dash2under.pl</title>
375     #!/usr/bin/perl<br />
376     $| = 1; # Turn off I/O buffering<br />
377     while (&lt;STDIN&gt;) {<br />
378         <indent>
379         s/-/_/g; # Replace dashes with underscores<br />
380         print $_;<br />
381         </indent>
382     }<br />
383     </example>
384
385 <note><title>Caution!</title>
386 <ul>
387 <li>Keep your rewrite map program as simple as possible. If the program
388 hangs, it will cause httpd to wait indefinitely for a response from the
389 map, which will, in turn, cause httpd to stop responding to
390 requests.</li>
391 <li>Be sure to turn off buffering in your program. In Perl this is done
392 by the second line in the example script: <code>$| = 1;</code> This will
393 of course vary in other languages. Buffered I/O will cause httpd to wait
394 for the output, and so it will hang.</li>
395 <li>Remember that there is only one copy of the program, started at
396 server startup. All requests will need to go through this one bottleneck.
397 This can cause significant slowdowns if many requests must go through
398 this process, or if the script itself is very slow.</li>
399 </ul>
400 </note>
401
402 </section>
403
404
405   <section id="dbd">
406     <title>dbd or fastdbd: SQL Query</title>
407
408     <p>When a MapType of <code>dbd</code> or <code>fastdbd</code> is
409     used, the MapSource is a SQL SELECT statement that takes a single
410     argument and returns a single value.</p>
411
412     <p><module>mod_dbd</module> will need to be configured to point at
413     the right database for this statement to be executed.</p>
414
415     <p>There are two forms of this MapType.
416     Using a MapType of <code>dbd</code> causes the query to be
417     executed with each map request, while using <code>fastdbd</code>
418     caches the database lookups internally. So, while
419     <code>fastdbd</code> is more efficient, and therefore faster, it
420     won't pick up on changes to the database until the server is
421     restarted.</p>
422
423     <p>If a query returns more than one row, a random row from
424 the result set is used.</p>
425
426     <example><title>Example</title>
427 RewriteMap myquery "fastdbd:SELECT destination FROM rewrite WHERE source = %s"
428     </example>
429
430   </section>
431   <section id="summary">
432     <title>Summary</title>
433
434     <p>The <directive>RewriteMap</directive> directive can occur more than
435     once. For each mapping-function use one
436     <directive>RewriteMap</directive> directive to declare its rewriting
437     mapfile.</p>
438       
439     <p>While you cannot <strong>declare</strong> a map in
440     per-directory context (<code>.htaccess</code> files or
441     &lt;Directory&gt; blocks) it is possible to
442     <strong>use</strong> this map in per-directory context. </p>
443
444   </section>
445 </manualpage>