web-dev-qa-db-fra.com

Nginx: problème de type de contenu par URI défini

Je suis en train de mettre en place un petit hébergement de fichiers personnel, j'ai créé un backend pour stocker les fichiers téléchargés par leur hachage directement sur le disque dur, comme /f/ab/cd/ef012345678..., mais sans extensions de fichier et générer un URI comme example.com/f/ab/cd/ef012345678.../filename.jpg.

Nginx sert les fichiers directement depuis le disque dur en utilisant cette configuration:

location /f {
     rewrite "^/f/([a-z0-9]+)/([a-z0-9]+)/([a-z0-9]+)(.*)$" /$1/$2/$3 break;
     root /srv/cdn/f;
}

C'est à dire. il coupe la dernière partie de l'URI et lit le fichier en utilisant uniquement son hash. Cela fonctionne bien, mais il supprime les types MIME des fichiers en application/octet-stream qui oblige le navigateur à télécharger tous les fichiers, mais en affichant les images en ligne.

J'ai fait une solution de contournement en incluant dans cet emplacement un morceau de config comme ceci:

if ($request_uri ~* \.png$) {
    add_header Content-Type "image/png";
}

Ce qui corrige le problème pour Google Chrome et pour le premier chargement dans Firefox.

Mais lorsque j'ouvre le lien la deuxième fois dans Firefox ou que je recharge simplement la page, cela me demande de le télécharger. Apparemment, Firefox gère mal le type de contenu avec 304 réponses (j'ai vérifié les en-têtes, Nginx envoie la réponse 304 et l'en-tête de type de contenu avec cette configuration si le fichier a été extrait du cache).

Je cherche un moyen de déterminer dans Nginx si le fichier est un serveur de cache et de ne pas ajouter l'en-tête de pour mieux Nginx solution.

Je sais que la meilleure idée est de modifier mon backend et d'ajouter des extensions de fichier, cela résoudra également certains problèmes futurs, mais maintenant je ne peux pas dormir et j'ai besoin de connaître la réponse à l'aide de Nginx uniquement s'il y a est un.

3
Eirenliel

Je n'ai aucune idée pourquoi cette méthode fonctionne et votre méthode rewrite...break ne fonctionne pas. Mais vous pouvez capturer l'expression régulière dans l'instruction location et l'utiliser dans une expression alias, et il semble laisser le Content-Type conformément à l'URI de la demande d'origine.

Par exemple:

location ~ ^/(f/[a-z0-9]+/[a-z0-9]+/[a-z0-9]+) {
    alias /srv/cdn/$1;
}

Voir ce document pour plus.

Notez que les expressions rationnelles location sont ordonnées. Par conséquent, sa position dans votre fichier de configuration peut être significative. Voir ce document pour plus.

0
Richard Smith