переписывание URL nginx: разница между разрывом и последним

45

Я не понимаю разницу между разрывом и последним (флаги перезаписи). Документация довольно заумная. Я пытался переключаться между ними в некоторых своих конфигах, но не мог заметить никакой разницы в поведении. Может кто-нибудь объяснить эти флаги поподробнее? Предпочтительно с примером, который показывает другое поведение при переключении одного флага на другой.


источник
Я не знаю ответа, но, пожалуйста, обновите wiki.nginx.org, когда получите ответ. Кроме того, англоязычный список рассылки nginx довольно активен, и Игорь (главный разработчик) отвечает на сотни вопросов в месяц, так что, возможно, задайте его там.
rmalayter
@rmalayter - этот вопрос был задан в списке рассылки nginx. Игорь ответил, но ответ для меня тоже не имел особого смысла: pubbs.net/nginx/200908/46047
Ссылка на pubbs.net не работает, так как домен был захвачен. Извините, не смог найти, куда это должно указывать. ; (
Тино

Ответы:

40

У вас могут быть разные наборы правил перезаписи для разных мест. Когда встречается модуль перезаписи last, он останавливает обработку текущего набора, и переписанный запрос передается еще раз, чтобы найти подходящее местоположение (и новый набор правил перезаписи). Если правило заканчивается на break, перезапись также останавливается, но переписанный запрос не передается в другое место.

То есть, если есть два местоположения: loc1 и loc2, и в loc1 есть правило перезаписи, которое заменяет loc1 на loc2 И заканчивается на него last, запрос будет переписан и передан в местоположение loc2. Если правило заканчивается на break, оно будет принадлежать местоположению loc1.

Минаев
источник
Вы имеете в виду, что если перезапись имеет флаг разрыва, она не будет искать соответствующий блок местоположения, таким образом делая его принадлежащим местоположению loc1.
Мартин Фьордвальд,
Именно так. Исправлена.
Минаев
43

ОП предпочел пример. Кроме того, то, что написал @minaev, было только частью истории! Итак, поехали ...

Пример 1: Нет (перерыв или последний) флаги

server {
    server_name example.com;
    root 'path/to/somewhere';

    location / {
        echo 'finally matched location /';
    }

    location /notes {
        echo 'finally matched location /notes';
    }

    location /documents {
        echo 'finally matched location /documents';
    }

    rewrite ^/([^/]+.txt)$ /notes/$1;
    rewrite ^/notes/([^/]+.txt)$ /documents/$1;
}

Результат:

# curl example.com/test.txt
finally matched location /documents

Объяснение:

Ведь rewriteфлаги необязательны!

Пример 2. Внешний блок локации (перерыв или последний)

server {
    server_name example.com;
    root 'path/to/somewhere';

    location / {
        echo 'finally matched location /';
    }

    location /notes {
        echo 'finally matched location /notes';
    }

    location /documents {
        echo 'finally matched location /documents';
    }

    rewrite ^/([^/]+.txt)$ /notes/$1 break; # or last
    rewrite ^/notes/([^/]+.txt)$ /documents/$1; # this is not parsed
}

Результат:

# curl example.com/test.txt
finally matched location /notes

Объяснение:

За пределами блока локации оба breakи lastведут себя точно ...

  • больше нет парсинга условий перезаписи
  • Внутренний движок Nginx переходит на следующий этап (поиск locationсоответствия)

Пример 3: Внутренний блок локации - "break"

server {
    server_name example.com;
    root 'path/to/somewhere';

    location / {
        echo 'finally matched location /';
        rewrite ^/([^/]+.txt)$ /notes/$1 break;
        rewrite ^/notes/([^/]+.txt)$ /documents/$1; # this is not parsed
    }

    location /notes {
        echo 'finally matched location /notes';
    }

    location /documents {
        echo 'finally matched location /documents';
    }
}

Результат:

# curl example.com/test.txt
finally matched location /

Объяснение:

Внутри блока местоположения breakфлаг сделает следующее ...

  • больше нет парсинга условий перезаписи
  • Внутренний движок Nginx продолжает анализ текущего locationблока

Пример 4: Внутренний блок локации - «последний»

server {
    server_name example.com;
    root 'path/to/somewhere';

    location / {
        echo 'finally matched location /';
        rewrite ^/([^/]+.txt)$ /notes/$1 last;
        rewrite ^/notes/([^/]+.txt)$ /documents/$1;  # this is not parsed
    }

    location /notes {
        echo 'finally matched location /notes';
        rewrite ^/notes/([^/]+.txt)$ /documents/$1;  # this is not parsed, either!
    }

    location /documents {
        echo 'finally matched location /documents';
    }
}

Результат:

# curl example.com/test.txt
finally matched location /notes

Объяснение:

Внутри блока местоположения lastфлаг сделает следующее ...

  • больше нет парсинга условий перезаписи
  • Внутренний движок Nginx начинает искать другое совпадение местоположений на основе результата rewriteрезультата.
  • больше не нужно разбирать условия перезаписи, даже при следующем совпадении локаций!

Резюме:

  • Когда rewriteусловие с флагом breakили lastсовпадает, Nginx прекращает синтаксический анализ больше rewrites!
  • За пределами блока местоположения, с помощью breakили last, Nginx выполняет ту же работу (прекращает обработку, переписывает условия перезаписи).
  • Внутри блока местоположения, с помощью breakNginx прекращается только обработка условий перезаписи
  • Внутри блока местоположения, с помощью lastNginx прекращается обработка условий перезаписи, а затем начинается поиск нового соответствия locationблока! Nginx также игнорирует любой rewritesв новом locationблоке!

Заключительное примечание:

Я пропустил, чтобы включить еще несколько крайних случаев (на самом деле общая проблема с переписывает, например 500 internal error). Но это было бы за рамками этого вопроса. Вероятно, пример 1 тоже выходит за рамки!

Поти Калимуту
источник
ОШИБКА : «nginx.service не удалось, потому что процесс управления завершился с кодом ошибки.» ... неизвестная директива «echo»
Питер Краусс
nginx.com/resources/wiki/modules/echo . Некоторые дистрибутивы Linux, такие как Ubuntu 14.04 и выше, объединяют этот модуль в определенные пакеты (например, в nginx-extras). Надеюсь, это поможет.
Поти Калимуту
1
В примере 1 будет иметь значение, если правила перезаписи будут размещены над всеми тремя директивами местоположения?
Крейг Хикс,
1
@CraigHicks Нет, не будет. Правило перезаписи имеет более высокий приоритет и выполняется сначала, прежде чем сопоставляются местоположения.
Поти Калимуту
1
Это должен быть лучший ответ. Это легко понять, обратившись к этим примерам и прочитав документацию по nginx.
Дон Диланга