幸福日记

nginx中文文档-ngx_http_rewrite_module

ngx_http_rewrite_module模块的指令按以下顺序处理:

break

语法:break
默认:—
上下文:server, location, if

停止当前ngx_http_rewrite_module的指令处理。
如果指令定义在location中,请求的后续处理继续在当前location中。
例子:

if ($slow) {
    limit_rate 10k;
    break;
}

if

语法:if (condition) { … }
默认:—
上下文:server, location

指定的condition会被解析,如果结果是真值,该模块会被执行,请求会分配到if指令的配置中。if指令中的配置继承自上级配置。
条件可以是下面的值:

例子:

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 code [text]
return code URL
return URL
默认:—
上下文:server, location, if

停止处理,并返回指定的code给客户端。非标准错误码444关闭连接并不返回响应头。
从0.8.42版本起,可以定义重定向URL(为301、302、303或307错误码),或响应体文本(其他错误码)。响应体文本及重定向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。
307错误码在1.1.16 和 1.0.13版本前不会当做重定向。

rewrite

语法:rewrite regex replacement [flag]
默认:—
上下文:server, location, if

如果指定的正则表达式匹配请求URI,URI会按照replacement字符串进行改变。rewrite指令按照它们出现在配置文件中的顺序执行。可以使用标识对后续处理进行终结。如果替换字符串以“http://”或“https://”开始,处理停止并返回重定向到客户端。
可选flag参数可以是下面值之一:
last
停止处理当前ngx_http_rewrite_module的指令,并开始寻找匹配URI的新location。

break
停止处理ngx_http_rewrite_module的指令,同break指令。

redirect
如果替换字符串不以“http://”和“https://”开头,返回临时响应码302。

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 on | off
默认:rewrite_log off
上下文:http, server, location, if

启用或禁用将ngx_http_rewrite_module模块指令的处理结果记录到error_log的notice级别中。

set

语法:set $variable value
默认:—
上下文:server, location, if

为指定变量设置值,值可以包含文本、变量及它们的混合。

uninitialized_variable_warn

语法:uninitialized_variable_warn on | off
默认: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块创建。如果条件为true,请求会分配到该配置上,限速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
退出移动版