unescaping character in url

Maxim Dounin mdounin at mdounin.ru
Sun Oct 25 03:39:10 MSK 2009


On Sat, Oct 24, 2009 at 04:46:07PM +0200, Fr Tr wrote:

> Hi all,
> I have a problem trying to rewrite a URL.
> It should be pretty straightforward but it has been taking me hours
> searching.
> Google indexed urls containing ";", which gets escaped to %3B:
> http://server.com/plan/52%3Bjsessionid=A9594B224FF913C1A1AB83B0368C1581
> (the original url that works is
> http://server.com/path/52;jsessionid=A9594B224FF913C1A1AB83B0368C1581)
> First approach was:
> server {
> location /plan/ {
>   rewrite /plan/(.*)%3Bjsessionid=[A-Za-z0-9]+(.*)
> http://www.server.com/plan/$1$2 permanent;
> }
> (...)
> }
> but no dice, I get errors because it tries to fetch a file from disk (!)
> /usr/local/nginx/html/plan/52" failed (2: No such file or directory),
> Just to test I tried also with
> if ($args ^~ jsessionid){
>   rewrite ^ http://example.com/ permanent;
> }
> ...but it doesn't like the ^~ which btw means the wiki for
> NginxHttpRewriteModule is outdated for 0.6.29.

If never has "^~".  This combination used in location matching and 
means "no regex", i.e. do not search for regex locations if this 
static location match.

Proably you mean "!~" instead, but this anyway won't work as in 
your case jsessionid isn't in args but in path instead (three is 
no '?' which separates them).

> My question is: how can I simply do a rewrite to replace "%3B" to ";" ?

The basic problem is that you want to match "%3B" while nginx 
already decoded it to be ";" instead.  So the only aproach that 
will work is matching against $request_uri, the original URI as got 
from client.

Try this:

    if ($request_uri ~ "%3Bjsessionid=") {
        rewrite  ^(.*)$  http://example.com$1  permanent;

This will catch clients with "%3B" but not ones with ";".  
Resulting redirect will have "%3B" replaced by ";" as nginx 
already decoded it in internal representation.

Maxim Dounin

More information about the nginx mailing list