Mod rewrite » History » Revision 47
Revision 46 (nitrox, 2009-01-18 02:59) → Revision 47/64 (Shtirlic, 2009-03-10 16:22)
h1. URL Rewrites
{{>toc}}
*Module: mod_rewrite*
h2. Description
internal redirects, url rewrite
h2. Options
h3. url.rewrite-once
Rewrites a set of URLs internally in the webserver BEFORE they are handled.
e.g.
<pre>
url.rewrite-once = ( "<regex>" => "<relative-uri>" )
</pre>
h3. url.rewrite-repeat
Rewrites a set of URLs internally in the webserver BEFORE they are handled
e.g.
<pre>
url.rewrite-repeat = ( "<regex>" => "<relative-uri>" )
</pre>
The difference between these options is that, while url.rewrite-repeat allows for applying multiple (seperately defined) rewrite rules in a row, url.rewrite-once will cause further rewrite rules to be skipped if the expression was matched. As such, url.rewrite-once behaves like Apaches' RewriteRule ... [L]: http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriterule
The options @url.rewrite@ and @url.rewrite-final@ were mapped to @url.rewrite-once@ in 1.3.16.
*{color:red}NOTE: url rewriting does not work within a $HTTP["url"] conditional.* [http://forum.lighttpd.net/topic/1092#3028]
h2. Regular Expressions
* Patterns ("wildcards") are matched against a string
* Special characters (see [http://www.regular-expressions.info/reference.html] for reference):
** . (full stop) - match any character
** \* (asterisk) - match zero or more of the previous symbol
** \+ (plus) - match one or more of the previous symbol
** ? (question) - match zero or one of the previous symbol
** \\? (backslash-something) - match special characters
** ^ (caret) - match the start of a string
** $ (dollar) - match the end of a string
** [set] - match any one of the symbols inside the square braces.
** [^set] - match any symbol that is NOT inside the square braces.
** (pattern) - grouping, remember what the pattern matched as a special variable
** {n,m} - from n to m times matching the previous character (m could be omitted to mean >=n times)
** (?!expression) - match anything BUT expression at the current position. Example: @"^(/(?!(favicon.ico$|js/|images/)).*)" => "/fgci/$1"@
* Normal alphanumeric characters are treated as normal
h3. Replacement Patterns
If the matched regex contains groups in parentheses, $1..$9 in the replacement refer to the captured text in the
matching group "$1" meaning the first group, "$2" the second, and so on.
Note that % replacements (like %1, %2, %0, etc.) in url.rewrite-* targets are permitted, but do *not* have the meaning they would have in evhost.path-pattern. If url.rewrite-* is specified within a regex conditional, % patterns are replaced by the corresponding groups from the condition regex. %1 is replaced with the first subexpression, %2 with the second, etc. %0 is replaced by the entire substring matching the regexp. See below for an example using "%0".
h2. Examples
The regex is matching the full REQUEST_URI which is supplied by the user including
query-string.
<pre>
# the following example, is, however just simulating vhost by rewrite
# * you can never change document-root by mod_rewrite
# use mod_*host instead to make real mass-vhost
server.document-root = "/www/htdocs/"
$HTTP["host"] =~ "^.*\.([^.]+\.com)$" {
url.rewrite-once = ( "^/(.*)" => "/%0/$1" )
}
# request: http://any.domain.com/url/
# before rewrite: REQUEST_URI="/www/htdocs/url/"
# and DOCUMENT_ROOT="/www/htdocs/" %0="any.domain.com" $1="url/"
# after rewrite: REQUEST_URI="/www/htdocs/any.domain.com/url/"
# still, you have DOCUMENT_ROOT=/www/htdocs/
# please note, that we have two regular expressions: the one which
# $HTTP["host"] is been compared with, and the one of the rewrite rule.
# the numbered subexpressions available to build the relative uri are
# being prefixed by '%' for subexpressions of the first regular expression
# match and by '$' for subexpressions of the second one.
# subexpression 0 interpolates the whole matching string: %0 for the whole
# string matching the conditional, and $0 for the whole string matching the
# rewrite rule.
# if the rewrite rule is not included in a conditional
# block, only the '$' prefixed variables are available.
url.rewrite-once = ( "^/id/([0-9]+)$" => "/index.php?id=$1",
"^/link/([a-zA-Z]+)" => "/index.php?link=$1" )
</pre>
h3. With mod_redirect
Rewrite rules always execute before redirect rules. This is true regardless of the order of module loading or the order of rules in the configuration (lighttpd v1.4.13). However, mod_rewrite provides a mechanism to pass URLs through unmangled: specify "$0" as the rule target.
e.g.
<pre>
url.rewrite-once = (
"^/foo" => "$0",
"^/(.*)" => "/handler/$1"
)
url.redirect = (
"^/foo" => "http://foo.bar/"
)
</pre>
h3. Workaround for "File name too long" on Windows
While running Lighttpd on Windows you may get @500 Internal Server Error@ if computed filename is longer than 255 symbols.
In error log it will be @(response.c.537) file not found ... or so: File name too long /very_looooong_path ->@.
As workaround you can use @mod_rewrite@ to avoid this error.
<pre>
server.modules += ("mod_rewrite")
url.rewrite-once = ( ".{250,}" => "/toolong.php" )
</pre>
If error handler is PHP, @$_SERVER['REQUEST_URI']@ will contain full URI.
h3. Passing / Matching the Query string (GET variables)
If you wanna pass the Query String (?foo=bar) to the rewrite destination you have to explicitly match it:
<pre>
url.rewrite-once = (
"^/news/([^\?]+)(\?(.*))?" => "/news.php?title=$1&$3"
)
</pre>