Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Here's my abbreviated nginx vhost conf:

upstream gunicorn {
    server 127.0.0.1:8080 fail_timeout=0;
}

server {
    listen 80;
    listen 443 ssl;
    server_name domain.com ~^.+\.domain\.com$;

    location / {
        try_files $uri @proxy;
    }

    location @proxy {
        proxy_pass_header Server;
        proxy_redirect off;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 10;
        proxy_read_timeout 120;
        proxy_pass http://gunicorn;
    }
}

The same server needs to serve both HTTP and HTTPS, however, when the upstream issues a redirect (for instance, after a form is processed), all HTTPS requests are redirected to HTTP. The only thing I have found that will correct this issue is changing proxy_redirect to the following:

proxy_redirect http:// https://;

That works wonderfully for requests coming from HTTPS, but if a redirect is issued over HTTP it also redirects that to HTTPS, which is a problem.

Out of desperation, I tried:

if ($scheme = 'https') {
    proxy_redirect http:// https://;
}

But nginx complains that proxy_redirect isn't allowed here.

The only other option I can think of is to define the two servers separately and set proxy_redirect only on the SSL one, but then I would have duplicate the rest of the conf (there's a lot in the server directive that I omitted for simplicity sake). I know I could also use an include directive to factor out the redundancy, but I really want to keep just one conf file without any dependencies.

So, first, is there something I'm missing that will negate the problem entirely? Or, second, if not, is there any other way (besides including an external file) to factor out the redundant config information so that I can separate out the HTTP and HTTPS versions of the server config?

share|improve this question

2 Answers 2

up vote 2 down vote accepted

Well, I got a bit of inspiration and tried:

proxy_redirect http:// $scheme://;

Which seems to do the trick. This still seems hacky to me, though, so I still welcome any guidance on anything I might be doing wrong or less hacky ways to achieve the same result.

share|improve this answer

The other solution is to indicate to the upstream whether the request is HTTP or HTTPS and have it issue the according redirect. Adding this in the nginx config would set a header for the upstream to inspect.

proxy_set_header    X-Scheme $scheme;
share|improve this answer
    
Ah, I see now that you already have that configuration. –  mgorven Mar 23 '12 at 23:03
    
Yep. But I appreciate the attempt to help, nonetheless. –  Chris Pratt Mar 26 '12 at 15:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.