Skip to content

Instantly share code, notes, and snippets.

@jrom
Created February 7, 2012 17:14
Show Gist options
  • Save jrom/1760790 to your computer and use it in GitHub Desktop.
Save jrom/1760790 to your computer and use it in GitHub Desktop.
nginx hack for multiple conditions
if ($request_uri = /) {
set $test A;
}
if ($host ~* teambox.com) {
set $test "${test}B";
}
if ($http_cookie !~* "auth_token") {
set $test "${test}C";
}
if ($test = ABC) {
proxy_pass http://teambox-cms.heroku.com;
break;
}
@osabate
Copy link

osabate commented Aug 21, 2015

👍

@Richzendy
Copy link

Thank you so much, this hack is awesome! 🤘

@zarza
Copy link

zarza commented Oct 29, 2015

Thank you!

@maderlock
Copy link

What versions of nginx does this work on? I can't get it working on 1.4.7

@Hubbitus
Copy link

Why not just use map instead?

@achorein
Copy link

👍

@Asoul
Copy link

Asoul commented Mar 15, 2016

Awesome!

@sketchthat
Copy link

Thanks, worked great.

I had some problems with it if it was within a location statement, taking it out and putting it in the server statement helped fix it.

@prafulliu
Copy link

Thanks !

@laike9m
Copy link

laike9m commented Apr 19, 2016

Wow

@songsfromthewood
Copy link

songsfromthewood commented May 17, 2016

Seems, you are not familiar with map, or do not like it. More short and elegant:

":" is used just like delimiter, you can use any other symbol not used in checked variables.

map "$request_uri:$host:$http_cookie" $test {
    default 0;
    "/:teambox.com:auth_token"  1;
}

server {
    if ( $test ) {
      proxy_pass http://teambox-cms.heroku.com;
      break;
    }
}

@osgregs
Copy link

osgregs commented Aug 15, 2016

Só precisava disso pra dar nó em pingo d agua, thks

@dxgldotorg
Copy link

dxgldotorg commented Sep 27, 2016

This will help me migrate a .htaccess based referer filter to nginx; my first try caused redirect loops in Firefox but Chrome displayed the error page after giving up on the loop. I set A for the referer check, and B for the check that it isn't trying to load the error page, then I check to see if the combined variable is A, as the B check is a "not" check.
I will test the filter out tomorrow, and if it works I will be able to migrate away from Apache handling my .php files.

Edit: Worked like a charm! Thanks for the tutorial!

@GeoffreyHervet
Copy link

Thanks !

@sinasalek
Copy link

You are a god :D

@PeterRJones
Copy link

Great solution! For those suggestion a map, that is great if condition variable remains the same for all checks. If not, this solution trumps map.
+1

@danlsgiga
Copy link

Thanks for this but I prefer to use @songsfromthewood map solution.

@glamrock
Copy link

@songsfromthewood's example works great, with the exception of empty strings (like referer or useragent). But for blank referer and useragent, it's still pretty good :D

@aluttik
Copy link

aluttik commented Aug 30, 2017

for those who haven't read this yet: If Is Evil

@nkn786
Copy link

nkn786 commented Nov 30, 2017

Hi All,

I am checking the header "x-token" present from the incoming request if not i have to send 403 in nginx below is my code

if ($http_x-token = ""){
return 403;
break;
}
proxy_pass http://127.0.0.1:1234;

But here "-" is the problem so how do i achieve this. if i pass the header as "xtoken" its working as expected
Could you please any one guide on this query.

Regards,
Naveen

@NickHibma
Copy link

nkn786, try $http_x_token.

@havilchis
Copy link

You truly are the king of kings

@onier
Copy link

onier commented Aug 10, 2018

awesome ! 666666

@ezra-obiwale
Copy link

Nice. Thanks

@escudero89
Copy link

Awesome man, thanks.

@Azzurite
Copy link

Azzurite commented Sep 6, 2019

Seems, you are not familiar with map, or do not like it. More short and elegant:

":" is used just like delimiter, you can use any other symbol not used in checked variables.

map "$request_uri:$host:$http_cookie" $test {
    default 0;
    "/:teambox.com:auth_token"  1;
}

server {
    if ( $test ) {
      proxy_pass http://teambox-cms.heroku.com;
      break;
    }
}

@songsfromthewood Actually no, yours does not match "test.teambox.com" while the original post does.

@boddumanohar
Copy link

this is awesome!

@GoodJob
Copy link

GoodJob commented Mar 17, 2021

Need explanation.... what actually this does:
if ($host ~* teambox.com) {
set $test "${test}+teambox.com";
}
Does it takes "this".teambox.com or what? Thanks!

How to write this condition?

if ($host *.teambox.com) {
set $subdomain_name = ?;
}

Thanks!

@lordspace
Copy link

lordspace commented Jun 26, 2023

Awesome!!!! Thanks!
If somebody needs an explanation what the code does is it sequentially appends different letters to one variable.
When all the letters are present that means that all the required conditions have been met.

@eladnava
Copy link

This works great!

I recommend initializing the $test variable outside and above all the conditional statements to avoid endless using uninitialized "test" variable errors piling up in /var/log/nginx/error.log as follows:

set $test "";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment