remapping.xml revision 6896b3498e144d33f374efe93e6bab2669af535f
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen<?xml version="1.0" encoding="UTF-8" ?>
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen<!DOCTYPE manualpage SYSTEM "/style/manualpage.dtd">
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen<?xml-stylesheet type="text/xsl" href="/style/manual.en.xsl"?>
6896b3498e144d33f374efe93e6bab2669af535fnd<!-- $LastChangedRevision$ -->
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen<!--
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen Licensed to the Apache Software Foundation (ASF) under one or more
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen contributor license agreements. See the NOTICE file distributed with
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen this work for additional information regarding copyright ownership.
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen The ASF licenses this file to You under the Apache License, Version 2.0
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen (the "License"); you may not use this file except in compliance with
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen the License. You may obtain a copy of the License at
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen http://www.apache.org/licenses/LICENSE-2.0
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen Unless required by applicable law or agreed to in writing, software
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen distributed under the License is distributed on an "AS IS" BASIS,
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen See the License for the specific language governing permissions and
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen limitations under the License.
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen-->
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen<manualpage metafile="remapping.xml.meta">
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen <parentdocument href="./">Rewrite</parentdocument>
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen<title>Redirecting and Remapping with mod_rewrite</title>
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen<summary>
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen<p>This document supplements the <module>mod_rewrite</module>
2bb0656f94af82b1ff5e3e77a99b4427c52e4953rbowen<a href="/mod/mod_rewrite.html">reference documentation</a>. It describes
4a1711ab536d965e63d7be80e29f912287fe70b2rbowenhow you can use <module>mod_rewrite</module> to redirect and remap
4a1711ab536d965e63d7be80e29f912287fe70b2rbowenrequest. This includes many examples of common uses of mod_rewrite,
4a1711ab536d965e63d7be80e29f912287fe70b2rbowenincluding detailed descriptions of how each works.</p>
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen<note type="warning">Note that many of these examples won't work unchanged in your
4a1711ab536d965e63d7be80e29f912287fe70b2rbowenparticular server configuration, so it's important that you understand
4a1711ab536d965e63d7be80e29f912287fe70b2rbowenthem, rather than merely cutting and pasting the examples into your
4a1711ab536d965e63d7be80e29f912287fe70b2rbowenconfiguration.</note>
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen</summary>
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen<seealso><a href="/mod/mod_rewrite.html">Module documentation</a></seealso>
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen<seealso><a href="intro.html">mod_rewrite introduction</a></seealso>
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen<!--<seealso><a href="remapping.html">Redirection and remapping</a></seealso>-->
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen<seealso><a href="access.html">Controlling access</a></seealso>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen<seealso><a href="vhosts.html">Virtual hosts</a></seealso>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen<seealso><a href="proxy.html">Proxying</a></seealso>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen<seealso><a href="advanced.html">Advanced techniques and tricks</a></seealso>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen<seealso><a href="avoid.html">When not to use mod_rewrite</a></seealso>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen<section id="old-to-new">
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <title>From Old to New (internal)</title>
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen <dl>
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen <dt>Description:</dt>
8b79a240383bcecf28b75d4803683a7d101d2713rbowen
8b79a240383bcecf28b75d4803683a7d101d2713rbowen <dd>
10705fbc225dcf590c9ba24a4f04de221358060arbowen <p>Assume we have recently renamed the page
10705fbc225dcf590c9ba24a4f04de221358060arbowen <code>foo.html</code> to <code>bar.html</code> and now want
3723c5ef4beec0403b4daa6c64fc0a8f53541018rbowen to provide the old URL for backward compatibility. However,
8b79a240383bcecf28b75d4803683a7d101d2713rbowen we want that users of the old URL even not recognize that
10705fbc225dcf590c9ba24a4f04de221358060arbowen the pages was renamed - that is, we don't want the address to
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen change in their browser.</p>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen </dd>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <dt>Solution:</dt>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <dd>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <p>We rewrite the old URL to the new one internally via the
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen following rule:</p>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen<example><pre>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowenRewriteEngine on
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowenRewriteRule ^<strong>/old</strong>\.html$ <strong>/new</strong>.html [PT]
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen</pre></example>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen </dd>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen </dl>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen</section>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen<section id="old-to-new-extern">
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <title>Rewriting From Old to New (external)</title>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <dl>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <dt>Description:</dt>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <dd>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <p>Assume again that we have recently renamed the page
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <code>foo.html</code> to <code>bar.html</code> and now want
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen to provide the old URL for backward compatibility. But this
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen time we want that the users of the old URL get hinted to
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen the new one, i.e. their browsers Location field should
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen change, too.</p>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen </dd>
365711300b7310a1efed8aa9f01492086882ba7crbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <dt>Solution:</dt>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <dd>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <p>We force a HTTP redirect to the new URL which leads to a
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen change of the browsers and thus the users view:</p>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen<example><pre>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowenRewriteEngine on
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowenRewriteRule ^<strong>/foo</strong>\.html$ <strong>bar</strong>.html [<strong>R</strong>]
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen</pre></example>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen</dd>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen<dt>Discussion</dt>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <dd>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <p>In this example, as contrasted to the <a
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen href="#old-to-new-intern">internal</a> example above, we can simply
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen use the Redirect directive. mod_rewrite was used in that earlier
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen example in order to hide the redirect from the client:</p>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <example>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen Redirect /foo.html /bar.html
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen </example>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen </dd>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen </dl>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen</section>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen<section id="movehomedirs">
817e2217798a69597ab1da450376abac7b239814rbowen
817e2217798a69597ab1da450376abac7b239814rbowen <title>Resource Moved to Another Server</title>
817e2217798a69597ab1da450376abac7b239814rbowen
cd16bb1940b0d07b466ac46b9be3f1bba7ce62ffrbowen <dl>
817e2217798a69597ab1da450376abac7b239814rbowen <dt>Description:</dt>
817e2217798a69597ab1da450376abac7b239814rbowen
817e2217798a69597ab1da450376abac7b239814rbowen <dd>
817e2217798a69597ab1da450376abac7b239814rbowen <p>If a resource has moved to another server, you may wish to have
817e2217798a69597ab1da450376abac7b239814rbowen URLs continue to work for a time on the old server while people
817e2217798a69597ab1da450376abac7b239814rbowen update their bookmarks.</p>
817e2217798a69597ab1da450376abac7b239814rbowen </dd>
817e2217798a69597ab1da450376abac7b239814rbowen
817e2217798a69597ab1da450376abac7b239814rbowen <dt>Solution:</dt>
817e2217798a69597ab1da450376abac7b239814rbowen
817e2217798a69597ab1da450376abac7b239814rbowen <dd>
817e2217798a69597ab1da450376abac7b239814rbowen <p>You can use <module>mod_rewrite</module> to redirect these URLs
817e2217798a69597ab1da450376abac7b239814rbowen to the new server, but you might also consider using the Redirect
817e2217798a69597ab1da450376abac7b239814rbowen or RedirectMatch directive.</p>
817e2217798a69597ab1da450376abac7b239814rbowen
817e2217798a69597ab1da450376abac7b239814rbowen<example><title>With mod_rewrite</title><pre>
817e2217798a69597ab1da450376abac7b239814rbowenRewriteEngine on
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowenRewriteRule ^/docs/(.+) http://new.example.com/docs/$1 [R,L]
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen</pre></example>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
365711300b7310a1efed8aa9f01492086882ba7crbowen<example><title>With RedirectMatch</title><pre>
1570744e45f66e479e87117f23048c44712a31bcrbowenRedirectMatch ^/docs/(.*) http://new.example.com/docs/$1
1570744e45f66e479e87117f23048c44712a31bcrbowen</pre></example>
1570744e45f66e479e87117f23048c44712a31bcrbowen
d8be577d18fda0d6b74a6fe5a5e1c0f0b3bf246clgentis<example><title>With Redirect</title><pre>
1570744e45f66e479e87117f23048c44712a31bcrbowenRedirect /docs/ http://new.example.com/docs/
2852e66e1a44feed2919689711060b8fe720a1fbrbowen</pre></example>
d8be577d18fda0d6b74a6fe5a5e1c0f0b3bf246clgentis </dd>
1570744e45f66e479e87117f23048c44712a31bcrbowen </dl>
1570744e45f66e479e87117f23048c44712a31bcrbowen
1570744e45f66e479e87117f23048c44712a31bcrbowen</section>
1570744e45f66e479e87117f23048c44712a31bcrbowen
1570744e45f66e479e87117f23048c44712a31bcrbowen<section id="static-to-dynamic">
1570744e45f66e479e87117f23048c44712a31bcrbowen
1570744e45f66e479e87117f23048c44712a31bcrbowen <title>From Static to Dynamic</title>
1570744e45f66e479e87117f23048c44712a31bcrbowen
1570744e45f66e479e87117f23048c44712a31bcrbowen <dl>
1570744e45f66e479e87117f23048c44712a31bcrbowen <dt>Description:</dt>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <dd>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen <p>How can we transform a static page
cd16bb1940b0d07b466ac46b9be3f1bba7ce62ffrbowen <code>foo.html</code> into a dynamic variant
cd16bb1940b0d07b466ac46b9be3f1bba7ce62ffrbowen <code>foo.cgi</code> in a seamless way, i.e. without notice
cd16bb1940b0d07b466ac46b9be3f1bba7ce62ffrbowen by the browser/user.</p>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen </dd>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen <dt>Solution:</dt>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen <dd>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen <p>We just rewrite the URL to the CGI-script and force the
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen handler to be <strong>cgi-script</strong> so that it is
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen executed as a CGI program.
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen This way a request to <code>/~quux/foo.html</code>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen internally leads to the invocation of
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen <code>/~quux/foo.cgi</code>.</p>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen<example><pre>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowenRewriteEngine on
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowenRewriteBase /~quux/
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowenRewriteRule ^foo\.<strong>html</strong>$ foo.<strong>cgi</strong> [H=<strong>cgi-script</strong>]
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen</pre></example>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen </dd>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen </dl>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen</section>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen<section id="backward-compatibility">
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen <title>Backward Compatibility for file extension change</title>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen <dl>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen <dt>Description:</dt>
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen
7ed90ff2ffacbd64549ed58890e0e44dbd2b2a49rbowen <dd>
cd16bb1940b0d07b466ac46b9be3f1bba7ce62ffrbowen <p>How can we make URLs backward compatible (still
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen existing virtually) after migrating <code>document.YYYY</code>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen to <code>document.XXXX</code>, e.g. after translating a
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen bunch of <code>.html</code> files to <code>.php</code>?</p>
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen </dd>
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowen
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowen <dt>Solution:</dt>
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowen
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowen <dd>
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowen <p>We rewrite the name to its basename and test for
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowen existence of the new extension. If it exists, we take
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowen that name, else we rewrite the URL to its original state.</p>
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowen
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowen<example><pre>
c7f365f090f1a2ddb14059d75e223ecfc4ae0eb4rbowen# backward compatibility ruleset for
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowen# rewriting document.html to document.php
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowen# when and only when document.php exists
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowen&lt;Directory /var/www/htdocs&gt;
454f7910368c351cca3f92ec75935df177f333a5rbowenRewriteEngine on
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowenRewriteBase /var/www/htdocs
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowen
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowenRewriteCond $1.php -f
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowenRewriteCond $1.html !-f
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowenRewriteRule ^(.*).html$ $1.php
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowen&lt;/Directory&gt;
da15e975ccc42c6c1f1d9a9b30d47fa1bd0b6a48rbowen</pre></example>
ee55237b797cb7b343048d38ffd77a7ac4da3f9erbowen </dd>
ee55237b797cb7b343048d38ffd77a7ac4da3f9erbowen
ee55237b797cb7b343048d38ffd77a7ac4da3f9erbowen <dt>Discussion</dt>
ee55237b797cb7b343048d38ffd77a7ac4da3f9erbowen <dd>
5bfbe6eab78fa063a7de24cea3262293fcd5499erbowen <p>This example uses an often-overlooked feature of mod_rewrite,
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen by taking advantage of the order of execution of the ruleset. In
4a1711ab536d965e63d7be80e29f912287fe70b2rbowen particular, mod_rewrite evaluates the left-hand-side of the
9e4fd920b1e57cb1a7113cde0959b9ff1689d1dfrbowen RewriteRule before it evaluates the RewriteCond directives.
Consequently, $1 is already defined by the time the RewriteCond
directives are evaluated. This allows us to test for the existence
of the original (<code>document.html</code>) and target
(<code>document.php</code>) files using the same base filename.</p>
<p>This ruleset is designed to use in a per-directory context (In a
&lt;Directory&gt; block or in a .htaccess file), so that the
<code>-f</code> checks are looking at the correct directory path.
You may need to set a <directive
module="mod_rewite">RewriteBase</directive> directive to specify the
directory base that you're working in.</p>
</dd>
</dl>
</section>
<section id="canonicalhost">
<title>Canonical Hostnames</title>
<dl>
<dt>Description:</dt>
<dd>The goal of this rule is to force the use of a particular
hostname, in preference to other hostnames which may be used to
reach the same site. For example, if you wish to force the use
of <strong>www.example.com</strong> instead of
<strong>example.com</strong>, you might use a variant of the
following recipe.</dd>
<dt>Solution:</dt>
<dd>
<p>For sites running on a port other than 80:</p>
<example><pre>
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{SERVER_PORT} !^80$
RewriteRule ^/?(.*) http://www.example.com:%{SERVER_PORT}/$1 [L,R,NE]
</pre></example>
<p>And for a site running on port 80</p>
<example><pre>
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/?(.*) http://www.example.com/$1 [L,R,NE]
</pre></example>
<p>
If you wanted to do this generically for all domain names - that
is, if you want to redirect <strong>example.com</strong> to
<strong>www.example.com</strong> for all possible values of
<strong>example.com</strong>, you could use the following
recipe:</p>
<example><pre>
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/?(.*) http://www.%{HTTP_HOST}/$1 [L,R,NE]
</pre></example>
<p>These rulesets will work either in your main server configuration
file, or in a <code>.htaccess</code> file placed in the <directive
module="core">DocumentRoot</directive> of the server.</p>
</dd>
</dl>
</section>
<section id="multipledirs">
<title>Search for pages in more than one directory</title>
<dl>
<dt>Description:</dt>
<dd>
<p>A particular resource might exist in one of several places, and
we want to look in those places for the resource when it is
requested. Perhaps we've recently rearranged our directory
structure, dividing content into several locations.</p>
</dd>
<dt>Solution:</dt>
<dd>
<p>The following ruleset searches in two directories to find the
resource, and, if not finding it in either place, will attempt to
just serve it out of the location requested.</p>
<example><pre>
RewriteEngine on
# first try to find it in dir1/...
# ...and if found stop and be happy:
RewriteCond %{DOCUMENT_ROOT}/<strong>dir1</strong>/%{REQUEST_URI} -f
RewriteRule ^(.+) %{DOCUMENT_ROOT}/<strong>dir1</strong>/$1 [L]
# second try to find it in dir2/...
# ...and if found stop and be happy:
RewriteCond %{DOCUMENT_ROOT}/<strong>dir2</strong>/%{REQUEST_URI} -f
RewriteRule ^(.+) %{DOCUMENT_ROOT}/<strong>dir2</strong>/$1 [L]
# else go on for other Alias or ScriptAlias directives,
# etc.
RewriteRule ^(.+) - [PT]
</pre></example>
</dd>
</dl>
</section>
<section id="archive-access-multiplexer">
<title>Redirecting to Geographically Distributed Servers</title>
<dl>
<dt>Description:</dt>
<dd>
<p>We have numerous mirrors of our website, and want to redirect
people to the one that is located in the country where they are
located.</p>
</dd>
<dt>Solution:</dt>
<dd>
<p>Looking at the hostname of the requesting client, we determine
which country they are coming from. If we can't do a lookup on their
IP address, we fall back to a default server.</p>
<p>We'll use a <directive module="mod_rewrite">RewriteMap</directive>
directive to build a list of servers that we wish to use.</p>
<example><pre>
HostnameLookups on
RewriteEngine on
RewriteMap multiplex txt:/path/to/map.mirrors
RewriteCond %{REMOTE_HOST} ([a-z]+)$ [NC]
RewriteRule ^/(.*)$ ${multiplex:<strong>%1</strong>|http://www.example.com/}$1 [R,L]
</pre></example>
<example><pre>
## map.mirrors -- Multiplexing Map
de http://www.example.de/
uk http://www.example.uk/
com http://www.example.com/
##EOF##
</pre></example>
</dd>
<dt>Discussion</dt>
<dd>
<note type="warning">This ruleset relies on
<directive module="core">HostNameLookups</directive>
being set <code>on</code>, which can be
a significant performance hit.</note>
<p>The <directive module="mod_rewrite">RewriteCond</directive>
directive captures the last portion of the hostname of the
requesting client - the country code - and the following RewriteRule
uses that value to look up the appropriate mirror host in the map
file.</p>
</dd>
</dl>
</section>
<section id="browser-dependent-content">
<title>Browser Dependent Content</title>
<dl>
<dt>Description:</dt>
<dd>
<p>We wish to provide different content based on the browser, or
user-agent, which is requesting the content.</p>
</dd>
<dt>Solution:</dt>
<dd>
<p>We have to decide, based on the HTTP header "User-Agent",
which content to serve. The following config
does the following: If the HTTP header "User-Agent"
contains "Mozilla/3", the page <code>foo.html</code>
is rewritten to <code>foo.NS.html</code> and the
rewriting stops. If the browser is "Lynx" or "Mozilla" of
version 1 or 2, the URL becomes <code>foo.20.html</code>.
All other browsers receive page <code>foo.32.html</code>.
This is done with the following ruleset:</p>
<example><pre>
RewriteCond %{HTTP_USER_AGENT} ^<strong>Mozilla/3</strong>.*
RewriteRule ^foo\.html$ foo.<strong>NS</strong>.html [<strong>L</strong>]
RewriteCond %{HTTP_USER_AGENT} ^<strong>Lynx/</strong>.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^<strong>Mozilla/[12]</strong>.*
RewriteRule ^foo\.html$ foo.<strong>20</strong>.html [<strong>L</strong>]
RewriteRule ^foo\.html$ foo.<strong>32</strong>.html [<strong>L</strong>]
</pre></example>
</dd>
</dl>
</section>
<section id="canonicalurl">
<title>Canonical URLs</title>
<dl>
<dt>Description:</dt>
<dd>
<p>On some webservers there is more than one URL for a
resource. Usually there are canonical URLs (which are be
actually used and distributed) and those which are just
shortcuts, internal ones, and so on. Independent of which URL the
user supplied with the request, they should finally see the
canonical one in their browser address bar.</p>
</dd>
<dt>Solution:</dt>
<dd>
<p>We do an external HTTP redirect for all non-canonical
URLs to fix them in the location view of the Browser and
for all subsequent requests. In the example ruleset below
we replace <code>/puppies</code> and <code>/canines</code>
by the canonical <code>/dogs</code>.</p>
<example><pre>
RewriteRule ^/(puppies|canines)/(.*) /dogs/$2 [R]
</pre></example>
</dd>
<dt>Discussion:</dt>
<dd>
This should really be accomplished with Redirect or RedirectMatch
directives:
<example><pre>
RedirectMatch ^/(puppies|canines)/(.*) /dogs/$2
</pre></example>
</dd>
</dl>
</section>
<section id="moveddocroot">
<title>Moved <code>DocumentRoot</code></title>
<dl>
<dt>Description:</dt>
<dd>
<p>Usually the <directive module="core">DocumentRoot</directive>
of the webserver directly relates to the URL "<code>/</code>".
But often this data is not really of top-level priority. For example,
you may wish for visitors, on first entering a site, to go to a
particular subdirectory <code>/about/</code>. This may be accomplished
using the following ruleset:</p>
</dd>
<dt>Solution:</dt>
<dd>
<p>We redirect the URL <code>/</code> to
<code>/about/</code>:
</p>
<example><pre>
RewriteEngine on
RewriteRule <strong>^/$</strong> /about/ [<strong>R</strong>]
</pre></example>
<p>Note that this can also be handled using the <directive
module="mod_alias">RedirectMatch</directive> directive:</p>
<example>
RedirectMatch ^/$ http://example.com/about/
</example>
<p>Note also that the example rewrites only the root URL. That is, it
rewrites a request for <code>http://example.com/</code>, but not a
request for <code>http://example.com/page.html</code>. If you have in
fact changed your document root - that is, if <strong>all</strong> of
your content is in fact in that subdirectory, it is greatly preferable
to simply change your <directive module="core">DocumentRoot</directive>
directive, or move all of the content up one directory,
rather than rewriting URLs.</p>
</dd>
</dl>
</section>
<section id="fallback-resource">
<title>Fallback Resource</title>
<dl>
<dt>Description:</dt>
<dd>You want a single resource (say, a certain file, like index.php) to
handle all requests that come to a particular directory, except those
that should go to an existing resource such as an image, or a css file.</dd>
<dt>Solution:</dt>
<dd>
<p>As of version 2.4, you should use the <directive
module="mod_dir">FallbackResource</directive> directive for this:</p>
<example>
<pre>
&lt;Directory /var/www/my_blog&gt;
FallbackResource index.php
&lt;/Directory&gt;
</pre>
</example>
<p>However, in earlier versions of Apache, or if your needs are more
complicated than this, you can use a variation of the following rewrite
set to accomplish the same thing:</p>
<example>
<pre>
&lt;Directory /var/www/my_blog&gt;
RewriteBase /my_blog
RewriteCond /var/www/my_blog/%{REQUEST_FILENAME} !-f
RewriteCond /var/www/my_blog/%{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [PT]
&lt;/Directory&gt;
</pre>
</example>
<p>If, on the other hand, you wish to pass the requested URI as a query
string argument to index.php, you can replace that RewriteRule with:</p>
<example>
<pre>
RewriteRule (.*) index.php?$1 [PT,QSA]
</pre>
</example>
<p>Note that these rulesets can be uses in a <code>.htaccess</code>
file, as well as in a &lt;Directory&gt; block.</p>
</dd>
</dl>
</section>
</manualpage>