In-depth understanding of Nginx's rewrite module

The rewrite module is the ngx_http_rewrite_modulemodule. Its main function is to rewrite the request URI, which is the module installed by default in Nginx. The rewrite module will match the rewrite URI according to the PCRE regularity, and then initiate an internal jump to match the location, or directly do a 30x redirect back to the client.

Instruction execution order

  1. First execute the rewrite module instructions in the server block in sequence to get the request URI after rewrite
  2. Then loop through the following instructions

    > 如果没有遇到中断循环标志,此循环最多执行10次,但是我们可以使用break指令来中断rewrite后的新一轮的循环
    

(1). According to the request URI after rewrite, match the defined location block

(2). Sequentially execute the rewrite module instructions in the matched location

instruction

break

Context: server, location, if

Stop executing the ngx_http_rewrite_module instruction set, but the instructions of other modules are not affected
.

server {
    listen 8080;
    # 此处 break 会停止执行 server 块的 return 指令(return 指令属于rewrite模块) # 如果把它注释掉 则所有请求进来都返回 ok
    break; return 200 "ok"; location = /testbreak { break; return 200 $request_uri; proxy_pass http://127.0.0.1:8080/other; } location / { return 200 $request_uri; } } # 发送请求如下 # curl 127.0.0.1:8080/testbreak # /other # 可以看到 返回 `/other` 而不是 `/testbreak`,说明 `proxy_pass` 指令还是被执行了 # 也就是说 其他模块的指令是不会被 break 中断执行的 # (proxy_pass是ngx_http_proxy_module的指令) 

if

Context: server, location

Decide whether to execute the content in the if block statement according to the specified conditions

Several judgment conditions in if

  1. One 变量名, if the value of the variable $ variable is an empty string or the string "0", it is false
  2. 变量Comparison with a string Equal to (=) Not equal to (! =) 注意此处不要把相等当做赋值语句啊
  3. 变量And a regular expression pattern matching may be operator ( ~ case-sensitive matching regular,  ~*case-insensitive matching regular ,  !~ !~*non both front)
  4. Check if the file exists -f( Use  ) and  !-f(Does not exist)
  5. Check whether the path exists  -d(exist) and  !-d(not exist), and then judge whether it can be a string or a variable
  6. Check whether the file, path, or link file exists  -e(exists) and  !-e(exists), and then judge whether it can be a string or a variable
  7. Check whether the file is executable  -x(executable) and (unexecutable), and  !-xthen judge whether it can be a string or a variable

Note that items 1, 2, and 3 above must be judged as variables. 4, 5, 6, 7 can be either variables or strings. The basic usage of -f / -d / -e / -x is consistent with bash .

set $variable "0"; 
if ($variable) { # 不会执行,因为 "0" 为 false break; } # 使用变量与正则表达式匹配 没有问题 if ( $http_host ~ "^star\.igrow\.cn$" ) { break; } # 字符串与正则表达式匹配 报错 if ( "star" ~ "^star\.igrow\.cn$" ) { break; } # 检查文件类的 字符串与变量均可 if ( !-f "/data.log" ) { break; } if ( !-f $filename ) { break; }

return

Context: server, location, if

return code [text];
return code URL;
return URL;

Stop processing and codereturn the specified code to the client. The non-standard codecode 444 closes the connection without sending a response header.

Starting from the 0.8.42version, the  return statement can specify the redirection  url (status codes can be as follows 301,302,303,307),
can also specify the response text content for other status codes, and the redirected urland response text can be included 变量.

There is a special case, is redirected urlcan be specified for this local server urI, this is the case, nginxwill be based on protocol requests $schemeserver_name_in_redirect and  port_in_redirectautomatically generates a complete  url (to be described here is server_name_in_redirect and port_in_redirect instruction indicating whether the serverblock  server_name and  listen the port For redirectuse)

# return code [text]; 返回 ok 给客户端
location = /ok {
    return 200 "ok";
}

# return code URL; 临时重定向到 百度 location = /redirect { return 302 http://www.baidu.com; } # return URL; 和上面一样 默认也是临时重定向 location = /redirect { return http://www.baidu.com; }

rewrite

Context: server, location, if

rewrite regex replacement [flag];

rewrite The instruction uses the specified regular expression regexto match the request, urIand if the match is successful, the replacementchange is used URI. rewriteThe instructions are executed in the order they appear in the configuration file. The flagflag can be used to terminate further processing of the instruction. If the replacement string replacementstarts with http://, https://or $ scheme, it stops processing subsequent content and redirects directly back to the client.

String rewritten in the first casehttp://

location / {
    # 当匹配 正则表达式 /test1/(.*)时 请求将被临时重定向到 http://www.$1.com
    # 相当于 flag 写为 redirect
    rewrite /test1/(.*) http://www.$1.com; return 200 "ok"; } # 在浏览器中输入 127.0.0.1:8080/test1/baidu # 则临时重定向到 www.baidu.com # 后面的 return 指令将没有机会执行了

The second case rewrites the string withouthttp://

location / {
    rewrite /test1/(.*) www.$1.com;
    return 200 "ok"; } # 发送请求如下 # curl 127.0.0.1:8080/test1/baidu # ok # 此处没有带http:// 所以只是简单的重写。请求的 uri 由 /test1/baidu 重写为 www.baidu.com # 因为会顺序执行 rewrite 指令 所以 下一步执行 return 指令 响应了 ok 

The four flags of rewrite

  1. last
    Stop processing the current ngx_http_rewrite_moduleinstruction set and start searching for matches with the changed URIones location; (because last means "continue" in English, it will continue to try to match and jump to other locations)
  2. break
    Stop processing the current ngx_http_rewrite_moduleinstruction set, just like the breakinstructions above ; ( break is "interrupt stop" )
  3. redirect
    Return 302 for a temporary redirect. (It can be understood as "temporary rent")
  4. permanent
    Return 301 permanent redirect. (It can be understood as "moving a new home")
# 没有rewrite 后面没有任何 flag 时就顺序执行 
# 当 location 中没有 rewrite 模块指令可被执行时 就重写发起新一轮location匹配
location / {
    # 不加 flag, 默认顺序执行
    rewrite ^/test1 /test2; rewrite ^/test2 /test3; # 此处发起新一轮location匹配 uri为/test3 } location = /test2 { return 200 "/test2"; } location = /test3 { return 200 "/test3"; } # 发送如下请求 # curl 127.0.0.1:8080/test1 # /test3
The difference between last and break

Last and break, they will terminate the execution of other rewrite module instructions in this location,
but last immediately initiates a new round of location matching and break will not

location / {
    rewrite ^/test1 /test2;
    rewrite ^/test2 /test3 last; # 此处发起新一轮location匹配 uri为/test3 rewrite ^/test3 /test4; proxy_pass http://www.baidu.com; } location = /test2 { return 200 "/test2"; }  location = /test3 { return 200 "/test3"; } location = /test4 { return 200 "/test4"; } # 发送如下请求 # curl 127.0.0.1:8080/test1 # /test3 当如果将上面的 location / 改成如下代码 location / { rewrite ^/test1 /test2;  # 此处 不会 发起新一轮location匹配;当是会终止执行后续rewrite模块指令 重写后的uri为 /more/index.html rewrite ^/test2 /more/index.html break; rewrite /more/index\.html /test4; # 这条指令会被忽略  # 因为 proxy_pass 不是rewrite模块的指令 所以它不会被 break终止 proxy_pass https://www.baidu.com; } # 发送如下请求 # 浏览器输入 127.0.0.1:8080/test1 # 代理到 百度产品大全页面 https://www.baidu.com/more/index.html;
 

Request parameters after rewrite

If the replacement string replacementcontains new request parameters, the previous request parameters are appended after them. If you do n’t want the previous parameters, replacement put a question mark at the end of the replacement string  to avoid appending them .

# 由于最后加了个 ?,原来的请求参数将不会被追加到rewrite之后的url后面 
rewrite ^/users/(.*)$ /show?user=$1? last;

rewrite_log

Context: http, server, location, if

Open or close  rewritethe log of module instruction execution. If it is enabled, the rewrite will record notice the log of the next level to nginx the  error_log default, which is closed by default off

Syntax: rewrite_log on | off;

set

Context: server, location, if

Set the value of the specified variable. Variable values ​​can contain text, variables, or a combination of them.

location / {
    set $var1 "host is ";
    set $var2 $host; set $var3 " uri is $request_uri"; return 200 "response ok $var1$var2$var3"; } # 发送如下请求 # curl 127.0.0.1:8080/test # response ok host is 127.0.0.1 uri is /test

uninitialized_variable_warn

Context: http, server, location, if

Controls whether to log warnings about uninitialized variables. On by default

 

Internal realization

The ngx_http_rewrite_modulemodule instructions are compiled into the requested processing during the configuration phase to interpret internal instructions. The interpreter is a simple virtual stacking machine.

For example, the instruction

location /download/ {
    if ($forbidden) {
        return 403;
    }

    if ($slow) {
        limit_rate 10k;
    }

    rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;
}

Will be translated into the following instructions:

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

Please note that the limit_rate instruction  above does not have any  instructions because it has nothing to do  with the ngx_http_rewrite_modulemodule . Create a separate configuration for the if block . If the condition is true, a request will be allocated for this configuration, whichlimit_rate is equal to 10k.

instruction

rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;

If the first slash in the regular expression is placed in parentheses, it can be simplified:

rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;

The corresponding instructions will be as follows:

match of regular expression
copy $1
copy "/mp3/"
copy $2
copy ".mp3"
end of regular expression
end of code

 


location (non-rewrite module)

grammar

serverUsed in blocks, such as:

  • server {
  • location expression {
  • }
  • }

location expression type

  • If you write a path directly, it matches the path
  • ~ Means perform a regular match, case sensitive
  • ~ * Means perform a regular match, not case sensitive
  • ^ ~ Indicates common character matching. Use prefix matching. If the match is successful, it will no longer match other locations.
  • = Perform exact character matching. That is an exact match.

priority

    1. The equal sign type (=) has the highest priority. Once the match is successful, no other matches are found.
    2. ^ ~ Type expression. Once the match is successful, no other matches are found.
    3. Regular expression types (~~ *) take precedence. If the regularity of multiple locations can match, the longest regular expression is used.
    4. Regular string matching type. Match by prefix.

Guess you like

Origin www.cnblogs.com/sunsky303/p/12718378.html