Home > Enterprise >  Test if parameter exists and handle proxy_pass in nginx
Test if parameter exists and handle proxy_pass in nginx

Time:12-08

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 ifs.

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 ifs 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 ...;
    ...
}
  • Related