Nginx can not forward the request protocol correct

2019-01-18 04:26发布

问题:

I have a website in rails 4 beta. It is running on Nginx + Unicorn. I want nginx to forward the request protocol ( 'http' or 'https' ) to unicorn so that I can work with them. However I am not able to make it work.

I put <%= request.ssl? %> and <%= request.protocol %> in the view file for testing. My nginx server config file is as following:

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

I found that the 2 lines I marked are not acting right. Here is my test result:

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

Line 1 commented out, Line 2 commented out too :

visit http://the.url

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

visit https://the.url

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

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

Line 1 commented out, Line 2 is not OR Line 2 commented out, Line 1 is not OR Neither is comments out

visit http://the.url

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

visit https://the.url

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

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

That is to say, if one of those two lines appears, nginx forward "https" to upstream no matter what the actual protocol is. But if none of those two lines appears, nginx forward "http" to upstream no matter what the actual protocol is.

Please can someone tell me how to write the nginx config file so that it can forward the protocol correctly? Thank you very much.

回答1:

try:

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


回答2:

You will need to configure two separate server blocks. One for HTTP and one for HTTPS. It will make configuring the two a whole lot easier. Parts that are identical you can include from a separate shared config file.