Weak ETags and on-the-fly gzipping

I am serving dynamic requests behind the Nginx HTTP server. HTTP
requests
are mostly from mobile HTTP clients. That’s is why I care about two
things.

  1. Do not send the same representation twice: Use ETag caching
    mechanism.
  2. Make better us of available bandwidth: Use Accept-Encoding HTTP
    compression.

Today I noticed that these two don’t match. My application sets the ETag
header in the response, but when I set the ‘Accept-Encoding: gzip’ in
the
request header, nginx clears the ETag header when gzipping on-the-fly.

I understand why this is: If two responses have the same ETag, their
bodies
should be byte-for-byte comparable. When the content is gzipped, and
actually modified, this is of course not the case. The gzipped response
is
not equal to the non-gzipped response.

That’s why there are two ETag validation mechanisms. A strong
validation,
used in case of byte-for-byte comparable responses, and a weak
validation,
to indicate semantic equivalency.

In the case of weak validation an ETag would look like:
ETag: W/“123456789”

Why is Nginx stripping weak ETag validators in its gzip filter?

Hello!

On Sat, Jun 15, 2013 at 02:58:33PM +0200, Matthijs L. wrote:

ETag: W/“123456789”

Why is Nginx stripping weak ETag validators in its gzip filter?

Just stripping ETags are easier than converting them to weak
etags (and implementing weak etags support various places).

On the other hand, relevant caching functionality is still here
with Last-Modified cache validator.


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

Hi, thanks for answering so quickly.

You are right, we should not go so far as to implement a conversion from
strong to weak ETags.
And alo, Last-Modified header could be preferable.

Wen dynamic content is generated, setting a Last-Modified header
requires
inside knowledge from the app server. ETags are much simpler, as it’s
often
implemented as an md5 hash of the response body. A (Ruby) app server can
easily add an ETag to all responses. Setting a Last-Modified header is
different per request, depending on what dynamic resource is generated.

So I would not say that the Last-Modified header covers all cases that
ETag
does.

Instead of stripping all ETags, I would propose to only strip strong
ETags.

According to the spec:
HTTP/1.1: Caching in HTTP a weak
ETag is perfectly fine for validating semantic equivalence. Just not for
range requests.

So by adding something like:

if (is_strong_etag(r)) {
ngx_http_clear_etag(r)
}

We would allow applications to set weak Etags for caching.

Please someone implement weak etags or a “do_not_strip_etags” options
for
this,
it’s a big hit on our performance / page response time and we cannot
simply
replace that with Last-Modified.

Posted at Nginx Forum:

There take this patch and just apply it :slight_smile:

— nginx-1.3.8/src/http/modules/ngx_http_gzip_filter_module.c
2012-07-07 17:22:27.000000000 -0400
+++
nginx-1.3.8-weak-etags-shorter/src/http/modules/ngx_http_gzip_filter_module.c2012-11-21
17:05:12.758389000 -0500
@@ -306,7 +306,15 @@

ngx_http_clear_content_length(r);
ngx_http_clear_accept_ranges(r);

  • ngx_http_clear_etag(r);
  • /* Clear etags unless they’re marked as weak (prefixed with ‘W/’) */
  • h = r->headers_out.etag;
  • if (h && !(h->value.len >= 3 &&
  • h->value.data[0] == ‘W’ &&
  • h->value.data[1] == ‘/’ &&
  • h->value.data[2] == ‘"’)) {
  • ngx_http_clear_etag(r);
  • }

return ngx_http_next_header_filter(r);
}

Posted at Nginx Forum:

Is there anyway i can override this from nginx config file?
I need weak etag to be untouched by nginx :frowning:

Posted at Nginx Forum:

Hello!

On Tue, May 17, 2016 at 10:05:53AM -0400, neoelit wrote:

Is there anyway i can override this from nginx config file?
I need weak etag to be untouched by nginx :frowning:

Weak ETags are supported and used since nginx 1.7.3 as released on
08 Jul 2014, quote from http://nginx.org/en/CHANGES:

*) Feature: weak entity tags are now preserved on response
   modifications, and strong ones are changed to weak.

You are writing to an ancient thread from 2013.

If you are still using an older version, it should be a good idea
to upgrade.


Maxim D.
http://nginx.org/

Thanks for the quick reply. :slight_smile:
Yeah so nginx shouldn’t be the issue. I’m trying to figure why
If-None-Match
header not reaching rails on passenger-standalone. Since it has nginx
version 1.8+ this should be the issue.
https://groups.google.com/forum/#!topic/phusion-passenger/eZgw3TqrfSI

Posted at Nginx Forum:

neoelit Wrote:

Thanks for the quick reply. :slight_smile:
Yeah so nginx shouldn’t be the issue. I’m trying to figure why
If-None-Match header not reaching rails on passenger-standalone. Since
it has nginx version 1.8+ this should be the issue.
I mean this shouldn’t be the issue :stuck_out_tongue:
Redirecting to Google Groups

Posted at Nginx Forum: