Nginx IFisEVIL – развёрнутое объяснение, почему ифы – зло

Ниже приводится развёрнутое объяснение работы директивы 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 – в некоторых случаях есть проблемы.

Больше примеров тут:

Leave a Reply

Your email address will not be published. Required fields are marked *