переписывание 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.
— Дон Диланга
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.