#1568 closed defect (invalid)

Multiple header_filter_by_lua_block wont working with FastCGI cache

Reported by: i.zaporozhets.owox.com@… Owned by:
Priority: minor Milestone:
Component: other Version: 1.15.x
Keywords: header_filter_by_lua_block, fcgi_cache Cc:
uname -a: Linux 1f17cc6d093a 4.4.0-127-generic #153~14.04.1-Ubuntu SMP Sat May 19 14:00:03 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.13.4 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC) built with OpenSSL 1.0.2l 25 May 2017 TLS SNI support enabled configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=owox --group=owox --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-openssl=openssl --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_perl_module=dynamic --add-dynamic-module=njs-1c50334fbea6/nginx --add-module=nginx_modules/ngx_cache_purge --add-dynamic-module=nginx_modules/ngx_http_redis --add-dynamic-module=nginx_modules/redis2-nginx-module --add-dynamic-module=nginx_modules/ngx_http_geoip2_module --add-dynamic-module=nginx_modules/lua-nginx-module --add-dynamic-module=nginx_modules/lua-upstream-nginx-module --add-dynamic-module=nginx_modules/ngx_devel_kit --add-dynamic-module=nginx_modules/set-misc-nginx-module --add-dynamic-module=nginx_modules/ngx_small_light --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --with-debug

Description

One lua script in server section changes GET parameters of fcgi cached response to current, because i wont include GET in facgi_cache_key (buisines logic).
Including empty second lua script in location causes first lua script does not working.
Here is example:





fastcgi_cache_path /var/www/test.com/cache/nginx/products levels=1:2 keys_zone=fastcgi_cache_foo:512m max_size=320G inactive=12h;

upstream backends  {
      server 127.0.0.1:9000 weight=1 max_fails=2 fail_timeout=5s;
}

server {
	listen  *:80;
	server_name test.com;

	header_filter_by_lua_block {
		 -- Update GET parameters with current get parameters in cached response
                if ngx.resp.get_headers()["Location"] ~= nil and ngx.var.upstream_cache_status ~= nil then

			local is_cache = string.find("HIT STALE UPDATING", ngx.var.upstream_cache_status)

			if is_cache ~= nil then
				local location = string.gsub(ngx.header.location, "(\?.*)", "")

				if ngx.header.cacheparam ~= nil then
			    		location = location .. "?" .. ngx.header.cacheparam
				elseif ngx.var.is_args ~= '' then
			    		location = location .. "?" .. ngx.var.args
				end
				ngx.header.location = location
			end
		end
	}

	root /var/www/test.com/cgi-bin;
        index index.php;

        location / {
		try_files $uri $uri/ /index.php;
	}

	location ~ \.php$ {

		try_files $uri =404;
		fastcgi_pass backends;
		fastcgi_index index.php;
		include fastcgi_params;
		fastcgi_param SCRIPT_FILENAME /var/www/test.com/cgi-bin/index.php;
		fastcgi_param SCRIPT_NAME /var/www/test.com/cgi-bin/index.php;

		fastcgi_cache fastcgi_cache_foo;
		fastcgi_cache_valid 200 304 404 25h;
		fastcgi_cache_valid 302 5m;
		fastcgi_cache_valid 500 502 20s;

		fastcgi_param BACKGROUND_UPDATE_CACHE_ZONE 'fastcgi_cache_products';
		fastcgi_param BACKGROUND_UPDATE_CACHE_STATUSES '302';

		fastcgi_cache_lock on;
		fastcgi_cache_lock_timeout 25s;

		add_header X-Cache-Status $upstream_cache_status;

		set $fastcgi_cache_key "$request_method|$scheme|$host|$uri|old";
                fastcgi_cache_key $fastcgi_cache_key;
                fastcgi_param BACKGROUND_UPDATE_CACHE_KEY $fastcgi_cache_key;

		#If uncomment this, everything is working
		#header_filter_by_lua_block {}

	}

}

PHP script is very simple:

<?php

header("Location: foo?" . http_build_query($_GET));
exit;

Request cached page with commented second block header_filter_by_lua_block:
curl -v http://test.com/?test1

  • About to connect() to test.com port 80 (#0)
  • Trying 127.0.0.1... connected
  • Connected to test.com (127.0.0.1) port 80 (#0)

    GET /?test1 HTTP/1.1
    User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
    Host: test.com
    Accept: */*

< HTTP/1.1 302 Found
< Server: nginx
< Date: Mon, 04 Jun 2018 15:22:27 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Keep-Alive: timeout=75
< X-Powered-By: PHP/7.1.16
< Location: foo?test1=
< X-Cache-Status: HIT
<

  • Connection #0 to host test.com left intact

curl -v http://test.com/?test2

  • About to connect() to test.com port 80 (#0)
  • Trying 127.0.0.1... connected
  • Connected to test.com (127.0.0.1) port 80 (#0)

    GET /?test2 HTTP/1.1
    User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
    Host: test.com
    Accept: */*

< HTTP/1.1 302 Found
< Server: nginx
< Date: Mon, 04 Jun 2018 15:22:30 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Keep-Alive: timeout=75
< X-Powered-By: PHP/7.1.16
< location: foo?test2
< X-Cache-Status: HIT
<

  • Connection #0 to host test.com left intact
  • Closing connection #0

Request cached page with uncommented block:

curl -v http://test.com/?test1

  • About to connect() to test.com port 80 (#0)
  • Trying 127.0.0.1... connected
  • Connected to test.com (127.0.0.1) port 80 (#0)

    GET /?test1 HTTP/1.1
    User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
    Host: test.com
    Accept: */*

< HTTP/1.1 302 Found
< Server: nginx
< Date: Mon, 04 Jun 2018 15:24:24 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Keep-Alive: timeout=75
< X-Powered-By: PHP/7.1.16
< Location: foo?test1=
< X-Cache-Status: HIT
<

  • Connection #0 to host test.com left intact
  • Closing connection #0

curl -v http://test.com/?test2

  • About to connect() to test.com port 80 (#0)
  • Trying 127.0.0.1... connected
  • Connected to test.com (127.0.0.1) port 80 (#0)

    GET /?test2 HTTP/1.1
    User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
    Host: test.com
    Accept: */*

< HTTP/1.1 302 Found
< Server: nginx
< Date: Mon, 04 Jun 2018 15:24:26 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Keep-Alive: timeout=75
< X-Powered-By: PHP/7.1.16
< Location: foo?test1=
< X-Cache-Status: HIT
<

  • Connection #0 to host test.com left intact
  • Closing connection #0

Change History (1)

comment:1 Changed 18 months ago by mdounin

  • Resolution set to invalid
  • Status changed from new to closed

For problems with 3rd party modules please contact module authors instead.

Note though that in this particular case the behaviour looks perfectly correct as per normal nginx inheritance rules: a directive is inherited from the previous levels if the directive is not used on the current level. Using header_filter_by_lua_block in the location ~ \.php$ block prevents inheritance of the header_filter_by_lua_block defined at the server{} level to the location in question. Instead, the one defined in the location ~ \.php$ block will be used.

Note: See TracTickets for help on using tickets.