5

I see indications that this should work, so I'm hoping I'm missing something simple.

We have two nginx "servers", a proxy_pass cache in front and an SSI server behind it. If I go directly to the SSI server with an If-Modified-Since header in the request, it will return a 304-Not Modified response just fine, which is what we want. But I cannot get the proxy_pass cache server to return a 304-Not Modified for anything.

Should I be able to get the proxy_pass to return a 304-Not Modified? Does anyone else have it working with a config you could share? Or can you spot the problem in my config?

# this is the cache in front server { listen 8096; server_name _; proxy_buffering on; location /assets { proxy_pass http://localhost:8095; proxy_cache my-cache; proxy_cache_valid 200s; if_modified_since before; } } server { listen 8095; server_name _; root /var/www/; location / { deny all; } location /assets {} ssi on; # on or off doesn't make a difference to the front-end cache behavior if_modified_since before; } } # here's the base config, fwiw: proxy_buffering on; proxy_cache_valid any 10m; proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my-cache:8m max_size=3000m inactive=24h; proxy_temp_path /var/cache/nginx/tmp; proxy_buffer_size 4k; proxy_buffers 100 8k; 

Thanks.

2
  • 3
    With proxy_cacheenabled, the request will not be proxied to the upstream server when the cache is hit. However, in order for your upstream server to return a 304, you'll want to send the if_modified_since header along with the request. Try out proxy_set_header If-Modified-Since $http_if_modified_since. Commented Apr 18, 2013 at 17:28
  • It's actually the downstream server I wanted to return a 304. But your comment got me heading in the right direction--I found nginx had cached an Expires header from a previous test that was off into next week. So yes, it works with my config, thanks! Commented Apr 18, 2013 at 18:28

3 Answers 3

3

The problem is that nginx won't pass if-modified-since from the client through to the upstream server when caching is in effect (I believe it will depend on the presence of a proxy_cache setting). Nginx strips the if-modified-since header based on my investigation [1].

The solution is add proxy_set_header If-Modified-Since $http_if_modified_since to the front-end [2]. Fortunately, nginx doesn't try to be too smart here ... it faithfully replicates the header in the request to upstream, which is what we want.

The default Nginx behaviour makes sense if we're just caching static files, but if it's a more complex decision on the application server deciding whether to re-generate content, we need to pass it through!

  1. In case anyone wants to look into this, I discovered this is happening by adding $http_if_modified_since to the nginx access log format, on the front-end server as well as the upsteam server. For a given request, the front-end server logged the if-modified-since header that had been sent by the client, but the same request was logged with an empty if-modified-since header until I applied the proxy_set_header fix.

  2. As mentioned in Andrew Ty's comment on the question here.

1

Yes it's possible, and yes this config works fine. Turns out nginx was caching an Expires header set to next week from my testing. Never Mind :-/

0

The solution is to add proxy_cache_revalidate on. NGINX does not by default includes the If-Modified-Since and other conditional request headers in the request to the upstream server if caching is enabled. It requires this directive to get instructed to make conditional request to the upstream server when a resource expires.

Resources: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_revalidate

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.