1

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!

mentinet
  • 744
  • 3
  • 9
  • 23

1 Answers1

0
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.

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77