Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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;
}
@openalmeida

This comment has been minimized.

Copy link

openalmeida commented Nov 7, 2013

This method is totally awesome !
Nginx conf file hack for multiple conditions of if statement.

@willejs

This comment has been minimized.

Copy link

willejs commented Feb 24, 2014

if is evil

@bakulrujak

This comment has been minimized.

Copy link

bakulrujak commented Mar 25, 2014

I got "invalid variable name in..." when implementing this trick.

@stannehill

This comment has been minimized.

Copy link

stannehill commented Apr 19, 2014

About if being "evil"... it's not that simple. The nginx docs say "There are cases where you simply cannot avoid using an if, for example if you need to test a variable which has no equivalent directive."

@FestivalBobcats

This comment has been minimized.

Copy link

FestivalBobcats commented Jul 19, 2014

If is only "evil" in location context.

@nukulb

This comment has been minimized.

Copy link

nukulb commented Feb 6, 2015

brilliant!

@akraskov

This comment has been minimized.

Copy link

akraskov commented Mar 19, 2015

Nice, thanks!

@shranet

This comment has been minimized.

Copy link

shranet commented Mar 28, 2015

Thanks!

@joehillen

This comment has been minimized.

Copy link

joehillen commented Apr 8, 2015

This actually isn't a bad solution if you have more descriptive flags than A, B, C.

    if ($request_uri = /) {
      set $test  root;
    }

    if ($host ~* teambox.com) {
      set $test  "${test}+teambox.com";
    }

    if ($http_cookie !~* "auth_token") {
      set $test  "${test}+no_auth_token";
    }

    if ($test = "root+teambox.com+no_auth_token") {
      proxy_pass http://teambox-cms.heroku.com;
      break;
    }
@farrellit

This comment has been minimized.

Copy link

farrellit commented Apr 16, 2015

awesome.

@osabate

This comment has been minimized.

Copy link

osabate commented Aug 21, 2015

👍

@Richzendy

This comment has been minimized.

Copy link

Richzendy commented Oct 27, 2015

Thank you so much, this hack is awesome! 🤘

@zarza

This comment has been minimized.

Copy link

zarza commented Oct 29, 2015

Thank you!

@maderlock

This comment has been minimized.

Copy link

maderlock commented Nov 16, 2015

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

@Hubbitus

This comment has been minimized.

Copy link

Hubbitus commented Nov 21, 2015

Why not just use map instead?

@achorein

This comment has been minimized.

Copy link

achorein commented Mar 13, 2016

👍

@Asoul

This comment has been minimized.

Copy link

Asoul commented Mar 15, 2016

Awesome!

@sketchthat

This comment has been minimized.

Copy link

sketchthat commented Apr 7, 2016

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

This comment has been minimized.

Copy link

prafulliu commented Apr 19, 2016

Thanks !

@laike9m

This comment has been minimized.

Copy link

laike9m commented Apr 19, 2016

Wow

@songsfromthewood

This comment has been minimized.

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

This comment has been minimized.

Copy link

osgregs commented Aug 15, 2016

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

@dxgldotorg

This comment has been minimized.

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

This comment has been minimized.

Copy link

GeoffreyHervet commented Dec 1, 2016

Thanks !

@sinasalek

This comment has been minimized.

Copy link

sinasalek commented Jan 3, 2017

You are a god :D

@PeterRJones

This comment has been minimized.

Copy link

PeterRJones commented Feb 17, 2017

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

This comment has been minimized.

Copy link

danlsgiga commented Apr 5, 2017

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

@glamrock

This comment has been minimized.

Copy link

glamrock commented May 16, 2017

@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

This comment has been minimized.

Copy link

aluttik commented Aug 30, 2017

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

@nkn786

This comment has been minimized.

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

This comment has been minimized.

Copy link

NickHibma commented Dec 15, 2017

nkn786, try $http_x_token.

@havilchis

This comment has been minimized.

Copy link

havilchis commented Jul 28, 2018

You truly are the king of kings

@onier

This comment has been minimized.

Copy link

onier commented Aug 10, 2018

awesome ! 666666

@ezra-obiwale

This comment has been minimized.

Copy link

ezra-obiwale commented Aug 17, 2018

Nice. Thanks

@escudero89

This comment has been minimized.

Copy link

escudero89 commented Jun 11, 2019

Awesome man, thanks.

@Azzurite

This comment has been minimized.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.