przepisywanie adresu URL nginx: różnica między przerwą a ostatnim


45

Nie rozumiem różnicy między przerwaniem a ostatnim (flagi przepisywania). Dokumentacja jest raczej zawężona. Próbowałem przełączać się między nimi w niektórych moich konfiguracjach, ale nie zauważyłem żadnej różnicy w zachowaniu. Czy ktoś może wyjaśnić te flagi bardziej szczegółowo? Najlepiej z przykładem, który pokazuje inne zachowanie podczas przewracania jednej flagi na drugą.


Nie znam odpowiedzi, ale zaktualizuj wiki.nginx.org, kiedy otrzymasz odpowiedź. Ponadto anglojęzyczna lista mailingowa nginx jest dość aktywna, a Igor (główny programista) odpowiada na setki pytań miesięcznie, więc może tam zadaj.
rmalayter

@rmalayter - to pytanie zostało zadane na liście mailingowej nginx. Igor odpowiedział, ale odpowiedź też nie miała dla mnie większego sensu: pubbs.net/nginx/200908/46047

link pubbs.net jest zepsuty podczas przejęcia domeny. Przepraszamy, nie udało się znaleźć miejsca, w którym powinien on wskazywać. ; (
Tino,

Odpowiedzi:


40

Możesz mieć różne zestawy reguł przepisywania dla różnych lokalizacji. Gdy moduł przepisywania spełnia się last, przestaje przetwarzać bieżący zestaw, a przepisane żądanie zostaje ponownie przekazane w celu znalezienia odpowiedniej lokalizacji (i nowego zestawu reguł przepisywania). Jeśli reguła kończy się na break, przepisywanie również się zatrzymuje, ale przepisane żądanie nie jest przekazywane do innej lokalizacji.

Oznacza to, że jeśli istnieją dwie lokalizacje: loc1 i loc2, aw loc1 istnieje reguła przepisywania, która zmienia loc1 na loc2 ORAZ kończy się na last, żądanie zostanie przepisane i przekazane do lokalizacji loc2. Jeśli reguła kończy się na break, będzie należeć do lokalizacji loc1.


Masz na myśli, że jeśli przepisanie ma flagę break, to nie będzie szukało pasującego bloku lokalizacji, dzięki czemu będzie należeć do lokalizacji loc1.
Martin Fjordvald,

Dokładnie. Naprawiony.
minaev

43

OP wolał przykład. To, co napisał @minaev, było tylko częścią historii! Więc zaczynamy...

Przykład 1: Brak flag (przerwa lub ostatnia)

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;
}

Wynik:

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

Wyjaśnienie:

Ponieważ rewriteflagi są opcjonalne!

Przykład 2: Zewnętrzny blok lokalizacji (przerwa lub ostatni)

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
}

Wynik:

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

Wyjaśnienie:

Poza bloku lokalizacja, zarówno breaki lastzachowują się dokładnie w sposób ...

  • koniec analizowania warunków ponownego zapisu
  • Wewnętrzny silnik Nginx przechodzi do następnej fazy (szukanie locationdopasowania)

Przykład 3: Wewnętrzny blok lokalizacji - „przerwa”

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';
    }
}

Wynik:

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

Wyjaśnienie:

Wewnątrz bloku lokalizacji breakflaga wykona następujące czynności ...

  • koniec analizowania warunków ponownego zapisu
  • Wewnętrzny silnik Nginx kontynuuje analizowanie bieżącego locationbloku

Przykład 4: Wewnętrzny blok lokalizacji - „ostatni”

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';
    }
}

Wynik:

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

Wyjaśnienie:

Wewnątrz bloku lokalizacji lastflaga wykona następujące czynności ...

  • koniec analizowania warunków ponownego zapisu
  • Silnik wewnętrzny Nginx zaczyna szukać innego dopasowania lokalizacji na podstawie wyniku rewritewyniku.
  • koniec analizy warunków zapisu, nawet przy następnym dopasowaniu lokalizacji!

Podsumowanie:

  • Kiedy rewritewarunek z flagą breaklub lastdopasowaniami, Nginx przestaje się parsować rewrites!
  • Poza blokiem lokalizacji, przy pomocy breaklub last, Nginx wykonuje to samo zadanie (przestaje przetwarzać warunki ponownego zapisu).
  • Wewnątrz bloku lokalizacji break, Nginx przestaje przetwarzać już tylko warunki przepisywania
  • Wewnątrz bloku lokalizacji lastNginx przestaje przetwarzać warunki ponownego zapisu, a następnie zaczyna szukać nowego dopasowania locationbloku! Nginx ignoruje również dowolne rewritesw nowym locationbloku!

Uwaga końcowa:

Brakowało mi, aby dołączyć więcej przypadków krawędzi (w rzeczywistości częsty problem z przepisywaniem, np. 500 internal error). Ale to byłoby poza zakresem tego pytania. Prawdopodobnie przykład 1 również jest poza zakresem!


BŁĄD : „nginx.service nie powiodło się, ponieważ proces kontroli zakończył się z kodem błędu.” ... nieznana dyrektywa „echo”
Peter Krauss

nginx.com/resources/wiki/modules/echo . Niektóre dystrybucje Linuksa, takie jak Ubuntu 14.04, zawierają ten moduł w niektórych pakietach (np. W dodatkach nginx). Mam nadzieję że to pomogło.
Pothi Kalimuthu

1
W przykładzie 1 miałoby to znaczenie, gdyby reguły przepisywania były umieszczone nad wszystkimi trzema dyrektywami lokalizacji?
Craig Hicks,

1
@CraigHicks Nie, nie byłoby. Reguła przepisywania ma wyższy priorytet i jest wykonywana na początku przed dopasowaniem lokalizacji.
Pothi Kalimuthu

1
To powinna być najlepsza odpowiedź. Łatwo to zrozumieć, odwołując się do tych przykładów i czytając dokumentację nginx.
Don Dilanga,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.