I have an URL of this type:

http://www.example.com/?param1=val1&param2=&param3=val3&param4=val4&param5=val5

And I want to redirect it to this one:

http://www.example.com/newparam/val3/val4

So I have tried this rewrite rule with no success:

rewrite "/?param1=val1&param2=&param3=(.+)&param4=(.+)&param5=(.+)" http://www.example.com/newparam/$1/$2 redirect;

Is nginx not able to deal with query parameters?

EDIT: I don't want to rewrite all petitions. I only need to rewrite that URL, without affecting the others.

link|improve this question

75% accept rate
feedback

3 Answers

Ok, thanks to the initial help of rzab, I have redefined his rule to this working solution:

location / {
    if ($args ~* "/?param1=val1&param2=&param3=[0-9]+&param4=.+&param5=[0-9]+") {
        rewrite ^ http://www.example.com/newparam/$arg_param3/$arg_param4? last;
    }
}

I just added a condition to avoid infinite recursion, and a ? at the end of the rule to get rid of the initial params. It works perfectly :)

link|improve this answer
Query string allows a different order of parameters. So your if will stop working when e.g. param2 goes before param1. – Alexander Azarov Jul 17 '10 at 5:52
Interesting. In my case it will not occur because it's a clickable url in an e-mail, but it's good to know. Thanks. – David Jul 19 '10 at 7:14
feedback
location = / {
  rewrite ^ http://www.example.com/newparam/$arg_param3/$arg_param4;
}
link|improve this answer
So, must I write $arg_ and then the parameter name? – David Jul 15 '10 at 18:36
Yes, that would be the easiest. – Martin Fjordvald Jul 15 '10 at 19:36
Ok, but I don't want to rewrite all petitions. I only need to rewrite that URL, without affecting the others. – David Jul 16 '10 at 7:59
I have made some tests. That rule will generate an infinite redirection. I will write a new answer with the code I got to work. Thanks :) – David Jul 16 '10 at 8:13
I should probably mention, that you have to declare "location /" besides "location = /" to avoid recursion. I guess you'll have it to proxy_pass somewhere as the main route. "location = /" matches exactly / requests. Anyway, matching $args seems ok, except it'll match any request with the parameters ?param1=val1&.... – rzab Jul 16 '10 at 8:45
feedback

if is rather limited. It does not support conjunction, so the only way to replace and is to write nested ifs:

location / {
  if ($arg_param1 = "val1") {
    if ($arg_param2 = "") {
      if ($arg_param3 ~* "[0-9]+") {
        if ($arg_param4 ~* ".+") {
          if ($arg_param5 ~* "[0-9]+") {
            rewrite ^ http://www.example.com/newparam/$arg_param3/$arg_param4? last;
          }
        }
      }
    }
  }
}
link|improve this answer
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.