String replace on rewrite module

My goal is simple. Rewrite the following URL:

[b]http://example.com/path/to/folder/image/picture1.jpg[/b]

to

[b]http://example.com/image/path_to_folder/picture1.jpg[/b]

My doubt is: how can I transform path/to/folder into
path_to_folder?

In fact, all I want to know is how to substitute the forward slashes
“/” by underscores “_”

The path/to/folder can be nested in unknown levels (as in
path/to/a/very/deep/level/folder )

Is there a “string replace” function in rewrite module to do this? Or
something else?

Thanks!

Posted at Nginx Forum:

JBruni,

Eventually you’ll need something like:

rewrite ^(/.)/(.)/(.)/image/(.)$ $1_$2_$3/$4 break;

More info available at: Module ngx_http_rewrite_module

Alex.

Oh, missed part about nestedness to more levels…

You just can write multiple rewrites for 1 level, 2 levels and so on for
up to 9 levels deep. Would that be enough?

You can also build map of all possible redirects from all "virtual
folder names to “underscored” and use it faster than rewrite everything
at once.

You can also build recursive redirects like in my example, without break
to make nginx repeat cycle of rewrites again, up to 10 times.

Alex

2010/7/20 jbruni [email protected]:

Anyway, a “string replace” function for the rewrite module remains a
wish as a feature request

I think there’s embedded perl for that kind of stuff, but i can’t help
because i don’t know perl :slight_smile:

Alex S. Wrote:

You can also build recursive redirects like in my
example, without break
to make nginx repeat cycle of rewrites again, up
to 10 times.

Thanks a lot, Alex,

Your comments enlightened my path!

Here is the working configuration:

  location ~ ^/(.*)/([^/]+)/image/([^/]*)$ {
    set $part1 $1;
    set $part2 $2;
    set $filename $3;
    rewrite ^.*$ /${part1}_$part2/image/$filename last;
  }

  location ~ ^/([^/]+)/image/([^/]*)$ {
    set $folder $1;
    set $filename $2;
    rewrite ^.*$ /image/$folder/$filename break;
  }

The first location directive is recursive, and keeps joining the paths,
replacing “/” by “_” on each iteration.

The second location directive is the final one. When all path pieces are
already joined, it does the final rewrite.

Cool!

Anyway, a “string replace” function for the rewrite module remains a
wish as a feature request

Thanks!

Posted at Nginx Forum:

On Wed, 2010-07-21 at 10:32 +0600, Mikhail Mazursky wrote:

I think there’s embedded perl for that kind of stuff, but i can’t help
because i don’t know perl :slight_smile:

Yeah… something like this would also work

perl_set $underscored_uri ‘sub { ($_ = $[0]->uri) =~
s/(?<=.)/(?=.*/)/
/g; $_ }’

location /something {
rewrite . $underscored_uri last;
}

  1. you’re ending up with perl module which is big
  2. could be trickier if you have querystring to process
  3. likely it’ll be slower than recursive rewrites.

Alex.

p.s.
if you want to debug this in command line:

perl -Mstrict -we ‘sub uri{$ARGV[0]} sub test{($=uri()) =~
s/(?<=.)/(?=.*/)/
/g;$_} print
test()."\n"’ /lkasld/asda/sda/sd/image.gif

will print you
/lkasld_asda_sda_sd/image.gif