Skip to content

Add ETag value normalization to HttpCacheMiddleware - #31

Open
KalimeroMK wants to merge 2 commits into
yiisoft:masterfrom
KalimeroMK:etag-value-normalizer
Open

Add ETag value normalization to HttpCacheMiddleware#31
KalimeroMK wants to merge 2 commits into
yiisoft:masterfrom
KalimeroMK:etag-value-normalizer

Conversation

@KalimeroMK

@KalimeroMK KalimeroMK commented Aug 20, 2026

Copy link
Copy Markdown
Q A
Is bugfix?
New feature? ✔️
Breaks BC?

Fix #11

When a web server compression module (e.g. Apache mod_deflate or mod_brotli) modifies the ETag header value by appending a suffix (-gzip, -br), the client sends the modified value back in If-None-Match and it no longer matches the application generated ETag, so the cache never hits.

Following the direction from #11 (comment) (normalize raw values after retrieving them from the request), this PR adds:

  • ETagValueNormalizerInterface — normalizes raw ETag values obtained from the If-None-Match request header before comparison.
  • NullETagValueNormalizer — default, returns values unmodified.
  • SuffixETagValueNormalizer — removes the first matching suffix from a given list (e.g. ['-gzip', '-br']).
  • New optional HttpCacheMiddleware constructor parameter $eTagValueNormalizer (defaults to NullETagValueNormalizer, no BC break).

Note: the W/ weak prefix (the Nginx case) was already handled by the existing value extraction; this PR covers the suffix case.

Introduce ETagValueNormalizerInterface to normalize raw ETag values from
the If-None-Match request header before comparison. This fixes cache
validation when a web server compression module (e.g. Apache mod_deflate
or mod_brotli) appends a suffix such as -gzip or -br to the ETag value.

Includes NullETagValueNormalizer (default, no changes) and
SuffixETagValueNormalizer (removes the first matching suffix).

Fixes yiisoft#11
@codecov

codecov Bot commented Aug 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (2d05f7a) to head (ab620f8).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff             @@
##              master       #31   +/-   ##
===========================================
  Coverage     100.00%   100.00%           
- Complexity       112       118    +6     
===========================================
  Files             23        25    +2     
  Lines            274       282    +8     
===========================================
+ Hits             274       282    +8     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

- Remove redundant early return for an empty If-None-Match header value:
  in_array() with an empty list already returns false (equivalent mutant
  reported by Infection).
- Add a test asserting the ETag value normalizer is not called for an
  empty If-None-Match header value.

MSI for the file is now 100%.
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.

Etag Header Compliance with RFC

1 participant