Currently when using nginx behind an SSL-stripping load-balancer, there is no 
way to control the scheme used when generating directory redirects. By this I 
mean, if you are serving a static directory tree and you visit the URL of a 
directory without the trailing / (eg https://example.com/foo), you get served a 
redirect to http://example.com/foo/ (note trailing slash, and "http" instead of 
"https").

You could argue that the front-end load balancer should rewrite the redirect on 
its way from the backend to the client in this case, but alas not all 
hardware/software used for the front-end supports this correctly, and it also 
reduces the scalability/performance of the front-end if it has to scan for 
these URLs and correct them. I think nginx should support generating these 
redirects correctly in the back-end.

The code that generates these redirects is in ngx_http_header_filter_module.c, 
around line 528-529 (in v1.6.2). It only looks at whether connection->ssl is 0 
or not before deciding whether to introduce the 's' after 'http'.

This patch adds an extra flag to the ngx_connection_t called "ssl_set", and 
makes this redirect generator, as well as the getters for $scheme and $https, 
look at this flag as well as ->ssl. Then it adds a variable setter for $https 
that uses this flag where appropriate.

After this, you can simply add "set $https on;" to the server block on the 
backend server and it will generate correct redirects. Conveniently, you can 
also then use the stock fastcgi.conf / fastcgi_params for a back-end nginx and 
not have to worry about creating a different variable to make the fastcgi_param 
HTTPS be set correctly.

I thought about some alternatives to the "set $https on;" semantic -- maybe you 
should "set $scheme"? Or, as I've seen suggested once before, a "real_scheme" 
directive to pull it out of an HTTP header? It seems like there is not that 
much difference between the approaches though, and the "set variable" based 
approach is the most general: you can emulate the real_scheme directive with it 
by using a "map", but not the other way around. So if there are other ideas for 
a better approach I'd like to hear them, otherwise here is a patch for "set 
$https" :)


Attachment: nginx-set-https.patch
Description: Binary data

_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Reply via email to