Skip to content

Conversation

bensheldon
Copy link

@bensheldon bensheldon commented Sep 3, 2025

This revisits the discussion in #197 to handle gzipped assets appropriately in the context of web assets.

  • Sets the GZip mtime header value to a fixed value. By spec this should be 0, but Ruby < 2.7 had a ZLib bug that caused a 0 value to be equivalent to unset which results in it being set to the current time. So 1 is used instead. The same compromise was just merged into Rack::Deflater.
  • Sets the correct File mtime for both GZip and Zopfli compressed files. It looks like that was overlooked when Zopfli support was added.

Why

The GZip mtime is a header value of the compressed file; changing the header file changes the contents (content integrity hash) of the file. That's annoying when writing to Docker or Git (#707) that just look at the file contents and can affect caching/cacheability (not strictly Conditional Requests). It's not necessary to set this GZip header to an accurate value. I documented this more over in the Rack::Deflater PR, but briefly:

  • Apache mod_deflate sets gzip mtime to 0
  • nginx ngx_http_gzip_module uses deflateInit2 with a setting that sets mtime to 0
  • Zopfli sets the header to zero (code).

We do want to set the File mtime because that is used for setting the last-modified http header, and this ensures that the uncompressed source and the compressed file share the same last-modified value. This change aligns the lifecycle of the uncompressed and compressed files so that both last-modified and file contents change together.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant