Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#607 closed defect (worksforme)

proxy_set_header drops certain headers

Reported by: Ryan Versaw Owned by:
Priority: minor Milestone:
Component: nginx-core Version: 1.7.x
Keywords: Cc:
uname -a: nginx: invalid option: "a"
nginx -V: nginx version: nginx/1.6.1
TLS SNI support enabled
configure arguments: --with-cc=cl --builddir=objs.msvc8 --with-debug --prefix= -
-conf-path=conf/nginx.conf --pid-path=logs/nginx.pid --http-log-path=logs/access
.log --error-log-path=logs/error.log --sbin-path=nginx.exe --http-client-body-te
mp-path=temp/client_body_temp --http-proxy-temp-path=temp/proxy_temp --http-fast
cgi-temp-path=temp/fastcgi_temp --http-scgi-temp-path=temp/scgi_temp --http-uwsg
i-temp-path=temp/uwsgi_temp --with-cc-opt=-DFD_SETSIZE=1024 --with-pcre=objs.msv
c8/lib/pcre-8.35 --with-zlib=objs.msvc8/lib/zlib-1.2.8 --with-select_module --wi
th-http_realip_module --with-http_addition_module --with-http_sub_module --with-
http_dav_module --with-http_stub_status_module --with-http_flv_module --with-htt
p_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-htt
p_auth_request_module --with-http_random_index_module --with-http_secure_link_mo
dule --with-mail --with-openssl=objs.msvc8/lib/openssl-1.0.1h --with-openssl-opt
=enable-tlsext --with-http_ssl_module --with-mail_ssl_module --with-ipv6

Description

This is when running on Windows, so I'm not sure if that could be related, but here's what we're seeing.

We set multiple headers, two of which look similar to the following:

proxy_set_header X-Origin Header1;
proxy_set_header X-Origin-App Header2;

Only the second header ends up getting passed through, while the first one is lost. In this simple example, if we swap these two lines, things work as expected.

Change History (5)

comment:1 by Maxim Dounin, 6 years ago

Resolution: worksforme
Status: newclosed

Works fine here, even on Windows. Just tested with the following config:

http {
    server {
        listen 8080;

        location / {
            proxy_set_header X-Origin Header1;
            proxy_set_header X-Origin-App Header2;
            proxy_pass http://127.0.0.1:8081;
        }
    }

    server {
        listen 8081;

        location / {
            return 200 "h1: $http_x_origin, h2: $http_x_origin_app\n";
        }
    }
}

It properly returns h1: Header1, h2: Header2.

I suspect one of the two possible reasons:

  • There is a missing semicolon in you config, and first directive is interpreted as part of some other directive. This doesn't explain why things work properly with lines swapped though.
  • The problem is in your backend application you are testing with.

If you still think the problem is in nginx, please provide more details on how to reproduce the problem.

comment:2 by Ryan Versaw, 6 years ago

Strange. I'll admit that I didn't break this down into the simplest example case, but I'll work through it some more and report back with my findings.

comment:3 by Ryan Versaw, 6 years ago

I found a way to repro what I'm experiencing, but you're correct that my post wasn't correct. Here's a sample config:

http {
    proxy_set_header X-Header1 1;
    server {
        listen 8080;
        proxy_set_header X-Header2 2;

        location / {
            proxy_set_header X-Header3 3;
            proxy_pass http://127.0.0.1:8081;
        }
    }

    server {
        listen 8081;

        location / {
            return 200 "h1: $http_x_header1, h2: $http_x_header2, h3: $http_x_header3\n";
        }
    }
}

It looks like if you set headers in a nested scope, set_headers from outer scopes do nothing. In this case, only X-Header3 will end up with a value. Similarly, commenting out X-Header3 means that only X-Header2 will have a value. Is this intentional behavior?

We have cases where we want a header across everything we're sending traffic to, as well as an additional header that's unique to each location group. Without duplicating the proxy_set_header call into all location groups, is there another solution?

If it makes sense to post these questions elsewhere, please let me know!

in reply to:  3 ; comment:4 by Valentin V. Bartenev, 6 years ago

Replying to Ryan Versaw <ryan@versaw.com>:

It looks like if you set headers in a nested scope, set_headers from outer scopes do nothing. In this case, only X-Header3 will end up with a value. Similarly, commenting out X-Header3 means that only X-Header2 will have a value. Is this intentional behavior?

A quote from the official documentation:

These directives are inherited from the previous level if and only if there are no proxy_set_header directives defined on the current level.

Replying to Ryan Versaw <ryan@versaw.com>:

We have cases where we want a header across everything we're sending traffic to, as well as an additional header that's unique to each location group. Without duplicating the proxy_set_header call into all location groups, is there another solution?

Nginx configuration file isn't a programming language, where you probably want to avoid duplication. Duplicating nginx directives doesn't decrease its performance, but it makes configuration straight and maintainable with minimum side effects.

Replying to Ryan Versaw <ryan@versaw.com>:

If it makes sense to post these questions elsewhere, please let me know!

This place is only for bug reports and feature requests. If you have any questions, please use mailing lists: http://mailman.nginx.org/mailman/listinfo

in reply to:  4 comment:5 by Ryan Versaw, 6 years ago

Replying to Valentin V. Bartenev:

This place is only for bug reports and feature requests. If you have any questions, please use mailing lists: http://mailman.nginx.org/mailman/listinfo

Understandable. I only started here as I (incorrectly) thought I found some bad behavior, and will use the list in the future. Regardless, all of my current questions are taken care of, so thanks a lot for the help!

Note: See TracTickets for help on using tickets.