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