If-Modified-Since and If-None-Match conditionals with X-Accel-Redirect responses ?

Tom Lanyon tom+nginx at oneshoeco.com
Fri Oct 10 00:34:46 UTC 2014


We've got an upstream returning X-Accel-Redirect responses to an internal location (which itself proxies to another upstream). Something like:

	upstream fileserver {
		server foo;
	}

	upstream backend {
		server bar;
	}

	server {
		location /filestore {
			internal;
			proxy_cache filestore_cache;
			proxy_pass http://fileserver;
		}
		
		# responses from backend include header:
		# X-Accel-Redirect: /filestore/<pathname>
		location / {
			proxy_set_header Host $host;
			proxy_pass http://backend;
		}
	}

Both upstreams return Last-Modified and ETag headers. We want to keep the ETag and Last-Modified from the original backend (not the fileserver), so we changed the X-Accel-Redirect upstream to:

	location /filestore {
		internal;
		
		set $first_etag $upstream_http_etag;
		set $first_last_modified $upstream_http_last_modified;
		add_header ETag $first_etag;
		add_header Last-Modified $first_last_modified;
		
		proxy_cache filestore_cache;
		proxy_pass http://fileserver;
	}

This appears to work OK, because a response returns the ETag and Last-Modified we'd expect:
	ETag: "ce79a35523521ae64290db620e1073b1ea145497"
	Expires: Fri, 09 Oct 2015 05:46:35 GMT
	Last-Modified: Fri, 17 Jan 2014 05:20:40 GMT

But if we send a matching:
	If-None-Match: "ce79a35523521ae64290db620e1073b1ea145497"
or:
	If-Modified-Since: Fri, 17 Jan 2014 05:20:40 GMT
request header, then we get a HTTP 200 response, not a 304 Not Modified as we'd hope for.

I assume that this is because we're relying on the ETag and Last-Modified being set from temporary variables rather than the ones from the fileserver upstream. Is there any way we can work around this to pass through the ETag and Last-Modified from the backend sending X-Accel-Redirect responses whilst still supporting conditional requests and 304 responses?

Thanks,
Tom



More information about the nginx mailing list