It is currently not possible to compress static resources that are passed through the VersionResourceResolver.

VersionResourceResolver (or FileNameVersionedResource , to be more precise) unconditionally sets the ETag-header to a resource's MD5 hash whenever getResponseHeaders() is called (cf. here). On the other hand, Tomcat's CompressionConfig#useCompression() (and probably other web servers) considers resources with a strong ETag-header not eligible for compression (cf. code line here). This seems to be reasonable to not break the semantics of strong ETags.

A minimal reproducable setup is provided in this Github project. I also posted a question on Stack Overflow without any considerable input to resolve the problem (yet).

Is the desired use case (hash-based cache busting and compression) completely off what you normally do? Did I miss something? Or do you agree that making it possible to disable setting the ETag-header is a viable way to allow for this use case? At least issue 17963 mentioned the ETag-header feature, but "provide optional configuration setting to disable that behavior" seems not to have been considered.

Removing the ETag header before the web server checks if compression can be used seems like a hack to me (e.g. using this mechanism). Also, this might break other use cases within an application where ETag headers are desirable...

Comment From: bclozel

@luddwichr Maybe this is a case for not disabling that ETag completely, but turning it into a weak ETag by default instead? We'd lose byte-range requests; but arguably candidates for byte-range requests could be handled by application handlers and not resource handling.

Would you see a problem with turning those ETag values into weak ETags?

Comment From: luddwichr

@bclozel thanks for your fast response! I am not a HTTP expert, really. For instance, I cannot judge the effects on byte-range requests (just reading up what that is right now). But with my current knowledge of HTTP caching, I agree that using a weak ETag instead of removing it entirely is in deed a better decision.

I just read RFC 7232. In section 2.1 it is stated that

"In other words, a weak entity-tag ought to change whenever the origin server wants caches to invalidate old responses."

, which is the case when using the MD5-hash as is currently done.

As far as I understand, it's not even a breaking change because it would not cause cache invalidations for existing clients that cached a resource with strong Etag. See table in section 2.3.2.

However, RFC 7233 states in section 3.2 that

"A server that evaluates an If-Range precondition MUST use the strong comparison function when comparing entity-tags"

So switching from strong to weak ETags would break current behavior for byte-range requests on cached resources. I don't really know what you mean by "candidates for byte-range requests could be handled by application handlers and not resource handling".

Btw, RFC 7232 also states in section 2.3.3, why using compression for a resource that already has an ETag assigned is a bad idea (just to understand why Tomcat behaves the way it does - it took me a while to find an authoritative document...):

"Note: Content codings are a property of the representation data, so a strong entity-tag for a content-encoded representation has to be distinct from the entity tag of an unencoded representation to prevent potential conflicts during cache updates and range requests."

Comment From: michael-o

Here is the reason for the change in Tomcat: https://bz.apache.org/bugzilla/show_bug.cgi?id=63932 I have reported it.