Skip to content

Mention the issues of ETag-based validation and Apache compression #12796

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 11, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions http_cache/validation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ to implement the validation model: ``ETag`` and ``Last-Modified``.
Validation with the ``ETag`` Header
-----------------------------------

The ``ETag`` header is a string header (called the "entity-tag") that uniquely
identifies one representation of the target resource. It's entirely generated
and set by your application so that you can tell, for example, if the ``/about``
resource that's stored by the cache is up-to-date with what your application
would return. An ``ETag`` is like a fingerprint and is used to quickly compare
if two different versions of a resource are equivalent. Like fingerprints,
each ``ETag`` must be unique across all representations of the same resource.
The `HTTP ETag`_ ("entity-tag") header is an optional HTTP header whose value is
an arbitrary string that uniquely identifies one representation of the target
resource. It's entirely generated and set by your application so that you can
tell, for example, if the ``/about`` resource that's stored by the cache is
up-to-date with what your application would return.

An ``ETag`` is like a fingerprint and is used to quickly compare if two
different versions of a resource are equivalent. Like fingerprints, each
``ETag`` must be unique across all representations of the same resource.

To see a simple implementation, generate the ETag as the md5 of the content::

Expand Down Expand Up @@ -72,6 +74,20 @@ method compares the ``If-None-Match`` header with the ``ETag`` response header.
If the two match, the method automatically sets the ``Response`` status code
to 304.

.. note::

When using ``mod_deflate`` or ``mod_brotli`` in Apache 2.4, the original
``ETag`` value is modified (e.g. if ``ETag`` was ``foo``, Apache turns it
into ``foo-gzip`` or ``foo-br``), which breaks the ETag-based validation.

You can control this behavior with the `DeflateAlterETag`_ and `BrotliAlterETag`_
directives. Alternatively, you can use the following Apache configuration to
keep both the original ETag and the modified one when compressing responses:

.. code-block:: apache

RequestHeader edit "If-None-Match" '^"((.*)-(gzip|br))"$' '"$1", "$2"'

.. note::

The cache sets the ``If-None-Match`` header on the request to the ``ETag``
Expand Down Expand Up @@ -219,3 +235,6 @@ headers that must not be present for ``304`` responses (see
:method:`Symfony\\Component\\HttpFoundation\\Response::setNotModified`).

.. _`expiration model`: https://tools.ietf.org/html/rfc2616#section-13.2
.. _`HTTP ETag`: https://en.wikipedia.org/wiki/HTTP_ETag
.. _`DeflateAlterETag`: https://httpd.apache.org/docs/trunk/mod/mod_deflate.html#deflatealteretag
.. _`BrotliAlterETag`: https://httpd.apache.org/docs/2.4/mod/mod_brotli.html#brotlialteretag