nginx maps and controlgroups

I’ll start it by telling you that an IF control flow is evil at nginx and you should avoid it at all cost.

If you need it to make a control group based on a header or more than one it’s a really easy task. Let’s take a look on the example shwon:

While navigating trough a GPRS/3G/LTE on certain URL’s the cellphone number can be seen in two different headers for brazilian carriers: MSISDN and X-UP-CALLING-LINE-ID, we want to get all headers ending in 01 to the proxied url

The if-only-version of our code would be:

location / {  
    $proxy = "no";

    if ($HTTP_MSISDN){$proxy = "no";}
    if ($HTTP_X_UP_CALLING_LINE_ID){$proxy = "no";}

    if ($HTTP_MSISDN ~b55.*?01b){$proxy = "yes";}
    if ($HTTP_X_UP_CALLING_LINE_ID ~b55.*?01b){$proxy = "yes";}

    if ($proxy = "yes") {
        proxy_pass  https://foo_upstream;
    }

and what if you needed to add a a few numbers that should be proxied as well? one more group of if’s?

Here lies the handy MAP HTTP Module:

# two headers to be tested together
map $HTTP_MSISDN$HTTP_X_UP_CALLING_LINE_ID $proxy {  
        default "no";

        # a few control numbers
        ~(5521999999999|5521999999992) "yes";

        # control group matching 55...01
        ~b55.*?01b "yes";
}

#simpler location based on a if
location / {  
    # header to info us about the flag (debug?)
    add_header X-PROXIED $proxy;
    if ($proxy = "yes") {
        proxy_pass  https://foo_upstream;
    }
}

Done, in a much simpler and elegant way.

Leave A Comment

Your email address will not be published. Required fields are marked *