Opened 4 years ago
Closed 4 years ago
#2059 closed defect (invalid)
add_header does not work inside if+location, http, or server blocks
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | major | Milestone: | |
Component: | nginx-core | Version: | 1.19.x |
Keywords: | Cc: | ||
uname -a: | Linux redacted 5.2.8-1.el7.elrepo.x86_64 #1 SMP Fri Aug 9 13:40:33 EDT 2019 x86_64 x86_64 x86_64 GNU/Linux | ||
nginx -V: |
nginx version: nginx/1.19.3
built by gcc 8.3.1 20190311 (Red Hat 8.3.1-3) (GCC) built with OpenSSL 1.1.1h 22 Sep 2020 TLS SNI support enabled configure arguments: --with-cc-opt='-O0 -g -march=native -flto -funsafe-math-optimizations -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=0 -fPIE -Wno-error=strict-aliasing -DTCP_FASTOPEN=23' --with-ld-opt='-Wl,-z,relro -Wl,--as-needed' --with-openssl-opt=enable-tls1_3 --with-openssl-opt=enable-ec_nistp_64_gcc_128 --with-openssl-opt=no-nextprotoneg --with-openssl-opt=no-weak-ssl-ciphers --with-openssl-opt=no-ssl3 --prefix=/usr/share/nginx --without-http_autoindex_module --without-http_ssi_module --conf-path=/opt/wordkeeper/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-openssl=/root/openssl-1.1.1h --with-zlib=/root/zlib-1.2.11.1_jtkv6.3 --with-http_realip_module --with-http_auth_request_module --with-http_gzip_static_module --with-http_v2_module --with-http_sub_module --with-libatomic --user=nobody --group=nobody --with-file-aio --with-http_gunzip_module --with-pcre=/root/pcre-8.44 --with-threads --without-http_scgi_module --without-http_uwsgi_module --add-module=/root/ngx_devel_kit-0.3.1 --add-module=/root/lua-nginx-module-0.10.17 --add-module=/root/echo-nginx-module-0.62 --add-module=/root/ngx_brotli --add-module=/root/ngx_http_geoip2_module-3.3 |
Description
Since at least Nginx 1.19.2, add_header has not been properly responding to its directives inside if blocks in locations, http, or server blocks.
In server blocks, we have defined things like this (paths and site specifics have been redacted)
server { listen 80; listen [::]:80; listen 443 ssl http2; listen [::]:443 ssl http2; ssl_certificate redacted; ssl_certificate_key redacted; root redacted; # Add index.php to the list if you are using PHP index index.html index.htm index.php; server_name redacted; add_header X-Tester-Value "tester";
This should output a header value of "tester" for X-Tester-Value. But this value is not output.
In location blocks, add_header does work but only if it is directly within the location block and not within an if block.
Here is a sample configuration inside of the / location.
set $test "0"; if ($test = "0") { add_header X-Test-Value $test; } set $hsts 1; add_header X-HSTS-Value $hsts;
In this configuration, Nginx outputs "X-HSTS-Value: 1" for the X-HSTS-Value header. The X-Test-Value header is not output. Other variations of if block test (e.g. =, ~, ~*, etc) also do not change the result of the add_header output as the test in the if block is not the issue.
These same header configurations also do not appear to work within the HTTP context. As of present, the only place that add_header does seem to be working correctly is inside of the location context and per the manual, it should be working in all of the locations that I have named here.
Due to differences between HTTP2 and HTTP1 in Nginx, we did try disabling HTTP2 within this server block and it did not produce any difference in results.
Much like any directives in nginx, the add_header directive is only inherited from previous levels if it is not set on the current level. This is explicitly outlined in the documentation:
That is, if you want to return some additional headers within a location, and still want the headers defined at the server level to be returned, you have to configure both at the location level, for example:
The same applies to
add_header
directives in theif
blocks: if you use theadd_header
directive in anif
, you have to define all headers to be returned. That is, your example should be instead written in this way to make sure bothX-Test-Value
andX-HSTS-Value
headers will be added:Alternatively, the same configuration can be written in a more readable form by simply using appropriate variable values. Note that an empty value implies that the header will not be added:
If you have further questions on how to configure nginx, consider using support options available.