重写#

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

breakifreturnrewriteset 指令按以下顺序处理:

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

  • 重复执行:

    • 基于请求 URI 搜索 location

    • 在找到的位置内按顺序执行此模块指定的指令;

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

指令#

break#

语法

break

默认值

上下文

server, location, if

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

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

示例:

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

if#

语法

if (condition) { ... }

默认值

上下文

server, location

指定的条件被评估。如果为真,则执行大括号内指定的模块指令,并将请求分配给 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#

语法

return code [text];

return code URL

return URL

默认值

上下文

server, location, if

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

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

此外,可以将代码 302 的临时重定向 URL 作为唯一参数指定。该参数应以 "http://"、"https://" 或 "$scheme" 字符串开头。URL 可以包含变量。

另请参阅 error_page 指令。

rewrite#

语法

rewrite regex replacement [flag];

默认值

上下文

server, location, if

如果指定的正则表达式匹配请求 URI,则 URI 将按 replacement 字符串中指定的方式更改。rewrite 指令按其在配置文件中的出现顺序顺序执行。可以使用 flags 终止指令的进一步处理。如果 replacement 字符串以 "http://"、"https://" 或 "$scheme" 开头,处理将停止并返回重定向给客户端。

可选的 flag 参数可以是以下之一:

last

停止处理当前的 http_rewrite 指令集,并开始搜索与更改后的 URI 匹配的新 location

break

停止处理当前的 http_rewrite 指令集,如同 break 指令;

redirect

返回临时重定向,状态码为 302;如果 replacement 字符串不以 "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/" 位置内,last 标志应替换为 break,否则 Angie 将循环 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

启用或禁用将 http_rewrite 模块指令处理结果记录到 error_lognotice 级别。

set#

语法

set $variable value

默认值

上下文

server, location, if

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

uninitialized_variable_warn#

语法

uninitialized_variable_warn on | off

默认值

uninitialized_variable_warn on;

上下文

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