Question nginx: Spécifier des en-têtes personnalisés dans des blocs d'emplacement réécrits


J'essaie de définir des en-têtes uniquement pour des location des blocs en nginx.

Le problème que j'ai est que ceux location les blocs contiennent rewrite déclarations, qui semblent apparemment laisser tomber les en-têtes personnalisés.

Dans cet exemple, je souhaite deux règles:

  • Fichiers à l'intérieur /static avoir dû expires max; (qui définit les en-têtes Cache-Control: max-age=some huge value et Expires: some future date really far off) et faire réécrire leurs noms en quelque chose qui ne contient pas /static
  • Les fichiers partout ailleurs devraient avoir Cache-Control: public (non max-age)

Voici la configuration que j'ai essayée:

server {
    listen [::]:80;
    root /somepath;
    location /static {
        expires max;
        rewrite /static(.*) /whatever$1;
    }
    add_header Cache-Control public;
}

Et ayant la structure de répertoire suivante:

/somepath
/somepath/f1.txt
/somepath/static/f2.txt

Ensuite, nous obtenons ce qui suit:

  • f1.txt: Cache-Control: public, non Expires entête
  • f2.txt: Cache-Control: public, non Expires entête

C'est valable pour f1.txt mais non f2.txt. Je veux que ce soit comme ça:

  • f1.txt: Cache-Control: public, non Expires entête
  • f2.txt: Cache-Control: max-age=some huge value, Expires: some future date really far off

Je pense que le problème découle de la rewrite /static(.*) /whatever$1; ligne, ce qui oblige nginx à annuler les en-têtes qu’il a ajoutés jusqu’à maintenant, puis à les rajouter Cache-Control). En tant que tel, une solution de contournement triviale serait la suivante:

server {
    listen [::]:80;
    root /somepath;
    location /static {
        rewrite /static(.*) /whatever$1;
    }
    location /whatever {
        expires max;
    }
    add_header Cache-Control public;
}

Le problème est que dans mon vrai fichier de configuration, le rewrite n'est pas aussi amical que ça. L'URL réécrite est pas facilement assimilable d'une manière qui ne correspond pas aussi à certains fichiers qui ne devraient pas avoir expires max, donc je ne peux pas vraiment utiliser cette solution de contournement.

Y at-il un moyen de faire en sorte que ces en-têtes collent après un rewrite?

MODIFIER: Voici à quoi ressemblent mes vraies URL:

location ~ /(?:posts-)?img/.*-res- {
    access_log               off;
    expires                  max;
    rewrite                  "/img/(.*)-res-.{8}(.*)" /img/$1$2;
    rewrite                  "/posts-img/(.*)-res-.{8}(.*)" /posts/$1$2;
}

Bien que je puisse ajouter un location bloquer pour /img qui s’occuperait des fichiers réécrits en utilisant le premier rewrite règle, je ne peux pas en ajouter un pour le second (/posts) car certains fichiers de /posts ne sont pas des ressources en cache et ne devraient donc pas avoir expires max.

EDIT 2: Configuration complète (ou au moins contenant toutes les parties pertinentes):

server {
    listen [::]:80;
    root /somepath;
    server_name domain.tld;
    location ~ /(?:posts-)?img/.*-res- {
        access_log               off;
        expires                  max;
        rewrite                  "/img/(.*)-res-.{8}(.*)" /img/$1$2;
        rewrite                  "/posts-img/(.*)-res-.{8}(.*)" /posts/$1$2;
    }
    add_header Cache-Control public;
}

Structure du répertoire:

/somepath
/somepath/img/f1.png
/somepath/posts/post1.html
/somepath/posts/d1/f2.png
/somepath/posts/d2/f2.png

Comportement attendu en fonction de la requête HTTP:

  • GET /somepath: Sert /somepath avec Cache-Control: public
  • GET /somepath/img/f1.png: Sert /somepath/img/f1.png avec Cache-Control: public
  • GET /somepath/img/f1-res-whatever.png: Sert /somepath/img/f1.png avec les en-têtes envoyés par expires max
  • GET /somepath/posts/post1.html: Sert /somepath/posts/post1.html avec Cache-Control: public
  • GET /somepath/posts/d1/f2.png: Sert /somepath/posts/d1/f2.png avec Cache-Control: public
  • GET /somepath/posts-img/d1/f2-res-whatever.png: Sert /somepath/posts/d1/f2.png avec les en-têtes envoyés par expires max

5
2017-12-21 02:47


origine


proxy_pass'ing to self fonctionne, mais ce n'est pas vraiment une solution. Peut-être pourriez-vous utiliser «alias»? - sendmoreinfo
alias fonctionnerait dans l'exemple simple ci-dessus, mais malheureusement, cela ne fonctionnerait pas dans mon exemple réel, car le nom du fichier change (de something-somehash.extension à something.extension) - Etienne Perot
Ajout de l'apparence des URL dans ma vraie configuration - Etienne Perot
pouvez-vous partager la configuration complète - Sameer
Ajout d'une configuration de travail et d'un exemple de structure de répertoire et du comportement attendu pour ces fichiers - Etienne Perot


Réponses:


Cela devrait fonctionner (je l'ai cependant vérifié avec une configuration un peu plus simple). En passant, Igor Sysoev recommande d'utiliser le moins possible les localisations regex.

    location /img {
        if ($arg_max) { expires max; }
        ...
    }

    location /posts-img {
        if ($arg_max) { expires max; }
        ...
    }

    location ~ /(?:posts-)?img/.*-res- {
        access_log               off;
        expires                  max;
        rewrite                  "/img/(.*)-res-.{8}(.*)" /img/$1$2?max=1;
        rewrite                  "/posts-img/(.*)-res-.{8}(.*)" /posts/$1$2?max=1;
    }

2
2017-12-27 14:41



Très bien, remarquez aussi que ?max=1 paramètre n'est pas exposé aux utilisateurs finaux et peut être nommé comme vous le souhaitez. - giorgiosironi
Cependant, méfiez-vous que si vous avez d'autres en-têtes définis dans les premier et deuxième location les blocs, ils ne fonctionneront pas ... avec beaucoup d'autres cas; ifest répertorié comme dangereux nginx.com/resources/wiki/start/topics/depth/ifisevil - giorgiosironi


Pour insensible à la casse correspondance d'emplacement.

location ~* /static/

insensible à la casse enlever le "*****"

location ~* /static/

Directive d'emplacement source Nginx Documentation 


0
2017-12-24 02:58



Désolé mais je ne pense pas que vous ayez compris la question. Je ne parle pas de correspondance sensible à la casse / insensible ici ... - Etienne Perot
Je pense que Sameer a raison: il suffit de remplacer "emplacement / statique" par "emplacement ~ / statique" - Andrei Mikhaltsov
Vous souhaitez ajouter des en-têtes en fonction d'une condition, vous devez donc les rechercher / les rechercher. - Sameer
La partie "Ajouter un en-tête basé sur une condition" fonctionne, l'URL d'origine (/static/something) est apparié. Ce qui ne fonctionne pas, c’est que les en-têtes ajoutés ne collent pas après le rewrite règle. De plus, parce que l'URL réécrite ne correspond pas /static (alors location ~ /static ne l’attrapera pas), l’en-tête n’est plus ajouté après la réécriture. - Etienne Perot