riscrittura url nginx: differenza tra interruzione e ultima


45

Non capisco la differenza tra break e last (flag di riscrittura). La documentazione è piuttosto astrusa. Ho provato a passare tra i due in alcune delle mie configurazioni, ma non sono riuscito a individuare alcuna differenza nel comportamento. Qualcuno può spiegare queste bandiere in modo più dettagliato? Preferibilmente con un esempio che mostra un comportamento diverso quando si gira una bandiera su un'altra.


Non conosco la risposta, ma per favore aggiorna wiki.nginx.org quando ricevi la tua risposta. Inoltre, la mailing list di nginx in lingua inglese è piuttosto attiva e Igor (lo sviluppatore principale) risponde a centinaia di domande al mese, quindi forse fai lì.
rmalayter,

@rmalayter - questa domanda è stata posta nella mailing list di nginx. Igor rispose, ma la risposta non aveva molto senso neanche per me: pubbs.net/nginx/200908/46047

Il link pubbs.net si interrompe quando il dominio viene acquisito. Spiacenti, non sono riuscito a trovare dove dovrebbe puntare. ; (
Tino,

Risposte:


40

Potresti avere diversi set di regole di riscrittura per posizioni diverse. Quando il modulo di riscrittura si incontra last, interrompe l'elaborazione del set corrente e la richiesta riscritta viene nuovamente passata per trovare la posizione appropriata (e il nuovo set di regole di riscrittura). Se la regola termina con break, anche la riscrittura si interrompe, ma la richiesta riscritta non viene passata in un'altra posizione.

Cioè, se ci sono due posizioni: loc1 e loc2 e c'è una regola di riscrittura in loc1 che cambia loc1 in loc2 E termina con last, la richiesta verrà riscritta e passata alla posizione loc2. Se la regola termina con break, apparterrà alla posizione loc1.


Intendi che se la riscrittura ha il flag di interruzione non cercherà un blocco di posizione corrispondente, facendolo quindi appartenere alla posizione loc1.
Martin Fjordvald,

Esattamente. Fisso.
minaev,

43

OP ha preferito un esempio. Inoltre, ciò che ha scritto @minaev era solo una parte della storia! Quindi, eccoci qui ...

Esempio 1: nessun flag (break o last)

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

Risultato:

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

Spiegazione:

Per rewrite, le bandiere sono opzionali!

Esempio 2: blocco posizione esterna (interruzione o ultimo)

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
}

Risultato:

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

Spiegazione:

Al di fuori del blocco posizione, entrambi breake si lastcomportano esattamente ...

  • non più analisi delle condizioni di riscrittura
  • Il motore interno di Nginx passa alla fase successiva (ricerca della locationcorrispondenza)

Esempio 3: blocco di posizione interno - "interruzione"

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

Risultato:

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

Spiegazione:

All'interno di un blocco di posizione, breakflag farebbe il seguente ...

  • non più analisi delle condizioni di riscrittura
  • Il motore interno di Nginx continua ad analizzare il locationblocco corrente

Esempio 4: blocco posizione interno - "ultimo"

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

Risultato:

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

Spiegazione:

All'interno di un blocco di posizione, lastflag farebbe il seguente ...

  • non più analisi delle condizioni di riscrittura
  • Il motore interno di Nginx inizia a cercare un'altra corrispondenza di posizione in base al risultato del rewriterisultato.
  • non sarà più necessario analizzare le condizioni di riscrittura, anche nella prossima posizione corrispondente!

Sommario:

  • Quando una rewritecondizione con la bandiera breako le lastpartite, Nginx smette di analizzare più rewrites!
  • Al di fuori di un blocco di posizione, con breako last, Nginx fa lo stesso lavoro (interrompe l'elaborazione delle condizioni di riscrittura).
  • All'interno di un blocco di posizione, con break, Nginx interrompe l'elaborazione delle condizioni di riscrittura
  • All'interno di un blocco di posizione, con lastNginx interrompe l'elaborazione delle condizioni di riscrittura e quindi inizia a cercare una nuova corrispondenza del locationblocco! Nginx ignora anche quelli rewritesnel nuovo locationblocco!

Nota finale:

Ho perso di includere alcuni casi limite (in realtà un problema comune con le riscritture, come 500 internal error). Ma sarebbe fuori dalla portata di questa domanda. Probabilmente, anche l'esempio 1 è fuori portata!


ERRORE : "nginx.service non riuscito a causa della chiusura del processo di controllo con codice di errore." ... direttiva sconosciuta "echo"
Peter Krauss,

nginx.com/resources/wiki/modules/echo . Alcune distribuzioni Linux come Ubuntu 14.04 in poi raggruppano questo modulo in alcuni pacchetti (come in nginx-extra). Spero che aiuti.
Pothi Kalimuthu,

1
Nell'esempio 1 farebbe la differenza se le regole di riscrittura fossero posizionate sopra tutte e tre le direttive sulla posizione?
Craig Hicks,

1
@CraigHicks No, non lo farebbe. Una regola di riscrittura ha una precedenza più elevata e viene eseguita all'inizio prima che le posizioni vengano abbinate.
Pothi Kalimuthu,

1
Questa dovrebbe essere la risposta migliore. È facile da capire facendo riferimento a questi esempi e leggendo la documentazione di nginx.
Don Dilanga,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.