Redirect on $args based on multiple params?


#1

Is there any way to capture multiple parameters from a querystring for a
rewrite?

For example:
The request is: /myscript.php?a=b&c=d&z=y
The target is: /script/a/b/c/d/z/y

So, the basic rewrite would be:

location /myscript.php {
if( $args ~* ^a=([^&]+)&b=([^&]+)&z=([^&]+)$ ){
rewrite ^ /script/a/$1/b/$2/z/$3 permanent;
}
}

However, how would I cope with situations where the args aren’t in the
order of a/b/z? Obviously if I have 10 args I don’t want to have to do
an “if” for each permutation, that could get both confusing and lengthy!


#2

On Wed, Mar 25, 2009 at 03:55:02PM +0000, Phillip B Oldham wrote:

if( $args ~* ^a=([^&]+)&b=([^&]+)&z=([^&]+)$ ){
rewrite ^ /script/a/$1/b/$2/z/$3 permanent;
}
}

However, how would I cope with situations where the args aren’t in the
order of a/b/z? Obviously if I have 10 args I don’t want to have to do
an “if” for each permutation, that could get both confusing and lengthy!

No way. This is one of the reasons why locations test URI only.


#3

On Wed, Mar 25, 2009 at 08:58:00PM +0300, Maxim D. wrote:

to avoid query string appending.
}
location /myscript.php {
rewrite ^ /script/a/$arg_a/b/$arg_b/z/$arg_z? permanent;
}

I forgot simply about them :slight_smile:


#4

Hello!

On Wed, Mar 25, 2009 at 03:55:02PM +0000, Phillip B Oldham wrote:

if( $args ~* ^a=([^&]+)&b=([^&]+)&z=([^&]+)$ ){
rewrite ^ /script/a/$1/b/$2/z/$3 permanent;

JFYI: This won’t ever pass configuration tests - captures from
if() will be reset by rewrite itself. It should use intermediate
set’s to save captures. Also, “if(” should be rewritten as “if (”,
and probably trailing ‘?’ should be added to rewrite destination
to avoid query string appending.

Correct version would be

location /myscript.php {
    if ($args ~* ^a=([^\&]+)&b=([^\&]+)&z=([^\&]+)$) {
        set $a $1;
        set $b $2;
        set $z $3;
        rewrite ^ /script/a/$a/b/$b/z/$z? permanent;
    }
}

}
}

However, how would I cope with situations where the args aren’t in the
order of a/b/z? Obviously if I have 10 args I don’t want to have to do
an “if” for each permutation, that could get both confusing and lengthy!

In 0.7.8+ you may use $arg_* variables for this, e.g.

location /myscript.php {
    rewrite ^ /script/a/$arg_a/b/$arg_b/z/$arg_z? permanent;
}

Note that this isn’t exactly the same thing as the original one
since it doesn’t actually test presence of the arguments.

Compatible with 0.6.* version would be

location /myscript.php3 {
    set $a "";
    set $b "";
    set $z "";
    if ($args ~* "(?:^|&)a=([^&]+)") {
        set $a $1;
    }
    if ($args ~* "(?:^|&)b=([^&]+)") {
        set $b $1;
    }
    if ($args ~* "(?:^|&)z=([^&]+)") {
        set $z $1;
    }
    rewrite ^ /script/a/$a/b/$b/z/$z? permanent;
}

Maxim D.


#5

Hello!

On Thu, Mar 26, 2009 at 01:17:36AM +0300, Igor S. wrote:

The request is: /myscript.php?a=b&c=d&z=y
set’s to save captures. Also, “if(” should be rewritten as “if (”,
rewrite ^ /script/a/$a/b/$b/z/$z? permanent;
In 0.7.8+ you may use $arg_* variables for this, e.g.

location /myscript.php {
    rewrite ^ /script/a/$arg_a/b/$arg_b/z/$arg_z? permanent;
}

I forgot simply about them :slight_smile:

Sure. :slight_smile:

And it looks like you also forgot about my patch that fixes them
when used in ssi subrequests. It still applies cleanly to 0.7.44.
Should I resend it?

Maxim D.


#6

On Thu, Mar 26, 2009 at 01:35:40PM +0300, Maxim D. wrote:

Is there any way to capture multiple parameters from a querystring for a
rewrite ^ /script/a/$1/b/$2/z/$3 permanent;
if ($args ~* ^a=([^&]+)&b=([^&]+)&z=([^&]+)$) {
However, how would I cope with situations where the args aren’t in the

Sure. :slight_smile:

And it looks like you also forgot about my patch that fixes them
when used in ssi subrequests. It still applies cleanly to 0.7.44.
Should I resend it?

No, it will be in next 0.7.48, thank you.


#7

Maxim D. wrote:

In 0.7.8+ you may use $arg_* variables for this, e.g.

location /myscript.php {
    rewrite ^ /script/a/$arg_a/b/$arg_b/z/$arg_z? permanent;
}

Ah, perfect!

Note that this isn’t exactly the same thing as the original one
since it doesn’t actually test presence of the arguments.

I’d still be able to wrap that rewrite in an if though, to test whether
any of the params are there, wouldn’t I?

Phillip B Oldham
The Activity People
removed_email_address@domain.invalid mailto:removed_email_address@domain.invalid


Policies

This e-mail and its attachments are intended for the above named
recipient(s) only and may be confidential. If they have come to you in
error, please reply to this e-mail and highlight the error. No action
should be taken regarding content, nor must you copy or show them to
anyone.

This e-mail has been created in the knowledge that Internet e-mail is
not a 100% secure communications medium, and we have taken steps to
ensure that this e-mail and attachments are free from any virus. We must
advise that in keeping with good computing practice the recipient should
ensure they are completely virus free, and that you understand and
observe the lack of security when e-mailing us.