模块 ngx_http_rewrite_module

指令
     break
     if
     return
     rewrite
     rewrite_log
     set
     uninitialized_variable_warn
内部实现

ngx_http_rewrite_module 模块用于使用 PCRE 正则表达式更改请求 URI,返回重定向以及有条件地选择配置。

以下列顺序处理 breakifreturnrewriteset 指令

指令

语法 break;
默认值
上下文 serverlocationif

停止处理当前一组 ngx_http_rewrite_module 指令。

如果在 location 内指定了指令,则在此 location 中继续处理请求。

示例

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

语法 if (条件) { ... }
默认值
上下文 serverlocation

评估指定的 条件。如果为真,则执行大括号内指定的此模块指令,并将请求分配给 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 代码 URL;
return URL;
默认值
上下文 serverlocationif

停止处理并将指定的 代码 返回给客户端。非标准代码 444 在不发送响应标头的情况下关闭连接。

从 0.8.42 版开始,可以指定重定向 URL(对于代码 301、302、303、307 和 308)或响应正文 文本(对于其他代码)。响应正文文本和重定向 URL 可以包含变量。作为特殊情况,可以将重定向 URL 指定为此服务器的本地 URI,在这种情况下,将根据请求方案 ($scheme) 以及 server_name_in_redirectport_in_redirect 指令形成完整的重定向 URL。

此外,可以将代码 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 正则表达式 替换 [标志];
默认值
上下文 serverlocationif

如果指定的正则表达式与请求 URI 匹配,则 URI 将根据 替换 字符串中指定的内容更改。rewrite 指令按其在配置文件中的出现顺序依次执行。可以使用标志终止指令的进一步处理。如果替换字符串以“http://”、“https://”或“$scheme”开头,则处理停止并返回重定向到客户端。

可选的 标志 参数可以是以下之一

last
停止处理当前一组 ngx_http_rewrite_module 指令并开始搜索与已更改的 URI 匹配的新 location;
break
break 指令一样,停止处理当前一组 ngx_http_rewrite_module 指令;
redirect
返回带有 302 代码的临时重定向;如果替换字符串不以“http://”、“https://”或“$scheme”开头,则使用;
permanent
返回带有 301 代码的永久重定向。

完整的重定向 URL 是根据请求方案 ($scheme) 以及 server_name_in_redirectport_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;
}

如果 替换 字符串包含新的请求参数,则先前的请求参数将附加在其后。如果不需要这样做,则在替换字符串末尾加上问号可以避免将其附加,例如

rewrite ^/users/(.*)$ /show?user=$1? last;

如果正则表达式包含“}”或“;”字符,则整个表达式应括在单引号或双引号中。

语法 rewrite_log on | off;
默认值
rewrite_log off;
上下文 httpserverlocationif

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

语法 set $变量 ;
默认值
上下文 serverlocationif

为指定的 变量 设置 可以包含文本、变量及其组合。

语法 uninitialized_variable_warn on | off;
默认值
uninitialized_variable_warn on;
上下文 httpserverlocationif

控制是否记录有关未初始化变量的警告。

内部实现

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