fix(etag): avoid skipping headers when filtering 304 response headers - #5234
Conversation
|
Hi @spellsaif, Thanks for opening this PR. Nice catch! The proposed fix is functionally correct as written, and I don’t see any behavioral issue with it. That said, how about using Both approaches allocate a temporary array. The performance difference may depend on the proportion of headers being deleted, but with realistic header counts, I expect it to be too small to measure in practice. for (const key of Array.from(c.res.headers.keys())) {
if (retainedHeaders.indexOf(key.toLowerCase()) === -1) {
c.res.headers.delete(key)
}
} |
|
@usualoma Hi! Thanks for the review and suggestion. :) I've updated the implementation to use |
|
Thank you 👍 |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5234 +/- ##
=======================================
Coverage 79.77% 79.77%
=======================================
Files 155 155
Lines 10934 10934
Branches 2292 2292
=======================================
Hits 8723 8723
Misses 2211 2211 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Ah, this was actually a bug. Thanks! |
Fixes an issue in the
etagmiddleware where non-retained headers could be skipped during 304 response filtering due to mutating theHeadersinstance duringforEachiteration.Problem
In
src/middleware/etag/index.ts, non-retained headers are deleted insidec.res.headers.forEach:Under standard Headers (and Map) iterator semantics, calling .delete() on the underlying collection during .forEach() shifts internal iterator indices, causing the iterator to skip subsequent header entries.
Solution
Collect the keys to delete in a temporary array first, and then delete them in a separate loop so the collection being iterated is not mutated in-flight.
The author should do the following, if applicable
bun run format:fix && bun run lint:fixto format the code