Nginx can not forward the request protocol correctly to upstream

Spread the love

Question Description

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.

Practice As Follows

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

Leave a Comment