重写#
该模块用于使用PCRE正则表达式更改请求URI,返回重定向,并有条件地选择配置。
break、if、return、rewrite 和 set 指令按以下顺序处理:
在 server 级别指定的本模块指令按顺序执行;
-
重复:
指令#
break#
停止处理当前的 http_rewrite 指令集。
如果在 location 内指定了指令,则请求的进一步处理将在此 location 中继续。
示例:
if ($slow) {
limit_rate 10k;
break;
}
if#
指定的条件被评估。如果为真,则括号内指定的本模块指令被执行,并且请求被分配在 if 指令中的配置。if 指令中的配置继承自上一级配置。
一个条件可以是以下任何一种:
一个变量名;如果变量的值为空字符串或"0",则为假;
使用"="和"!="操作符将变量与字符串进行比较;
使用"~"(区分大小写匹配)和"~*"(不区分大小写匹配)操作符将变量与正则表达式匹配。正则表达式可以包含捕获,供以后在$1..$9变量中重用。也可以使用否定操作符"!~"和"!~*"。如果正则表达式包含"}"或";"字符,整个表达式应放在单引号或双引号内。
使用"-f"和"!-f"操作符检查文件是否存在;
使用"-d"和"!-d"操作符检查目录是否存在;
使用"-e"和"!-e"操作符检查文件、目录或符号链接是否存在;
使用"-x"和"!-x"操作符检查可执行文件。
示例:
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
}
if ($request_method = POST) {
return 405;
}
if ($slow) {
limit_rate 10k;
}
if ($invalid_referer) {
return 403;
}
备注
$invalid_referer 内置变量的值由 valid_referers 指令设置。
return#
停止处理并返回指定的 code
给客户端。非标准代码444关闭连接而不发送响应头。
可以为代码301、302、303、307和308指定重定向URL,或为其他代码指定响应体文本。响应体文本和重定向URL可以包含变量。作为一种特殊情况,重定向URL可以被指定为此服务器的本地URI,在这种情况下,完整的重定向URL根据请求方案($scheme)以及 server_name_in_redirect 和 port_in_redirect 指令形成。
此外,可以将用于临时重定向的302代码URL指定为唯一参数。此类参数应以"http://"、"https://"或"$scheme"字符串开头。URL可以包含变量。
另见 error_page 指令。
rewrite#
如果指定的正则表达式匹配请求URI,则根据 replacement
字符串更改URI。rewrite 指令按其在配置文件中的出现顺序依次执行。可以使用 flags
终止进一步的指令处理。如果 replacement
字符串以"http://"、"https://"或"$scheme"开头,处理将停止并返回重定向给客户端。
可选的 flag
参数可以是以下之一:
|
停止处理当前的 http_rewrite 指令集,并开始搜索与更改后的URI匹配的新 location; |
|
停止处理当前的 http_rewrite 指令集,如同 break 指令; |
|
返回带有302代码的临时重定向;如果 |
|
返回带有301代码的永久重定向。 |
完整的重定向URL根据请求方案($scheme)以及 server_name_in_redirect 和 port_in_redirect 指令形成。
示例:
server {
# ...
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
return 403;
# ...
}
但如果这些指令放在"/download/"位置内部,则 last
标志应替换为 break
,否则将进行10个循环并返回500错误:
location /download/ {
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
return 403;
}
如果 replacement
字符串包含新的请求参数,则以前的请求参数会附加在它们之后。如果不希望这样,可以在替换字符串末尾放置一个问号以避免其附加,例如:
rewrite ^/users/(.*)$ /show?user=$1? last;
如果正则表达式包含"}"或";"字符,整个表达式应放在单引号或双引号内。
rewrite_log#
启用或禁用将 http_rewrite 模块指令处理结果记录到 error_log 中的 notice 级别。
set#
为指定变量设置值。该值可以包含文本、变量及其组合。
uninitialized_variable_warn#
|
|
默认值 |
|
http, server, location, if |
控制是否记录未初始化变量的警告。
内部实现#
http_rewrite 模块指令在配置阶段编译为内部指令,并在请求处理期间解释执行。解释器是一个简单的虚拟堆栈机。
例如,指令
location /download/ {
if ($forbidden) {
return 403;
}
if ($slow) {
limit_rate 10k;
}
rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;
}
将被翻译为这些指令:
variable $forbidden
check against zero
return 403
end of code
variable $slow
check against zero
match of regular expression
copy "/"
copy $1
copy "/mp3/"
copy $2
copy ".mp3"
end of regular expression
end of code
注意,上述指令中没有关于 limit_rate 的指令,因为它与 http_rewrite 模块无关。为 if 块创建了一个单独的配置。如果条件为真,请求被分配此配置,其中 limit_rate 等于10k。
指令
rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;
如果正则表达式中的第一个斜杠放在括号内,可以通过一个指令将其缩小:
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
相应的指令将如下所示:
match of regular expression
copy $1
copy "/mp3/"
copy $2
copy ".mp3"
end of regular expression
end of code