среда, 5 декабря 2012 г.

nginx: пишем location-ы

Оказалось, есть нюансы...

Основная дока:
(en) http://wiki.nginx.org/HttpCoreModule#location
(ru) http://wiki.nginx.org/NginxRuHttpCoreModule#location
Лучше читать англ версию, она актуальнее и более полная. Что странно, учитывая автора.

2 вида записи:

location [ = | ~ | ~* | ^~ ] uri { ... }
location { } @ name { ... }

Первый вариант рассмотрим далее, 2 - это внутренняя секция, куда можно попасть через try_files, error_page

Шаблоны указываются без кавычек.


Порядок обработки:

  1. = Строковые совпадения. Если найдено, проверка заканчивается. = значит полное совпадение шаблона и проверяемой строки, например = / - заход в секцию будет исключительно для корня, и даже файлы в корне уже сюда не подходят.
  2. ^~ Приоритетное строковое значение. Хотя по-моему было бы правильнее назвать "приоритетным регулярным выражением", поскольку в отличии от = требуется совпадение только начала. ^~ / полностью отключит регулярные выражения для секции server, если нет более точного location без ^~
  3. Строковые значения (/download/). Ищется максимальное совпадение, смотрится только с начала пути. Если нужно совпадение вида /*/download/, то это уже будет п.4, так что в уме можно читать такую запись как /download/* Но на этом проверка не заканчивается!
  4. ~, ~* Регулярные выражения, в порядке определения в конфиге. При совпадении - выполняется этот регэксп, проверка заканчивается. ~ - с учётом регистра, ~* - без.
  5. Если не было найдено подходящей регулярки, используется наибольшее совпадение из п.3.

"Для определения соответствия location'а и запроса сначала проверяются location'ы, заданные обычными строками. Среди них ищется максимальное совпадение. Так как строки лексически отсортированы, то поиск прекращается, как только URI становится лексически больше location'а. Конфигурация максимально совпавшего location'а запоминается. Затем проверяются регулярные выражения. В отличие от обычных строк, они не сортируются, а проверяются в порядке их следования в конфигурационном файле. И, кроме того, поиск прекращается уже после первого совпадения.

Если нужно запретить проверку регулярных выражений после проверки обычных строк, то это можно сделать с помощью префикса "^~". Если у максимально совпавшего location'а есть этот префикс, то регулярные выражения не проверяются.

Кроме того, с помощью префикса "=" можно задать точное совпадение URI и location. При совпадении поиск сразу же прекращается, так как дальше искать не имеет смысла. Например, если запрос "/" очень частый, то указав "location = /", можно ускорить обработку этого запроса, так как поиск location прекратится после первого же сравнения."

Некоторую путаницу может вызвать ^~ - тильда это признак регулярки, но символы регулярных выражений не принимаются.

Как быть, если надо ловить пути вида /что-то/что-то-еще/path123/ ? Путь только 1 - регэкспы.
location ~ /path123/ {

При отладке не забываем про режим debug в error_log сайта и оператор break, позволяющий остановить проверку.

2 комментария:

  1. Этот комментарий был удален автором.

    ОтветитьУдалить
    Ответы
    1. можно описать нужные каталоги отдельными location, можно через try_files $uri @apache
      или if ($is_args = "") {...}

      Удалить