ngx_http_rewrite_module 模組

指令
     break
     if
     return
     rewrite
     rewrite_log
     set
     uninitialized_variable_warn
內部實作

ngx_http_rewrite_module 模組用於使用 PCRE 正規表示式變更請求 URI、傳回重新導向,以及有條件地選取組態。

breakifreturnrewriteset 指令會依下列順序處理:

指令

語法 break;
預設值
Context serverlocationif

停止處理目前設定的 ngx_http_rewrite_module 指令。

如果指令是在 location 內指定,則會在此 location 中繼續處理請求。

範例

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

語法 if (condition) { ... }
預設值
Context serverlocation

評估指定的 condition。如果為 true,則會執行在此模組中,於大括號內指定的指令,且請求會被指派 if 指令內的組態。if 指令內的組態會繼承自先前的組態層級。

條件可以是下列任一項:

範例

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 code [text];
return code URL;
return URL;
預設值
Context serverlocationif

停止處理並將指定的 code 傳回給用戶端。非標準代碼 444 會關閉連線,而不傳送回應標頭。

從 0.8.42 版開始,可以指定重新導向 URL (適用於代碼 301、302、303、307 和 308) 或回應本文 text (適用於其他代碼)。回應本文文字和重新導向 URL 可以包含變數。在特殊情況下,可以將重新導向 URL 指定為此伺服器的本機 URI,在這種情況下,完整重新導向 URL 會根據請求結構描述 ($scheme) 和 server_name_in_redirectport_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 regex replacement [flag];
預設值
Context serverlocationif

如果指定的正規表示式符合請求 URI,則會根據 replacement 字串中的指定變更 URI。rewrite 指令會依其在組態檔中出現的順序依序執行。可以使用旗標終止指令的進一步處理。如果取代字串以「http://」、「https://」或「$scheme」開頭,則處理會停止,並將重新導向傳回給用戶端。

可選的 flag 參數可以是下列其中一項:

last
停止處理目前設定的 ngx_http_rewrite_module 指令,並開始搜尋符合變更後 URI 的新 location;
break
停止處理目前設定的 ngx_http_rewrite_module 指令,如同 break 指令一樣;
redirect
傳回代碼為 302 的臨時重新導向;如果取代字串不是以「http://」、「https://」或「$scheme」開頭,則會使用此旗標;
permanent
傳回代碼為 301 的永久重新導向。

完整重新導向 URL 會根據請求結構描述 ($scheme) 和 server_name_in_redirectport_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;
}

如果 replacement 字串包含新的請求引數,則會在其後附加先前的請求引數。如果不需要,則在取代字串的結尾加上問號,以避免附加這些引數,例如

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

如果正規表示式包含「}」或「;」字元,則整個表示式應該以單引號或雙引號括住。

語法 rewrite_log on | off;
預設值
rewrite_log off;
Context httpserverlocationif

啟用或停用將 ngx_http_rewrite_module 模組指令處理結果記錄到 notice 層級的 error_log 中。

語法 set $variable value;
預設值
Context serverlocationif

為指定的 variable 設定 valuevalue 可以包含文字、變數及其組合。

語法 uninitialized_variable_warn on | off;
預設值
uninitialized_variable_warn on;
Context httpserverlocationif

控制是否記錄關於未初始化變數的警告。

內部實作

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