ngx_http_rewrite_module

編譯自:
ngx_http_rewrite_module

目錄

  1. 模塊指令:

    • break
    • if
    • return
    • rewrite
    • rewrite_log
    • set
    • uninitialized_variable_warn
  2. 內(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_redirectport_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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市舀射,隨后出現(xiàn)的幾起案子窘茁,更是在濱河造成了極大的恐慌,老刑警劉巖脆烟,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件山林,死亡現(xiàn)場離奇詭異,居然都是意外死亡邢羔,警方通過查閱死者的電腦和手機(jī)驼抹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拜鹤,“玉大人框冀,你說我怎么就攤上這事∶舨荆” “怎么了明也?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵宣虾,是天一觀的道長。 經(jīng)常有香客問我温数,道長绣硝,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任撑刺,我火速辦了婚禮鹉胖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘够傍。我一直安慰自己甫菠,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布王带。 她就那樣靜靜地躺著,像睡著了一般市殷。 火紅的嫁衣襯著肌膚如雪愕撰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天醋寝,我揣著相機(jī)與錄音搞挣,去河邊找鬼。 笑死音羞,一個胖子當(dāng)著我的面吹牛囱桨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嗅绰,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼舍肠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了窘面?” 一聲冷哼從身側(cè)響起翠语,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎财边,沒想到半個月后肌括,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡酣难,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年谍夭,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片憨募。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡紧索,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出菜谣,到底是詐尸還是另有隱情齐板,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站甘磨,受9級特大地震影響橡羞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜济舆,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一卿泽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧滋觉,春花似錦签夭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至我纪,卻和暖如春慎宾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背浅悉。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工趟据, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人术健。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓汹碱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親荞估。 傳聞我的和親對象是個殘疾皇子咳促,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容