Mod rewrite » History » Revision 42
Revision 41 (Anonymous, 2008-08-02 09:05) → Revision 42/64 (Sfiera, 2008-11-06 05:05)
h1. [[TracNav(DocsToc)]] <pre> #!rst ============ URL Rewrites ============ h2. ------------------- Module: mod_rewrite ------------------- .. meta:: :keywords: lighttpd, rewrite .. contents:: Table of Contents h2. Description =========== internal redirects, url rewrite h2. Options ======= h3. url.rewrite-once Rewrites 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 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@ ``url.rewrite`` and @url.rewrite-final@ ``url.rewrite-final`` were mapped to @url.rewrite-once@ ``url.rewrite-once`` in 1.3.16. 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/)).*)" ``"^(/(?!(favicon.ico$|js/|images/)).*)" => "/fgci/$1"@ "/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. You can also use certain meta-patterns in replacement text (NOTE: these inferred from examples in other modules, but unverified yet.): * %% => % sign * %0 => domain name + tld (Top Level Domain, like .com or .net) * %1 => tld * %2 => domain name without tld * %3 => subdomain 1 name * %4 => subdomain 2 name h2. Examples ======== The regex is matching the full REQUEST_URI which is supplied by the user including query-string. <pre> query-string.:: url.rewrite-once = ( "^/id/([0-9]+)$" => "/index.php?id=$1", "^/link/([a-zA-Z]+)" => "/index.php?link=$1" ) # 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 # 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/ server.document-root = "/www/htdocs/" $HTTP["host"] =~ "^.*\.([^.]+\.com)$" { url.rewrite-once = ( "^/(.*)" => "/%0/$1" ) } # 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. # in the case, when the rewrite rule is not included in a conditional # block, only the '$' prefixed variables are available. # subexpression 0 is the whole matching expression. </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 ``500 Internal Server Error@ Error`` if computed filename is longer than 255 symbols. In error log it will be @(response.c.537) ``(response.c.537) file not found ... or so: File name too long /very_looooong_path ->@. ->``. As workaround you can use @mod_rewrite@ ``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']@ ``$_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>