Hi,
I have observed strange behavior with nginx rewrites. What happens: I get request going to myserver.com/appID/path1/path2/uglyID and I need to proxy this to appID.backend.internal/path1/path2/uglyID. The uglyID is URL encoded because it contains characters like commas and forward slashes. When I do location matching in nginx, nginx will url decode $uri parameter on which it does matches. That's not a problem, when the location matches, I can extract the appID and then extract the rest from $request_uri. And here the issue happens. If I use:
if ($request_uri ~ ^/[^\/]+(/.*)$ ) { set $path $1; }, the uglyID (but only uglyID) gets URL encoded again. The $path simply is /path1/path2/urlEncoded(uglyID). However, when I do
if ($uri ~ ^/[^\/]+(/.*)$ ) { set $path $1; }, then $path will be the urlDecoded(/path1/path2/uglyID) - as expected.
I have tested this on ubuntu 12.04 (Linux ip-10-50-20-57 3.2.0-36-virtual #57-Ubuntu SMP Tue Jan 8 22:04:49 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux) and nginx versions nginx/1.1.19 and nginx/1.5.6 - and the behavior is consistently same in both versions. The nginx config is identical in all cases, only difference is the name of the variable in the if statement, where using $request_uri simply implies uglyID (but only uglyID - not the whole matched string) will be url encoded again. Meanwhile I have found possible workaround using maps, where matching on $request_uri works correctly and doesn't modify matched data anyhow.
So I wonder, has anyone else experienced this? Is this expected? Why is the uglyID (but only uglyID) url encoded again? I would expect either urlEncoding of the whole match, or none at all - as it doesn't happen when I try to match e.g. $uri... Could this indicate a possible bug?
Thanks,
Michael
I have observed strange behavior with nginx rewrites. What happens: I get request going to myserver.com/appID/path1/path2/uglyID and I need to proxy this to appID.backend.internal/path1/path2/uglyID. The uglyID is URL encoded because it contains characters like commas and forward slashes. When I do location matching in nginx, nginx will url decode $uri parameter on which it does matches. That's not a problem, when the location matches, I can extract the appID and then extract the rest from $request_uri. And here the issue happens. If I use:
if ($request_uri ~ ^/[^\/]+(/.*)$ ) { set $path $1; }, the uglyID (but only uglyID) gets URL encoded again. The $path simply is /path1/path2/urlEncoded(uglyID). However, when I do
if ($uri ~ ^/[^\/]+(/.*)$ ) { set $path $1; }, then $path will be the urlDecoded(/path1/path2/uglyID) - as expected.
I have tested this on ubuntu 12.04 (Linux ip-10-50-20-57 3.2.0-36-virtual #57-Ubuntu SMP Tue Jan 8 22:04:49 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux) and nginx versions nginx/1.1.19 and nginx/1.5.6 - and the behavior is consistently same in both versions. The nginx config is identical in all cases, only difference is the name of the variable in the if statement, where using $request_uri simply implies uglyID (but only uglyID - not the whole matched string) will be url encoded again. Meanwhile I have found possible workaround using maps, where matching on $request_uri works correctly and doesn't modify matched data anyhow.
So I wonder, has anyone else experienced this? Is this expected? Why is the uglyID (but only uglyID) url encoded again? I would expect either urlEncoding of the whole match, or none at all - as it doesn't happen when I try to match e.g. $uri... Could this indicate a possible bug?
Thanks,
Michael