Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: ea125d52f300b8e221b6a54aa9731d45df85d36a
https://github.com/WebKit/WebKit/commit/ea125d52f300b8e221b6a54aa9731d45df85d36a
Author: Chris Dumez <[email protected]>
Date: 2026-07-02 (Thu, 02 Jul 2026)
Changed paths:
A
LayoutTests/http/tests/cache/disk-cache/memory-cache-revalidation-preserves-disk-cache-body-expected.txt
A
LayoutTests/http/tests/cache/disk-cache/memory-cache-revalidation-preserves-disk-cache-body.html
M Source/WebKit/NetworkProcess/cache/NetworkCache.cpp
M Source/WebKit/NetworkProcess/cache/NetworkCache.h
M Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp
Log Message:
-----------
Regression(315450@main) boingboing.net articles often load without style
https://bugs.webkit.org/show_bug.cgi?id=318413
rdar://181130091
Reviewed by Youenn Fablet.
315450@main relaxed makeStoreDecision() to store any response carrying explicit
freshness regardless of status code, dropping the
isStatusCodePotentiallyCacheable()
allowlist. This unintentionally made 304 (Not Modified) responses storable.
When a revalidation is driven by the memory cache, the conditional request
reaches the
network process as originalRequest().isConditional(). After applying the 304 to
the
existing entry via Cache::update(), NetworkResourceLoader clears
m_cacheEntryForValidation
(to forward the 304 to WebCore) and falls through to tryStoreAsCacheEntry().
Because the
304 carries Cache-Control: max-age / Expires, makeStoreDecision() now returned
Yes, and
the 304 -- which has no body -- was stored over the good entry with an empty
body. The
empty entry is fresh, so it is served on every subsequent load: pages render
broken
(e.g. stylesheets come back empty / with the wrong MIME type) and stay broken
across
reloads until the cache is cleared. Private browsing is unaffected because it
does not
use the persistent disk cache.
Fix: makeStoreDecision() never stores a 304. A 304 is a validation response,
not a
complete representation; a successful revalidation is applied to the stored
entry via
Cache::update(). Cache::store() already treats a non-Yes decision on a 304 as a
successful revalidation, so the just-updated entry is preserved rather than
evicted.
Because the regression was in the tree for a while, some users already have
poisoned
304 entries in their disk cache. Add a temporary workaround to discard any 304
entry read
back from the disk cache -- in both the normal (Cache::retrieve) and speculative
(SpeculativeLoadManager::retrieveEntryFromStorage) retrieval paths -- so the
resource is
re-fetched and the entry heals itself. Returning false purges the poisoned
record. This
is safe because a legitimately stored entry never has a 304 status. The
workaround is
annotated with rdar://181130091 and a FIXME to remove it once affected caches
age out.
Test: memory-cache-revalidation-preserves-disk-cache-body.html exercises a
memory-cache
revalidation whose 304 updates the disk cache, then clears the memory cache and
asserts
the resource is still served intact from disk ("Disk cache", full body). It
fails without
the fix (empty body); it also fails with only the workaround (served "Network"
instead of
"Disk cache"), confirming the test gates the fix and is not masked by the
workaround.
Test:
http/tests/cache/disk-cache/memory-cache-revalidation-preserves-disk-cache-body.html
*
LayoutTests/http/tests/cache/disk-cache/memory-cache-revalidation-preserves-disk-cache-body-expected.txt:
Added.
*
LayoutTests/http/tests/cache/disk-cache/memory-cache-revalidation-preserves-disk-cache-body.html:
Added.
* Source/WebKit/NetworkProcess/cache/NetworkCache.cpp:
(WebKit::NetworkCache::makeStoreDecision):
(WebKit::NetworkCache::Cache::retrieve):
* Source/WebKit/NetworkProcess/cache/NetworkCache.h:
* Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp:
(WebKit::NetworkCache::SpeculativeLoadManager::retrieveEntryFromStorage):
Canonical link: https://commits.webkit.org/316381@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications