#1504 closed defect (invalid)
Redirect issue when equaling $request_uri and $uri with unicode characters
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | major | Milestone: | |
Component: | nginx-core | Version: | 1.13.x |
Keywords: | Cc: | ||
uname -a: | Linux 541bb2841bf8 4.9.60-linuxkit-aufs #1 SMP Mon Nov 6 16:00:12 UTC 2017 x86_64 GNU/Linux | ||
nginx -V: | nginx version: nginx/1.13.9 |
Description
Nginx version: nginx:latest from docker (v1.13, tested in 1.12 too)
server { #root /var/www/html/public; location / { set $test_uri https://$host$request_uri; if ($test_uri != https://$host$uri) { #rewrite ^ $scheme://$host$uri$is_args$args? permanent; rewrite ^ http://test?uri=$uri&request_uri=$request_uri&test_uri=$test_uri; } root /usr/share/nginx/html; index index.html index.htm; } }
- curl -I
http://localhost:8081/čřčžřčž
- you get
http://test/?uri=/%C4%8D%C5%99%C4%8D%C5%BE%C5%99%C4%8D%C5%BE&request_uri=/%C4%8D%C5%99%C4%8D%C5%BE%C5%99%C4%8D%C5%BE&test_uri=https://localhost/%C4%8D%C5%99%C4%8D%C5%BE%C5%99%C4%8D%C5%BE
Attachments (1)
Change History (9)
by , 7 years ago
Attachment: | nginx-redirect-unicode-bug.png added |
---|
comment:1 by , 7 years ago
comment:2 by , 7 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
It is not clear what are you trying to do, but the if directive when used with the =
and !=
operators only allows comparing a variable with a string. As such, the condition used is always true, as you compare with the https://$host$uri
static string.
comment:3 by , 7 years ago
this example will solve for example duplicates versions of urls
http://example.com/test//test2/ will make redirect to http://example.com/test/test2/
set $test_uri $scheme://$host$request_uri; if ($test_uri != $scheme://$host$uri) { rewrite ^ $scheme://$host$uri$is_args$args? permanent; }
but
if your url contains nonASCI symbols like ůěščřžýáíé
... condition matcher will do infinite redirect because /%C4!=/%C4
it is bug in equal condition matcher
comment:4 by , 7 years ago
Resolution: | invalid |
---|---|
Status: | closed → reopened |
comment:5 by , 7 years ago
Resolution: | → invalid |
---|---|
Status: | reopened → closed |
Ah, I was actually wrong: the second operand of !=
can contain variables, hence the test actually works.
You misunderstand the difference between $uri
and $request_uri
though. Among other things, $uri
is unescaped, hence it is never equal to $request_uri
if the latter contains any escaped characters. This is obvious if you'll actually try to use curl with an actual escaped URL and the configuration you've provided:
$ curl -I http://127.0.0.1:8080/%C4%8D HTTP/1.1 302 Moved Temporarily Server: nginx/1.13.10 Date: Tue, 13 Mar 2018 02:46:40 GMT Content-Type: text/html Content-Length: 162 Connection: keep-alive Location: http://test?uri=/č&request_uri=/%C4%8D&test_uri=https://127.0.0.1/%C4%8D
Note that unescaped non-ASCII characters are not permitted in URIs, and browsers will escape them automatically, confusing things.
follow-up: 7 comment:6 by , 7 years ago
and what about this forgotten? patch 5years ago?
http://nginx.2469901.n2.nabble.com/ngx-unescape-uri-bug-td7584520.html
I think there should be 2 variables for $uri: $uri_escaped and $uri_unescaped
comment:7 by , 7 years ago
Replying to insekticid@…:
and what about this forgotten? patch 5years ago?
http://nginx.2469901.n2.nabble.com/ngx-unescape-uri-bug-td7584520.html
The "patch" in question doesn't really make sense - see my response there. And, more importantly, it is completely unrelated to your case, as the ngx_unescape_uri()
function is not used to unescape request URIs, it happens in the ngx_http_parse_complex_uri()
function (and it rejects invalid escaping).
I think there should be 2 variables for $uri: $uri_escaped and $uri_unescaped
See ticket #52.
the same problem with this config