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

Reply via email to