全球主机交流论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

CeraNetworks网络延迟测速工具IP归属甄别会员请立即修改密码
查看: 3055|回复: 10

[经验] Lighttpd Module : Rewrites 使用详解

[复制链接]
发表于 2009-11-13 17:01:40 | 显示全部楼层 |阅读模式
GOOGLE 了半天找到的几篇值得收藏的文章。。不知道有没有用LIGHTTPD 的  这个应该很有用。。。
说明: 本文章来源于Lighttpd 官方网站,这里只做翻译和解释说明,并保留原文。
原文地址: http://redmine.lighttpd.net/wiki/1/Docs:ModRewrite
h1. URL Rewrites
*Module: mod_rewrite*
h2. Description
     [描述]
internal redirects, url rewrite
内部从定向,URL重写

h2. Options
        [选项]
h3. url.rewrite-once

Rewrites a set of URLs internally in the webserver BEFORE they are handled.[在URL设置被处理之前,在webserver服务器内部重写这个URL,只匹配一次]

e.g.

<pre>
url.rewrite-once = ( "<regex>" => "<relative-uri>" )
(说明:在上面的语句中, <regex> 代表正则表达式部分, <relative-uri>代表被替换或处理的文本部分,也就是说,凡是URL设置中,符合<regex>部分正则表达式部分的字符串会被后面的<relative-uri>替换, 这个有点向javascript 字符串处理,其中url.rewrite-once,表示URL字符对象本身。)
</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
[以上两个选项的区别在于url.rewrite-repeat 允许在一行中进行多次URL重写,而url.rewrite-once 只能重写一次,其它匹配重写规则会跳过,只有第一次生效。例如:url.rewrite-once行为类似Apaches 的 RewriteRule,呵呵,这里言下之意,就是url.rewrite-repeat是lighttpd的独特之处了。]

The options @url.rewrite@ and @url.rewrite-final@ were mapped to @url.rewrite-once@ in 1.3.16.
[url.rewrite和url.rewrite-final 在1.3.16的url.rewrite-once中说明。]

*{color:red}NOTE: url rewriting does not work within a $HTTP["url"] conditional.* [http://forum.lighttpd.net/topic/1092#3028]
[ 注释: url rewriting 在$HTTP['url']情况下无效。 ]


h2. Regular Expressions
    [正则表达式]

* Patterns ("wildcards") are matched against a string
  模式("通配符")被用来陪陪一个字符串
* Special characters (see [http://www.regular-expressions.info/reference.html] for reference):
  特殊字符请参考: http://www.regular-expressions.info/reference.html  , (这个网站似乎是正则表达式官方网站,看来lighttpd正则表达式很规范。)
** . (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) 匹配n到m次。
** (?!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.
如果匹配的正则中包括子集,那么$1--$9所在的位置会被替换成扑获到的文本,在匹配的子集中$1表似乎第一个子集,$2表示第二个子集,以此类推。

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".
注释: %替换符,(例如%1,%2,%0等等) 在url.rewrite-*选项中是许可的,但是这并不意味着可以在evhost.path-pattern模式中许可。如果url.rewrite-*是通过正则表达式指定的,%模式被相应的正则自己所替换。%1被第一个子集替换,%2被第二个子集替换,依次类推。%0被整个的字符串替换,下面是一个用%0的例子。

h2. Examples例子

The regex is matching the full REQUEST_URI which is supplied by the user including
query-string.
正则表达式匹配全部用户提交的REQUEST_URI,包括查询字符串(query-string:a=123&b=234).

<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
下面的例子描述了怎样可以通过重写来模拟虚拟域名,这样你不再需要通过mod_rewrite模块修改document-root参数参数,通过mod_*host来代替产生一个真实的虚拟主机集群。

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/
注释:通过上面的实例可以看出,重写模块url.rewrite-* 是在url被服务器执行之前所调用的,因此我猜测lighttpd 的WEB服务器是有事件管理的,通过事件管理来增强服务器性能。
     url.rewrite-*的事件顺序是,REQUEST_URL被扑获后,和被正式处理前的这一段时间执行。可以通过url.rewrite-once('.*'=>"/%0");获取完成的URL字符串,输出%0就可以了。
         个人猜想url这个模块应该有办法可以直接输出url字符,进行一些常规的字符串判断或处理。

# 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.
请注意,我们有两个正则表达式,$HTTP['host']被匹配的是第一个。能够用来建立相关URI的数字化表达式由‘%’作为前缀,这个数字化的表达式是作为第一个正则表达式的子表达式。第二个是用‘$’作为前缀。   第一个正则表达式,由‘%’作为前缀,数字化的表示方式,例如(%1,%2 ...)能够用来建立相关的URI,表达式0(%0或$0)包含了整个匹配的字符串。


# if the rewrite rule is not included in a conditional
# block, only the '$' prefixed variables are available.
如果rewrite rule(重写规则)没有被包含在一个条件代码块内,只有'$'作为前缀的变量是有效的。所谓代码块,指被大括号‘{’和‘}’包围着的一段代码,这里看起来有点局部变量的意思。
也就是在局部范围内%是有效的变量前缀,在全局范围内$是有效的变量前缀。
(附加注释:在lighttpd的evhost模块中有说明,$1-$5是REQUEST_URL的指定变量,分别表示一个REQUEST_URL的不同部分,即使$HTTP['host']=~"正则表达式"{},$1-$5的内并并没有被改变
   ,在上面的实例中可以看到$1代表的是"url/"部分,因此$1-$5和全局变量是有区别的,而下面的正则表达式通过$1、$2....这样的形式来提取正则表达式子集匹配,那么这个是否会和全局$1-$5的定义冲突?)


汗 限制一万字... 下一半在一楼
 楼主| 发表于 2009-11-13 17:01:47 | 显示全部楼层
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.
重写规则允许在重定向之前执行,忽视模块导入请求和配置规则是一个事实。但是,重写模块提供了一个机制,通过unmangled来传递URL,指定的"$0"作为规则的目标.

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
在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.
当在windows下运行Lighttpd时,如果文件名长度大于225个字符,也许你会获得 @500 Internal Server Error@ 服务器错误,在错误日志中,这个记录是@(response.c.537)
文件没有找到,或着,文件名太长等等,在这个情况下,你可以通过mod_rewrite来避免这个问题。

<pre>
server.modules += ("mod_rewrite")
url.rewrite-once = ( ".{250,}" => "/toolong.php" )
</pre>

If error handler is PHP, @$_SERVER['REQUEST_URI']@ will contain full URI.
如果由PHP来处理这个错误,那么$_SERVER['REQUEST_URI']会包含全部的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:
如果你想通过rewrite功能来传递query-string,你必须明确匹配。

<pre>
url.rewrite-once = (
    "^/news/([^\?]+)(\?(.*))?" => "/news.php?title=$1&$3"
)
</pre>
发表于 2009-11-13 17:04:17 | 显示全部楼层
即使知道办法一般也懒得写的
发表于 2009-11-13 17:09:43 | 显示全部楼层
看了一部分我就开始头晕了。
发表于 2009-11-13 17:23:30 | 显示全部楼层
恩.看过了.也用过了....
这个规则还是比较简单的.如果有一些是要进行目录判断的.比如shopex程序.你用这个简单的rewrite就不行咯...

你得用lighttpd-mod-magnet这个模块.可以进行比较高阶的规则匹配.这个是我配置的shopex的伪静态规则.你有空可以参考一下
http://www.xmlchina.org/original ... ttpd-pseudo-static/
发表于 2009-11-13 17:26:41 | 显示全部楼层

回复 5# 的帖子

shopex程序在Apache下的伪静态都够复杂的。
发表于 2009-11-13 17:28:42 | 显示全部楼层

回复 6# 的帖子

在nginx很简单哦...
在lighttpd下也很简单.只要用我那个方法...
发表于 2009-11-13 19:39:43 | 显示全部楼层

回复 7# 的帖子

我去学习下了
发表于 2009-11-13 19:41:28 | 显示全部楼层
一般默认的阿帕奇规则扔到里面都可以用,我上次试的
发表于 2009-11-13 20:17:35 | 显示全部楼层
还是使用nginx吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|全球主机交流论坛

GMT+8, 2024-5-10 10:59 , Processed in 0.070436 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表