Nginx not honoring proxy_cache_valid - nginx

I have a nginx cache configure as follows:
location / {
rewrite ^/(.*)$ /$1 break;
proxy_pass http://news;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Protocol http;
proxy_read_timeout 480;
proxy_connect_timeout 480;
set $cache_key "$uri";
proxy_cache my-cache;
proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 30s;
proxy_cache_methods GET;
add_header X-Cache-Status $upstream_cache_status;
}
When I check the x-cache-status header of the response the second time its value is HIT. The problem is that the after about 20 seconds the response is giving MISS. The http response code is 200. Any ideas?

Be aware of the inactive=time setting in the nginx.conf for proxy_cache_path. Proxy_cache_invalid does not override this value.

Related

Preflight + proxy_cache = "GET + Preflight" + CORS error. Without proxy_cache everything is ok. Is there a way to use proxy_cache?

I got the next 2 errors in console:
Access to XMLHttpRequest at 'https://api.domain1.com/rest/v1/reviews' from origin 'https://domain1.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
GET https://api.domain1.com/rest/v1/reviews net::ERR_FAILED 200
Network tab of Chrome's inspector shows a list of requests, but just 2 requests are relevant to my issue:
Name: reviews; Method: Options; Status 200; Type: preflight.
Name: reviews; Method: GET + Preflight; Status: CORS error; Type: xhr
My Nginx config:
proxy_cache_path /tmp/backend_cache levels=1:2 keys_zone=backend_cache:250m max_size=250m inactive=2d use_temp_path=off;
proxy_cache_key "$scheme$request_method$http_domain$host$request_uri";
proxy_cache_background_update on;
proxy_cache_lock on;
proxy_cache_lock_age 30s;
proxy_cache_revalidate on;
proxy_cache_valid 200 302 30m;
proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
upstream fastapi {
ip_hash;
server backend-fastapi:80;
}
server {
listen 80 default_server;
server_name api.domain1.com api.domain2.com;
charset utf-8;
keepalive_timeout 5;
location / {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 1m;
proxy_connect_timeout 1m;
proxy_pass http://fastapi;
proxy_cache backend_cache;
}
}
Preflight happens because I have custom header.
If I remove the line proxy_cache backend_cache; everything works without problem. Is there a way to use cache and avoid error?

Redirecting url using the ip sent as parameter with the api call on nginx. /status/ip -> http://ip:4444/status

I'm trying to get a response back from an api call to the machine.
ex: http://ip:4444/status
My internal api looks something like this : /status/ip.
I want my api calls from /status/ip to pick up the ip as a parameter and use it as a url like http://ip:4444/status and get a response from there.
Currently I have a failed implementation of nginx server that looks like this:
location /status/ {
if ($args ~* "/status/param1=val1") {
rewrite ^ http://$arg_param1:4444/status redirect;
}
proxy_pass http://ggr;
add_header Access-Control-Allow-Origin '*' always;
add_header Access-Control-Allow-Headers 'X-Requested-With,Content-Type' always;
add_header Cross-Origin-Resource-Policy 'cross-origin' always;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 10;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_buffers 32 64m;
proxy_buffer_size 64k;
proxy_next_upstream error timeout http_502 http_503 http_504;
client_max_body_size 64m;
client_body_buffer_size 64m;
}
I'm expecting <localhost:3000/status/ip> to redirect me to <ip:4444/status>.

Nginx proxy_cache miss if URI has slash

My nginx location block is:
location ^~ /get/preview {
add_header X-Proxy-Cache $upstream_cache_status;
proxy_buffering on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_ignore_headers Cache-Control Set-Cookie;
proxy_ssl_protocols TLSv1.3;
proxy_ssl_session_reuse on;
proxy_cache upstream;
proxy_cache_key $scheme$host$uri$is_args$args;
proxy_cache_methods GET HEAD;
proxy_cache_min_uses 0;
proxy_cache_valid 200 301 302 1h;
proxy_cache_use_stale updating;
proxy_cache_background_update on;
proxy_cache_lock on;
proxy_pass https://tar.backend.com;
}
This will be a HIT after the 1st request:
https://example.com/get/preview?fileId=17389&x=256&y=256&a=true&v=5fe320ede1bb5
This is always a MISS:
https://example.com/get/preview.png?file=/zedje/118812514_3358890630894241_5001264763560347393_n.jpg&c=5fe3256d45a8c&x=150&y=150
You should check "Expires" header from your upstream. Documentation said "parameters of caching may be set in the header fields “Expires” or “Cache-Control”."
Another option - maybe you have another location for .(png|jpg|css|js)$ files with different options.

How make long time cache in nginx?

I have an app, that generate a pictures. Before him is Nginx. I need make nginx cache with big value of proxy_cache_valid. I set this value to 365 days. But cache expires in 10 minutes, and my app generate same image again. How make long time nginx cache? Here is my nginx config:
proxy_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=cache:100m max_size=100G;
proxy_temp_path /var/lib/nginx/proxy 1 2;
proxy_ignore_headers Expires Cache-Control;
proxy_cache_use_stale error timeout invalid_header http_502;
proxy_no_cache $cookie_session;
proxy_cache_bypass $cookie_session $http_x_myupdate;
server {
server_name conv.site.com ;
client_max_body_size 32m;
location / {
proxy_cache cache;
proxy_cache_valid 365d
proxy_cache_valid 404 1m;
proxy_ignore_headers X-Accel-Expires Set-Cookie;
proxy_pass http://127.0.0.1:3021 ;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

nginx reverse proxy disable cache

i use nginx as a reverse proxy to connect a api. The problem is when i send a query after add or remove something. Nginx send me the old json value. I tried to disabled cache but it's not working.
my nginx config:
location / {
sendfile off;
add_header Last-Modified $date_gmt;
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
proxy_no_cache 1;
proxy_cache_bypass 1;
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header HTTPS $https;
}
i tried query without nginx and all work well in console
thank you!
According to the documentation proxy_cache you have to replace
proxy_no_cache 1;
proxy_cache_bypass 1;
proxy_no_cache and proxy_cache_bypass defines conditions under which the response will not be saved to a cache.
Then to disable the cache, you can replace these two condition with
proxy_cache off;
Here a full exemple that you can use to configure a proxy for a stateless api server
location /myapi {
# Proxy
proxy_set_header X-Localhost true;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080/myapi;
proxy_redirect off;
proxy_buffers 32 16k;
proxy_busy_buffers_size 64k;
proxy_cache off;
# Headers for client browser NOCACHE + CORS origin filter
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
expires off;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept' always;
allow all;
}

Resources