I'm trying to set up a reverse proxy for an app that handles HTTPS redirect itself (i.e. if it notices that the protocol is not HTTPS it will redirect user to secure site):
server {
listen 80 default_server;
listen 443 ssl;
location / {
proxy_pass http://localhost:8080;
proxy_redirect default;
proxy_redirect https://$proxy_host/ https://$host/;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
The upstream server needs to know whether the original request was over https or not, which it should know via the X-Forwarded-Proto header, assuming $scheme
is be "http" on 80 and "https" on 443.
However, it seems that for requests to both 443 and port 80 have $scheme
set to "https" and $https
set to "on" always — i.e. those variables always say the connection is secure even when it's NOT? Are these variables "hardcoded" based on server configuration, and not the actual incoming request?
Best Answer
My bad. nginx does set
$scheme
(and presumably$https
) as I would expect, per-request.The trouble was the following node.js code:
It looks correct, but the operator precedence is actually wrong! Should be something like:
Without the fix, whenever
req.headers['x-forwarded-proto']
was present my localproto
would get set to "https" even though the header from nginx was correct!