Warm tip: This article is reproduced from serverfault.com, please click

Nginx: using X-Accel-Expires with Cache-Control

发布于 2021-02-28 08:58:40

I'm using Nginx as a caching proxy server. I have problems with caching responses using both X-Accel-Expires and Cache-Control headers.

My upstream returns some request body with headers to nginx:

[...]
X-Accel-Expires: 60
Cache-Control: no-cache
[...]

My intent is that nginx will cache response for 60 seconds but clients will get only Cache-Control: no-cache header (so they will not cache response in the browser).

But nginx isnt caching that response. Nginx honour Cache-Control header and ignoring X-Accel-Expires header. I thought that X-Accel-Expires is "stronger" that Cache-Control but it is not.

Is there any way to change that?

I know that I can use:

proxy_ignore_headers Cache-Control;

But I cant do that because I don't have X-Accel-Expires headers in every response from upstream server.


To sum up when I return thoose headers from upstream:

X-Accel-Expires: 60
Cache-Control: no-cache

I want to cache response in nginx cache for 60s but return to clients Cache-Control: no-cache.

But when I return this:

Cache-Control: max-age=90

(without X-Accel-Expires header) I want to cache response in nginx cache for 60s and return to clients Cache-Control: max-age=90 header.

Is this possible?

Questioner
Tereska
Viewed
0
Xavier Lucas 2014-11-02 19:42:37

Then,

  • Modify the upstream to send X-Accel-Expires header everytime or add it with add_header directive (using for instance $http_cache_control in a if statement).
  • Ignore Cache-Control header for caching everytime.
  • Use an upstream block.
map $upstream_http_cache_control $cache_control_value {
    "~^max-age=(?<duration>\d+)$" "$duration";
}

server {

   listen 127.0.0.1:80;

    upstream nodes {
        server foo;
    }

    location / {

        if ($upstream_http_x_accel_expires = '') {
            add_header "X-Accel-Expires" $cache_control_value;
        }

        proxy_set_header "Host" $host;
        proxy_pass http://nodes;
    }

}

server {

   server_name mydomain.com;

   listen X.X.X.X:80;

   upstream intermediate {
       server 127.0.0.1;
   }

   location / {
       proxy_set_header "Host" $host;
       proxy_pass http://intermediate;
       proxy_ignore_headers 'Cache-Control';
       proxy_cache mycache;
   }

}

For the last case refer to the first point or use proxy_cache_valid, but with this last paremeter you can't make the timeout dynamic. You need some coherent workflow at one point.