Moved apache code into a folder to help prepare for packaging where we dont want...
[httpd-crcsyncproxy.git] / apache / docs / manual / rewrite / rewrite_guide.html.en
blob958448c65eaad2948724a828369ba9f70ced996a
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head><!--
4 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5 This file is generated from xml source: DO NOT EDIT
6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7 -->
8 <title>URL Rewriting Guide - Apache HTTP Server</title>
9 <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
10 <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
11 <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" />
12 <link href="../images/favicon.ico" rel="shortcut icon" /></head>
13 <body id="manual-page"><div id="page-header">
14 <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="../faq/">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
15 <p class="apache">Apache HTTP Server Version 2.3</p>
16 <img alt="" src="../images/feather.gif" /></div>
17 <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
18 <div id="path">
19 <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.3</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>URL Rewriting Guide</h1>
20 <div class="toplang">
21 <p><span>Available Languages: </span><a href="../en/rewrite/rewrite_guide.html" title="English">&nbsp;en&nbsp;</a></p>
22 </div>
25 <p>This document supplements the <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
26 <a href="../mod/mod_rewrite.html">reference documentation</a>.
27 It describes how one can use Apache's <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
28 to solve typical URL-based problems with which webmasters are
29 commonly confronted. We give detailed descriptions on how to
30 solve each problem by configuring URL rewriting rulesets.</p>
32 <div class="warning">ATTENTION: Depending on your server configuration
33 it may be necessary to slightly change the examples for your
34 situation, e.g. adding the <code>[PT]</code> flag when
35 additionally using <code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code> and
36 <code class="module"><a href="../mod/mod_userdir.html">mod_userdir</a></code>, etc. Or rewriting a ruleset
37 to fit in <code>.htaccess</code> context instead
38 of per-server context. Always try to understand what a
39 particular ruleset really does before you use it. This
40 avoids many problems.</div>
42 </div>
43 <div id="quickview"><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#canonicalurl">Canonical URLs</a></li>
44 <li><img alt="" src="../images/down.gif" /> <a href="#canonicalhost">Canonical Hostnames</a></li>
45 <li><img alt="" src="../images/down.gif" /> <a href="#moveddocroot">Moved <code>DocumentRoot</code></a></li>
46 <li><img alt="" src="../images/down.gif" /> <a href="#trailingslash">Trailing Slash Problem</a></li>
47 <li><img alt="" src="../images/down.gif" /> <a href="#movehomedirs">Move Homedirs to Different Webserver</a></li>
48 <li><img alt="" src="../images/down.gif" /> <a href="#multipledirs">Search for pages in more than one directory</a></li>
49 <li><img alt="" src="../images/down.gif" /> <a href="#setenvvars">Set Environment Variables According To URL Parts</a></li>
50 <li><img alt="" src="../images/down.gif" /> <a href="#uservhosts">Virtual Hosts Per User</a></li>
51 <li><img alt="" src="../images/down.gif" /> <a href="#redirecthome">Redirect Homedirs For Foreigners</a></li>
52 <li><img alt="" src="../images/down.gif" /> <a href="#redirectanchors">Redirecting Anchors</a></li>
53 <li><img alt="" src="../images/down.gif" /> <a href="#time-dependent">Time-Dependent Rewriting</a></li>
54 <li><img alt="" src="../images/down.gif" /> <a href="#backward-compatibility">Backward Compatibility for YYYY to XXXX migration</a></li>
55 <li><img alt="" src="../images/down.gif" /> <a href="#old-to-new">From Old to New (intern)</a></li>
56 <li><img alt="" src="../images/down.gif" /> <a href="#old-to-new-extern">From Old to New (extern)</a></li>
57 <li><img alt="" src="../images/down.gif" /> <a href="#static-to-dynamic">From Static to Dynamic</a></li>
58 <li><img alt="" src="../images/down.gif" /> <a href="#blocking-of-robots">Blocking of Robots</a></li>
59 <li><img alt="" src="../images/down.gif" /> <a href="#blocked-inline-images">Forbidding Image "Hotlinking"</a></li>
60 <li><img alt="" src="../images/down.gif" /> <a href="#proxy-deny">Proxy Deny</a></li>
61 <li><img alt="" src="../images/down.gif" /> <a href="#external-rewriting">External Rewriting Engine</a></li>
62 </ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module
63 documentation</a></li><li><a href="rewrite_intro.html">mod_rewrite
64 introduction</a></li><li><a href="rewrite_guide_advanced.html">Advanced Rewrite Guide - advanced
65 useful examples</a></li><li><a href="rewrite_tech.html">Technical details</a></li></ul></div>
66 <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
67 <div class="section">
68 <h2><a name="canonicalurl" id="canonicalurl">Canonical URLs</a></h2>
72 <dl>
73 <dt>Description:</dt>
75 <dd>
76 <p>On some webservers there are more than one URL for a
77 resource. Usually there are canonical URLs (which should be
78 actually used and distributed) and those which are just
79 shortcuts, internal ones, etc. Independent of which URL the
80 user supplied with the request he should finally see the
81 canonical one only.</p>
82 </dd>
84 <dt>Solution:</dt>
86 <dd>
87 <p>We do an external HTTP redirect for all non-canonical
88 URLs to fix them in the location view of the Browser and
89 for all subsequent requests. In the example ruleset below
90 we replace <code>/~user</code> by the canonical
91 <code>/u/user</code> and fix a missing trailing slash for
92 <code>/u/user</code>.</p>
94 <div class="example"><pre>
95 RewriteRule ^/<strong>~</strong>([^/]+)/?(.*) /<strong>u</strong>/$1/$2 [<strong>R</strong>]
96 RewriteRule ^/u/(<strong>[^/]+</strong>)$ /$1/$2<strong>/</strong> [<strong>R</strong>]
97 </pre></div>
98 </dd>
99 </dl>
101 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
102 <div class="section">
103 <h2><a name="canonicalhost" id="canonicalhost">Canonical Hostnames</a></h2>
105 <dl>
106 <dt>Description:</dt>
108 <dd>The goal of this rule is to force the use of a particular
109 hostname, in preference to other hostnames which may be used to
110 reach the same site. For example, if you wish to force the use
111 of <strong>www.example.com</strong> instead of
112 <strong>example.com</strong>, you might use a variant of the
113 following recipe.</dd>
115 <dt>Solution:</dt>
117 <dd>
118 <p>For sites running on a port other than 80:</p>
119 <div class="example"><pre>
120 RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
121 RewriteCond %{HTTP_HOST} !^$
122 RewriteCond %{SERVER_PORT} !^80$
123 RewriteRule ^/?(.*) http://www.example.com:%{SERVER_PORT}/$1 [L,R]
124 </pre></div>
126 <p>And for a site running on port 80</p>
127 <div class="example"><pre>
128 RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
129 RewriteCond %{HTTP_HOST} !^$
130 RewriteRule ^/?(.*) http://www.example.com/$1 [L,R]
131 </pre></div>
134 If you wanted to do this generically for all domain names - that
135 is, if you want to redirect <strong>example.com</strong> to
136 <strong>www.example.com</strong> for all possible values of
137 <strong>example.com</strong>, you could use the following
138 recipe:</p>
140 <div class="example"><pre>
141 RewriteCond %{HTTP_HOST} !^www\. [NC]
142 RewriteCond %{HTTP_HOST} !^$
143 RewriteRule ^/?(.*) http://www.%{HTTP_HOST}/$1 [L,R]
144 </pre></div>
146 <p>These rulesets will work either in your main server configuration
147 file, or in a <code>.htaccess</code> file placed in the <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> of the server.</p>
148 </dd>
149 </dl>
151 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
152 <div class="section">
153 <h2><a name="moveddocroot" id="moveddocroot">Moved <code>DocumentRoot</code></a></h2>
157 <dl>
158 <dt>Description:</dt>
160 <dd>
161 <p>Usually the <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>
162 of the webserver directly relates to the URL "<code>/</code>".
163 But often this data is not really of top-level priority. For example,
164 you may wish for visitors, on first entering a site, to go to a
165 particular subdirectory <code>/about/</code>. This may be accomplished
166 using the following ruleset:</p>
167 </dd>
169 <dt>Solution:</dt>
171 <dd>
172 <p>We redirect the URL <code>/</code> to
173 <code>/about/</code>:
174 </p>
176 <div class="example"><pre>
177 RewriteEngine on
178 RewriteRule <strong>^/$</strong> /about/ [<strong>R</strong>]
179 </pre></div>
181 <p>Note that this can also be handled using the <code class="directive"><a href="../mod/mod_alias.html#redirectmatch">RedirectMatch</a></code> directive:</p>
183 <div class="example"><p><code>
184 RedirectMatch ^/$ http://example.com/about/
185 </code></p></div>
187 <p>Note also that the example rewrites only the root URL. That is, it
188 rewrites a request for <code>http://example.com/</code>, but not a
189 request for <code>http://example.com/page.html</code>. If you have in
190 fact changed your document root - that is, if <strong>all</strong> of
191 your content is in fact in that subdirectory, it is greatly preferable
192 to simply change your <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>
193 directive, rather than rewriting URLs.</p>
194 </dd>
195 </dl>
197 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
198 <div class="section">
199 <h2><a name="trailingslash" id="trailingslash">Trailing Slash Problem</a></h2>
203 <dl>
204 <dt>Description:</dt>
206 <dd><p>The vast majority of "trailing slash" problems can be dealt
207 with using the techniques discussed in the <a href="http://httpd.apache.org/docs/misc/FAQ-E.html#set-servername">FAQ
208 entry</a>. However, occasionally, there is a need to use mod_rewrite
209 to handle a case where a missing trailing slash causes a URL to
210 fail. This can happen, for example, after a series of complex
211 rewrite rules.</p>
212 </dd>
214 <dt>Solution:</dt>
216 <dd>
217 <p>The solution to this subtle problem is to let the server
218 add the trailing slash automatically. To do this
219 correctly we have to use an external redirect, so the
220 browser correctly requests subsequent images etc. If we
221 only did a internal rewrite, this would only work for the
222 directory page, but would go wrong when any images are
223 included into this page with relative URLs, because the
224 browser would request an in-lined object. For instance, a
225 request for <code>image.gif</code> in
226 <code>/~quux/foo/index.html</code> would become
227 <code>/~quux/image.gif</code> without the external
228 redirect!</p>
230 <p>So, to do this trick we write:</p>
232 <div class="example"><pre>
233 RewriteEngine on
234 RewriteBase /~quux/
235 RewriteRule ^foo<strong>$</strong> foo<strong>/</strong> [<strong>R</strong>]
236 </pre></div>
238 <p>Alternately, you can put the following in a
239 top-level <code>.htaccess</code> file in the content directory.
240 But note that this creates some processing overhead.</p>
242 <div class="example"><pre>
243 RewriteEngine on
244 RewriteBase /~quux/
245 RewriteCond %{REQUEST_FILENAME} <strong>-d</strong>
246 RewriteRule ^(.+<strong>[^/]</strong>)$ $1<strong>/</strong> [R]
247 </pre></div>
248 </dd>
249 </dl>
251 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
252 <div class="section">
253 <h2><a name="movehomedirs" id="movehomedirs">Move Homedirs to Different Webserver</a></h2>
257 <dl>
258 <dt>Description:</dt>
260 <dd>
261 <p>Many webmasters have asked for a solution to the
262 following situation: They wanted to redirect just all
263 homedirs on a webserver to another webserver. They usually
264 need such things when establishing a newer webserver which
265 will replace the old one over time.</p>
266 </dd>
268 <dt>Solution:</dt>
270 <dd>
271 <p>The solution is trivial with <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>.
272 On the old webserver we just redirect all
273 <code>/~user/anypath</code> URLs to
274 <code>http://newserver/~user/anypath</code>.</p>
276 <div class="example"><pre>
277 RewriteEngine on
278 RewriteRule ^/~(.+) http://<strong>newserver</strong>/~$1 [R,L]
279 </pre></div>
280 </dd>
281 </dl>
283 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
284 <div class="section">
285 <h2><a name="multipledirs" id="multipledirs">Search for pages in more than one directory</a></h2>
289 <dl>
290 <dt>Description:</dt>
292 <dd>
293 <p>Sometimes it is necessary to let the webserver search
294 for pages in more than one directory. Here MultiViews or
295 other techniques cannot help.</p>
296 </dd>
298 <dt>Solution:</dt>
300 <dd>
301 <p>We program a explicit ruleset which searches for the
302 files in the directories.</p>
304 <div class="example"><pre>
305 RewriteEngine on
307 # first try to find it in dir1/...
308 # ...and if found stop and be happy:
309 RewriteCond %{DOCUMENT_ROOT}/<strong>dir1</strong>/%{REQUEST_URI} -f
310 RewriteRule ^(.+) %{DOCUMENT_ROOT}/<strong>dir1</strong>/$1 [L]
312 # second try to find it in dir2/...
313 # ...and if found stop and be happy:
314 RewriteCond %{DOCUMENT_ROOT}/<strong>dir2</strong>/%{REQUEST_URI} -f
315 RewriteRule ^(.+) %{DOCUMENT_ROOT}/<strong>dir2</strong>/$1 [L]
317 # else go on for other Alias or ScriptAlias directives,
318 # etc.
319 RewriteRule ^(.+) - [PT]
320 </pre></div>
321 </dd>
322 </dl>
324 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
325 <div class="section">
326 <h2><a name="setenvvars" id="setenvvars">Set Environment Variables According To URL Parts</a></h2>
330 <dl>
331 <dt>Description:</dt>
333 <dd>
334 <p>Perhaps you want to keep status information between
335 requests and use the URL to encode it. But you don't want
336 to use a CGI wrapper for all pages just to strip out this
337 information.</p>
338 </dd>
340 <dt>Solution:</dt>
342 <dd>
343 <p>We use a rewrite rule to strip out the status information
344 and remember it via an environment variable which can be
345 later dereferenced from within XSSI or CGI. This way a
346 URL <code>/foo/S=java/bar/</code> gets translated to
347 <code>/foo/bar/</code> and the environment variable named
348 <code>STATUS</code> is set to the value "java".</p>
350 <div class="example"><pre>
351 RewriteEngine on
352 RewriteRule ^(.*)/<strong>S=([^/]+)</strong>/(.*) $1/$3 [E=<strong>STATUS:$2</strong>]
353 </pre></div>
354 </dd>
355 </dl>
357 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
358 <div class="section">
359 <h2><a name="uservhosts" id="uservhosts">Virtual Hosts Per User</a></h2>
363 <dl>
364 <dt>Description:</dt>
366 <dd>
367 <p>Assume that you want to provide
368 <code>www.<strong>username</strong>.host.domain.com</code>
369 for the homepage of username via just DNS A records to the
370 same machine and without any virtualhosts on this
371 machine.</p>
372 </dd>
374 <dt>Solution:</dt>
376 <dd>
377 <p>For HTTP/1.0 requests there is no solution, but for
378 HTTP/1.1 requests which contain a Host: HTTP header we
379 can use the following ruleset to rewrite
380 <code>http://www.username.host.com/anypath</code>
381 internally to <code>/home/username/anypath</code>:</p>
383 <div class="example"><pre>
384 RewriteEngine on
385 RewriteCond %{<strong>HTTP_HOST</strong>} ^www\.<strong>([^.]+)</strong>\.host\.com$
386 RewriteRule ^(.*) /home/<strong>%1</strong>$1
387 </pre></div>
389 <p>Parentheses used in a <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> are captured into the
390 backreferences <code>%1</code>, <code>%2</code>, etc, while parentheses
391 used in <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> are
392 captured into the backreferences <code>$1</code>, <code>$2</code>,
393 etc.</p>
394 </dd>
395 </dl>
397 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
398 <div class="section">
399 <h2><a name="redirecthome" id="redirecthome">Redirect Homedirs For Foreigners</a></h2>
403 <dl>
404 <dt>Description:</dt>
406 <dd>
407 <p>We want to redirect homedir URLs to another webserver
408 <code>www.somewhere.com</code> when the requesting user
409 does not stay in the local domain
410 <code>ourdomain.com</code>. This is sometimes used in
411 virtual host contexts.</p>
412 </dd>
414 <dt>Solution:</dt>
416 <dd>
417 <p>Just a rewrite condition:</p>
419 <div class="example"><pre>
420 RewriteEngine on
421 RewriteCond %{REMOTE_HOST} <strong>!^.+\.ourdomain\.com$</strong>
422 RewriteRule ^(/~.+) http://www.somewhere.com/$1 [R,L]
423 </pre></div>
424 </dd>
425 </dl>
427 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
428 <div class="section">
429 <h2><a name="redirectanchors" id="redirectanchors">Redirecting Anchors</a></h2>
433 <dl>
434 <dt>Description:</dt>
436 <dd>
437 <p>By default, redirecting to an HTML anchor doesn't work,
438 because mod_rewrite escapes the <code>#</code> character,
439 turning it into <code>%23</code>. This, in turn, breaks the
440 redirection.</p>
441 </dd>
443 <dt>Solution:</dt>
445 <dd>
446 <p>Use the <code>[NE]</code> flag on the
447 <code>RewriteRule</code>. NE stands for No Escape.
448 </p>
449 </dd>
450 </dl>
452 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
453 <div class="section">
454 <h2><a name="time-dependent" id="time-dependent">Time-Dependent Rewriting</a></h2>
458 <dl>
459 <dt>Description:</dt>
461 <dd>
462 <p>When tricks like time-dependent content should happen a
463 lot of webmasters still use CGI scripts which do for
464 instance redirects to specialized pages. How can it be done
465 via <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>?</p>
466 </dd>
468 <dt>Solution:</dt>
470 <dd>
471 <p>There are a lot of variables named <code>TIME_xxx</code>
472 for rewrite conditions. In conjunction with the special
473 lexicographic comparison patterns <code>&lt;STRING</code>,
474 <code>&gt;STRING</code> and <code>=STRING</code> we can
475 do time-dependent redirects:</p>
477 <div class="example"><pre>
478 RewriteEngine on
479 RewriteCond %{TIME_HOUR}%{TIME_MIN} &gt;0700
480 RewriteCond %{TIME_HOUR}%{TIME_MIN} &lt;1900
481 RewriteRule ^foo\.html$ foo.day.html
482 RewriteRule ^foo\.html$ foo.night.html
483 </pre></div>
485 <p>This provides the content of <code>foo.day.html</code>
486 under the URL <code>foo.html</code> from
487 <code>07:00-19:00</code> and at the remaining time the
488 contents of <code>foo.night.html</code>. Just a nice
489 feature for a homepage...</p>
490 </dd>
491 </dl>
493 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
494 <div class="section">
495 <h2><a name="backward-compatibility" id="backward-compatibility">Backward Compatibility for YYYY to XXXX migration</a></h2>
499 <dl>
500 <dt>Description:</dt>
502 <dd>
503 <p>How can we make URLs backward compatible (still
504 existing virtually) after migrating <code>document.YYYY</code>
505 to <code>document.XXXX</code>, e.g. after translating a
506 bunch of <code>.html</code> files to <code>.phtml</code>?</p>
507 </dd>
509 <dt>Solution:</dt>
511 <dd>
512 <p>We just rewrite the name to its basename and test for
513 existence of the new extension. If it exists, we take
514 that name, else we rewrite the URL to its original state.</p>
517 <div class="example"><pre>
518 # backward compatibility ruleset for
519 # rewriting document.html to document.phtml
520 # when and only when document.phtml exists
521 # but no longer document.html
522 RewriteEngine on
523 RewriteBase /~quux/
524 # parse out basename, but remember the fact
525 RewriteRule ^(.*)\.html$ $1 [C,E=WasHTML:yes]
526 # rewrite to document.phtml if exists
527 # Note: This is a per-directory example, so %{REQUEST_FILENAME} is the full
528 # filesystem path as already mapped by the server.
529 RewriteCond %{REQUEST_FILENAME}.phtml -f
530 RewriteRule ^(.*)$ $1.phtml [S=1]
531 # else reverse the previous basename cutout
532 RewriteCond %{ENV:WasHTML} ^yes$
533 RewriteRule ^(.*)$ $1.html
534 </pre></div>
535 </dd>
536 </dl>
538 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
539 <div class="section">
540 <h2><a name="old-to-new" id="old-to-new">From Old to New (intern)</a></h2>
544 <dl>
545 <dt>Description:</dt>
547 <dd>
548 <p>Assume we have recently renamed the page
549 <code>foo.html</code> to <code>bar.html</code> and now want
550 to provide the old URL for backward compatibility. Actually
551 we want that users of the old URL even not recognize that
552 the pages was renamed.</p>
553 </dd>
555 <dt>Solution:</dt>
557 <dd>
558 <p>We rewrite the old URL to the new one internally via the
559 following rule:</p>
561 <div class="example"><pre>
562 RewriteEngine on
563 RewriteBase /~quux/
564 RewriteRule ^<strong>foo</strong>\.html$ <strong>bar</strong>.html
565 </pre></div>
566 </dd>
567 </dl>
569 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
570 <div class="section">
571 <h2><a name="old-to-new-extern" id="old-to-new-extern">From Old to New (extern)</a></h2>
575 <dl>
576 <dt>Description:</dt>
578 <dd>
579 <p>Assume again that we have recently renamed the page
580 <code>foo.html</code> to <code>bar.html</code> and now want
581 to provide the old URL for backward compatibility. But this
582 time we want that the users of the old URL get hinted to
583 the new one, i.e. their browsers Location field should
584 change, too.</p>
585 </dd>
587 <dt>Solution:</dt>
589 <dd>
590 <p>We force a HTTP redirect to the new URL which leads to a
591 change of the browsers and thus the users view:</p>
593 <div class="example"><pre>
594 RewriteEngine on
595 RewriteBase /~quux/
596 RewriteRule ^<strong>foo</strong>\.html$ <strong>bar</strong>.html [<strong>R</strong>]
597 </pre></div>
598 </dd>
599 </dl>
601 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
602 <div class="section">
603 <h2><a name="static-to-dynamic" id="static-to-dynamic">From Static to Dynamic</a></h2>
607 <dl>
608 <dt>Description:</dt>
610 <dd>
611 <p>How can we transform a static page
612 <code>foo.html</code> into a dynamic variant
613 <code>foo.cgi</code> in a seamless way, i.e. without notice
614 by the browser/user.</p>
615 </dd>
617 <dt>Solution:</dt>
619 <dd>
620 <p>We just rewrite the URL to the CGI-script and force the
621 handler to be <strong>cgi-script</strong> so that it is
622 executed as a CGI program.
623 This way a request to <code>/~quux/foo.html</code>
624 internally leads to the invocation of
625 <code>/~quux/foo.cgi</code>.</p>
627 <div class="example"><pre>
628 RewriteEngine on
629 RewriteBase /~quux/
630 RewriteRule ^foo\.<strong>html</strong>$ foo.<strong>cgi</strong> [H=<strong>cgi-script</strong>]
631 </pre></div>
632 </dd>
633 </dl>
635 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
636 <div class="section">
637 <h2><a name="blocking-of-robots" id="blocking-of-robots">Blocking of Robots</a></h2>
641 <dl>
642 <dt>Description:</dt>
644 <dd>
645 <p>How can we block a really annoying robot from
646 retrieving pages of a specific webarea? A
647 <code>/robots.txt</code> file containing entries of the
648 "Robot Exclusion Protocol" is typically not enough to get
649 rid of such a robot.</p>
650 </dd>
652 <dt>Solution:</dt>
654 <dd>
655 <p>We use a ruleset which forbids the URLs of the webarea
656 <code>/~quux/foo/arc/</code> (perhaps a very deep
657 directory indexed area where the robot traversal would
658 create big server load). We have to make sure that we
659 forbid access only to the particular robot, i.e. just
660 forbidding the host where the robot runs is not enough.
661 This would block users from this host, too. We accomplish
662 this by also matching the User-Agent HTTP header
663 information.</p>
665 <div class="example"><pre>
666 RewriteCond %{HTTP_USER_AGENT} ^<strong>NameOfBadRobot</strong>.*
667 RewriteCond %{REMOTE_ADDR} ^<strong>123\.45\.67\.[8-9]</strong>$
668 RewriteRule ^<strong>/~quux/foo/arc/</strong>.+ - [<strong>F</strong>]
669 </pre></div>
670 </dd>
671 </dl>
673 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
674 <div class="section">
675 <h2><a name="blocked-inline-images" id="blocked-inline-images">Forbidding Image "Hotlinking"</a></h2>
679 <dl>
680 <dt>Description:</dt>
682 <dd>
683 <p>The following technique forbids the practice of other sites
684 including your images inline in their pages. This practice is
685 often referred to as "hotlinking", and results in
686 your bandwidth being used to serve content for someone else's
687 site.</p>
688 </dd>
690 <dt>Solution:</dt>
692 <dd>
693 <p>This technique relies on the value of the
694 <code>HTTP_REFERER</code> variable, which is optional. As
695 such, it's possible for some people to circumvent this
696 limitation. However, most users will experience the failed
697 request, which should, over time, result in the image being
698 removed from that other site.</p>
699 <p>There are several ways that you can handle this
700 situation.</p>
702 <p>In this first example, we simply deny the request, if it didn't
703 initiate from a page on our site. For the purpose of this example,
704 we assume that our site is <code>www.example.com</code>.</p>
706 <div class="example"><pre>
707 RewriteCond %{HTTP_REFERER} <strong>!^$</strong>
708 RewriteCond %{HTTP_REFERER} !www.example.com [NC]
709 RewriteRule <strong>\.(gif|jpg|png)$</strong> - [F,NC]
710 </pre></div>
712 <p>In this second example, instead of failing the request, we display
713 an alternate image instead.</p>
715 <div class="example"><pre>
716 RewriteCond %{HTTP_REFERER} <strong>!^$</strong>
717 RewriteCond %{HTTP_REFERER} !www.example.com [NC]
718 RewriteRule <strong>\.(gif|jpg|png)$</strong> /images/go-away.png [R,NC]
719 </pre></div>
721 <p>In the third example, we redirect the request to an image on some
722 third-party site.</p>
724 <div class="example"><pre>
725 RewriteCond %{HTTP_REFERER} <strong>!^$</strong>
726 RewriteCond %{HTTP_REFERER} !www.example.com [NC]
727 RewriteRule <strong>\.(gif|jpg|png)$</strong> http://other.site.com/image.gif [R,NC]
728 </pre></div>
730 <p>Of these techniques, the last two tend to be the most effective
731 in getting people to stop hotlinking your images, because they will
732 simply not see the image that they expected to see.</p>
734 </dd>
735 </dl>
737 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
738 <div class="section">
739 <h2><a name="proxy-deny" id="proxy-deny">Proxy Deny</a></h2>
743 <dl>
744 <dt>Description:</dt>
746 <dd>
747 <p>How can we forbid a certain host or even a user of a
748 special host from using the Apache proxy?</p>
749 </dd>
751 <dt>Solution:</dt>
753 <dd>
754 <p>We first have to make sure <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
755 is below(!) <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code> in the Configuration
756 file when compiling the Apache webserver. This way it gets
757 called <em>before</em> <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>. Then we
758 configure the following for a host-dependent deny...</p>
760 <div class="example"><pre>
761 RewriteCond %{REMOTE_HOST} <strong>^badhost\.mydomain\.com$</strong>
762 RewriteRule !^http://[^/.]\.mydomain.com.* - [F]
763 </pre></div>
765 <p>...and this one for a user@host-dependent deny:</p>
767 <div class="example"><pre>
768 RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} <strong>^badguy@badhost\.mydomain\.com$</strong>
769 RewriteRule !^http://[^/.]\.mydomain.com.* - [F]
770 </pre></div>
771 </dd>
772 </dl>
774 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
775 <div class="section">
776 <h2><a name="external-rewriting" id="external-rewriting">External Rewriting Engine</a></h2>
780 <dl>
781 <dt>Description:</dt>
783 <dd>
784 <p>A FAQ: How can we solve the FOO/BAR/QUUX/etc.
785 problem? There seems no solution by the use of
786 <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>...</p>
787 </dd>
789 <dt>Solution:</dt>
791 <dd>
792 <p>Use an external <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>, i.e. a program which acts
793 like a <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>. It is run once on startup of Apache
794 receives the requested URLs on <code>STDIN</code> and has
795 to put the resulting (usually rewritten) URL on
796 <code>STDOUT</code> (same order!).</p>
798 <div class="example"><pre>
799 RewriteEngine on
800 RewriteMap quux-map <strong>prg:</strong>/path/to/map.quux.pl
801 RewriteRule ^/~quux/(.*)$ /~quux/<strong>${quux-map:$1}</strong>
802 </pre></div>
804 <div class="example"><pre>
805 #!/path/to/perl
807 # disable buffered I/O which would lead
808 # to deadloops for the Apache server
809 $| = 1;
811 # read URLs one per line from stdin and
812 # generate substitution URL on stdout
813 while (&lt;&gt;) {
814 s|^foo/|bar/|;
815 print $_;
817 </pre></div>
819 <p>This is a demonstration-only example and just rewrites
820 all URLs <code>/~quux/foo/...</code> to
821 <code>/~quux/bar/...</code>. Actually you can program
822 whatever you like. But notice that while such maps can be
823 <strong>used</strong> also by an average user, only the
824 system administrator can <strong>define</strong> it.</p>
825 </dd>
826 </dl>
828 </div></div>
829 <div class="bottomlang">
830 <p><span>Available Languages: </span><a href="../en/rewrite/rewrite_guide.html" title="English">&nbsp;en&nbsp;</a></p>
831 </div><div id="footer">
832 <p class="apache">Copyright 2009 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
833 <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="../faq/">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div>
834 </body></html>