Comment try_files fonctionne?

72

J'ai jeté un œil à la documentation de nginx et elle me confond encore complètement.

Comment ça try_filesmarche? Voici ce que dit la documentation:

De NginxHttpCoreModule

try_files

syntaxe: try_files chemin1 [chemin2] uri

défaut: aucun

contexte: serveur, emplacement

disponibilité: 0.7.27

Vérifie l'existence des fichiers dans l'ordre et renvoie le premier fichier trouvé. Un slash de fin indique un répertoire - $ uri /. Si aucun fichier n'est trouvé, une redirection interne vers le dernier paramètre est appelée. Le dernier paramètre est l'URI de secours et doit exister, sinon une erreur interne sera générée. Contrairement à la réécriture, $ args ne sont pas automatiquement conservés si la solution de secours n’est pas un emplacement nommé. Si vous avez besoin de préserver les arguments, vous devez le faire explicitement:

Je ne comprends pas comment il vérifie les chemins et que se passe-t-il si je ne veux pas d'erreur interne mais le fait de résumer le reste du chemin pour essayer de trouver un autre fichier?

Si je veux essayer un fichier en cache à /path/app/cache/url/index.htmlet s'il échoue, /path/app/index.phpcomment pourrais-je l'écrire? Si j'ai écrit:

try_files /path/app/cache/ $uri
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php-fastcgi/php-fastcgi.socket;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;

J'ai index index.php index.html index.htm;. Quand je visiterai /urlname, va-t-il essayer de vérifier /path/app/cache/urlname/index.phpalors /path/app/cache/urlname/index.html? Si nous ignorons tout après, try_filesest-il possible try_filesde vérifier le dossier de cache? J'ai essayé et j'ai échoué.

76484
la source

Réponses:

64

try_files essaie le chemin littéral que vous spécifiez par rapport à la directive racine définie et définit le pointeur de fichier interne. Si vous utilisez par exemple try_files /app/cache/ $uri @fallback;avec, index index.php index.html;il testera les chemins dans cet ordre:

  1. $document_root/app/cache/index.php
  2. $document_root/app/cache/index.html
  3. $document_root$uri

avant de procéder à la redirection interne vers l’emplacement nommé @fallback. Vous pouvez également utiliser un fichier ou un code d'état ( =404) comme dernier paramètre, mais si vous utilisez un fichier, celui-ci doit exister .

Vous devriez noter que try_files lui-même n'émettra pas de redirection interne pour autre chose que le dernier paramètre. Cela signifie que vous ne pouvez pas effectuer les opérations suivantes: try_files $uri /cache.php @fallback;car cela obligerait nginx à définir le pointeur de fichier interne sur $ document_root / cache.php et à le servir, mais comme aucune redirection interne n’a lieu, les emplacements ne sont pas réévalués. servi comme texte brut. (La raison pour laquelle cela fonctionne avec les fichiers PHP que l'indice est que la directive de l' indice va émettre une redirection interne)

Martin Fjordvald
la source
2
C'est BEAUCOUP plus clair. Merci. Je ne sais pas trop comment fonctionne l'emplacement nommé. Si @fallback a des lignes pour fastcgi php, cela servirait de fichier php plutôt que de texte? Le repli est-il utilisé lorsque tout avant échoue?
2
D'un point de vue fonctionnel, un emplacement nommé est identique à un emplacement normal, à la différence qu'il est uniquement accessible via des mécanismes internes tels que error_page et try_files. Le repli dans try_files n'est utilisé que si aucun des chemins spécifiés ne donne lieu à un fichier valide. Vous avez toujours besoin d'un emplacement pour capturer les \ .php $ URIs, sinon try_files se déclenchera sur $ uri si le fichier existe et le servira comme texte brut.
Martin Fjordvald
Merci pour cette réponse .. J'ai encore une question ici: try_files est-il exécuté immédiatement ou l'emplacement imbriqué sera-t-il essayé avant?
Stéphane
@ Stéphane Vous vous dirigez dans des eaux troubles. L'héritage dans nginx est complexe, désordonné et totalement incohérent. Je devais examiner mes anciennes notes pour ne pas oublier cela, donc, il semble que pour try_files, en particulier lorsqu'il s'agit d'emplacements imbriqués uniquement, ne s'exécutera pas si l'emplacement intérieur correspond. Je recommanderais de le tester, cependant.
Martin Fjordvald le
5

Voici une autre utilisation pratique de try_files, en tant que redirection inconditionnelle vers des emplacements nommés. Les emplacements nommés agissent en tant que sous-routines, évitant ainsi la duplication du code. Lorsque le premier argument de try_files est "_", la redirection de secours est toujours prise.

    location =/wp-login.php { try_files _ @adminlock; }
    location ^~ /wp-admin/  { try_files _ @adminlock; }
    location @adminlock  {
            allow 544.23.310.198;
            deny all;
            try_files _ @backend;
            # wp-admin traffic is tiny so ok to send all reqs to backend 
    }
    location ~ \.php {  try_files _ @backend; }
    location / { try_files $uri $uri/ =403; }
    location @backend {
            fastcgi_pass 127.0.0.1:9000;
            include snippets/fastcgi-php.conf;
    }
Craig Hicks
la source