user3105453
user3105453

Reputation: 1981

proxy_pass based on headers without using if condition

I'm looking for a way to reroute all requests that have set an account-id in the HTTP header Account-ID with the last two digits (of a ten digit number) 00 to 05 (to touch only 5% of the total traffic). In addition, if a request has set the HTTP header Server-A, that request should be forwarded to that server regardless of the set account-id. Otherwise and by default, all traffic should be handled by server-b. My current location-rule looks like this:

location /rest/accounts/ {
  if ( $http_account_id ~ '([\d]{8})(0[0-4])') {
    proxy_pass http://server-a.company.com;
  }

  if ( $http_server_a = true) {
    proxy_pass http://server-a.company.com;
  }

  proxy_pass http://server-b.company.com;
}

As I read in the official documents here, if is considered evil.

Is there a better solution for my approach which isn't considered evil?

Upvotes: 6

Views: 2859

Answers (1)

Shawn C.
Shawn C.

Reputation: 6851

You can actually chain map directives a which would make it cleaner. For example:

map $http_server_a $server_a_check {
    default                 "http://server-b.company.com";
    ""                      "http://server-a.company.com";
}

map $http_account $account_check{
    default                 $server_a_check;
    "~([\d]{8})(0[0-4])"    "http://server-a.company.com";
}

server {
    ....
    location / {
        proxy_pass          $account_check;
    }
}

So proxy_pass is getting its value from $account_check which does a check against Account header with a regex check. Then if none of the variants pass their checks, the default gets its value from the result of $server_a_check which looks for Server-A header with no data for the value as the question didn't state what the accepted values would be.

Upvotes: 6

Related Questions