Как работает if внутри блока location в nginx conf?

Я прочитал https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/

Я хочу проверить, добавило ли мое приложение rails заголовок (Access-Control-Allow-Origin), а если нет, добавьте заголовок.

Приведенные здесь примеры пытались объяснить поведение условия if в nginx.conf http://agentzh.blogspot.in/2011/03/how-nginx-location-if-works.html

Но я этого не понял. Один из вопросов, который у меня есть, - что имеется в виду, когда говорят директива или фазовая директива?

Я сам кое-что пробовал. Нравиться:

location / {
  add_header My-outer-header '*';
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_set_header X-NginX-Proxy true; 

  if($sent_http_access_control_allow_origin != /*){
    add_header My-inner-header '**';
  }
}

Здесь, когда выполняется условие if, устанавливается только My-inner-header, а не My-outer-header.

Но когда я сделаю:

location / {
  add_header My-outer-header '*';
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_set_header X-NginX-Proxy true; 
  set $a 1;
  if($a == 1){
    add_header My-inner-header '**';
  }
}

Здесь переменная $ a установлена ​​в 1, но снова устанавливается только My-inner-header, а не My-outer-header.

Я хочу проверить и убедиться, выполняются ли такие инструкции, как proxy_set_header, или нет.


person Abhishek Kumar    schedule 07.02.2016    source источник


Ответы (1)


Я не тестировал ваш код. Я говорю только по собственному опыту !!!

Для начала позвольте мне указать, что конфигурация Nginx совсем НЕ похожа на какое-либо поведение ООП (объектно-ориентированное программирование). Одним словом, непредсказуемо «декларативно».

Смысл ... Если у вас есть 2 оператора IF в одном блоке, которые оба соответствуют критериям, ТОЛЬКО второй будет преобладать и выполняться.

То же самое происходит с 1 if и всеми его предыдущими объявлениями в том же блоке. Некоторые переменные (не все) не будут выполняться из-за наличия IF, и nginx ожидает, что они будут повторно объявлены внутри. Это происходит в вашем примере. Для наглядности возьмем вторую. Внутри вашего блока местоположения вы объявляете несколько значений заголовка. НО, когда выполняется оператор IF, они НЕ выполняются (IF действительно зло в nginx). Чтобы иметь полное выполнение, вам нужно повторно объявить большинство переменных заголовка внутри и все остальное за пределами if, снова внутри оператора if, чтобы они были выполнены в случае выполнения оператора if. ПРИМЕЧАНИЕ: нет карты, в которой перечислены все переменные, на которые влияет IF в nginx, и вам следует проверить нашу конфигурацию на наличие ошибок. Некоторые переменные НЕ нужно будет повторно объявлять, и в этом случае nginx сообщит об ошибке при перезапуске. Единственный способ выяснить, какой из них, - это пойти на все и исключить ошибочные сообщения, о которых было сообщено.

Предложения

а) По возможности избегайте использования IF в nginx. Вместо этого используйте блоки местоположения. например Если вы просто хотите добавить переменную заголовка, например Access-Control-Allow-Origin для определенных файлов, НЕ используйте if, а вместо этого второй блок местоположения (см. Ниже)

location / {
  // some code here
}
location ~* \.(eot|ttf|woff|woff2)$ {
    add_header Access-Control-Allow-Origin *;
}

б) В случаях, когда IF является обязательным, используйте с осторожностью и тестируйте тестовый тест. Как и выше, повторное объявление всего в операторе if является хорошей практикой (как было предложено выше, проверьте и исключите любое повторное объявление, нарушающее конфигурацию).

Удачи.

person Angelos Hadjiphilippou    schedule 07.02.2016