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ą.


źródło
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.

minaev
źródło
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!

Pothi Kalimuthu
źródło
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,