41

How can I add header conditionally in nginx(1.4.6 ubuntu) configuration?

At first I tried like this.

 location / {
      add_header X-TEST-0 always-0;

      set $true 1;
      if ($true) {
          add_header X-TEST-1 only-true;
      }

      add_header X-TEST-2 always-2;
  }    

Although I expected my nginx set all header(X-TEST-0,1,2), it added header only X-TEST-1.

Next I tried like this.

 location / {
      add_header X-TEST-0 always-0;

      ##set $true 1;
      ##if ($true) {
      ##    add_header X-TEST-1 only-true;
      ##}

      add_header X-TEST-2 always-2;
  }    

My nginx added header X-TEST-1 and X-TEST-2 as I expected.

My quastions are...

  1. How can I add header conditionally?

  2. Why does nginx add only X-TEST-1 with my first example above?

Thanks in advance!

5
  • 2
    That's a classic example from If is evil Commented Apr 6, 2015 at 11:01
  • 2
    You could use set inside if. Or use map directive. Commented Apr 6, 2015 at 11:03
  • Thank you for the information! I could get all I wanted in the page you linked. Commented Apr 7, 2015 at 1:05
  • Use map as described in serverfault.com/a/598106/119913 Commented Jul 22, 2016 at 15:49
  • Thanks @KevinSmyth ! I will try it later. Commented Aug 8, 2016 at 6:21

3 Answers 3

17

This is simple if you think differently and use a map.

map $variable  $headervalue {
    1        only-true;
    default  '';
}

# ...later...
location / {
    add_header X-TEST-1   $headervalue;
}

If $variable is 1, $headervalue will be set and hence the header will be added. By default $headervalue will be empty and the header will not be added.

This is efficient because Nginx only evaluates the map when it's needed (when it gets to a point where $headervalue is referenced).

See similar: https://serverfault.com/questions/598085/nginx-add-header-conditional-on-an-upstream-http-variable

Sign up to request clarification or add additional context in comments.

1 Comment

I believe it's important to add map is only valid on http context. I was using it on server context (right above the location directive) and got an error about "map" directive is not allowed here. nginx.org/en/docs/http/ngx_http_map_module.html#map
6

I used lua nginx module to solve a similar problem:

localtion / {
  header_filter_by_lua_block {
    ngx.header["X-TEST-0"] = "always-0";
    # example of conditional header
    if ngx.req.get_method() == ngx.HTTP_POST {
      ngx.header["X-TEST-1"] = "only if POST request";
    }
    ngx.header["X-TEST-2"] = "always-2";
  }
}    

https://github.com/openresty/lua-nginx-module#header_filter_by_lua_block ```

2 Comments

Thanks for your useful information. It could be a solution for the nginx user who don't mind to use the modules which is not the standard of nginx.I voted +1.
If anybody is trying something like this, be aware that the correct lua syntax is possibly if ... then ... end :-)
0

I solve it this way, I wanted to print a specified country symbol first, I map the geo if certain IP's in the server blocks

geo $CNTRY {
    default '';
    192.104.49.0/24 ML;
    192.104.46.0/24 ML;
    192.104.47.0/24 ML;
}

Then I simply add it to server block, (anywhere doesn't matter)

add_header x-CNTRY $CNTRY;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.