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!