AnthonyMMK
AnthonyMMK

Reputation: 11

Rewrite one specific argument with nginx rewrite

I want to rewrite an argument given via URL on my nginx server from "my_arg" to "my-arg". The problem is that I can't know how many arguments there will be in advance nor the position of these arguments. I can only know if the arguments is there using :

if ($args ~ (.*)my_arg=(.*)) {
    rewrite ....
}

But i cannot achieve to only change the name of this argument without changing every others.

Thanks by advance

Upvotes: 1

Views: 2162

Answers (1)

Ivan Shatsky
Ivan Shatsky

Reputation: 15518

For anything except HTTP 301/302 redirection you'd better just change an $args variable value:

if ($args ~ (^|.*&)my_arg=(.*)) {
    set $args $1my-arg=$2;
}

If you want to generate a redirect, things will be more complicated. Since any rewrite directive performs its own URI matching against some regex pattern, all the $1, $2 and so on variables from previous matching will be overwritten, and you can't match a query part of the URI to get them re-evaluated since rewrite directive works with normalized URI that doesn't include a query part. Your only way is to use named capture groups:

if ($args ~ (?<prefix>^|.*&)my_arg=(?<suffix>.*)) {
    rewrite ^ $uri${prefix}my-arg=$suffix? <redirect|permanent>;
}

Trailing question mark used intentionally since as rewrite directive documentation says,

If a replacement string includes the new request arguments, the previous request arguments are appended after them. If this is undesired, putting a question mark at the end of a replacement string avoids having them appended, for example:

rewrite ^/users/(.*)$ /show?user=$1? last;

Upvotes: 1

Related Questions