2013-01-16 73 views
4

我們的網站是一個圖像存儲庫的種類。每個圖像都有一個外部URL和一個內部URL的概念。外部URL被客戶看到,並且隨着我們對SEO的實驗而改變。內部網址是指向我們圖片託管服務的永久性網址。我們使用我們的Ruby on Rails應用程序來提供URL翻譯。以下是一個請求示例:Nginx的代理服務器重定向到另一個URI

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

該體系結構正在工作,但通過RoR流式傳輸圖像效率不高。我想讓Nginx做代理。這就是它的目的。建議的架構應該是這樣的:

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

我可以發送給Nginx來讓它代理數據?我不介意在我的基礎架構中添加Nginx模塊,當然我可以改變我的nginx.conf。

X-Sendfile是我發現的最接近的東西,但只允許從本地文件系統流式傳輸。也許還有一些其他模糊的HTTP響應頭或狀態碼,我不知道。

回答

3

使用X-Accel-Redirect頭文件與特殊的Nginx location結合使Nginx代理成爲遠程文件。

這裏是location添加到您的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; 
} 

現在,你只需要設置你的響應X-Accel-Redirect頭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 

完整的解決方案被發現here 。我建議在實施之前閱讀它。

+0

這是一個很好的解決方案,儘管一個小記錄...你不需要構造變量來重定向,你可以這樣做: proxy_set_pass http:// $ 1/$ 2; –

+0

我想這是爲了可讀性和可維護性的考慮。爲了避免將讀取該配置的下一個管理員的可能的WTF。 – Konstantin

相關問題