ngx_http_rewrite_module 模块

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

break、if、return、rewrite 和 set 指令按以下顺序处理:

  • 在 server 级别指定的此模块的指令按顺序执行;

  • 重复地:

    • 根据请求 URI 搜索 location

    • 在找到的 location 中,指定的这个模块的指令是顺序执行的;

    • 如果请求 URI 被重写,则循环重复,但不超过 10 次;

指令

break 指令

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

停止处理当前的 ngx_http_rewrite_module 指令集。

如果在该 location 内指定了指令,则在该 location 继续进一步处理请求。

例子:

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

if 指令

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

评估指定的条件。如果为 true,则执行大括号内指定的此模块指令,并为请求分配 if 指令内的配置。if 指令中的配置继承自之前的配置级别。

条件可以是以下任何一种:

  • 变量名;如果变量的值为空字符串或 “0”,则为 false;在 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 code [text];
    return code URL;
    return URL;
默认值:—
上下文:server, location, if

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

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

此外,可以将代码为 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 才被视为重定向。

代码 308 直到版本 1.13.0 才被视为重定向。

另请参阅 error_page 指令。

rewrite 指令

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

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

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

  • last  停止处理当前的 ngx_http_rewrite_module 指令集并开始搜索与更改的 URI 匹配的新位置;

  • break  停止处理当前的 ngx_http_rewrite_module 指令集,就像 break 指令一样;

  • redirect  返回302代码的临时重定向;当替换字符串不是以“http://”、“https://”或“$schema”开头时使用;

  • permanent  返回带有301代码的永久重定向。

完整的重定向URL是根据请求方案($SCHEMA)以及 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/” 位置,最后一个标志应该被 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 指令

语 法:rewrite_log on | off;
默认值:rewrite_log off;
上下文:http, server, location, if

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

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 块创建了一个单独的配置。 如果条件成立,则为请求分配此配置,其中 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
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号