i am trying use Nginx rewrite.
somehow its deletes the /
key when its first in string
nginx/1.21.3
rewrite rule:
#nginx not relevant conf here
location / {
rewrite ^(.*)data/([0-9] )/(. )?$ $1processor.php?key=$2&data=$3 last;
}
#nginx not relevant conf here
when i use this rewrite rule for any url i tested it was okay. when i tried url like the example below it somehow omitted the /
in the beginning.
https://example.com/data/9//*-+.`!@#$%^&*()_+`-=[];'\,./{}:"|<>?
when i reloaded nginx with notices and rewrite_log=on;
i got the output:
2021/09/25 13:08:29 [notice] 528#528: *11710 "^(.*)data/([0-9] )/(. )?$" matches "/data/199/*- .`!@#$%^&*()_ `-=[];'\,./{}:"|<>?", client: 192.168.255.107, server: localhost, request: "GET /data/199//*-+.`!@#$%^&*()_+`-=[];'\,./{}:"|<>? HTTP/2.0", host: "example.com", referrer: "https://example.com/"
php (8.0.10) $_GET["data"]
output is (as you can see without /
thus not exact math):
*- .`!@#$%^&*()_ `-=[];'\,./{}:"|<>?
how can i solve it?
CodePudding user response:
Both rewrite
and location
directives works with so-called normalized URI:
The matching is performed against a normalized URI, after decoding the text encoded in the “%XX” form, resolving references to relative path components “.” and “..”, and possible compression of two or more adjacent slashes into a single slash.
This means that on the first stage your URL /data/9//*-+.`!@#$%^&*()_+`-=[];'\,./{}:"|<>?
gets URL-decoded:
/data/9//*- .`!@#$%^&*()_ `-=[];'\,./{}:"|<>?
and on the second stage two adjacent slashes getting compressed into the one:
/data/9/*- .`!@#$%^&*()_ `-=[];'\,./{}:"|<>?
Exactly the above string is subject to test for rewrite
directive thus leading to missing of the first URL-encoded slash. However you can use the $request_uri
variable which contains the request URI in a non-modified form. You can use either
if ($request_uri ~ ^(?<prefix>.*/)data/(?<key>\d )/(?<data>[^?] )) {
rewrite ^ ${prefix}processor.php?key=$key&data=$data;
}
block to be placed under server context or
location /
if ($request_uri ~ ^(?<prefix>.*/)data/(?<key>\d )/(?<data>[^?] )) {
rewrite ^ ${prefix}processor.php?key=$key&data=$data last;
}
...
}
block placed under location context.