Nginx Multiple Conditional Test
Luke Hebert
- 2 minutes read - 320 wordsNginx does not support compound boolean expressions inside a single if block, so you often need to chain multiple if statements to build a decision. The trick is to accumulate a value into a variable across several conditions, then test that variable once at the end.
Building a Composite Variable
The example below checks three conditions in sequence. Each one appends a letter to $test when its condition is true:
if ($request_uri = /) {
set $test "A";
}
if ($host ~* teambox.com) {
set $test "${test}B";
}
if ($http_cookie !~* "auth_token") {
set $test "${test}C";
}After all three blocks run, $test holds a string like ABC, BC, or C depending on which conditions matched.
Routing on the Combined Result
Once the variable is assembled, a final if block performs the actual routing decision:
if ($test = ABC) {
proxy_pass http://teambox-cms.heroku.com;
break;
}The break directive is important here. It tells Nginx to stop processing further if blocks in the current context and use the proxy_pass that was just set. Without it, a later if could overwrite the upstream.
Things to Keep in Mind
Nginx if directives are notoriously tricky. The official docs call them “evil” for a reason. Stick to simple equality or regex tests, avoid nesting if blocks, and always pair proxy_pass with break to prevent unexpected overrides.
A few practical tips:
- Use
set(notrewrite ... last) when you only need to store a value. - Quote your variable expansions (
"${test}B") so Nginx does not misparse the string. - Test your configuration with
nginx -tbefore reloading. - If the logic grows beyond three or four conditions, consider moving the decision into a Lua script via
lua-nginx-modulefor cleaner, more maintainable code.
This pattern is especially handy when you need to combine a URI check, a host check, and a cookie check into a single routing rule without writing a separate server block for every combination.