Nginx ngx_http_rewrite_module模块基本指令整理

  categories:nginx  author:

原创文章,转载请指明出处并保留原文url地址

本文主要针对nginx的ngx_http_rewrite_module模块做简单介绍,本文具体包括如下指令:

break,if,return,rewrite,rewrite_log,set,uninitialized_variable_warn

ngx_http_rewrite_module模块允许通过正则表达式修改用户请求的uri, 返回从定向,并有条件的选择配置等。

该模块的指令按照如下顺序进行处理

该模块制定的指令在选定的server层级上进行处理(不跨越server,若是从本server处理完成到另外server则开始别的过程,同本级server没有关系了)

请求处理在一个选定的location中被处理

本模块中制定的指令在选定的location中被处理,如果他们改变了uri则一个新的location将被从新选定, 然后进行处理。如果处理的循环达到10次,系统将返回500错误信息(服务器内部错误)

Nginx原文:

The ngx_http_rewrite_module module allows to change URIs using regular expressions, return redirects, and conditionally select configurations.

The ngx_http_rewrite_module module directives are processed in the following order:

    the directives of this module specified on the server level are processed;

    a location for a request is searched;

    the directives of this module specified in the selected location are processed, and if they changed a URI, a new location is searched for the new URI. This cycle may be repeated up to 10 times after which the error 500 (Internal Server Error) is returned.

1. break;

syntax:

break;

default:

context:

server, location, if

停止当前ngx_http_rewrite_module模块指令集的处理工作

示例如下:

if ($slow) {

        limit_rate 10k;

        break;

}

Nginx原文:

Stops processing the current set of ngx_http_rewrite_module directives.

Example:

    if ($slow) {

        limit_rate 10k;

        break;

    }

2. if

syntax:

if (condition) { … }

default:

context:

server, location

指定的条件进行判断。如果TRUE,该模块在括号中指定的命令被执行,请求执行的相关配置信息使用相应的if指令内部配置信息。如果if内置的配置信息继承自前一个级别的配置信息

If语句的条件可以下面的任何一个

变量名称;false值如果一个变量的值是一个空字符串或“0”;

在1.0.1版本,任何以“0”开始的字符串被认为是falase。

使用“=”和“!=”运算符对一个变量同一个字符串相比较。

针对变量同正则表达式匹配使用“~”(区分大小写匹配)和“~ *”(不区分大小写匹配)运算符号。正则表达式可以包含捕获功能,可在后面使用$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;

    }

    A value of the embedded variable $invalid_referer is set by the valid_referers directive.

Nginx原文:

The specified condition is evaluated. If true, the directives of this module specified inside the braces are executed, and a request is assigned the configuration inside the if directive. Configurations inside the if directives are inherited from the previous configuration level.

A condition may be any of the following:

    a variable name; false if the value of a variable is an empty string or “0”;

        Before version 1.0.1, any string starting with “0” was considered a false value.

    comparing a variable with a string using the “=” and “!=” operators;

    matching a variable against a regular expression using the “~” (for case-sensitive matching) and “~*” (for case-insensitive matching) operators. Regular expressions can contain captures that are made available for later reuse in the $1..$9 variables. Negative operators “!~” and “!~*” are also available. If a regular expression includes the characters “}” or “;”, the whole expressions should be enclosed in single or double quotes.

    checking a file existence with the “-f” and “!-f” operators;

    checking a directory existence with the “-d” and “!-d” operators;

    checking a file, directory, or symbolic link existence with the “-e” and “!-e” operators;

    checking for an executable file with operators “-x” and “!-x” operators.

Examples:

    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;

    }

    A value of the embedded variable $invalid_referer is set by the valid_referers directive.

3. return

syntax:

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

default:

context:

server, location, if

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

从版本0.8.42开始,既可以指定重定向的URL(码301,302,303,和307),或响应正文文本(其他代码)。响应正文文本或URL重定向可以包含变量。作为一个特殊的情况,重定向URL可以指定为本server内的一个局部URI,在这种情况下,将完整的URL是根据请求scheme($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。

307的代码不被看做重定向到版本直到1.1.16和1.0.13版本为止

Nginx原文:

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

Starting from version 0.8.42, it is possible to specify either the URL of redirect (for codes 301, 302, 303, and 307), or the text of a response body (for other codes). A response body text or URL of redirect can contain variables. As a special case, a URL of redirect can be specified as a URI local to this server, in which case the full URL of redirect is formed according to the request scheme ($scheme) and the server_name_in_redirect and port_in_redirect directives.

In addition, a URL for temporary redirect with the code 302 can be specified as the sole parameter. Such a parameter should start with the string “http://”, “https://”, or “$scheme”. A URL can contain variables.

    Only the following codes could be returned before version 0.7.51: 204, 400, 402 — 406, 408, 410, 411, 413, 416, and 500 — 504.

    The code 307 was not treated as a redirect until versions 1.1.16 and 1.0.13.

4. rewrite

syntax:

rewrite   regexreplacement [flag];

default:

context:

server, location, if

如果指定的正则表达式同uri匹配, 这个uri被相应表达式中替换字符串替换。重写指令根据重写指令在配置文件中出现的次序依次被执行。Flags(标志位)可能会终止处理指令的进一步处理。如果替换字符串以“http://”或者“https://”开始则处理被停止, 返回从定向语句给客户端。

一个可选的标志参数可以是如下:

last(最后的):

停止当前ngx_http_rewrite_module指令集的处理, 搜索一个新的匹配的location(在进行相关的处理工作,里面有可能还有rewrite,也可能没有, 若是有重复相关过程, 但是总的重复次数是10次,超过后服务器返回500错误信息);

break

停止处理当前ngx_http_rewrite_module指令集(中断了,不再继续找了, 其他location了);

redirect

返回代码为302的临时重定向;如果一个替换字符串不以“http://”和“https://”开头;

permanent

返回一个永久重定向的代码301。

重定向的完整URL是根据请求scheme ($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;

        …

    }

但如果这些指令被放在“/下载/”的location中,最后的标志应为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;

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

Nginx原文:

If the specified regular expression matches a URI, the URI is changed as specified in the replacement string. The rewrite directives are executed sequentially in order of their appearance in the configuration file. Flags make it possible to terminate further processing of directives. If a replacement string starts with “http://” or “https://”, the processing stops and a redirect is returned to a client.

An optional flag parameter can be one of:

last

    stops processing the current set of ngx_http_rewrite_module directives followed by a search for a new location matching the changed URI;

break

    stops processing the current set of ngx_http_rewrite_module directives;

redirect

    returns a temporary redirect with the code 302; used if a replacement string does not start with “http://” or “https://”;

permanent

    returns a permanent redirect with the code 301.

The full URL of redirects is formed according to the request scheme ($scheme) and the server_name_in_redirect and port_in_redirect directives.

Example:

    server {

        …

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

        rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra  last;

        return  403;

        …

    }

But if these directives are put inside the “/download/” location, the last flag should be replaced by break, otherwise nginx will make 10 cycles and return the error 500:

    location /download/ {

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

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

        return  403;

    }

If a replacement string includes the new request arguments, the previous request arguments are appended after them. If this is undesired, putting a question mark at the end of a replacement string avoids having them appended, for example:

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

If a regular expression includes the characters “}” or “;”, the whole expressions should be enclosed in single or double quotes.

5. rewrite_log

syntax:

rewrite_log         on | off;

default:

rewrite_log off;

context:

http, server, location, if

启用或禁用将ngx_http_rewrite_module模块指令处理结果以notice日志级别记录日志到error_log日志中的功能

Nginx原文:

Enables or disables logging of ngx_http_rewrite_module module directives processing results into the error_log at the notice level.

6. set

syntax:

set   variablevalue;

default:

context:

server, location, if

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

Nginx原文:

Sets a value for the specified variable. A value can contain text, variables, and their combination.

7. uninitialized_variable_warn

syntax:

uninitialized_variable_warn  on | off;

default:

uninitialized_variable_warn on;

context:

http, server, location, if

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

Nginx原文:

Controls whether warnings about uninitialized variables are logged.

内部的实现

该ngx_http_rewrite_module模块指令在配置阶段编译成内部指令(一个解析器),在用户请求到来时处理请求。解析器是一个简单的虚拟堆栈机(http://en.wikipedia.org/wiki/Stack_machine)。

示例如下:

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

并没有说上面提到的限速指令同ngx_http_rewrite_module模块无关。一个单独的配置将被创建。如果if条件成立,请求将同这个配置文件关联,这个速度限制为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

Internal Implementation

The ngx_http_rewrite_module module directives are compiled during the configuration stage into internal instructions that are interpreted during request processing. An interpreter is a simple virtual stack machine.

For example, the directives

    location /download/ {

        if ($forbidden) {

            return 403;

        }

        if ($slow) {

            limit_rate 10k;

        }

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

    }

will be translated into these 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

Note that there are no instructions for the limit_rate directive above as it is unrelated to the ngx_http_rewrite_module module. A separate configuration is created for the if block. If the condition holds true, a request is assigned this configuration where limit_rate equals to 10k.

The directive

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

can be made smaller by one instruction if the first slash in the regular expression is put inside the parentheses:

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

The corresponding instructions will then look like this:

    match of regular expression

    copy $1

    copy "/mp3/"

    copy $2

    copy ".mp3"

    end of regular expression

    end of code



快乐成长 每天进步一点点      京ICP备18032580号-1