Honoring ETag of cached content

Hi,
I’m using nginx proxy pass to cache content of our dynamic web
application.

In order to save some bandwidth our client application uses conditional
requests based on ETag. However nginx ignores the ETag of cached pages
:frowning:

What would be required if I want to honor the ETag of cached pages? Is
something that can be achieve by means of configuration? or I would need
to
write an nginx module in C?

Thanks!

Hello!

On Fri, Nov 01, 2013 at 10:29:06PM +0100, Marc Aymerich wrote:

Hi,
I’m using nginx proxy pass to cache content of our dynamic web application.

In order to save some bandwidth our client application uses conditional
requests based on ETag. However nginx ignores the ETag of cached pages :frowning:

What would be required if I want to honor the ETag of cached pages? Is
something that can be achieve by means of configuration? or I would need to
write an nginx module in C?

It is expected to just work in 1.3.3+. If you don’t see it
working, you may want to check the version you are running.


Maxim D.
http://nginx.org/en/donation.html

On Sat, Nov 2, 2013 at 12:16 AM, Maxim D. [email protected]
wrote:

What would be required if I want to honor the ETag of cached pages? Is
something that can be achieve by means of configuration? or I would need
to
write an nginx module in C?

It is expected to just work in 1.3.3+. If you don’t see it
working, you may want to check the version you are running.

Hi maxim,
yeap I’m running 1.4.1 but I never get a 304 :frowning:
This is what a response from cache looks like

wget --no-check https://[fdf5:5351:1dfd:0:0:0:0:2]/api/ -S --header

‘If-None-Match: “83393a3900e4abce27212d7a27cae589”’ -q
HTTP/1.1 200 OK
Server: nginx/1.4.1
Date: Sat, 02 Nov 2013 01:40:24 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
ETag: “83393a3900e4abce27212d7a27cae589”
Allow: GET, HEAD, OPTIONS
Vary: Accept, Cookie, Accept-Encoding
Expires: Sat, 02 Nov 2013 01:41:24 GMT
Cache-Control: max-age=60

This is my nginx config for this cached location

location /api/ {
proxy_pass http://127.0.0.1:8080;
proxy_redirect off;

proxy_ignore_headers Set-Cookie;
proxy_set_header  Host             $host;
proxy_set_header  X-Real-IP        $remote_addr;
proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
proxy_set_header  X-Forwarded-Protocol $scheme;

proxy_cache          cache;
proxy_cache_key

$host$uri$is_args$args$http_accept_encoding$http_accept;
proxy_cache_valid 1m;
expires 1m;

set $skip_cache 0;
if ($request_method != GET) {
    set $skip_cache 1;
}
if ($http_cookie) {
   set $skip_cache 1;
}
if ($http_authorization) {
   set $skip_cache 1;
}
proxy_cache_bypass  $skip_cache;

}

Maybe is there some conflicting configuration? I can not see it :frowning: and
ETags work just fine if I request to my backend server

wget --no-check http://127.0.0.1:8080/api/ -S --header 'If-None-Match:

“77e348fb6260a8dd90ca18c61f7cd472”’ -q
HTTP/1.1 304 NOT MODIFIED
Server: nginx/1.4.1
Date: Sat, 02 Nov 2013 01:47:30 GMT
Content-Length: 0
Connection: keep-alive

Notice the etag value from cached content is different from the fresh
one,
even though the content is exactly the same, I presume this is nginx
doing
its job of updating the ETag for some differences because of caching,
but
still fails to reply a conditional request properly :frowning:

Thanks for your help!!

On Sat, Nov 2, 2013 at 1:10 PM, Maxim D. [email protected] wrote:

Is

yeap I’m running 1.4.1 but I never get a 304 :frowning:
ETag: “83393a3900e4abce27212d7a27cae589”
doing
response. Meanwhile, you may add some Last-Modified to your
backend responses as a workaround.

Wowo that’s it :slight_smile:

wget --no-check https://[fdf5:5351:1dfd:0:0:0:0:2]/api/ -S --header

‘If-None-Match: “83393a3900e4abce27212d7a27cae589”’ -q
HTTP/1.1 304 Not Modified
Server: nginx/1.4.1
Date: Sat, 02 Nov 2013 14:53:29 GMT
Connection: keep-alive
Vary: Accept, Cookie, Accept-Encoding
Last-Modified: Sat, 02 Nov 2013 14:53:29 GMT
ETag: “83393a3900e4abce27212d7a27cae589”
Allow: GET, HEAD, OPTIONS
Expires: Sat, 02 Nov 2013 14:54:29 GMT
Cache-Control: max-age=60

Thank you very much for your help maxim!

Shall I report this to nginx bug tracker?

Hello!

On Sat, Nov 02, 2013 at 02:55:09AM +0100, Marc Aymerich wrote:

In order to save some bandwidth our client application uses conditional

Transfer-Encoding: chunked
Connection: keep-alive
ETag: “83393a3900e4abce27212d7a27cae589”
Allow: GET, HEAD, OPTIONS
Vary: Accept, Cookie, Accept-Encoding
Expires: Sat, 02 Nov 2013 01:41:24 GMT
Cache-Control: max-age=60

[…]

Notice the etag value from cached content is different from the fresh one,
even though the content is exactly the same, I presume this is nginx doing
its job of updating the ETag for some differences because of caching, but
still fails to reply a conditional request properly :frowning:

Ok, I see what goes on here. Condintional requests (even ones
using ETag in If-None-Match) are only handled by nginx if there is
Last-Modified response date set, and it’s not set in your backend
responses.

This needs to be addressed, If-None-Match / If-Match handling from
cache shouldn’t require Last-Modified being present in a cached
response. Meanwhile, you may add some Last-Modified to your
backend responses as a workaround.


Maxim D.
http://nginx.org/en/donation.html