VMold
VMold

Reputation: 37

Rename args in nginx redirect

I am trying to get an NGINX redirect to take me from:

https://example.com/ui/?outletID=123&setID=456

to:

https://example.com/ui/?outletId=123&setIds=456

So outletID -> outletId AND setID -> setIds

IMPORTANT: I don't know where these params appear inside the URL, so there might be other strings before or after these. I only care for this replacements: outletID -> outletId; setID -> setIds.

This works at first try:

if ($args ~* "^outletID=(\d+)&setID=(\d+)(.*)") {
    set $outletid $1;
    set $setid $2;
    set $everythingelse $3;
    set $args '';
    rewrite ^.*$ /ui/?outletId=$outletid&setIds=$setid$everythingelse permanent;
}

But it looks like really bad practice and I particularly hate the $everythingelse ($3) solution I ended up with.

Upvotes: 3

Views: 876

Answers (2)

Alexander Azarov
Alexander Azarov

Reputation: 13221

Per Nginx documentation,

If a replacement string includes the new request arguments, the previous request arguments are appended after them.

So, in case you don't mind having old outletID and setID hanging around, you could simply do:

rewrite (.*) $1?outletId=$arg_outletID&setIds=$arg_setID permanent;

This way, you'll get something like https://example.com/ui/?outletId=123&setIds=456&outletID=123&setID=456.


But if you would like to have the URLs clean after redirection, Nginx has you covered as well. The excerpt from the same documentation:

If this is undesired, putting a question mark at the end of a replacement string avoids having them appended

Which means, you have to enumerate all the parameters you need to pass. For example, if you have some another possible parameter in query string session, you'll need to include it:

rewrite (.*) $1?outletId=$arg_outletID&setIds=$arg_setID&session=$arg_session? permanent;

Note the ? in the end of replacement string.


Personally I would choose the first approach, because it is less error-prone and will not break your application unexpectedly at the time you added a new parameter.

Upvotes: 1

Richard Smith
Richard Smith

Reputation: 49702

To cover all possibilities, you probably need to do this in two stages, one redirect if outletID is present, and another redirect if setID is present.

For example:

if ($args ~ ^(.+&|)outletID(=.*)$) {
    return 301 "$uri?${1}outletId$2";
}
if ($args ~ ^(.+&|)setID(=.*)$) {
    return 301 "$uri?${1}setIds$2";
}

Upvotes: 1

Related Questions