Назад | Перейти на главную страницу

Перезапись url nginx: разница между break и last

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

ОП предпочел пример. Кроме того, то, что написал @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 flag сделает следующее ...

  • больше нет анализа условий перезаписи
  • Внутренний движок 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 flag сделает следующее ...

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

Резюме:

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

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

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

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

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