Переписування 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 AND, закінчується last, запит буде переписаний та переданий у location 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: Блок розташування всередині - "перерва"

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або lastNginx виконує ту саму роботу (припиняє обробку більше переписаних умов).
  • Всередині блоку локації, з break, Nginx лише припиняє обробляти більше умови перезапису
  • Всередині блоку локації, з last, Nginx припиняє обробляти більше умови перезапису, а потім починає шукати нову відповідність locationблоку! Nginx також ігнорує будь-які rewritesв новому locationблоці!

Заключна примітка:

Я пропустив включити ще кілька кращих справ (насправді загальна проблема з переписувачами, наприклад 500 internal error). Але це не виходить за межі цього питання. Можливо, приклад 1 теж поза сферою дії!


ПОМИЛКА : "Помилка nginx.service через те, що процес керування вийшов із кодом помилки." ... невідома директива "echo"
Пітер Краусс

nginx.com/resources/wiki/modules/echo . Деякі дистрибутиви Linux, такі як Ubuntu 14.04 і далі, об'єднують цей модуль у певні пакети (наприклад, у nginx-extras). Я сподіваюся, що це допомагає.
Pothi Kalimuthu

1
У прикладі 1 чи має значення значення, якби правила перезапису були розміщені над усіма трьома директивами про розташування?
Крейг Хікс

1
@CraigHicks Ні, це не буде. Правило перезапису має більш високий пріоритет і виконується спочатку, перш ніж місця розташування будуть зіставлені.
Pothi Kalimuthu

1
Це має бути найкращою відповіддю. Це легко зрозуміти, посилаючись на ці приклади та читаючи документацію nginx.
Дон Діланга
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.