ngx_http_rewrite_module 模块
| 指令 break if return rewrite rewrite_log set uninitialized_variable_warn 内部实现 |
ngx_http_rewrite_module 模块用于使用 PCRE 正则表达式更改请求 URI、返回重定向以及有条件地选择配置。
break、if、return、rewrite 和 set 指令按以下顺序处理
- 在 server 级别指定的该模块指令按顺序执行;
- 反复地
指令
| 语法 |
break; |
|---|---|
| 默认值 | — |
| 上下文 |
server, location, if |
停止处理当前这组 ngx_http_rewrite_module 指令。
如果指令在 location 内部指定,则请求的后续处理会在此 location 中继续。
示例
if ($slow) {
limit_rate 10k;
break;
}
| 语法 |
if ( |
|---|---|
| 默认值 | — |
| 上下文 |
server, location |
评估指定的 condition。如果为真,则执行大括号内指定的该模块指令,并且请求被赋予 if 指令内的配置。if 指令内的配置继承自前一个配置级别。
条件可以是以下任何一种
- 变量名;如果变量的值为空字符串或“
0”,则为假;在 1.0.1 版本之前,任何以“
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 return return |
|---|---|
| 默认值 | — |
| 上下文 |
server, location, if |
停止处理并向客户端返回指定的 code。非标准代码 444 会关闭连接,而不发送响应头。
从 0.8.42 版本开始,可以指定重定向 URL(对于代码 301、302、303、307 和 308)或响应体 text(对于其他代码)。响应体文本和重定向 URL 可以包含变量。作为特例,可以将重定向 URL 指定为此服务器的本地 URI,在这种情况下,完整的重定向 URL 将根据请求方案 ($scheme) 以及 server_name_in_redirect 和 port_in_redirect 指令形成。
此外,可以将代码 302 的临时重定向 URL 指定为唯一参数。此类参数应以“http://”、“https://”或“$scheme”字符串开头。URL 可以包含变量。
在 0.7.51 版本之前,只能返回以下代码:204、400、402 — 406、408、410、411、413、416 以及 500 — 504。
直到 1.1.16 和 1.0.13 版本,代码 307 才被视为重定向。
直到 1.13.0 版本,代码 308 才被视为重定向。
另请参阅 error_page 指令。
| 语法 |
rewrite |
|---|---|
| 默认值 | — |
| 上下文 |
server, location, if |
如果指定的正则表达式与请求 URI 匹配,则根据 replacement 字符串中的指定更改 URI。rewrite 指令按照它们在配置文件中出现的顺序依次执行。可以使用标志终止指令的进一步处理。如果替换字符串以“http://”、“https://”或“$scheme”开头,则处理停止并将重定向返回给客户端。
可选的 flag 参数可以是以下之一
last- 停止处理当前这组
ngx_http_rewrite_module指令,并开始搜索与更改后的 URI 匹配的新 location; break- 停止处理当前这组
ngx_http_rewrite_module指令,作用类似于 break 指令; redirect- 返回代码 302 的临时重定向;当替换字符串不以“
http://”、“https://”或“$scheme”开头时使用; permanent- 返回代码 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/” location 中,则 last 标志应替换为 break,否则 nginx 将执行 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 |
|---|---|
| 默认值 |
rewrite_log off; |
| 上下文 |
http, server, location, if |
启用或禁用将 ngx_http_rewrite_module 模块指令的处理结果记录到 error_log 的 notice 级别。
| 语法 |
set |
|---|---|
| 默认值 | — |
| 上下文 |
server, location, if |
为指定的 variable 设置 value。value 可以包含文本、变量及其组合。
| 语法 |
uninitialized_variable_warn |
|---|---|
| 默认值 |
uninitialized_variable_warn on; |
| 上下文 |
http, server, location, if |
控制是否记录有关未初始化变量的警告。
内部实现
ngx_http_rewrite_module 模块指令在配置阶段被编译成内部指令,这些指令在请求处理期间被解释执行。解释器是一个简单的虚拟堆栈机。
例如,指令
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 指令的指令,因为它与 ngx_http_rewrite_module 模块无关。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