Nginx Rewrites vs Redirects: Which Takes Precedence?

nginxredirectrewrite

I have some redirects set up in an include file for our nginx config. I noticed the other day that some redirects aren't working, and they seem to just be the ones that are impacted by rewrite rules.

Can anyone take a look and see what I've done wrong? Here are the relevant snippets:

/etc/nginx/sites-available/MySite.conf:

server {
    listen 443 ssl http2 default_server;
    server_name www.example.com ;
    include /etc/nginx/sites-available/includes/Redirects.conf;
    include /etc/nginx/sites-available/includes/Rewrites.conf;
    ...
}

/etc/nginx/sites-available/includes/Redirects.conf:

#This redirect works:
location ~ ^/images/products/1234.jpg { return 301 /images/products/5678.jpg$is_args$args ; }
#This redirect does NOT work
location ~ ^/p/1234 { return 301 /p/5678$is_args$args ; }

/etc/nginx/sites-available/includes/Rewrites.conf:

#This rewrites the short URL /p/<ProductCode> to our ecommerce system's default URL
#I think this is what is conflicting with the redirect above
rewrite ^/p/(.*) /mm5/merchant.mvc?Screen=PROD&Product_Code=$1 break;

Best Answer

It may not be clear from the documentation, but rewrite directives in the server block are evaluated sequentially before the search for a location to process the URI.

So the "rewrite ^/p/(.*) ..." statement will be evaluated before the "location ~ ^/p/1234 ..." statement, irrespective of the order of these two statements.

You could convert your rewrite statements into location blocks or vice versa.

For example:

rewrite ^/p/1234 /p/5678 permanent;
rewrite ^/p/(.*) /mm5/merchant.mvc?Screen=PROD&Product_Code=$1 break;
Related Topic