advanced.html.en revision 5d01f40ffd657dd2ac567aacd93cabd162ddfa79
b630661b71a5495a95831a05a6a2299fb1c7c771rbowen<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
b630661b71a5495a95831a05a6a2299fb1c7c771rbowen<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head><!--
b630661b71a5495a95831a05a6a2299fb1c7c771rbowen XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
b630661b71a5495a95831a05a6a2299fb1c7c771rbowen This file is generated from xml source: DO NOT EDIT
b630661b71a5495a95831a05a6a2299fb1c7c771rbowen XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
96ad5d81ee4a2cc66a4ae19893efc8aa6d06fae7jailletc<title>Advanced Techniques with mod_rewrite - Apache HTTP Server Version 2.5</title>
b630661b71a5495a95831a05a6a2299fb1c7c771rbowen<link href="/style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
b630661b71a5495a95831a05a6a2299fb1c7c771rbowen<link href="/style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen<link href="/style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="/style/css/prettify.css" />
2e545ce2450a9953665f701bb05350f0d3f26275nd<script src="/style/scripts/prettify.min.js" type="text/javascript">
b630661b71a5495a95831a05a6a2299fb1c7c771rbowen<link href="/images/favicon.ico" rel="shortcut icon" /></head>
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen<p class="menu"><a href="/mod/">Modules</a> | <a href="/mod/quickreference.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="/glossary.html">Glossary</a> | <a href="/sitemap.html">Sitemap</a></p>
b630661b71a5495a95831a05a6a2299fb1c7c771rbowen<div class="up"><a href="./"><img title="<-" alt="<-" src="/images/left.gif" /></a></div>
3f08db06526d6901aa08c110b5bc7dde6bc39905nd<a href="http://www.apache.org/">Apache</a> > <a href="http://httpd.apache.org/">HTTP Server</a> > <a href="http://httpd.apache.org/docs/">Documentation</a> > <a href="../">Version 2.5</a> > <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Advanced Techniques with mod_rewrite</h1>
b6e6d2139d50d64fc4bbd01c4f07d7a4accfec8cnd<p><span>Available Languages: </span><a href="/en/rewrite/advanced.html" title="English"> en </a></p>
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf<p>This document supplements the <code class="module"><a href="/mod/mod_rewrite.html">mod_rewrite</a></code>
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf<a href="/mod/mod_rewrite.html">reference documentation</a>. It provides
53abc235688d883cfa15cdfec354ba03128f357arbowena few advanced techniques using mod_rewrite.</p>
b630661b71a5495a95831a05a6a2299fb1c7c771rbowen<div class="warning">Note that many of these examples won't work unchanged in your
b630661b71a5495a95831a05a6a2299fb1c7c771rbowenparticular server configuration, so it's important that you understand
b630661b71a5495a95831a05a6a2299fb1c7c771rbowenthem, rather than merely cutting and pasting the examples into your
b630661b71a5495a95831a05a6a2299fb1c7c771rbowenconfiguration.</div>
3a8132a49d08458e2d9daa0af3fc0a36eaa8130erbowen<div id="quickview"><ul id="toc"><li><img alt="" src="/images/down.gif" /> <a href="#sharding">URL-based sharding across multiple backends</a></li>
b0306ceedec510a7b4ebe3a1b70c366bf5f2727crbowen<li><img alt="" src="/images/down.gif" /> <a href="#on-the-fly-content">On-the-fly Content-Regeneration</a></li>
ed84b2ae96180924248fbbc86b68d86ae8d88cb3rbowen<li><img alt="" src="/images/down.gif" /> <a href="#load-balancing">Load Balancing</a></li>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen<li><img alt="" src="/images/down.gif" /> <a href="#structuredhomedirs">Structured Userdirs</a></li>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen<li><img alt="" src="/images/down.gif" /> <a href="#redirectanchors">Redirecting Anchors</a></li>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen<li><img alt="" src="/images/down.gif" /> <a href="#time-dependent">Time-Dependent Rewriting</a></li>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen<li><img alt="" src="/images/down.gif" /> <a href="#setenvvars">Set Environment Variables Based On URL Parts</a></li>
3cfb051391f3d6aa28a25ca3feb81e841242f9d5humbedooh</ul><h3>See also</h3><ul class="seealso"><li><a href="/mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="access.html">Controlling access</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="proxy.html">Proxying</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li></ul><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
1525d3506d73644ae695624f16b15cc73cc1c7acrbowen<div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
3a8132a49d08458e2d9daa0af3fc0a36eaa8130erbowen<h2><a name="sharding" id="sharding">URL-based sharding across multiple backends</a></h2>
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf <p>A common technique for distributing the burden of
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf server load or storage space is called "sharding".
1525d3506d73644ae695624f16b15cc73cc1c7acrbowen When using this method, a front-end server will use the
1525d3506d73644ae695624f16b15cc73cc1c7acrbowen url to consistently "shard" users or objects to separate
1525d3506d73644ae695624f16b15cc73cc1c7acrbowen backend servers.</p>
1525d3506d73644ae695624f16b15cc73cc1c7acrbowen <p>A mapping is maintained, from users to target servers, in
1525d3506d73644ae695624f16b15cc73cc1c7acrbowen external map files. They look like:</p>
353e838f5716b394f2f9bf38549e1550a5e73570rbowenuser1 physical_host_of_user1<br />
353e838f5716b394f2f9bf38549e1550a5e73570rbowenuser2 physical_host_of_user2<br />
1525d3506d73644ae695624f16b15cc73cc1c7acrbowen <p>We put this into a <code>map.users-to-hosts</code> file. The
1525d3506d73644ae695624f16b15cc73cc1c7acrbowen aim is to map;</p>
1525d3506d73644ae695624f16b15cc73cc1c7acrbowen <p>thus every URL path need not be valid on every backend physical
1525d3506d73644ae695624f16b15cc73cc1c7acrbowen host. The following ruleset does this for us with the help of the map
1525d3506d73644ae695624f16b15cc73cc1c7acrbowen files assuming that server0 is a default server which will be used if
c2a88a7ef740c408aba42af38ddfb9ab8a7398d9nd a user has no entry in the map:</p>
5d01f40ffd657dd2ac567aacd93cabd162ddfa79coarRewriteMap users-to-hosts "txt:/path/to/map.users-to-hosts"
5d01f40ffd657dd2ac567aacd93cabd162ddfa79coarRewriteRule "^/u/([^/]+)/?(.*)" "http://${users-to-hosts:$1|server0}/u/$1/$2"</pre>
53abc235688d883cfa15cdfec354ba03128f357arbowen <p>See the <code class="directive"><a href="/mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>
53abc235688d883cfa15cdfec354ba03128f357arbowen documentation for more discussion of the syntax of this directive.</p>
b0306ceedec510a7b4ebe3a1b70c366bf5f2727crbowen</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
b0306ceedec510a7b4ebe3a1b70c366bf5f2727crbowen<h2><a name="on-the-fly-content" id="on-the-fly-content">On-the-fly Content-Regeneration</a></h2>
b0306ceedec510a7b4ebe3a1b70c366bf5f2727crbowen <p>We wish to dynamically generate content, but store it
b0306ceedec510a7b4ebe3a1b70c366bf5f2727crbowen statically once it is generated. This rule will check for the
b0306ceedec510a7b4ebe3a1b70c366bf5f2727crbowen existence of the static file, and if it's not there, generate
b0306ceedec510a7b4ebe3a1b70c366bf5f2727crbowen it. The static files can be removed periodically, if desired (say,
b0306ceedec510a7b4ebe3a1b70c366bf5f2727crbowen via cron) and will be regenerated on demand.</p>
b0306ceedec510a7b4ebe3a1b70c366bf5f2727crbowen This is done via the following ruleset:
4aa603e6448b99f9371397d439795c91a93637eand<pre class="prettyprint lang-config"># This example is valid in per-directory context only
5d01f40ffd657dd2ac567aacd93cabd162ddfa79coarRewriteCond "%{REQUEST_URI}" !-U
5d01f40ffd657dd2ac567aacd93cabd162ddfa79coarRewriteRule "^(.+)\.html$" "/regenerate_page.cgi" [PT,L]</pre>
53abc235688d883cfa15cdfec354ba03128f357arbowen <p>The <code>-U</code> operator determines whether the test string
53abc235688d883cfa15cdfec354ba03128f357arbowen (in this case, <code>REQUEST_URI</code>) is a valid URL. It does
53abc235688d883cfa15cdfec354ba03128f357arbowen this via a subrequest. In the event that this subrequest fails -
53abc235688d883cfa15cdfec354ba03128f357arbowen that is, the requested resource doesn't exist - this rule invokes
53abc235688d883cfa15cdfec354ba03128f357arbowen the CGI program <code>/regenerate_page.cgi</code>, which generates
53abc235688d883cfa15cdfec354ba03128f357arbowen the requested resource and saves it into the document directory, so
53abc235688d883cfa15cdfec354ba03128f357arbowen that the next time it is requested, a static copy can be served.</p>
53abc235688d883cfa15cdfec354ba03128f357arbowen <p>In this way, documents that are infrequently updated can be served in
53abc235688d883cfa15cdfec354ba03128f357arbowen static form. if documents need to be refreshed, they can be deleted
53abc235688d883cfa15cdfec354ba03128f357arbowen from the document directory, and they will then be regenerated the
53abc235688d883cfa15cdfec354ba03128f357arbowen next time they are requested.</p>
ed84b2ae96180924248fbbc86b68d86ae8d88cb3rbowen</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
ed84b2ae96180924248fbbc86b68d86ae8d88cb3rbowen<h2><a name="load-balancing" id="load-balancing">Load Balancing</a></h2>
ed84b2ae96180924248fbbc86b68d86ae8d88cb3rbowen <p>We wish to randomly distribute load across several servers
ed84b2ae96180924248fbbc86b68d86ae8d88cb3rbowen using mod_rewrite.</p>
ed84b2ae96180924248fbbc86b68d86ae8d88cb3rbowen <p>We'll use <code class="directive"><a href="/mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> and a list of servers
ed84b2ae96180924248fbbc86b68d86ae8d88cb3rbowen to accomplish this.</p>
5d01f40ffd657dd2ac567aacd93cabd162ddfa79coarRewriteRule "^/(.*)" "http://${lb:servers}/$1" [P,L]</pre>
ed84b2ae96180924248fbbc86b68d86ae8d88cb3rbowen<p><code>serverlist.txt</code> will contain a list of the servers:</p>
353e838f5716b394f2f9bf38549e1550a5e73570rbowenservers one.example.com|two.example.com|three.example.com<br />
ed84b2ae96180924248fbbc86b68d86ae8d88cb3rbowen<p>If you want one particular server to get more of the load than the
ed84b2ae96180924248fbbc86b68d86ae8d88cb3rbowenothers, add it more times to the list.</p>
ed84b2ae96180924248fbbc86b68d86ae8d88cb3rbowen<p>Apache comes with a load-balancing module -
ed84b2ae96180924248fbbc86b68d86ae8d88cb3rbowen<code class="module"><a href="/mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code> - which is far more flexible and
ed84b2ae96180924248fbbc86b68d86ae8d88cb3rbowenfeatureful than anything you can cobble together using mod_rewrite.</p>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen<h2><a name="structuredhomedirs" id="structuredhomedirs">Structured Userdirs</a></h2>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen <p>Some sites with thousands of users use a
43289eb78809cbdec92c7d90433a8852233f0b2brbowen structured homedir layout, <em>i.e.</em> each homedir is in a
43289eb78809cbdec92c7d90433a8852233f0b2brbowen subdirectory which begins (for instance) with the first
43289eb78809cbdec92c7d90433a8852233f0b2brbowen character of the username. So, <code>/~larry/anypath</code>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen is <code>/home/<strong>l</strong>/larry/public_html/anypath</code>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen <code>/home/<strong>w</strong>/waldo/public_html/anypath</code>.</p>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen <p>We use the following ruleset to expand the tilde URLs
43289eb78809cbdec92c7d90433a8852233f0b2brbowen into the above layout.</p>
5d01f40ffd657dd2ac567aacd93cabd162ddfa79coarRewriteRule "^/~(<strong>([a-z])</strong>[a-z0-9]+)(.*)" "/home/<strong>$2</strong>/$1/public_html$3"</pre>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen<h2><a name="redirectanchors" id="redirectanchors">Redirecting Anchors</a></h2>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen <p>By default, redirecting to an HTML anchor doesn't work,
43289eb78809cbdec92c7d90433a8852233f0b2brbowen because mod_rewrite escapes the <code>#</code> character,
43289eb78809cbdec92c7d90433a8852233f0b2brbowen turning it into <code>%23</code>. This, in turn, breaks the
43289eb78809cbdec92c7d90433a8852233f0b2brbowen redirection.</p>
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf <dd>This technique will of course also work with other
43289eb78809cbdec92c7d90433a8852233f0b2brbowen special characters that mod_rewrite, by default, URL-encodes.</dd>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen<h2><a name="time-dependent" id="time-dependent">Time-Dependent Rewriting</a></h2>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen <p>We wish to use mod_rewrite to serve different content based on
43289eb78809cbdec92c7d90433a8852233f0b2brbowen the time of day.</p>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen <p>There are a lot of variables named <code>TIME_xxx</code>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen for rewrite conditions. In conjunction with the special
43289eb78809cbdec92c7d90433a8852233f0b2brbowen lexicographic comparison patterns <code><STRING</code>,
43289eb78809cbdec92c7d90433a8852233f0b2brbowen <code>>STRING</code> and <code>=STRING</code> we can
43289eb78809cbdec92c7d90433a8852233f0b2brbowen do time-dependent redirects:</p>
5d01f40ffd657dd2ac567aacd93cabd162ddfa79coarRewriteCond "%{TIME_HOUR}%{TIME_MIN}" >0700
5d01f40ffd657dd2ac567aacd93cabd162ddfa79coarRewriteCond "%{TIME_HOUR}%{TIME_MIN}" <1900
5d01f40ffd657dd2ac567aacd93cabd162ddfa79coarRewriteRule "^foo\.html$" "foo.day.html" [L]
43289eb78809cbdec92c7d90433a8852233f0b2brbowen <p>This provides the content of <code>foo.day.html</code>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen <code>07:01-18:59</code> and at the remaining time the
43289eb78809cbdec92c7d90433a8852233f0b2brbowen <div class="warning"><code class="module"><a href="/mod/mod_cache.html">mod_cache</a></code>, intermediate proxies
43289eb78809cbdec92c7d90433a8852233f0b2brbowen and browsers may each cache responses and cause the either page to be
43289eb78809cbdec92c7d90433a8852233f0b2brbowen shown outside of the time-window configured.
43289eb78809cbdec92c7d90433a8852233f0b2brbowen <code class="module"><a href="/mod/mod_expires.html">mod_expires</a></code> may be used to control this
43289eb78809cbdec92c7d90433a8852233f0b2brbowen effect. You are, of course, much better off simply serving the
43289eb78809cbdec92c7d90433a8852233f0b2brbowen content dynamically, and customizing it based on the time of day.</div>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen<h2><a name="setenvvars" id="setenvvars">Set Environment Variables Based On URL Parts</a></h2>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen <p>At time, we want to maintain some kind of status when we
43289eb78809cbdec92c7d90433a8852233f0b2brbowen perform a rewrite. For example, you want to make a note that
43289eb78809cbdec92c7d90433a8852233f0b2brbowen you've done that rewrite, so that you can check later to see if a
43289eb78809cbdec92c7d90433a8852233f0b2brbowen request can via that rewrite. One way to do this is by setting an
43289eb78809cbdec92c7d90433a8852233f0b2brbowen environment variable.</p>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen <p>Use the [E] flag to set an environment variable.</p>
5d01f40ffd657dd2ac567aacd93cabd162ddfa79coarRewriteRule "^/horse/(.*)" "/pony/$1" [E=<strong>rewritten:1</strong>]</pre>
43289eb78809cbdec92c7d90433a8852233f0b2brbowen <p>Later in your ruleset you might check for this environment
43289eb78809cbdec92c7d90433a8852233f0b2brbowen variable using a RewriteCond:</p>
5d01f40ffd657dd2ac567aacd93cabd162ddfa79coar<pre class="prettyprint lang-config">RewriteCond "%{ENV:rewritten}" =1</pre>
53abc235688d883cfa15cdfec354ba03128f357arbowen <p>Note that environment variables do not survive an external
53abc235688d883cfa15cdfec354ba03128f357arbowen redirect. You might consider using the [CO] flag to set a
53abc235688d883cfa15cdfec354ba03128f357arbowen cookie.</p>
b6e6d2139d50d64fc4bbd01c4f07d7a4accfec8cnd<p><span>Available Languages: </span><a href="/en/rewrite/advanced.html" title="English"> en </a></p>
ed62c84ee0911cfebbd8da319ac00757b555707chumbedooh</div><div class="top"><a href="#page-header"><img src="/images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed again by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Freenode, or sent to our <a href="http://httpd.apache.org/lists.html">mailing lists</a>.</div>
ed62c84ee0911cfebbd8da319ac00757b555707chumbedoohvar comments_shortname = 'httpd';
b6e6d2139d50d64fc4bbd01c4f07d7a4accfec8cndvar comments_identifier = 'http://httpd.apache.org/docs/trunk/rewrite/advanced.html';
0d0ba3a410038e179b695446bb149cce6264e0abnd(function(w, d) {
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
ed62c84ee0911cfebbd8da319ac00757b555707chumbedooh d.write('<div id="comments_thread"><\/div>');
0d0ba3a410038e179b695446bb149cce6264e0abnd var s = d.createElement('script');
ac082aefa89416cbdc9a1836eaf3bed9698201c8humbedooh s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
0d0ba3a410038e179b695446bb149cce6264e0abnd (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
ed62c84ee0911cfebbd8da319ac00757b555707chumbedooh d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
0d0ba3a410038e179b695446bb149cce6264e0abnd})(window, document);
205f749042ed530040a4f0080dbcb47ceae8a374rjung<p class="apache">Copyright 2015 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>
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen<p class="menu"><a href="/mod/">Modules</a> | <a href="/mod/quickreference.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="/glossary.html">Glossary</a> | <a href="/sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
0d0ba3a410038e179b695446bb149cce6264e0abndif (typeof(prettyPrint) !== 'undefined') {
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd prettyPrint();