14

I'm trying to redirect requests to https in nginx, unless it is of the form HOST/ANY_STRING_OF_CHARS/END_OF_URI, e.g.:

http://host.org/about # no redirect

http://host.org/users/sign_in # redirects to https://host.org/users/sign_in

This apparently works in Apache, but I don't understand how the bang works (ignore if it doesn't really work):

RewriteRule !/([a-z]+)$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

How can I do this in a nginx rewrite rule? This is not working as I'd hoped:

rewrite !/([a-z]+)$ https://$server_name$request_uri redirect;

This doesn't do the redirect either, in case I had the logic backwards:

rewrite /([a-z]+)$ https://$server_name$request_uri redirect;

Help please?

kbighorse
  • 389
  • 1
  • 2
  • 15

2 Answers2

30

Sends a permanent redirect to the client:

server {
  listen 80;
  rewrite ^(/users/\w+)$ https://$host$1 permanent;
  ...
}

for negative match you could use:

if ($request_uri !~ "^/users/\w+$")
{
  return 301 https://$host$request_uri;
}
Jack
  • 1,892
  • 1
  • 19
  • 23
  • Thanks for this. I'm looking for a negative match, i.e. no redirect for a specific pattern, redirect for _everything_ else, not just requests with /users/ in it. Good call on `permanent`, I should be doing that. – kbighorse Apr 23 '13 at 06:15
  • I have added negative match for you. – Jack Apr 23 '13 at 11:51
  • Thank you! bonus points for a location block instead? I hear that's preferable to if, no? – kbighorse Apr 24 '13 at 18:13
  • 2
    You can't do negative match with location. – Jack Apr 24 '13 at 20:43
4
set $test "0";
if ($request_uri ~ "condition") {
   set $test "1";
}
if ($test ~ "0") {
   return 301 redirect url;
}
Sergiy Tytarenko
  • 472
  • 7
  • 17