Ниже приводится развёрнутое объяснение работы директивы if в nginx (по материалам рассылки):
В первую голову – надо уяснить для себя, что if создаёт вложенный location. И именно в этом location’е в результате будет обработан запрос, если if выполнится. Если таких if’ов много – то запрос будет обработан в последнем if’е, который выполнится. Поэтому конфигурация вида
location / { set $true 1; if ($true) { add_header X-Foo1 "bar"; } if ($true) { add_header X-Foo2 "bar"; } } |
добавит только один заголовок, X-Foo2. Эта особенность – что называется, не баг, а фича.
А дальше начинаются костыли, подпорки, и прочие нюансы, связанные, в первую очередь, с тем, что if’ы, в отличие от обычных вложенных location’ов, пытаются наследовать директивы, которые в норме не
наследуются во вложенные location’ы (e.g., proxy_pass). Иногда это получается, иногда – получается, но неправильно, иногда – не получается вовсе. Конкретные известные случаи нехорошего поведения – коллекционируются на страничке IfIsEvil.
Порядок наследования директив в скрытом локейшне, создаваемом директивой IF
Наследуется всё, кроме отдельных директив. Не наследуются – инструкции модуля rewrite (if, set, break, return, rewrite), директивы, устанавливающие обработчики (proxy_pass и остальные *_pass, empty_gif, stub_status, perl, mp4, flv), и директива try_files.
Внуть if’ов, в теории, должно наследоваться всё. По факту – см. http://wiki.nginx.org/IfIsEvil, как минимум с proxy_pass, try_files и alias – в некоторых случаях есть проблемы.
Больше примеров тут: