I\'m quite new to Nginx so please bear with me.
I\'m trying to redirect all requests from one subdirectory (store) to the root of another subdirectory (trade). See
You need to ensure that your location ~ \.php$
handler does not take any URLs below the old folder. Indeed, precedence rules are clearly documented within http://nginx.org/r/location, and you can either use regular expressions, or, better yet, use prefix-based matching with the ^~
modifier to instruct that the search must stop without trying to see if that regex-based \.php$
location
would match:
location ^~ /old/long/path/ { # will match /old/long/path/index.php, too
rewrite ^/old/long/path/(.*)$ /new/$1 permanent;
}
The above snippet is likely the most efficient way of doing this, but here is another way of doing the same:
location ~ /old/long/path/(.*) {
return 301 /new/$1$is_args$args;
}
Why does one example has $is_args$args
and the other one doesn't? Good question! Note that location
directive as well as the first parameter of the rewrite
directive both operate based on the contents of the $uri
variable, as opposed to $request_uri
. Long story short, but $uri
does not contain $args
, so, in both cases, $1
will not contain any args
; however, in the case of rewrite
, the case is deemed so common that $args
are automatically added back by nginx, unless the new string ends with a ?
character, see http://nginx.org/r/rewrite.
Ok,
Coming back to this I can see the issue.
In Nginx when you prepend a location directive with ~ this means that you want to process regular expressions in your directive (case sensitive, ~* for case insensitive). I believe that all regex directives will process before any others but I stand to be corrected.
So when I am using:
location ~/store {
rewrite /trade permanent;
}
There is no regex there. Its is simply matching /store and redirecting to trade.
After some investigation (and polishing up on my regex, which is rubbish), I came back to it and have come up with a working solution.
location ~ ^/store/(.*) {
rewrite ^/store(.*) /trade permanent;
}
Here I am asking the directive to process the regex by entering ~ then match any url with /store/ in it.
Then, according to the docs, the rewrite syntax is:
rewrite regex replacement [ flag ]
so I am matching all urls with store in it and permanently redirecting them to the new subfolder.
Pretty easy really, embarrassingly so actually but hey, every day is a school day. I'm open to correction on all of this and hope it helps someone.
ok try something like this
location ^~ /store(.*) {
return 301 $scheme://$http_host/trade$1$is_args$query_string;
}
Trying to avoid hardcoded stuff as much as possible and using return because it's prefered over permanent rewrites