2013-04-25 28 views
13

我有一个网站在rails 4测试版。它在Nginx + Unicorn上运行。我希望nginx将请求协议('http'或'https')转发给独角兽,以便我可以使用它们。但是我无法使它工作。Nginx无法正确转发请求协议到上游

我把<%= request.ssl? %><%= request.protocol %>放在视图文件中进行测试。我的Nginx服务器的配置文件是如下:

upstream unicorn { 
    server unix:/tmp/unicorn.blog.sock fail_timeout=0; 
} 

server { 
    listen 80; 
    listen 443; 
    server_name example.com; 
    root /home/example; 

    ssl on; 
    ssl_certificate /etc/nginx/ssl/server.crt; 
    ssl_certificate_key /etc/nginx/ssl/server.key; 

    location ^~ /assets/ { 
    gzip_static on; 
    expires max; 
    add_header Cache-Control public; 
    } 

    try_files $uri/index.html $uri @unicorn; 

    location @unicorn { 
    proxy_set_header X-Forwarded-Proto https; # <--- Line 1 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header Host $http_host; 
    proxy_set_header X-Forwarded-Ssl on;  # <--- Line 2 
    proxy_redirect off; 
    proxy_pass http://unicorn; 
    } 

    error_page 500 502 503 504 /500.html; 
    client_max_body_size 4G; 
    keepalive_timeout 10; 
} 

我发现,2线标志着我不采取行动的权利。下面是我的测试结果:

=================

1行注释掉,2号线注释掉太:

访问http://the.url

<%= request.ssl? %>  : false 
<%= request.protocol %> : http 

访问https://the.url

<%= request.ssl? %>  : false 
<%= request.protocol %> : http 

=================

注释掉1号线,2号线是不是OR 2行注释掉,1号线是不是OR 也不是注释掉

访问http://the.url

<%= request.ssl? %>  : true 
<%= request.protocol %> : https 

访问https://the.url

<%= request.ssl? %>  : true 
<%= request.protocol %> : https 

=================

也就是说,如果出现这两行中的一行,nginx会向上游转发“https”,无论实际的协议是什么。但是,如果这两行中没有一行出现,nginx会将“http”转发到上游,无论实际的协议是什么。

请有人能告诉我如何编写nginx配置文件,以便它可以正确地转发协议?非常感谢你。

回答

34

尝试:

proxy_set_header X-Forwarded-Proto $scheme; 

OR

server { 
    Listen 80 
    ... 
} 
server { 
    Listen 443 
    ... 
    location @unicorn { 
     proxy_set_header X-Forwarded-Proto https; 
     proxy_set_header X-Forwarded-Ssl on; 
    } 
} 
+0

谢谢,这工作。 – blacktulip 2013-04-25 20:02:35

+1

我的意思是第二种方法奏效。第一个不是。 – blacktulip 2013-04-25 20:13:31

+2

对我来说,第一种方法完美地工作(当添加到'location @ unicorn'块中时),但我只关心该方案(用于在我的Rails应用程序中正确构建URL)。 – spume 2013-12-12 17:06:59

1

您将需要配置两个独立的服务器块。一个用于HTTP,一个用于HTTPS。这将使配置这两个更容易。您可以从单独的共享配置文件中包含相同的部分。

+0

谢谢。我有一个模糊的感觉,它看起来像在proxy_set_header行硬编码... – blacktulip 2013-04-25 20:06:09