zoukankan      html  css  js  c++  java
  • Nginx 模块

    原文地址

    ngx_http_rewrite_module 模块用于通过 PCRE 正则表达式改变请求 URI,返回重定向并可以有条件地选择配置。

    break、if、return、rewrite 以及 set 指令的处理顺序如下:

    • 首先按顺序执行在 server 块中指定的该模块的指令
    • 然后循环:
      • 根据请求 URI 搜索 location
      • 该模块的指令在 location 内指定时,按顺序执行
      • 如果请求 URI 被重写,则重复循环但不超过 10 次。

    1. 指令

    break

    break 的可用上下文有:server、location、if。用于停止处理当前的 ngx_http_rewrite_module 指令集合。

    如果指令是在 location 中声明的,则在该 location 中继续处理请求。

    示例:

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

    if

    if 的可用上下文有:server、location。如果指定的条件为 true,则在花括号内指定的模块指令被执行,并且该请求被分配给 if 指令内的配置。if 指令中的配置从先前的配置级别继承。

    条件可能是以下任何一种情况:

    • 变量名;如果变量值是空字符串或“0”则为 FALSE。注意,在 1.0.1 版本之前,任何以“0”开头的字符串都会被当做 FALSE。
    • 使用“=”和“!=”的变量跟字符串的比较
    • 使用“~”(区分大小写匹配)和“~*”(不区分大小写匹配)运算符将变量与正则表达式匹配。正则表达式可以包含捕获,之后可以通过 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 的可用上下文有:server、location、if。
    停止处理并向客户端返回指定的代码。非标代码 444 会关闭连接并且不会发送响应头。

    从 0.8.42 版本开始,可以指定重定向 URL(代码 301,302,303,307 和 308)或响应正文文本(用于其他代码)。响应正文文本和重定向 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

    rewrite 的可用上下文有:server、location、if。

    如果指定的正则表达式与请求 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_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;
    }

    如果替换字符串包含新的请求参数,之前的请求参数会追加在新请求参数后面。如果不希望这样,那么在替换字符串的末尾添加一个问号可以避免添加它们,例如:

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

    如果正则表达式包含“}”或“;”字符,整个正则表达式需要放在单引号或双引号里。

    rewrite_log

    语法:rewrite_log on | off;
    默认值:rewrite_log off;
    rewrite_log 的可用上下文有: http、server、location、if。

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

    set

    语法:set $variable value;
    默认值:无

    set 的可用上下文有:server、location、if。

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

    uninitialized_variable_warn

    语法:uninitialized_variable_warn on | off
    默认值:uninitialized_variable_warn on;

    uninitialized_variable_warn 的可用上下文有:http、server、location、if。

    是否将未初始化变量导致的警告写入日志。

    2. 内部实现

    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
  • 相关阅读:
    C#’s ~ vs Java’s finalize
    做Java开发这一年
    assertThat, assertEquals, assertTrue
    给Cuke4Duke添加一个AfterAll标签(一):使用Cuke4Duke
    心理问题的根源
    何谓数学
    人生谁看透
    人本主义与自由意志
    哲学的基本问题
    贫穷与教育
  • 原文地址:https://www.cnblogs.com/kika/p/10851656.html
Copyright © 2011-2022 走看看