snh_nl
snh_nl

Reputation: 2955

Nginx Rewrite of query params with multiple replacements

Hi we use nginx and because of a change in the system we have to temporarily 301 some URL's with query params. I have searched a lot but did not find a solution.

We want to

So our URI's should be rewritten like:

/page?manufacturer=812 **becomes** /page?brand=812
/page?manufacturer=812&color=11 **becomes** /page?brand=812&colour=33
/page?manufacturer=812&color=11&type=new **becomes** /page?brand=812&colour=33&sorttype=new
/page?color=11&type=new&manufacturer=812 **becomes** /page?colour=33&sorttype=new&brand=812

I know how to search and replace. But how can one search and replace multiple values? I am trying the following:

# Rewrite after attributes renaming
rewrite ^/(.*)manufacturer\=(.*)$ /$1brand=$2;
rewrite ^/(.*)color=(.*)$ /$1colour=$2;
rewrite ^/(.*)type=(.*)$ /$1sorttype=$2;
# there are about 20 more ... 

My question: how can I do a multiple replacement? (doesnt even have to be rewrite as long as the server executes the 'old' command). Should I use a map statement or is there a better trick?

Thanks in advance!

Upvotes: 3

Views: 2806

Answers (1)

Richard Smith
Richard Smith

Reputation: 49672

Where you have an indeterminate number of arguments in an indeterminate order, it may be simplest to modify one at a time, and recursively redirect the URL until all of the arguments are replaced.

The map directive is convenient for managing a long list of regular expressions. See this document for details.

The solution uses the $args variable which contains everything following the ? in the URI. We capture anything before the match (in case it's not the first argument) in $prefix, and we capture the value of the argument and any arguments following in $suffix. We use named captures as numeric captures may not be in scope when the new value is evaluated.

For example:

map $args $newargs {
    default 0;
    ~^(?<prefix>.*&|)manufacturer(?<suffix>=.*)$    ${prefix}brand$suffix;
    ~^(?<prefix>.*&|)color(?<suffix>=.*)$           ${prefix}colour$suffix;
    ~^(?<prefix>.*&|)type(?<suffix>=.*)$            ${prefix}sorttype$suffix;
}

server {
    ...
    if ($newargs) { return 301 $uri?$newargs; }
    ...
}

Upvotes: 4

Related Questions