Opened 2 months ago

Closed 2 months ago

#2231 closed defect (invalid)

proxy_cache_bypass sets variable defined in map

Reported by: mr.oliver.nadj@… Owned by:
Priority: minor Milestone:
Component: nginx-core Version: 1.18.x
Keywords: Cc:
uname -a: Linux 56cb0fc19e3d 5.11.0-25-generic #27~20.04.1-Ubuntu SMP Tue Jul 13 17:41:23 UTC 2021 x86_64 Linux
nginx -V: nginx version: nginx/1.18.0
built with OpenSSL 1.1.1k 25 Mar 2021 (running with OpenSSL 1.1.1g 21 Apr 2020)
TLS SNI support enabled
configure arguments: --prefix=/var/lib/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --pid-path=/run/nginx/nginx.pid --lock-path=/run/nginx/nginx.lock --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --with-perl_modules_path=/usr/lib/perl5/vendor_perl --user=nginx --group=nginx --with-threads --with-file-aio --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-stream=dynamic --with-stream_ssl_module --with-stream_realip_module --with-stream_geoip_module=dynamic --with-stream_ssl_preread_module --add-dynamic-module=/home/buildozer/aports/main/nginx/src/njs-0.3.8/nginx --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_devel_kit-0.3.1 --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_cache_purge-2.5 --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-dav-ext-module-3.0.0 --add-dynamic-module=/home/buildozer/aports/main/nginx/src/echo-nginx-module-0.61 --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx-fancyindex-0.4.4 --add-dynamic-module=/home/buildozer/aports/main/nginx/src/headers-more-nginx-module-0.33 --add-dynamic-module=/home/buildozer/aports/main/nginx/src/lua-nginx-module-0.10.15 --add-dynamic-module=/home/buildozer/aports/main/nginx/src/lua-upstream-nginx-module-0.07 --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nchan-1.2.7 --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-http-shibboleth-2.0.1 --add-dynamic-module=/home/buildozer/aports/main/nginx/src/redis2-nginx-module-0.15 --add-dynamic-module=/home/buildozer/aports/main/nginx/src/set-misc-nginx-module-0.32 --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-upload-progress-module-0.9.2 --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-upstream-fair-0.1.3 --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-rtmp-module-1.2.1 --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-vod-module-1.25 --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_http_geoip2_module-3.3

Description

When I use the combination of

    map $upstream_http_content_length $no_cache {
        default 1;
        "~^[0-9]{1,6}$" 0;
    }

and proxy_cache_bypass $no_cache; it always defaults 1.

Example:

user  nginx;
worker_processes  auto;
error_log  /dev/stdout info;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
daemon off;
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /dev/stdout;
    sendfile        on;
    keepalive_timeout  65;
	proxy_cache_path /tmp/nginx-cache levels=1:2 keys_zone=static-cache:200m max_size=45g inactive=60m use_temp_path=off;
    proxy_cache_key "$scheme$host$request_uri";

    map $upstream_http_content_length $no_cache {
        default 1;
        "~^[0-9]{1,6}$" 0;
    }

    server {
        listen       80 default_server;
        server_name _;
        location / {
            proxy_set_header Host "docs.nginx.com";
            proxy_cache  static-cache;
            proxy_ignore_headers Cache-Control;
            add_header X-Cache-Status $upstream_cache_status;
            set $proxy_cache_key $scheme$proxy_host$uri$is_args$args;
            proxy_cache_valid 5d;
            proxy_no_cache $no_cache;
            # if you uncomment the line below it makes $no_cache = 1
            # proxy_cache_bypass $no_cache;
            add_header X-No-Cache $no_cache;
            proxy_pass              https://docs.nginx.com:443;
        }
    }
}

checkout: curl -I -s http://127.0.0.1/images/icons/NGINX-Docs-horiz-white-type.svg | grep X-

Attachments (2)

Dockerfile (161 bytes ) - added by mr.oliver.nadj@… 2 months ago.
nginx.conf (1.5 KB ) - added by mr.oliver.nadj@… 2 months ago.

Download all attachments as: .zip

Change History (3)

by mr.oliver.nadj@…, 2 months ago

Attachment: Dockerfile added

by mr.oliver.nadj@…, 2 months ago

Attachment: nginx.conf added

comment:1 by Maxim Dounin, 2 months ago

Resolution: invalid
Status: newclosed

The proxy_cache_bypass directive is evaluated before making a request to the upstream server. Since the $no_cache variable is derived from the $upstream_http_content_length variable, which is not defined before a response from the upstream server is received, it is expected that $no_cache evaluates to 1. The calculated variable value is cached for the lifetime of the request, so the behaviour you observe is expected and correct. If you want nginx to re-calculate the variable on subsequent accesses, consider using the volatile parameter in the map.

Note: See TracTickets for help on using tickets.