目錄:
-
模塊指令:
- break
- if
- return
- rewrite
- rewrite_log
- set
- uninitialized_variable_warn
內(nèi)部實現(xiàn)
簡介
ngx_http_rewrite_module 模塊可用于修改 HTTP 請求的 URI锦溪,支持正則表達(dá)式匹配屠缭。修改之后丛塌,返回重定向指令确买。
該模塊也支持條件式地選擇配置澜倦。
ngx_http_rewrite_module 模塊的指令按如下順序進(jìn)行處理:
- 在 server 區(qū)塊中股冗,按順序執(zhí)行翅阵;
- 重復(fù)執(zhí)行:
- 根據(jù) HTTP 請求的 URI惠勒,尋找對應(yīng)的 location角钩;
- 在找到的 location 中吝沫,ngx_http_rewrite_module 模塊的指令按順序執(zhí)行;
- 在 location 區(qū)塊中递礼,如果 HTTP 請求的 URI 被重寫惨险,將重復(fù)整個步驟,但不超過 10 次脊髓。
模塊指令
Syntax: break;
Default: —
Context: server, location, if
停止當(dāng)前 ngx_http_rewrite_module
模塊指令集的處理辫愉。
如果該指令是在 location 中,那么在這個 location 中将硝,對請求的進(jìn)一步處理將繼續(xù)進(jìn)行恭朗。
例子:
if ($slow) {
limit_rate 10k;
break;
}
Syntax: if (condition) { ... }
Default: —
Context: server, location
若條件判斷為真屏镊,則執(zhí)行花括號內(nèi)的指令,并且將括號內(nèi)的配置應(yīng)用到 HTTP 請求上痰腮。if 指令中的配置是從上一層配置中繼承的而芥。
條件判斷式的有如下種類:
- 一個變量名;當(dāng)變量值為0膀值,或為空字符串時棍丐,條件為 false;(1.0.1 版之前沧踏,以0開頭的字符串被判斷為 false)
- 對字符串變量進(jìn)行比較歌逢,使用
=
或!=
; - 測試一個變量是否與一個正則表達(dá)式匹配翘狱,正則表達(dá)式前使用
~
或~*
操作符趋翻,~*
對大小寫不敏感。正則表達(dá)式可包含“反向引用”盒蟆,使用 $1..$9 引用匹配的字符串踏烙。也支持!~
或!~*
操作符,表示不匹配历等。如果正則表達(dá)式中含有}
或;
符號讨惩,應(yīng)使用單引號或雙引號將正則表達(dá)式引用起來。 - 測試一個文件是否存在:
-f
and!-f
寒屯; - 測試一個目錄是否存在:
-d
and!-d
荐捻; - 測試一個文件、目錄寡夹、或符號鏈接文件是否存在:
-e
and!-e
处面; - 測試一個文件是否可執(zhí)行:
-x
and!-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 是一個內(nèi)建變量菩掏,由 valid_referers 指令進(jìn)行設(shè)置魂角。
Syntax: return code [text];
return code URL;
return URL;
Default: —
Context: server, location, if
停止處理,返回狀態(tài)碼 code 給客戶端智绸。返回 444 將關(guān)閉該連接野揪,而且不發(fā)送響應(yīng) header。
從 0.8.42 版開始瞧栗,可指定重定向 URL (限于 301斯稳,302,303迹恐,307 狀態(tài)碼)挣惰,或是指定響應(yīng) body 為 text (對于除了前面的狀態(tài)碼之外的所有狀態(tài)碼)。不論是指定重定向 URL 還是 text,其中都可以包含變量憎茂。重定向的 URL 可以指定為基于本機(jī)的 URI唆涝,這時,完整的重定向 URL 是根據(jù)請求 scheme ($scheme)唇辨,server_name_in_redirect 和 port_in_redirect 指令來構(gòu)建的。
對于臨時重定向能耻,一個 URL
和 302 狀態(tài)碼可被指定為唯一的參數(shù)赏枚。這樣的參數(shù)必須以 “http://”, “https://”, or “$scheme” 為起始。URL
可包含變量晓猛。
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.
另可參見 error_page 指令饿幅。
Syntax: rewrite regex replacement [flag];
Default: —
Context: server, location, if
如果 regex
匹配了一個請求的 URI,該 URI 被替換為 replacement
戒职。rewrite
指令在配置文件中按照出現(xiàn)的順序執(zhí)行栗恩。可使用 flag
中止進(jìn)一步的處理洪燥。如果 replacement
以 “http://”, “https://” 為起始磕秤,將中止處理,并返回重定向指令給客戶端捧韵。
flag 參數(shù)的值有:
last:停止當(dāng)前
ngx_http_rewrite_module
模塊指令集的處理市咆,并為修改后的 URI 尋找新的匹配的 location。break:停止當(dāng)前
ngx_http_rewrite_module
模塊指令集的處理再来,與 break 指令作用相同蒙兰。redirect:返回 “臨時重定向” 及 302 狀態(tài)碼;僅當(dāng)
replacement
不以 “http://”, “https://” 為起始時芒篷,該 flag 才生效搜变。permanent:返回 “永久重定向” 及 301 狀態(tài)碼
例子:
server {
...
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
return 403;
...
}
但如果這些指令被放入 “/download/” location 區(qū)塊中,應(yīng)將 last
flag 替換為 break
针炉,否則 nginx 會不斷循環(huán)挠他,達(dá)到 10 次后,返回 500 error篡帕。
location /download/ {
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
return 403;
}
如果 replacement
包含請求參數(shù)绩社,原來的請求參數(shù)將被追加在后面。如果不希望追加原來的請求參數(shù)赂苗,可在 replacement
字符串的末尾添加一個 “?” 符號愉耙,例如:
rewrite ^/users/(.*)$ /show?user=$1? last;
再提醒一次,如果正則表達(dá)式中含有 “}” 或 “;” 符號拌滋,應(yīng)使用單引號或雙引號將正則表達(dá)式引用起來朴沿。
Syntax: rewrite_log on | off;
Default:
rewrite_log off;
Context: http, server, location, if
是否開啟 ngx_http_rewrite_module
模塊的日志,如果開啟,該模塊的日志將被記錄進(jìn)入 error_log 中赌渣,日志的級別為 notice
魏铅。
Syntax: set $variable value;
Default: —
Context: server, location, if
為變量賦值。value
可包含:文本坚芜,變量览芳,或文本和變量的組合。
Syntax: uninitialized_variable_warn on | off;
Default:
uninitialized_variable_warn on;
Context: http, server, location, if
當(dāng)有變量沒有初始化時鸿竖,是否記錄日志沧竟。
內(nèi)部實現(xiàn)
ngx_http_rewrite_module
模塊的指令在配置階段被編譯進(jìn)內(nèi)部指令中,然后在對請求進(jìn)行處理時被解釋執(zhí)行缚忧。解釋指令的解釋器是一個簡單的虛擬棧機(jī)器悟泵。
例如,如下指令:
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 指令并沒有沒翻譯糕非,這是因為 limit_rate
指令不屬于 ngx_http_rewrite_module
模塊。由于有 if 區(qū)塊球榆,一份獨立的配置將被創(chuàng)建朽肥,如果該 if 區(qū)塊的條件判斷為真,那么其中的配置將應(yīng)用到請求中持钉,在這里的配置是 limit_rate
= 10k鞠呈。
指令:
rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;
可進(jìn)一步優(yōu)化,將第一個 “/” 放入括號中:
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
對應(yīng)的指令為:
match of regular expression
copy $1
copy "/mp3/"
copy $2
copy ".mp3"
end of regular expression
end of code
減少了 copy "/" 這一步驟右钾。
版權(quán)信息:
本文編譯自 nginx.org 的部分蚁吝,遵循其原來的 licence 聲明: 2-clause BSD-like license