I have a PHP CMS as an upstream/origin server that serves content. It is placed behind a Nginx web server configured as a reverse proxy cache with proxy_pass and proxy_cache.
While implementing 304 Not Modified response on the upstream/origin server, I noticed that I sometimes get 304 Not Modified response from the proxy without my upstream/origin server being called.
My proxy configuration looks like this (notice that I don't cache 304 responses):
http {
#...
proxy_cache_path /usr/share/nginx/cache/ levels=1:2 keys_zone=microcache:10m max_size=1024m inactive=1h;
}
server {
server_name _;
#...
location / {
proxy_cache microcache;
proxy_cache_revalidate on;
add_header X-Cache-Status $upstream_cache_status;
#...
proxy_cache_valid 200 301 302 1m;
proxy_pass http://upstream;
}
}
When hitting a URL for the first time, I get a 200 with a X-Cache-Status: MISS and the ETag and Last-Modified headers returned by the origin.
The second time I hit the URL, I get a X-Cache-Status: HIT and my origin doesn't get called, so all is great!
However, if I hit the URL again, this time with the If-Modified-Since and If-None-Match headers with the values received with the first call, I get a 304 Not Modified, with X-Cache-Status: HIT and still no call on my origin server!
I seems then that Nginx has the content in its cache, and figures with the incoming headers that it should return a 304. Meaning my origin never gets to return the 304 itself if the content is in the Nginx cache.
Am I right? I cannot find any documentation on this behavior. I, however found a module in the Nginx source code that seems the be handling something similar: https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_not_modified_filter_module.c#L78
Could you please provide me with insights on this behavior, how it works, and what enables it in my configuration?
Thank you very much!
proxy_cache_path /usr/share/nginx/cache/ levels=1:2 keys_zone=microcache:10m max_size=1024m inactive=1h;
proxy_cache microcache;
Meaning that nginx server stores cache data to /usr/share/nginx/cache/
and
proxy_cache_valid 200 301 302 1m;
This means any HTTP API calls that have HTTP statuses 200, 301, or 302 use nginx local cache (which is stored in /usr/shre/nginx/cache) for one minute.