1

From what I've gathered so far it's clear that running if statements in nginx should be avoided at all costs. Most of the examples I've found so far regarding specific page redirects involve multiple servers being used. But, isn't that a bit wasteful? I'm not sure, but I would think multiple servers to accomplish this would be somewhat slower then a single server when under heavy load.

My current server call is this:

server { listen 10.0.0.60:80; listen 10.0.0.60:443 default ssl; #other code } 

What I want to do is redirect certain http requests to https requests. For example, I want /login/ and /my-account/ to always be forced to use SSL. If you're on /help/ though, I want that served over the default http.

Is there a way to accomplish this within a single server call? Or is there no downside to using 2 server calls to get this working? nginx seems to be under pretty active development and a lot of the older guides I've followed were from times when you couldn't listen to requests for port 80 and 443 within the same server call. But now that nginx has been updated to support that (I'm running 1.2.4), I'm wondering if there's a "best practice" way of handling this today.

Any help would be greatly appreciated.

EDIT:

I did find this guide: http://redant.com.au/blog/manage-ssl-redirection-in-nginx-using-maps-and-save-the-universe/

and I updated my code as follows:

map $uri $my_preferred_proto { default "http"; ~^/#/user/login "https"; } server { listen 10.0.0.60:80; ## listen for ipv4; this line is default and implied listen 10.0.0.60:443 default ssl; if ($my_preferred_proto = "none") { set $my_preferred_proto $scheme; } if ($my_preferred_proto != $scheme) { return 301 $my_preferred_proto://mysite.com$request_uri; } 

It's not working though. When I change the default to https everything is redirected to SSL so it does somewhat work. But the redirect of /#/user/login is not redirecting to HTTPS. Any ideas? Also, is this a good way to go about this?

2
  • why not https everything? if you bother to setup https, then there is not much reason not to just serve everything over https. Commented Dec 12, 2012 at 12:39
  • Because a number of the files from the site are served via our API (different server) for normal HTTP requests. 98% of this sites traffic will come from http requests, so serving those files over https limits the load our nginx server can handle as we scale. But we do want our users to be able to log into this site and be forced to use SSL for both logging in and account management. Commented Dec 12, 2012 at 12:50

3 Answers 3

0

IFs are ok if used correctly. In your case you can try configuration block like this (not tested):

location /login { if ($scheme != 'https') { return 301 https://$host$url; } } 
1
  • What makes this IF statement better then others? Isn't this going to cause extra processing for every single request? I tried the statement by the way... but I had to change $url to $uri to get nginx working. That said, it's not redirecting to SSL for me. Commented Dec 12, 2012 at 13:34
0

It turns out I can't redirect this page due to the hash tag # in the URL. Because the hash tag only updates on the client browser side, the server can't see that URL. My original redirect code and Andrei's code (with my modification to the $uri) command also work correctly.

0

If using /login in the location block works for you, then changing the map entry to remove the hash similar to this ~/login "https"; should work as well.

Location blocks directly correlate to $uri maps like the one you used. Matching that works in a location block should work in a $uri mapping as well.

Also – as you realised – you need to match the path that the client requests from the server, not necessarily the same as what the client shows in the location bar.

p.s. – I wrote the guide you are linking to in the original question.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.