If Is Evil

介紹

當(dāng)在location區(qū)塊中使用 if 指令的時(shí)候會(huì)有一些問題, 在某些情況下它并不按照你的預(yù)期運(yùn)行而是做一些完全不同的事情. 而在另一些情況下他甚至?xí)霈F(xiàn)段錯(cuò)誤. 一般來說避免使用 if 指令是個(gè)好主意谜慌。

在 location 區(qū)塊里if指令下唯一100%安全的指令應(yīng)該只有:

  • return …;
  • rewrite … last;

除此以外的指令都可能導(dǎo)致不可預(yù)期的行為, 包括詭異的發(fā)出段錯(cuò)誤信號(hào)(SIGSEGV)已慢。

要著重注意的是if的行為不是反復(fù)無常的, 給出兩個(gè)條件完全一致的請(qǐng)求, Nginx并不會(huì)出現(xiàn)一個(gè)正常工作而一個(gè)請(qǐng)求失敗的隨機(jī)情況, 在明晰的測試和理解下 if 是完全可用的. 盡管如此, 在這里還是建議使用其他指令。

總有一些情況你無法避免去使用 if 指令, 比如你需要測試一個(gè)變量, 而它沒有相應(yīng)的配置指令禾蚕。

if ($request_method = POST) {
  return 405;
}
if ($args ~ post=140){
  rewrite ^ http://example.com/ permanent;
}

如何替換掉if

使用 try_files 如果他適合你的需求. 在其他的情況下使用 “return …” 或者 “rewrite … last”. 還有一些情況可能要把 if 移動(dòng)到 server 區(qū)塊下(只有當(dāng)其他的rewrite模塊指令也允許放在的地方才是安全的)。

如下可以安全地改變用于處理請(qǐng)求的 location。

location / {
  error_page 418 = @other;
  recursive_error_pages on;
 
  if ($something) {
    return 418;
  }
 
  # some configuration
  ...
}
 
location @other {
  # some other configuration
  ...
}

在某些情況下使用嵌入腳本模塊(嵌入perl或者其他一些第三方模塊)處理這些腳本更佳劳澄。

例子

以下是一些例子用來解釋為什么if是邪惡的. 非專業(yè)人事指, 請(qǐng)勿模仿!

# 這里收集了一些出人意料的坑爹配置來展示 location 中的 if 指令是萬惡的

# 只有第二個(gè) header 才會(huì)在響應(yīng)中展示
# 這不是Bug, 只是他的處理流程如此
 
location /only-one-if {
  set $true 1;
 
  if ($true) {
    add_header X-First 1;
  }
 
  if ($true) {
    add_header X-Second 2;
  }
 
  return 204;
}
 
# 因?yàn)閕f, 請(qǐng)求會(huì)在未改變uri的情況下下發(fā)送到后臺(tái)的 '/'
 
location /proxy-pass-uri {
  proxy_pass http://127.0.0.1:8080/;
 
  set $true 1;
 
  if ($true) {
    # nothing
  }
}
 
# 因?yàn)閕f, try_files 失效
 
location /if-try-files {
  try_files  /file  @fallback;
 
  set $true 1;
 
  if ($true) {
    # nothing
  }
}
 
# nginx 將會(huì)發(fā)出段錯(cuò)誤信號(hào)(SIGSEGV)
 
location /crash {
 
  set $true 1;
 
  if ($true) {
    # fastcgi_pass here
    fastcgi_pass  127.0.0.1:9000;
  }
 
  if ($true) {
    # no handler here
  }
}
 
# alias with captures isn't correcly inherited into implicit nested location created by if
# alias with captures 不能正確的繼承到由if創(chuàng)建的隱式嵌入的location 
 
location ~* ^/if-and-alias/(?<file>.*) {
  alias /tmp/$file;
 
  set $true 1;
 
  if ($true) {
    # nothing
  }
}

為什么會(huì)這樣且到現(xiàn)在都沒修復(fù)這些問題?

if 指令是 rewrite 模塊中的一部分, 是實(shí)時(shí)生效的指令.另一方面來說, nginx 配置大體上是陳述式的.在某些時(shí)候用戶出于特殊是需求的嘗試, 會(huì)在if里寫入一些非rewrite指令, 這直接導(dǎo)致了我們現(xiàn)處的情況. 大多數(shù)情況下他可以工作, 但是…看看上面。
看起來唯一正確的修復(fù)方式是完全禁用if中的非rewrite指令. 但是這將破壞很多現(xiàn)有可用的配置, 所以還沒有修復(fù)逝撬。

如果你還是想知道該如何使用if

如果你看完了上面所有內(nèi)容還是想使用 if:

請(qǐng)確認(rèn)你確實(shí)理解了該怎么用它.一些比較基本的用法可以在這里找到

做適當(dāng)?shù)臏y試

我已經(jīng)警告過你了!

文章翻譯自源: http://wiki.nginx.org/IfIsEvil

原文鏈接:Nginx配置陷阱之萬惡的if指令

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末浴骂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子宪潮,更是在濱河造成了極大的恐慌溯警,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狡相,死亡現(xiàn)場離奇詭異梯轻,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)尽棕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門喳挑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人滔悉,你說我怎么就攤上這事伊诵。” “怎么了回官?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵曹宴,是天一觀的道長。 經(jīng)常有香客問我歉提,道長笛坦,這世上最難降的妖魔是什么区转? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮版扩,結(jié)果婚禮上废离,老公的妹妹穿的比我還像新娘。我一直安慰自己礁芦,他們只是感情好蜻韭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宴偿,像睡著了一般湘捎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上窄刘,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天,我揣著相機(jī)與錄音舷胜,去河邊找鬼娩践。 笑死,一個(gè)胖子當(dāng)著我的面吹牛烹骨,可吹牛的內(nèi)容都是我干的翻伺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼沮焕,長吁一口氣:“原來是場噩夢啊……” “哼吨岭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起峦树,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤辣辫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后魁巩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體急灭,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年谷遂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了葬馋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡肾扰,死狀恐怖畴嘶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情集晚,我是刑警寧澤窗悯,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站甩恼,受9級(jí)特大地震影響蟀瞧,放射性物質(zhì)發(fā)生泄漏沉颂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一悦污、第九天 我趴在偏房一處隱蔽的房頂上張望铸屉。 院中可真熱鬧,春花似錦切端、人聲如沸彻坛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽昌屉。三九已至,卻和暖如春茵瀑,著一層夾襖步出監(jiān)牢的瞬間间驮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國打工马昨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留竞帽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓鸿捧,卻偏偏與公主長得像屹篓,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子匙奴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

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