add_header directives in location overwriting add_header directives in server

Using nginx 1.2.1 I am able to use add_header under some circumstances.

Here is a working example:

server {
    listen       80;
    server_name  localhost;
    root /var/www;
    add_header Name1 Value1;      <=== HERE
    add_header Name2 Value2;      <=== HERE

    location / {
        echo "Nginx localhost site";
    }
}

The result

GET /
HTTP/1.1 200 OK
Name1: Value1
Name2: Value2

Here is something that doesn't work: if I use the add_header directive inside location, the other add_header directives under server are ignored:

server {
    listen       80;
    server_name  localhost;
    root /var/www;
    add_header Name1 Value1;      <=== HERE
    add_header Name2 Value2;      <=== HERE

    location / {
        add_header Name3 Value3;  <=== HERE
        add_header Name4 Value4;  <=== HERE
        echo "Nginx localhost site";
    }
}

The result

GET /
HTTP/1.1 200 OK
Name3: Value3
Name4: Value4

The documentation says that both server and location are valid context and doesn't state that using add_header in one prevents using it in the other.

Q1: Do you know if this is a bug or the intended behaviour and why?

Q2: Do you see other options to get this fixed than using the HttpHeadersMoreModule module?


Solution 1:

This is expected behaviour. The add_header directives, much like all other array-type directives in nginx, are inherited from the previous level if and only if there are no add_header directives defined on the current level.

If you want nginx to add all headers in the location /, you have to list them all in location /, i.e.

location / {
    add_header Name1 Value1;
    add_header Name2 Value2;
    add_header Name3 Value3;
    add_header Name4 Value4;
    return 200 "";
}

If you need a way to list large subset of headers in a single place, you may use include directive for this. See docs here.