nginx caching: return cached page (when specific Cache-Control header given) only if the upstream server is not reachable

Mathiasdm

I'm trying to set up caching for an upstream server (which I do not manage). Most files can be cached (and don't have Cache-Control set), those work fine.

However, some locations on the server are directory listings (and have Cache-Control: no-store). I'd like to cache those only if the server is not reachable. Unfortunately, I either end up in one of the following:

  • In a situation where those listings are not cached (no file in the cache, header always shows a cache miss). If the server is not reachable, the directory listings are (obviously) not returned
  • In a situation where those listings are cached, but they never update afterwards (at least not as long as the cache is valid). Since I'd like to cache all of the other entries for a long time, the directory listings become outdated quickly.

I tried to modify the headers to stale-if-error, but that didn't seem to help either.

map $http_cache_control $http_updated_cache_control {
  no-store stale-if-error;
}

server {
...
  location /somewhere {
      sendfile on;
      sendfile_max_chunk 10m;
      tcp_nopush on;
      proxy_cache keyzone;

      # allow using stale requests in case of errors or when updating a file
      proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
      proxy_cache_revalidate on;
      proxy_cache_background_update on;

      # add header to indicate if caching works
      add_header X-Cache-Status $upstream_cache_status;

      proxy_cache_lock on;
      proxy_read_timeout  900;
      proxy_pass_header   Server;
      proxy_ignore_headers Set-Cookie;

      # allow caching of non-cacheable entries only when the server is erroring
      proxy_hide_header Cache-Control;
      add_header Cache-Control $http_updated_cache_control;

      # don't ignore the cache control header: some items (like directory listings) are marked as "don't cache")
      #proxy_ignore_headers Cache-Control;
  }
}

How can I cache entries with Cache-Control: no-store, but only use the cached entries if the upstream server is down?

x00

I see two possibilities:

  1. NGINX respects headers from the upstream server. So if the upstream sends Expires despite the Cache-Control: no-store then after you modify headers for NGINX they become Expires: ... Cache-Control: stale-if-error and it waits

    at least as long as the cache is valid

  2. proxy_cache_valid probably have the same effect

So you need to

  1. either set some small value for proxy_cache_valid for location /somewhere
  2. or/and remove Expires if it's present
  3. or/and add max-age=0 to Cache-Control

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

nginx as cache proxy not caching anything

Why is Cache-Control attribute sent in request header (client to server)?

nginx - read custom header from upstream server

Would a file with a response header `Cache-Control:Private` be prevented from being cached in a NSURLCache?

Spark Caching: RDD Only 8% cached

Serving images from s3 with Cache-Control header distributed with CloudFront not caching?

nginx upstream subdomain on the same server

Cache-Control header not being sent from Cloudfront Custom Object Caching

Can the results from the Wagtail API be cached or have a `Cache-Control` header set?

What happens when invalid amp page is cached in the google cache and open the cache url

Define specific cache control header for selected file only

Does the must-revalidate cache-control header tell the browser to only download a cached file if it has changed?

Does nginx reset cache for URL when requested with header Cache-control: no-cache?

Will New Cache Control Headers Be Seen If Page Previously Cached?

Browser caching request/response without any Cache-Control header

Why isn't Chrome caching responses, even when cache-control header is present?

Nginx add_header and cache control

Are server side header redirects cached?

Nginx: cache only specific urls and named location

Control caching and CDN on Cloudflare when SSL is forced "on" via a page rule

Server only reachable over VPN

Make Nginx caching respect cache-control headers

Does Cache-Control header control the cache for CSS and JS files within the page

HTTP Cache-Control header works only on localhost

Enable UWSGI caching only when Cache-Control headers are set

Cloudflare cached things without Cache-Control and Expires header by default

Do responses get cached even if there is no cache-control header?

NGINX: Proxy only upstream calls

Nginx only shows index page of running server when accessed with HTTPS