2013-01-16 2 views
4

우리 사이트는 이미지 저장소입니다. 각 이미지에는 외부 URL과 내부 URL이라는 개념이 있습니다. 외부 URL은 고객이 볼 수 있으며 SEO를 실험하면서 변경됩니다. 내부 URL은 이미지 호스팅 서비스를 가리키는 영구 URL입니다. 우리는 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

특수한 Nginx location과 함께 X-Accel-Redirect 헤더를 사용하면 Nginx 프록시에서 원격 파일을 프록시 처리 할 수 ​​있습니다. 여기

는 Nginx의 구성에 추가 할 location입니다 : 전체 솔루션 here을 발견

# 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 

:

# 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; 
} 

지금 당신은 Nginx에에 대한 응답에서 X-Accel-Redirect 헤더를 설정해야 . 구현하기 전에 그것을 읽는 것이 좋습니다.

+0

이것은 훌륭한 해결책입니다. 그러나 작은 노트 ... 리디렉션을 수행하기 위해 변수를 구성 할 필요가 없습니다. 단지 할 수 있습니다. proxy_set_pass http : // $ 1/$ 2; –

+0

가독성과 유지 관리상의 문제가 있다고 가정합니다. 다음 관리자로부터 가능한 설정을 읽을 수있는 WTF를 피하십시오. – Konstantin

관련 문제