I would like to check if a parameter named "token" exists in the url and is not empty. Based on the result of the test, I would like to redirect
or use a proxy_pass
.
Examples:
url | status |
---|---|
https://example.com/application/foo?token=123 | proxy_pass |
https://example.com/application/foo?token=&bar="abcde" | redirect |
https://example.com/application/foo?bar="abcde" | redirect |
https://example.com/application/foo?token= &bar="abcde" | redirect |
My current conf:
location /application/foo {
if ($arg_token) {
proxy_pass http://127.0.0.1:8512/application/foo;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
return 302 https://example.com/?application=foo&$args;
}
But it returns the following error:
nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block
I have checked this question about the aforementioned error, but it explains the behavior for location
directives and not for if
s.
I tried using a negation of the if test but could not manage to either make the desired behavior or have no error. I also know that if
s are evil in nginx, but I don't know enough about nginx to do what I want differently.
CodePudding user response:
The if
within a location
is best restricted to executing return
or rewrite
statements, as advised here.
In Nginx, an undefined or empty argument both evaluate to the empty string, so you can use = ""
to invert the logic of your if
statement. Thus moving the return
statement inside the block and the proxy_pass
statement outside of the block.
For example:
location /application/foo {
if ($arg_token = "") {
return 302 https://example.com/?application=foo&$args;
}
proxy_pass ...;
...
}