2008/12/21 Eric Covener <[email protected]>:
> committed to trunk with a tiny xml fix along with some related
> REQUEST_URI/REQUEST_FILENAME I had in my local tree.
Thanks. I made a mistake and wrote "encoded" but meant "decoded",
sorry. The attached patch addresses
http://article.gmane.org/gmane.comp.apache.devel/28052 (int: map
function) and PR 39739 (escape map) as well.
I have also some fixes for the rewrite guide: H flag in directory
context with a substitution, CondPattern -U checks only access
controls and not whether TestString resolves to sthg., so it's not
equivalent to the ruleset it is supposed to be and some cleanups.
Bob
Index: docs/manual/mod/mod_rewrite.xml
===================================================================
--- docs/manual/mod/mod_rewrite.xml (revision 729539)
+++ docs/manual/mod/mod_rewrite.xml (working copy)
@@ -444,7 +444,9 @@
function
<p>Here, the source is an internal Apache function.
- Currently you cannot create your own, but the following
+ Third-party modules can provide additional internal
+ functions by registring them with
+ <code>ap_register_rewrite_mapfunc</code>. The following
functions already exist:</p>
<ul>
@@ -456,7 +458,9 @@
<li><strong>escape</strong>:<br />
Translates special characters in the key to
- hex-encodings.</li>
+ hex-encodings. Certain characters which may be used
+ unencoded within an URL (e.g. <code>+=&</code>)
+ are not handled by this function.</li>
<li><strong>unescape</strong>:<br />
Translates hex-encodings in the key back to
@@ -1120,7 +1124,7 @@
<p><a id="patterns" name="patterns"><em>Pattern</em></a> is
a perl compatible <a id="regexp" name="regexp">regular
- expression</a>. On the first RewriteRule it is applied to the (%-encoded)
+ expression</a>. On the first RewriteRule it is applied to the (%-decoded)
<a href="./directive-dict.html#Syntax">URL-path</a> of the request;
subsequent patterns are applied to the output of the last matched
RewriteRule.</p>
Index: docs/manual/rewrite/rewrite_guide.xml
===================================================================
--- docs/manual/rewrite/rewrite_guide.xml (revision 728400)
+++ docs/manual/rewrite/rewrite_guide.xml (working copy)
@@ -81,8 +81,8 @@
<code>/u/user</code>.</p>
<example><pre>
-RewriteRule ^/<strong>~</strong>([^/]+)/?(.*) /<strong>u</strong>/$1/$2 [<strong>R</strong>]
-RewriteRule ^/u/(<strong>[^/]+</strong>)$ /$1/$2<strong>/</strong> [<strong>R</strong>]
+RewriteRule ^/<strong>~</strong>([^/]+)/?(.*) /<strong>u</strong>/$1/$2 [<strong>L,R</strong>]
+RewriteRule ^/u/(<strong>[^/]+</strong>)$ /$1/$2<strong>/</strong> [<strong>L,R</strong>]
</pre></example>
</dd>
</dl>
@@ -107,15 +107,15 @@
<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$
+RewriteCond %{HTTP_HOST} !=""
+RewriteCond %{SERVER_PORT} !=80
RewriteRule ^/?(.*) http://www.example.com:%{SERVER_PORT}/$1 [L,R]
</pre></example>
<p>And for a site running on port 80</p>
<example><pre>
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
-RewriteCond %{HTTP_HOST} !^$
+RewriteCond %{HTTP_HOST} !=""
RewriteRule ^/?(.*) http://www.example.com/$1 [L,R]
</pre></example>
@@ -128,10 +128,23 @@
<example><pre>
RewriteCond %{HTTP_HOST} !^www\. [NC]
-RewriteCond %{HTTP_HOST} !^$
+RewriteCond %{HTTP_HOST} !=""
RewriteRule ^/?(.*) http://www.%{HTTP_HOST}/$1 [L,R]
</pre></example>
+ <p>
+ If you wanted to do this generically for all domain names but
+ keep whether the request was served via <strong>https</strong> or
+ <strong>http</strong>, you could use the following
+ recipe:</p>
+
+<example><pre>
+RewriteCond %{HTTP_HOST} !^www\. [NC]
+RewriteCond %{HTTP_HOST} !=""
+RewriteCond %{HTTPS}s ^on(s)|^off
+RewriteRule ^/?(.*) http%1://www.%{HTTP_HOST}/$1 [L,R]
+</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>
@@ -613,14 +626,13 @@
<p>We just rewrite the URL to the CGI-script and force the
handler to be <strong>cgi-script</strong> so that it is
executed as a CGI program.
- This way a request to <code>/~quux/foo.html</code>
+ This way a request to <code>/foo.html</code>
internally leads to the invocation of
- <code>/~quux/foo.cgi</code>.</p>
+ <code>/foo.cgi</code>. Note: This is a per-server context example.</p>
<example><pre>
RewriteEngine on
-RewriteBase /~quux/
-RewriteRule ^foo\.<strong>html</strong>$ foo.<strong>cgi</strong> [H=<strong>cgi-script</strong>]
+RewriteRule ^/foo\.<strong>html</strong>$ /foo.<strong>cgi</strong> [H=<strong>cgi-script</strong>]
</pre></example>
</dd>
</dl>
@@ -697,8 +709,8 @@
we assume that our site is <code>www.example.com</code>.</p>
<example><pre>
-RewriteCond %{HTTP_REFERER} <strong>!^$</strong>
-RewriteCond %{HTTP_REFERER} !www.example.com [NC]
+RewriteCond %{HTTP_REFERER} <strong>!=""</strong>
+RewriteCond %{HTTP_REFERER} !www\.example\.com [NC]
RewriteRule <strong>\.(gif|jpg|png)$</strong> - [F,NC]
</pre></example>
@@ -706,8 +718,8 @@
an alternate image instead.</p>
<example><pre>
-RewriteCond %{HTTP_REFERER} <strong>!^$</strong>
-RewriteCond %{HTTP_REFERER} !www.example.com [NC]
+RewriteCond %{HTTP_REFERER} <strong>!=""</strong>
+RewriteCond %{HTTP_REFERER} !www\.example\.com [NC]
RewriteRule <strong>\.(gif|jpg|png)$</strong> /images/go-away.png [R,NC]
</pre></example>
@@ -715,8 +727,8 @@
third-party site.</p>
<example><pre>
-RewriteCond %{HTTP_REFERER} <strong>!^$</strong>
-RewriteCond %{HTTP_REFERER} !www.example.com [NC]
+RewriteCond %{HTTP_REFERER} <strong>!=""</strong>
+RewriteCond %{HTTP_REFERER} !www\.example\.com [NC]
RewriteRule <strong>\.(gif|jpg|png)$</strong> http://other.site.com/image.gif [R,NC]
</pre></example>
Index: docs/manual/rewrite/rewrite_guide_advanced.xml
===================================================================
--- docs/manual/rewrite/rewrite_guide_advanced.xml (revision 728400)
+++ docs/manual/rewrite/rewrite_guide_advanced.xml (working copy)
@@ -331,15 +331,25 @@
<dt>Solution:</dt>
<dd>
- <p>The first solution has the best performance but less
- flexibility, and is less safe:</p>
+ <p>The first solution can be used in per-directory context:</p>
<example><pre>
RewriteEngine on
-RewriteCond %{DOCUMENT_ROOT/%{REQUEST_URI} <strong>!-f</strong>
+# Note: This is a per-directory example, so %{REQUEST_FILENAME} is the full
+# filesystem path as already mapped by the server.
+RewriteCond %{REQUEST_FILENAME} <strong>!-f</strong>
RewriteRule ^(.+) http://<strong>webserverB</strong>.dom/$1
</pre></example>
+ <p>The next solution for per-server context has the best performance but less
+ flexibility:</p>
+
+<example><pre>
+RewriteEngine on
+RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} <strong>!-f</strong>
+RewriteRule ^/(.+) http://<strong>webserverB</strong>.dom/$1
+</pre></example>
+
<p>The problem here is that this will only work for pages
inside the <directive module="core">DocumentRoot</directive>. While you can add more
Conditions (for instance to also handle homedirs, etc.)
@@ -347,13 +357,13 @@
<example><pre>
RewriteEngine on
-RewriteCond %{REQUEST_URI} <strong>!-U</strong>
-RewriteRule ^(.+) http://<strong>webserverB</strong>.dom/$1
+RewriteCond %{LA-U:REQUEST_FILENAME} <strong>!-f</strong>
+RewriteRule ^/(.+) http://<strong>webserverB</strong>.dom/$1
</pre></example>
<p>This uses the URL look-ahead feature of <module>mod_rewrite</module>.
- The result is that this will work for all types of URLs
- and is safe. But it does have a performance impact on
+ The look-ahead provides the final full filesystem path. The result is that
+ this will work for all types of URLs. But it does have a performance impact on
the web server, because for every request there is one
more internal subrequest. So, if your web server runs on a
powerful CPU, use this one. If it is a slow machine, use
@@ -386,20 +396,19 @@
<dt>Solution:</dt>
<dd>
- <p>First we notice that as of version 3.0.0,
- <module>mod_rewrite</module> can
+ <p>First we notice that <module>mod_rewrite</module> can
also use the "<code>ftp:</code>" scheme on redirects.
And second, the location approximation can be done by a
<directive module="mod_rewrite">RewriteMap</directive>
over the top-level domain of the client.
- With a tricky chained ruleset we can use this top-level
+ With a RewriteCond we can use this top-level
domain as a key to our multiplexing map.</p>
<example><pre>
RewriteEngine on
RewriteMap multiplex txt:/path/to/map.cxan
-RewriteRule ^/CxAN/(.*) %{REMOTE_HOST}::$1 [C]
-RewriteRule ^.+\.<strong>([a-zA-Z]+)</strong>::(.*)$ ${multiplex:<strong>$1</strong>|ftp.default.dom}$2 [R,L]
+RewriteCond %{REMOTE_HOST} ^.+\.<strong>([a-zA-Z]+)</strong>$
+RewriteRule ^/CxAN/(.*) ${multiplex:<strong>%1</strong>|ftp://ftp.default.dom/}$1 [R,L]
</pre></example>
<example><pre>
@@ -766,7 +775,7 @@
<example><pre>
RewriteRule ^/[uge]/<strong>([^/]+)</strong>/\.www/(.+)\.scgi(.*) ...
-... /internal/cgi/user/cgiwrap/~<strong>$1</strong>/$2.scgi$3 [NS,<strong>T=application/x-http-cgi</strong>]
+... /internal/cgi/user/cgiwrap/~<strong>$1</strong>/$2.scgi$3 [NS,<strong>H=cgi-script</strong>]
</pre></example>
<p>Or assume we have some more nifty programs:
@@ -848,13 +857,13 @@
This is done via the following ruleset:
<example><pre>
-# This example is valid in per-directory context only
-RewriteCond %{REQUEST_FILENAME} <strong>!-s</strong>
-RewriteRule ^page\.<strong>html</strong>$ page.<strong>cgi</strong> [T=application/x-httpd-cgi,L]
+# This example is valid in per-server context only
+RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} <strong>!-s</strong>
+RewriteRule ^/page\.<strong>html</strong>$ /page.<strong>cgi</strong> [H=cgi-script,L]
</pre></example>
- <p>Here a request for <code>page.html</code> leads to an
- internal run of a corresponding <code>page.cgi</code> if
+ <p>Here a request for <code>/page.html</code> leads to an
+ internal run of a corresponding <code>/page.cgi</code> if
<code>page.html</code> is missing or has filesize
null. The trick here is that <code>page.cgi</code> is a
CGI script which (additionally to its <code>STDOUT</code>)
@@ -1086,7 +1095,7 @@
# 2. make sure we have a Host header, because
# currently our approach only supports
# virtual hosting through this header
-RewriteCond %{HTTP_HOST} !^$
+RewriteCond %{HTTP_HOST} !=""
#
# 3. lowercase the hostname
RewriteCond ${lowercase:%{HTTP_HOST}|NONE} ^(.+)$
@@ -1121,7 +1130,6 @@
<dt>Solution:</dt>
<dd>
- <p>For Apache >= 1.3b6:</p>
<example><pre>
RewriteEngine on
@@ -1131,17 +1139,6 @@
RewriteRule ^/.* - [F]
</pre></example>
- <p>For Apache <= 1.3b6:</p>
-
-<example><pre>
-RewriteEngine on
-RewriteMap hosts-deny txt:/path/to/hosts.deny
-RewriteRule ^/(.*)$ ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}/$1
-RewriteRule !^NOT-FOUND/.* - [F]
-RewriteRule ^NOT-FOUND/(.*)$ ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}/$1
-RewriteRule !^NOT-FOUND/.* - [F]
-RewriteRule ^NOT-FOUND/(.*)$ /$1
-</pre></example>
<example><pre>
##
@@ -1184,14 +1181,14 @@
<example><pre>
RewriteCond %{REMOTE_HOST} <strong>^badhost\.mydomain\.com$</strong>
-RewriteRule !^http://[^/.]\.mydomain.com.* - [F]
+RewriteRule !^http://[^/.]\.mydomain\.com.* - [F]
</pre></example>
<p>...and this one for a u...@host-dependent deny:</p>
<example><pre>
RewriteCond %{remote_ide...@%{remote_host} <strong>^bad...@badhost\.mydomain\.com$</strong>
-RewriteRule !^http://[^/.]\.mydomain.com.* - [F]
+RewriteRule !^http://[^/.]\.mydomain\.com.* - [F]
</pre></example>
</dd>
</dl>
@@ -1220,9 +1217,9 @@
our friends:</p>
<example><pre>
-RewriteCond %{remote_ide...@%{remote_host} <strong>!^[email protected]\.com$</strong>
-RewriteCond %{remote_ide...@%{remote_host} <strong>!^friend2</strong>@client2.quux-corp\.com$
-RewriteCond %{remote_ide...@%{remote_host} <strong>!^friend3</strong>@client3.quux-corp\.com$
+RewriteCond %{remote_ide...@%{remote_host} <strong>!^frie...@client1\.quux-corp\.com$</strong>
+RewriteCond %{remote_ide...@%{remote_host} <strong>!^friend2</strong>@client2\.quux-corp\.com$
+RewriteCond %{remote_ide...@%{remote_host} <strong>!^friend3</strong>@client3\.quux-corp\.com$
RewriteRule ^/~quux/only-for-friends/ - [F]
</pre></example>
</dd>
@@ -1252,7 +1249,7 @@
RewriteMap deflector txt:/path/to/deflector.map
RewriteCond %{HTTP_REFERER} !=""
-RewriteCond ${deflector:%{HTTP_REFERER}} ^-$
+RewriteCond ${deflector:%{HTTP_REFERER}} =-
RewriteRule ^.* %{HTTP_REFERER} [R,L]
RewriteCond %{HTTP_REFERER} !=""
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]