Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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.

share|improve this question

3 Answers 3

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 :)

share|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
location = / {
  rewrite ^ http://www.example.com/newparam/$arg_param3/$arg_param4;
}
share|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

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;
          }
        }
      }
    }
  }
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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