2013-01-16 3 views
4

Notre site est un référentiel d'images de toutes sortes. Chaque image a la notion d'une URL externe et d'une URL interne. Les URL externes sont vues par les clients et elles changent à mesure que nous expérimentons avec le SEO. Les URL internes sont des URL permanentes qui pointent vers notre service d'hébergement d'images. Nous utilisons notre application Ruby on Rails pour fournir la traduction de l'URL. Voici un exemple de demande:Redirection de proxy Nginx vers un autre URI

--------   -----  -------  -------   ------------ 
|  | --eURL--> | | --> |  | --> |  | -iURL--> |   | 
|client|   |CDN|  |Nginx|  | RoR |   |Image Host| 
|  | <-------- | | <-- |  | <-- |  | <-IMG--- |   | 
--------   -----  -------  -------   ------------ 

L'architecture fonctionne, mais le streaming de l'image via RoR est inefficace. Je veux que Nginx fasse le proxy. C'est pour ça. L'architecture proposée ressemblerait à quelque chose comme ceci:

--------   -----  -------   ------- 
|  | --eURL--> | | --> |  | ------> | RoR | 
|client|   |CDN|  |Nginx| <-????- |  | 
|  | <-------- | | <-- |  |   ------- 
--------   -----  |  |   ------------ 
          |  | -iURL-> |Image Host| 
          |  | <-IMG-- |   | 
          -------   ------------ 

Quelle réponse puis-je envoyer à Nginx pour avoir ce proxy les données? Cela ne me dérange pas d'ajouter des modules Nginx à mon infrastructure et bien sûr je suis ouvert à changer mon nginx.conf.

X-Sendfile est la chose la plus proche que j'ai trouvée, mais qui permet seulement la diffusion à partir du système de fichiers local. Peut-être qu'il y a un autre en-tête de réponse HTTP obscur ou un code d'état que je ne connais pas.

Répondre

3

Utilisez l'en-tête X-Accel-Redirect en combinaison avec un Nginx spécial location pour que le proxy Nginx soit le fichier distant.

Voici le location à ajouter à votre configuration Nginx:

# Proxy download 
location ~* ^/internal_redirect/(.*?)/(.*) { 
    # Do not allow people to mess with this location directly 
    # Only internal redirects are allowed 
    internal; 

    # Location-specific logging 
    access_log logs/internal_redirect.access.log main; 
    error_log logs/internal_redirect.error.log warn; 

    # Extract download url from the request 
    set $download_uri $2; 
    set $download_host $1; 

    # Compose download url 
    set $download_url http://$download_host/$download_uri; 

    # Set download request headers 
    proxy_set_header Host $download_host; 
    proxy_set_header Authorization ''; 

    # The next two lines could be used if your storage 
    # backend does not support Content-Disposition 
    # headers used to specify file name browsers use 
    # when save content to the disk 
    proxy_hide_header Content-Disposition; 
    add_header Content-Disposition 'attachment; filename="$args"'; 

    # Do not touch local disks when proxying 
    # content to clients 
    proxy_max_temp_file_size 0; 

    # Download the file and send it to client 
    proxy_pass $download_url; 
} 

Maintenant, il vous suffit de mettre l'en-tête X-Accel-Redirect dans vos réponses à Nginx:

# This header will ask nginx to download a file 
# from http://some.site.com/secret/url.ext and send it to user 
X-Accel-Redirect: /internal_redirect/some.site.com/secret/url.ext 

# This header will ask nginx to download a file 
# from http://blah.com/secret/url and send it to user as cool.pdf 
X-Accel-Redirect: /internal_redirect/blah.com/secret/url?cool.pdf 

La solution complète a été trouvé here . Je suggère de le lire avant de l'implémenter.

+0

Ceci est une excellente solution, une petite note cependant ... vous n'avez pas besoin de construire la variable pour faire la redirection, vous pouvez simplement faire: proxy_set_pass http: // $ 1/$ 2; –

+0

Je suppose que c'est fait pour des raisons de lisibilité et de maintenabilité. Pour éviter les WTF possibles du prochain administrateur qui lira cette config. – Konstantin

Questions connexes