web-dev-qa-db-fra.com

réécriture d'URL nginx: différence entre pause et dernière

Je ne comprends pas la différence entre break et last (drapeaux de réécriture). La documentation est plutôt abstraite. J'ai essayé de basculer entre les deux dans certaines de mes configurations, mais je n'ai remarqué aucune différence de comportement. Quelqu'un peut-il expliquer ces drapeaux plus en détail? De préférence avec un exemple qui montre un comportement différent lors du retournement d'un indicateur à un autre.

49
user39883

Vous pouvez avoir différents ensembles de règles de réécriture pour différents emplacements. Lorsque le module de réécriture rencontre last, il arrête de traiter l'ensemble actuel et la demande réécrite est de nouveau transmise pour trouver l'emplacement approprié (et le nouvel ensemble de règles de réécriture). Si la règle se termine par break, la réécriture s'arrête également, mais la demande réécrite n'est pas transmise à un autre emplacement.

Autrement dit, s'il existe deux emplacements: loc1 et loc2, et qu'il y a une règle de réécriture dans loc1 qui change loc1 en loc2 ET se termine par last, la demande sera réécrite et transmise à l'emplacement loc2. Si la règle se termine par break, elle appartiendra à l'emplacement loc1.

43
minaev

OP a préféré un exemple. De plus, ce que @minaev a écrit, n'était qu'une partie de l'histoire! Alors, c'est parti ...

Exemple 1: aucun indicateur (pause ou dernier)

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

Résultat:

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

Explication:

Pour rewrite, les drapeaux sont facultatifs!

Exemple 2: bloc d'emplacement extérieur (pause ou dernier)

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
}

Résultat:

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

Explication:

En dehors du bloc d'emplacement, break et last se comportent exactement de la même manière ...

  • plus d'analyse des conditions de réécriture
  • Le moteur interne Nginx passe à la phase suivante (recherche de la correspondance location)

Exemple 3: bloc d'emplacement intérieur - "pause"

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

Résultat:

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

Explication:

À l'intérieur d'un bloc d'emplacement, l'indicateur break ferait ce qui suit ...

  • plus d'analyse des conditions de réécriture
  • Le moteur interne Nginx continue d'analyser le bloc location en cours

Exemple 4: bloc d'emplacement intérieur - "dernier"

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

Résultat:

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

Explication:

À l'intérieur d'un bloc d'emplacement, l'indicateur last ferait ce qui suit ...

  • plus d'analyse des conditions de réécriture
  • Moteur interne Nginx commence à chercher pour une autre correspondance d'emplacement basée sur le résultat du résultat rewrite.
  • plus d'analyse des conditions de réécriture, même lors du prochain match d'emplacement!

Sommaire:

  • Lorsqu'une condition rewrite avec l'indicateur break ou last correspond, Nginx cesse d'analyser plus rewrites!
  • En dehors d'un bloc d'emplacement, avec break ou last, Nginx fait le même travail (arrête le traitement des conditions de réécriture).
  • À l'intérieur d'un bloc d'emplacement, avec break, Nginx arrête uniquement le traitement des conditions de réécriture
  • A l'intérieur d'un bloc d'emplacement, avec last, Nginx arrête de traiter les conditions de réécriture et ensuite commence à chercher pour une nouvelle correspondance du bloc location! Nginx ignore également tout rewrites dans le nouveau bloc location!

Note finale:

J'ai manqué d'inclure d'autres cas Edge (problème courant avec les réécritures, comme 500 internal error). Mais, ce serait hors de portée de cette question. Probablement, l'exemple 1 est également hors de portée!

48
Pothi Kalimuthu