advanced.xml revision 5d01f40ffd657dd2ac567aacd93cabd162ddfa79
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<?xml version="1.0" encoding="UTF-8" ?>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<!DOCTYPE manualpage SYSTEM "/style/manualpage.dtd">
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<?xml-stylesheet type="text/xsl" href="/style/manual.en.xsl"?>
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner<!-- $LastChangedRevision$ -->
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<!--
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Licensed to the Apache Software Foundation (ASF) under one or more
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin contributor license agreements. See the NOTICE file distributed with
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin this work for additional information regarding copyright ownership.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin The ASF licenses this file to You under the Apache License, Version 2.0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (the "License"); you may not use this file except in compliance with
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin the License. You may obtain a copy of the License at
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin http://www.apache.org/licenses/LICENSE-2.0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Unless required by applicable law or agreed to in writing, software
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin distributed under the License is distributed on an "AS IS" BASIS,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin See the License for the specific language governing permissions and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin limitations under the License.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin-->
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<manualpage metafile="advanced.xml.meta">
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <parentdocument href="./">Rewrite</parentdocument>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<title>Advanced Techniques with mod_rewrite</title>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<summary>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<p>This document supplements the <module>mod_rewrite</module>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<a href="/mod/mod_rewrite.html">reference documentation</a>. It provides
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968china few advanced techniques using mod_rewrite.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<!--
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinI question whether anything remailing in this document qualifies as
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"advanced". It's probably time to take inventory of the examples that we
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinhave in the various docs, and consider a reorg of the stuff in this
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindirectory. Again.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin-->
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<note type="warning">Note that many of these examples won't work unchanged in your
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinparticular server configuration, so it's important that you understand
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthem, rather than merely cutting and pasting the examples into your
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinconfiguration.</note>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</summary>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<seealso><a href="/mod/mod_rewrite.html">Module documentation</a></seealso>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<seealso><a href="intro.html">mod_rewrite introduction</a></seealso>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<seealso><a href="remapping.html">Redirection and remapping</a></seealso>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<seealso><a href="access.html">Controlling access</a></seealso>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<seealso><a href="vhosts.html">Virtual hosts</a></seealso>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<seealso><a href="proxy.html">Proxying</a></seealso>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<seealso><a href="rewritemap.html">Using RewriteMap</a></seealso>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<!--<seealso><a href="advanced.html">Advanced techniques</a></seealso>-->
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<seealso><a href="avoid.html">When not to use mod_rewrite</a></seealso>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<section id="sharding">
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <title>URL-based sharding across multiple backends</title>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dl>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dt>Description:</dt>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>A common technique for distributing the burden of
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin server load or storage space is called "sharding".
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin When using this method, a front-end server will use the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin url to consistently "shard" users or objects to separate
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin backend servers.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dt>Solution:</dt>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>A mapping is maintained, from users to target servers, in
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin external map files. They look like:</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<example>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinuser1 physical_host_of_user1<br />
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinuser2 physical_host_of_user2<br />
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin: :
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</example>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>We put this into a <code>map.users-to-hosts</code> file. The
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin aim is to map;</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<example>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/u/user1/anypath
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</example>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>to</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<example>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinhttp://physical_host_of_user1/u/user/anypath
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</example>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>thus every URL path need not be valid on every backend physical
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin host. The following ruleset does this for us with the help of the map
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin files assuming that server0 is a default server which will be used if
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a user has no entry in the map:</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<highlight language="config">
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinRewriteEngine on
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinRewriteMap users-to-hosts "txt:/path/to/map.users-to-hosts"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinRewriteRule "^/u/([^/]+)/?(.*)" "http://${users-to-hosts:$1|server0}/u/$1/$2"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</highlight>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dl>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>See the <directive module="mod_rewrite">RewriteMap</directive>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin documentation for more discussion of the syntax of this directive.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</section>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<section id="on-the-fly-content">
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <title>On-the-fly Content-Regeneration</title>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz <dl>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dt>Description:</dt>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>We wish to dynamically generate content, but store it
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin statically once it is generated. This rule will check for the
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz existence of the static file, and if it's not there, generate
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin it. The static files can be removed periodically, if desired (say,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin via cron) and will be regenerated on demand.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dt>Solution:</dt>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin This is done via the following ruleset:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<highlight language="config">
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# This example is valid in per-directory context only
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinRewriteCond "%{REQUEST_URI}" !-U
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinRewriteRule "^(.+)\.html$" "/regenerate_page.cgi" [PT,L]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</highlight>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>The <code>-U</code> operator determines whether the test string
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (in this case, <code>REQUEST_URI</code>) is a valid URL. It does
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin this via a subrequest. In the event that this subrequest fails -
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin that is, the requested resource doesn't exist - this rule invokes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin the CGI program <code>/regenerate_page.cgi</code>, which generates
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin the requested resource and saves it into the document directory, so
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin that the next time it is requested, a static copy can be served.</p>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>In this way, documents that are infrequently updated can be served in
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static form. if documents need to be refreshed, they can be deleted
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin from the document directory, and they will then be regenerated the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next time they are requested.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dl>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</section>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<section id="load-balancing">
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <title>Load Balancing</title>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dl>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dt>Description:</dt>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>We wish to randomly distribute load across several servers
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin using mod_rewrite.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dt>Solution:</dt>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>We'll use <directive
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin module="mod_rewrite">RewriteMap</directive> and a list of servers
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin to accomplish this.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<highlight language="config">
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinRewriteEngine on
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinRewriteMap lb "rnd:/path/to/serverlist.txt"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinRewriteRule "^/(.*)" "http://${lb:servers}/$1" [P,L]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</highlight>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<p><code>serverlist.txt</code> will contain a list of the servers:</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz<example>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin## serverlist.txt<br />
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<br />
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinservers one.example.com|two.example.com|three.example.com<br />
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</example>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin<p>If you want one particular server to get more of the load than the
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinothers, add it more times to the list.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin </dd>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dt>Discussion</dt>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<p>Apache comes with a load-balancing module -
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<module>mod_proxy_balancer</module> - which is far more flexible and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfeatureful than anything you can cobble together using mod_rewrite.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dl>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</section>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin<section id="structuredhomedirs">
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <title>Structured Userdirs</title>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dl>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dt>Description:</dt>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>Some sites with thousands of users use a
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin structured homedir layout, <em>i.e.</em> each homedir is in a
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin subdirectory which begins (for instance) with the first
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin character of the username. So, <code>/~larry/anypath</code>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin is <code>/home/<strong>l</strong>/larry/public_html/anypath</code>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while <code>/~waldo/anypath</code> is
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <code>/home/<strong>w</strong>/waldo/public_html/anypath</code>.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dt>Solution:</dt>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin <dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>We use the following ruleset to expand the tilde URLs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin into the above layout.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<highlight language="config">
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinRewriteEngine on
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinRewriteRule "^/~(<strong>([a-z])</strong>[a-z0-9]+)(.*)" "/home/<strong>$2</strong>/$1/public_html$3"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</highlight>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dl>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</section>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<section id="redirectanchors">
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin <title>Redirecting Anchors</title>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dl>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dt>Description:</dt>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin <dd>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin <p>By default, redirecting to an HTML anchor doesn't work,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin because mod_rewrite escapes the <code>#</code> character,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin turning it into <code>%23</code>. This, in turn, breaks the
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin redirection.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dd>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin <dt>Solution:</dt>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin <dd>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin <p>Use the <code>[NE]</code> flag on the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <code>RewriteRule</code>. NE stands for No Escape.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dt>Discussion:</dt>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dd>This technique will of course also work with other
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin special characters that mod_rewrite, by default, URL-encodes.</dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dl>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</section>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<section id="time-dependent">
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <title>Time-Dependent Rewriting</title>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dl>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dt>Description:</dt>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>We wish to use mod_rewrite to serve different content based on
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin the time of day.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dt>Solution:</dt>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>There are a lot of variables named <code>TIME_xxx</code>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for rewrite conditions. In conjunction with the special
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lexicographic comparison patterns <code>&lt;STRING</code>,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <code>&gt;STRING</code> and <code>=STRING</code> we can
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz do time-dependent redirects:</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<highlight language="config">
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinRewriteEngine on
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinRewriteCond "%{TIME_HOUR}%{TIME_MIN}" &gt;0700
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinRewriteCond "%{TIME_HOUR}%{TIME_MIN}" &lt;1900
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinRewriteRule "^foo\.html$" "foo.day.html" [L]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinRewriteRule "^foo\.html$" "foo.night.html"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</highlight>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>This provides the content of <code>foo.day.html</code>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin under the URL <code>foo.html</code> from
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <code>07:01-18:59</code> and at the remaining time the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin contents of <code>foo.night.html</code>.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <note type="warning"><module>mod_cache</module>, intermediate proxies
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin and browsers may each cache responses and cause the either page to be
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shown outside of the time-window configured.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <module>mod_expires</module> may be used to control this
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin effect. You are, of course, much better off simply serving the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin content dynamically, and customizing it based on the time of day.</note>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dl>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</section>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<section id="setenvvars">
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <title>Set Environment Variables Based On URL Parts</title>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dl>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dt>Description:</dt>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>At time, we want to maintain some kind of status when we
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin perform a rewrite. For example, you want to make a note that
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin you've done that rewrite, so that you can check later to see if a
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin request can via that rewrite. One way to do this is by setting an
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin environment variable.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dt>Solution:</dt>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>Use the [E] flag to set an environment variable.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<highlight language="config">
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinRewriteEngine on
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinRewriteRule "^/horse/(.*)" "/pony/$1" [E=<strong>rewritten:1</strong>]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</highlight>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>Later in your ruleset you might check for this environment
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin variable using a RewriteCond:</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin<highlight language="config">
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinRewriteCond "%{ENV:rewritten}" =1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</highlight>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin <p>Note that environment variables do not survive an external
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin redirect. You might consider using the [CO] flag to set a
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cookie.</p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin </dl>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</section>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin</manualpage>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin