这是indexloc提供的服务,不要输入任何密码
WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-201461-20191002152840.patch (text/plain), 45.06 KB, created by
Rob Buis
on 2019-10-02 06:28:42 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Rob Buis
Created:
2019-10-02 06:28:42 PDT
Size:
45.06 KB
patch
obsolete
>Subversion Revision: 250603 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 5a5844fd5e80a2c7d904a2e7f60f810691d118c8..c7a59c7cd5badc3ab5e7bbdde8849de3d191f74a 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,27 @@ >+2019-10-02 Rob Buis <rbuis@igalia.com> >+ >+ Support stale-while-revalidate cache strategy >+ https://bugs.webkit.org/show_bug.cgi?id=201461 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Start parsing the stale-while-revalidate Cache-Control directive >+ and expose it on ResourceResponse. >+ >+ Tests: imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https.html >+ imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch.html >+ imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-css.html >+ imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-image.html >+ imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-script.html >+ >+ * platform/network/CacheValidation.cpp: >+ (WebCore::parseCacheControlDirectives): >+ * platform/network/CacheValidation.h: >+ (WebCore::CacheControlDirectives::CacheControlDirectives): >+ * platform/network/ResourceResponseBase.cpp: >+ (WebCore::ResourceResponseBase::cacheControlStaleWhileRevalidate const): >+ * platform/network/ResourceResponseBase.h: >+ > 2019-10-02 Antoine Quint <graouts@apple.com> > > [Web Animations] Implement replaced animations >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 4aff249a723bf142b39b6d580d91189ee46aa93a..fc21ba12c2be8c3262448543defae8e9c7a29095 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,35 @@ >+2019-10-02 Rob Buis <rbuis@igalia.com> >+ >+ Support stale-while-revalidate cache strategy >+ https://bugs.webkit.org/show_bug.cgi?id=201461 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add a new UseDecision value AsyncRevalidate for async revalidation. This is used >+ when the retrieved cache entry is a stale-while-revalidate response [1]. >+ In case of AsyncRevalidate, a check is made to see if there is a >+ current async revalidation ongoing for the entry, if not one is >+ started. Regardless, the stale entry is returned, until either the >+ async revalidation ends successfully or at the moment where the >+ response expires for real. >+ >+ [1] https://fetch.spec.whatwg.org/#concept-stale-while-revalidate-response >+ >+ * NetworkProcess/cache/NetworkCache.cpp: >+ (WebKit::NetworkCache::responseHasExpired): >+ (WebKit::NetworkCache::responseNeedsRevalidation): >+ (WebKit::NetworkCache::makeUseDecision): >+ (WebKit::NetworkCache::makeStoreDecision): >+ (WebKit::NetworkCache::Cache::retrieve): >+ * NetworkProcess/cache/NetworkCache.h: >+ * NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp: >+ (WebKit::NetworkCache::constructRevalidationRequest): >+ (WebKit::NetworkCache::AsyncRevalidation::AsyncRevalidation): >+ (WebKit::NetworkCache::AsyncRevalidation::load const): >+ (WebKit::NetworkCache::AsyncRevalidation::staleWhileRevalidateEnding): >+ (WebKit::NetworkCache::SpeculativeLoadManager::startAsyncRevalidationIfNeeded): >+ * NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h: >+ > 2019-10-02 Zan Dobersek <zdobersek@igalia.com> > > Unreviewed build fix for non-Mac ports after r250600. >diff --git a/Source/WebCore/platform/network/CacheValidation.cpp b/Source/WebCore/platform/network/CacheValidation.cpp >index 4959050679ce0504842447eb1f5a0bf8a67683ce..76379816e333f5aaeb13687009e281470432bc57 100644 >--- a/Source/WebCore/platform/network/CacheValidation.cpp >+++ b/Source/WebCore/platform/network/CacheValidation.cpp >@@ -313,8 +313,20 @@ CacheControlDirectives parseCacheControlDirectives(const HTTPHeaderMap& headers) > double maxStale = directives[i].second.toDouble(&ok); > if (ok) > result.maxStale = Seconds { maxStale }; >- } else if (equalLettersIgnoringASCIICase(directives[i].first, "immutable")) >+ } else if (equalLettersIgnoringASCIICase(directives[i].first, "immutable")) { > result.immutable = true; >+ } else if (equalLettersIgnoringASCIICase(directives[i].first, "stale-while-revalidate")) { >+ if (result.staleWhileRevalidate) { >+ // First stale-while-revalidate directive wins if there are multiple ones. >+ continue; >+ } >+ bool ok; >+ double staleWhileRevalidate = directives[i].second.toDouble(&ok); >+ if (ok) { >+ result.maxStale = Seconds { staleWhileRevalidate }; >+ result.staleWhileRevalidate = true; >+ } >+ } > } > } > >diff --git a/Source/WebCore/platform/network/CacheValidation.h b/Source/WebCore/platform/network/CacheValidation.h >index 56efea62154479506a1664ffd08e08ab2c556bcd..8e6a8fc3d633548da17a8f0c485bbaa7b5ad93b0 100644 >--- a/Source/WebCore/platform/network/CacheValidation.h >+++ b/Source/WebCore/platform/network/CacheValidation.h >@@ -65,6 +65,7 @@ struct CacheControlDirectives { > , noStore(false) > , mustRevalidate(false) > , immutable(false) >+ , staleWhileRevalidate(false) > { } > > Markable<Seconds, Seconds::MarkableTraits> maxAge; >@@ -73,6 +74,7 @@ struct CacheControlDirectives { > bool noStore : 1; > bool mustRevalidate : 1; > bool immutable : 1; >+ bool staleWhileRevalidate : 1; > }; > WEBCORE_EXPORT CacheControlDirectives parseCacheControlDirectives(const HTTPHeaderMap&); > >diff --git a/Source/WebCore/platform/network/ResourceResponseBase.cpp b/Source/WebCore/platform/network/ResourceResponseBase.cpp >index 20ac64d57034c69ea92bc7a43536f16d795ffa29..5cbdbfec9adcc7c77fa091c992804de49527fd1b 100644 >--- a/Source/WebCore/platform/network/ResourceResponseBase.cpp >+++ b/Source/WebCore/platform/network/ResourceResponseBase.cpp >@@ -655,6 +655,15 @@ Optional<Seconds> ResourceResponseBase::cacheControlMaxAge() const > return m_cacheControlDirectives.maxAge; > } > >+Optional<Seconds> ResourceResponseBase::cacheControlStaleWhileRevalidate() const >+{ >+ if (!m_haveParsedCacheControlHeader) >+ parseCacheControlDirectives(); >+ if (m_cacheControlDirectives.staleWhileRevalidate) >+ return m_cacheControlDirectives.maxStale; >+ return WTF::nullopt; >+} >+ > static Optional<WallTime> parseDateValueInHeader(const HTTPHeaderMap& headers, HTTPHeaderName headerName) > { > String headerValue = headers.get(headerName); >diff --git a/Source/WebCore/platform/network/ResourceResponseBase.h b/Source/WebCore/platform/network/ResourceResponseBase.h >index cb17b595487d10b773c4e4853543024a50f1a97f..40681f077ab9eed09c935bb0baac9e0b409c38de 100644 >--- a/Source/WebCore/platform/network/ResourceResponseBase.h >+++ b/Source/WebCore/platform/network/ResourceResponseBase.h >@@ -136,6 +136,7 @@ public: > WEBCORE_EXPORT bool cacheControlContainsImmutable() const; > WEBCORE_EXPORT bool hasCacheValidatorFields() const; > WEBCORE_EXPORT Optional<Seconds> cacheControlMaxAge() const; >+ WEBCORE_EXPORT Optional<Seconds> cacheControlStaleWhileRevalidate() const; > WEBCORE_EXPORT Optional<WallTime> date() const; > WEBCORE_EXPORT Optional<Seconds> age() const; > WEBCORE_EXPORT Optional<WallTime> expires() const; >diff --git a/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp b/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp >index f344d1aba64fe93c9cbebd47f43e8163bacd7c17..8709e0be9bcd8174d617f57e31f840a9a91fea3a 100644 >--- a/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp >+++ b/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp >@@ -152,7 +152,7 @@ static bool cachePolicyAllowsExpired(WebCore::ResourceRequestCachePolicy policy) > return false; > } > >-static bool responseHasExpired(const WebCore::ResourceResponse& response, WallTime timestamp, Optional<Seconds> maxStale) >+static bool responseHasExpired(const WebCore::ResourceResponse& response, WallTime timestamp, Optional<Seconds> maxStale, bool& inResponseStaleness) > { > if (response.cacheControlContainsNoCache()) > return true; >@@ -162,25 +162,35 @@ static bool responseHasExpired(const WebCore::ResourceResponse& response, WallTi > > auto maximumStaleness = maxStale ? maxStale.value() : 0_ms; > bool hasExpired = age - lifetime > maximumStaleness; >+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION) >+ if (hasExpired) { >+ auto responseMaxStaleness = response.cacheControlStaleWhileRevalidate(); >+ maximumStaleness += responseMaxStaleness ? responseMaxStaleness.value() : 0_ms; >+ inResponseStaleness = age - lifetime < maximumStaleness; >+ } >+#endif > > #ifndef LOG_DISABLED > if (hasExpired) >- LOG(NetworkCache, "(NetworkProcess) needsRevalidation hasExpired age=%f lifetime=%f max-stale=%g", age, lifetime, maxStale); >+ LOG(NetworkCache, "(NetworkProcess) needsRevalidation hasExpired age=%f lifetime=%f max-staleness=%f", age, lifetime, maximumStaleness); > #endif > > return hasExpired; > } > >-static bool responseNeedsRevalidation(const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& request, WallTime timestamp) >+static UseDecision responseNeedsRevalidation(const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& request, WallTime timestamp) > { > auto requestDirectives = WebCore::parseCacheControlDirectives(request.httpHeaderFields()); > if (requestDirectives.noCache) >- return true; >+ return UseDecision::Validate; > // For requests we ignore max-age values other than zero. > if (requestDirectives.maxAge && requestDirectives.maxAge.value() == 0_ms) >- return true; >+ return UseDecision::Validate; > >- return responseHasExpired(response, timestamp, requestDirectives.maxStale); >+ bool inResponseStaleness = false; >+ if (responseHasExpired(response, timestamp, requestDirectives.maxStale, inResponseStaleness)) >+ return inResponseStaleness ? UseDecision::AsyncRevalidate : UseDecision::Validate; >+ return UseDecision::Use; > } > > static UseDecision makeUseDecision(NetworkProcess& networkProcess, const PAL::SessionID& sessionID, const Entry& entry, const WebCore::ResourceRequest& request) >@@ -197,8 +207,9 @@ static UseDecision makeUseDecision(NetworkProcess& networkProcess, const PAL::Se > if (cachePolicyAllowsExpired(request.cachePolicy())) > return UseDecision::Use; > >- if (!responseNeedsRevalidation(entry.response(), request, entry.timeStamp())) >- return UseDecision::Use; >+ auto decision = responseNeedsRevalidation(entry.response(), request, entry.timeStamp()); >+ if (decision != UseDecision::Validate) >+ return decision; > > if (!entry.response().hasCacheValidatorFields()) > return UseDecision::NoDueToMissingValidatorFields; >@@ -251,8 +262,10 @@ static StoreDecision makeStoreDecision(const WebCore::ResourceRequest& originalR > bool storeUnconditionallyForHistoryNavigation = isMainResource || originalRequest.priority() == WebCore::ResourceLoadPriority::VeryHigh; > if (!storeUnconditionallyForHistoryNavigation) { > auto now = WallTime::now(); >- bool hasNonZeroLifetime = !response.cacheControlContainsNoCache() && WebCore::computeFreshnessLifetimeForHTTPFamily(response, now) > 0_ms; >- >+ Seconds allowedStale; >+ if (auto value = response.cacheControlStaleWhileRevalidate()) >+ allowedStale = value.value(); >+ bool hasNonZeroLifetime = !response.cacheControlContainsNoCache() && (WebCore::computeFreshnessLifetimeForHTTPFamily(response, now) > 0_ms || allowedStale > 0_ms); > bool possiblyReusable = response.hasCacheValidatorFields() || hasNonZeroLifetime; > if (!possiblyReusable) > return StoreDecision::NoDueToUnlikelyToReuse; >@@ -334,12 +347,11 @@ void Cache::retrieve(const WebCore::ResourceRequest& request, const GlobalFrameI > } > #endif > >- m_storage->retrieve(storageKey, priority, [request, completionHandler = WTFMove(completionHandler), info = WTFMove(info), storageKey, networkProcess = makeRef(networkProcess()), sessionID = m_sessionID](auto record, auto timings) mutable { >+ m_storage->retrieve(storageKey, priority, [this, request, completionHandler = WTFMove(completionHandler), info = WTFMove(info), storageKey, networkProcess = makeRef(networkProcess()), sessionID = m_sessionID, frameID](auto record, auto timings) mutable { > info.storageTimings = timings; > > if (!record) { > LOG(NetworkCache, "(NetworkProcess) not found in storage"); >- > completeRetrieve(WTFMove(completionHandler), nullptr, info); > return false; > } >@@ -350,6 +362,15 @@ void Cache::retrieve(const WebCore::ResourceRequest& request, const GlobalFrameI > > auto useDecision = entry ? makeUseDecision(networkProcess, sessionID, *entry, request) : UseDecision::NoDueToDecodeFailure; > switch (useDecision) { >+ case UseDecision::AsyncRevalidate: { >+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION) >+ if (m_speculativeLoadManager) { >+ std::unique_ptr<Entry> entryCopy = makeUnique<Entry>(*entry); >+ m_speculativeLoadManager->startAsyncRevalidationIfNeeded(request, storageKey, WTFMove(entryCopy), frameID); >+ } >+#endif >+ FALLTHROUGH; >+ } > case UseDecision::Use: > break; > case UseDecision::Validate: >diff --git a/Source/WebKit/NetworkProcess/cache/NetworkCache.h b/Source/WebKit/NetworkProcess/cache/NetworkCache.h >index 0dee7f88dff6162cc3fd7851b8380fc5a83bd5ae..cafc5672d6e4b3d578ac931a98b172c970a14a4c 100644 >--- a/Source/WebKit/NetworkProcess/cache/NetworkCache.h >+++ b/Source/WebKit/NetworkProcess/cache/NetworkCache.h >@@ -82,6 +82,7 @@ enum class StoreDecision { > enum class UseDecision { > Use, > Validate, >+ AsyncRevalidate, > NoDueToVaryingHeaderMismatch, > NoDueToMissingValidatorFields, > NoDueToDecodeFailure, >diff --git a/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp b/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp >index 6794039b7e1917a4aabad4d2d508f73953786567..4beb050f1b52006e02d952810e158dd6b2ea5356 100644 >--- a/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp >+++ b/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp >@@ -486,7 +486,77 @@ void SpeculativeLoadManager::revalidateSubresource(const SubresourceInfo& subres > }); > m_pendingPreloads.add(key, WTFMove(revalidator)); > } >- >+ >+static inline ResourceRequest constructRevalidationRequest(const Key& key, const ResourceRequest& request, const Entry* entry) >+{ >+ ResourceRequest revalidationRequest = request; >+ if (!key.partition().isEmpty()) >+ revalidationRequest.setCachePartition(key.partition()); >+ ASSERT_WITH_MESSAGE(key.range().isEmpty(), "range is not supported"); >+ >+ revalidationRequest.makeUnconditional(); >+ if (entry) { >+ String eTag = entry->response().httpHeaderField(HTTPHeaderName::ETag); >+ if (!eTag.isEmpty()) >+ revalidationRequest.setHTTPHeaderField(HTTPHeaderName::IfNoneMatch, eTag); >+ >+ String lastModified = entry->response().httpHeaderField(HTTPHeaderName::LastModified); >+ if (!lastModified.isEmpty()) >+ revalidationRequest.setHTTPHeaderField(HTTPHeaderName::IfModifiedSince, lastModified); >+ } >+ >+ revalidationRequest.setPriority(WebCore::ResourceLoadPriority::Low); >+ >+ return revalidationRequest; >+} >+ >+class AsyncRevalidation { >+ WTF_MAKE_FAST_ALLOCATED; >+public: >+ typedef Function<void (bool)> AsyncRevalidationCompletionHandler; >+ AsyncRevalidation(Cache& cache, const GlobalFrameID& frameID, const ResourceRequest& request, std::unique_ptr<NetworkCache::Entry> entry, AsyncRevalidationCompletionHandler&& handler) >+ : m_timer(*this, &AsyncRevalidation::staleWhileRevalidateEnding) >+ , m_completionHandler(WTFMove(handler)) >+ { >+ auto key = entry->key(); >+ auto revalidationRequest = constructRevalidationRequest(key, request, entry.get()); >+ auto age = WebCore::computeCurrentAge(entry->response(), entry->timeStamp()); >+ auto lifetime = WebCore::computeFreshnessLifetimeForHTTPFamily(entry->response(), entry->timeStamp()); >+ auto responseMaxStaleness = entry->response().cacheControlStaleWhileRevalidate(); >+ ASSERT(responseMaxStaleness); >+ m_timer.startOneShot(*responseMaxStaleness - (age - lifetime)); >+ m_load = makeUnique<SpeculativeLoad>(cache, frameID, revalidationRequest, WTFMove(entry), [this, key, revalidationRequest](std::unique_ptr<Entry> revalidatedEntry) { >+ ASSERT(!revalidatedEntry || !revalidatedEntry->needsValidation()); >+ ASSERT(!revalidatedEntry || revalidatedEntry->key() == key); >+ m_completionHandler(revalidatedEntry.get()); >+ }); >+ } >+ >+ const SpeculativeLoad& load() const { return *m_load; } >+ >+ void staleWhileRevalidateEnding() { m_completionHandler(true); } >+ >+private: >+ std::unique_ptr<SpeculativeLoad> m_load; >+ Timer m_timer; >+ AsyncRevalidationCompletionHandler m_completionHandler; >+}; >+ >+void SpeculativeLoadManager::startAsyncRevalidationIfNeeded(const ResourceRequest& request, const NetworkCache::Key& key, std::unique_ptr<Entry> entry, const GlobalFrameID& frameID) >+{ >+ auto* pendingAsyncRevalidation = m_pendingAsyncRevalidations.get(key); >+ if (pendingAsyncRevalidation && canUsePendingPreload(pendingAsyncRevalidation->load(), request)) >+ return; >+ >+ auto revalidator = makeUnique<AsyncRevalidation>(m_cache, frameID, request, WTFMove(entry), [this, key](bool ending) { >+ if (ending) { >+ m_pendingAsyncRevalidations.take(key); >+ LOG(NetworkCache, "(NetworkProcess) Async revalidation completed for '%s':", key.identifier().utf8().data()); >+ } >+ }); >+ m_pendingAsyncRevalidations.add(key, WTFMove(revalidator)); >+} >+ > static bool canRevalidate(const SubresourceInfo& subresourceInfo, const Entry* entry) > { > ASSERT(!subresourceInfo.isTransient()); >diff --git a/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h b/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h >index 3af4fdb8121fd7c5e918a039b400a5f3a3a86efa..f202fd666ec6705d7b6d48b3f48b4383a006a802 100644 >--- a/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h >+++ b/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h >@@ -38,6 +38,7 @@ namespace WebKit { > > namespace NetworkCache { > >+class AsyncRevalidation; > class Entry; > class SpeculativeLoad; > class SubresourceInfo; >@@ -56,6 +57,8 @@ public: > bool canRetrieve(const Key& storageKey, const WebCore::ResourceRequest&, const GlobalFrameID&) const; > void retrieve(const Key& storageKey, RetrieveCompletionHandler&&); > >+ void startAsyncRevalidationIfNeeded(const WebCore::ResourceRequest&, const NetworkCache::Key&, std::unique_ptr<Entry>, const GlobalFrameID&); >+ > private: > class PreloadedEntry; > >@@ -81,6 +84,8 @@ private: > > HashMap<Key, std::unique_ptr<PreloadedEntry>> m_preloadedEntries; > >+ HashMap<Key, std::unique_ptr<AsyncRevalidation>> m_pendingAsyncRevalidations; >+ > class ExpiringEntry; > HashMap<Key, std::unique_ptr<ExpiringEntry>> m_notPreloadedEntries; // For logging. > }; >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 801432098273365b7c3f06aeb6d610e04b5c6777..095b05ad0df769233f7224bfdba15a5f6f7d520b 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,15 @@ >+2019-10-02 Rob Buis <rbuis@igalia.com> >+ >+ Support stale-while-revalidate cache strategy >+ https://bugs.webkit.org/show_bug.cgi?id=201461 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Skip newly imported tests for WK1. >+ >+ * platform/ios-wk1/TestExpectations: >+ * platform/mac-wk1/TestExpectations: >+ > 2019-10-02 Carlos Garcia Campos <cgarcia@igalia.com> > > Unreviewed GTK gardening. Add missing results after r250276. >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index d91b8249fcba6383c735110eaa48eabf45c35107..8b70cfc48eca0287ce436c35256b279d266a784b 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,3 +1,35 @@ >+2019-10-02 Rob Buis <rbuis@igalia.com> >+ >+ Support stale-while-revalidate cache strategy >+ https://bugs.webkit.org/show_bug.cgi?id=201461 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Import stale-while-revalidate WPT tests. >+ >+ * resources/import-expectations.json: >+ * web-platform-tests/fetch/stale-while-revalidate/fetch-expected.txt: Added. >+ * web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https-expected.txt: Added. >+ * web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https.html: Added. >+ * web-platform-tests/fetch/stale-while-revalidate/fetch.html: Added. >+ * web-platform-tests/fetch/stale-while-revalidate/resources/stale-css.py: Added. >+ (main): >+ * web-platform-tests/fetch/stale-while-revalidate/resources/stale-image.py: Added. >+ (main): >+ * web-platform-tests/fetch/stale-while-revalidate/resources/stale-script.py: Added. >+ (id_token): >+ (main): >+ * web-platform-tests/fetch/stale-while-revalidate/resources/w3c-import.log: Added. >+ * web-platform-tests/fetch/stale-while-revalidate/stale-css-expected.txt: Added. >+ * web-platform-tests/fetch/stale-while-revalidate/stale-css.html: Added. >+ * web-platform-tests/fetch/stale-while-revalidate/stale-image-expected.txt: Added. >+ * web-platform-tests/fetch/stale-while-revalidate/stale-image.html: Added. >+ * web-platform-tests/fetch/stale-while-revalidate/stale-script-expected.txt: Added. >+ * web-platform-tests/fetch/stale-while-revalidate/stale-script.html: Added. >+ * web-platform-tests/fetch/stale-while-revalidate/sw-intercept.js: Added. >+ (async.broadcast): >+ * web-platform-tests/fetch/stale-while-revalidate/w3c-import.log: Added. >+ > 2019-10-02 Antoine Quint <graouts@apple.com> > > [Web Animations] Implement replaced animations >diff --git a/LayoutTests/imported/w3c/resources/import-expectations.json b/LayoutTests/imported/w3c/resources/import-expectations.json >index c88d54e509aea4eb73207e861cb3d2f7d044da33..378d041d176a2ccd988e93ff83671c0240c9d7a4 100644 >--- a/LayoutTests/imported/w3c/resources/import-expectations.json >+++ b/LayoutTests/imported/w3c/resources/import-expectations.json >@@ -159,6 +159,7 @@ > "web-platform-tests/fetch/api": "import", > "web-platform-tests/fetch/api/cors": "import", > "web-platform-tests/fetch/range": "import", >+ "web-platform-tests/fetch/stale-while-revalidate": "import", > "web-platform-tests/fullscreen": "skip", > "web-platform-tests/gamepad": "skip", > "web-platform-tests/generic-sensor": "skip", >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..46bf26f4ab11c777adf248aa37ac0c7728237072 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS Second fetch returns same response >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..46bf26f4ab11c777adf248aa37ac0c7728237072 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS Second fetch returns same response >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https.html b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..efcebc24a63f40de54a4c3991c9050eb74486a29 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https.html >@@ -0,0 +1,65 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <meta charset="utf-8"> >+ <title>Stale Revalidation Requests don't get sent to service worker</title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="../../service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ <script src="/common/utils.js"></script> >+</head> >+<body> >+<script> >+ >+ // Duplicating this resource to make service worker scoping simpler. >+ async function setupRegistrationAndWaitToBeControlled(t, scope) { >+ const controlled = new Promise((resolve) => { >+ navigator.serviceWorker.oncontrollerchange = () => { resolve(); }; >+ }); >+ const reg = await navigator.serviceWorker.register('sw-intercept.js'); >+ await wait_for_state(t, reg.installing, 'activated'); >+ await controlled; >+ add_completion_callback(_ => reg.unregister()); >+ return reg; >+ } >+ >+ // Using 250ms polling interval to provide enough 'network calmness' to give >+ // the background low priority revalidation request a chance to kick in. >+ function wait250ms(test) { >+ return new Promise(resolve => { >+ test.step_timeout(() => { >+ resolve(); >+ }, 250); >+ }); >+ } >+ >+ promise_test(async (test) => { >+ var request_token = token(); >+ const uri = 'resources/stale-script.py?token=' + request_token; >+ >+ await setupRegistrationAndWaitToBeControlled(test, 'resources/stale-script.py'); >+ >+ var service_worker_count = 0; >+ navigator.serviceWorker.addEventListener('message', function once(event) { >+ if (event.data.endsWith(uri)) { >+ service_worker_count++; >+ } >+ }); >+ >+ const response = await fetch(uri); >+ const response2 = await fetch(uri); >+ assert_equals(response.headers.get('Unique-Id'), response2.headers.get('Unique-Id')); >+ while(true) { >+ const revalidation_check = await fetch(`resources/stale-script.py?query&token=` + request_token); >+ if (revalidation_check.headers.get('Count') == '2') { >+ // The service worker should not see the revalidation request. >+ assert_equals(service_worker_count, 2); >+ break; >+ } >+ await wait250ms(test); >+ } >+ }, 'Second fetch returns same response'); >+ >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch.html b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch.html >new file mode 100644 >index 0000000000000000000000000000000000000000..73390c7ad5948c682b2fbdcb3c95a4c374dbba2d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch.html >@@ -0,0 +1,32 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Tests Stale While Revalidate is not executed for fetch API</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/utils.js"></script> >+<script> >+function wait25ms(test) { >+ return new Promise(resolve => { >+ test.step_timeout(() => { >+ resolve(); >+ }, 25); >+ }); >+} >+ >+promise_test(async (test) => { >+ var request_token = token(); >+ >+ const response = await fetch(`resources/stale-script.py?token=` + request_token); >+ const response2 = await fetch(`resources/stale-script.py?token=` + request_token); >+ >+ assert_equals(response.headers.get('Unique-Id'), response2.headers.get('Unique-Id')); >+ >+ while(true) { >+ const revalidation_check = await fetch(`resources/stale-script.py?query&token=` + request_token); >+ if (revalidation_check.headers.get('Count') == '2') { >+ break; >+ } >+ await wait25ms(test); >+ } >+}, 'Second fetch returns same response'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-css.py b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-css.py >new file mode 100644 >index 0000000000000000000000000000000000000000..a6ae546d0651f97f3020829452db6225486dc451 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-css.py >@@ -0,0 +1,28 @@ >+def main(request, response): >+ >+ token = request.GET.first("token", None) >+ is_query = request.GET.first("query", None) != None >+ with request.server.stash.lock: >+ value = request.server.stash.take(token) >+ count = 0 >+ if value != None: >+ count = int(value) >+ if is_query: >+ if count < 2: >+ request.server.stash.put(token, count) >+ else: >+ count = count + 1 >+ request.server.stash.put(token, count) >+ if is_query: >+ headers = [("Count", count)] >+ content = "" >+ return 200, headers, content >+ else: >+ content = "body { background: rgb(0, 128, 0); }" >+ if count > 1: >+ content = "body { background: rgb(255, 0, 0); }" >+ >+ headers = [("Content-Type", "text/css"), >+ ("Cache-Control", "private, max-age=0, stale-while-revalidate=60")] >+ >+ return 200, headers, content >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-image.py b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-image.py >new file mode 100644 >index 0000000000000000000000000000000000000000..839eb84bb34bbd15e2ca7061ee4fa5724d2c64f8 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-image.py >@@ -0,0 +1,38 @@ >+import os.path >+ >+def main(request, response): >+ >+ token = request.GET.first("token", None) >+ is_query = request.GET.first("query", None) != None >+ with request.server.stash.lock: >+ value = request.server.stash.take(token) >+ count = 0 >+ if value != None: >+ count = int(value) >+ if is_query: >+ if count < 2: >+ request.server.stash.put(token, count) >+ else: >+ count = count + 1 >+ request.server.stash.put(token, count) >+ >+ if is_query: >+ headers = [("Count", count)] >+ content = "" >+ return 200, headers, content >+ else: >+ filename = "green-16x16.png" >+ if count > 1: >+ filename = "green-256x256.png" >+ >+ path = os.path.join(os.path.dirname(__file__), "../../../images", filename) >+ body = open(path, "rb").read() >+ >+ response.add_required_headers = False >+ response.writer.write_status(200) >+ response.writer.write_header("content-length", len(body)) >+ response.writer.write_header("Cache-Control", "private, max-age=0, stale-while-revalidate=60") >+ response.writer.write_header("content-type", "image/png") >+ response.writer.end_headers() >+ >+ response.writer.write(body) >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-script.py b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-script.py >new file mode 100644 >index 0000000000000000000000000000000000000000..8ad54671f4211735f56df50a55deea6ed281d5a2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-script.py >@@ -0,0 +1,32 @@ >+import random, string, datetime >+ >+def id_token(): >+ letters = string.ascii_lowercase >+ return ''.join(random.choice(letters) for i in range(20)) >+ >+def main(request, response): >+ token = request.GET.first("token", None) >+ is_query = request.GET.first("query", None) != None >+ with request.server.stash.lock: >+ value = request.server.stash.take(token) >+ count = 0 >+ if value != None: >+ count = int(value) >+ if is_query: >+ if count < 2: >+ request.server.stash.put(token, count) >+ else: >+ count = count + 1 >+ request.server.stash.put(token, count) >+ >+ if is_query: >+ headers = [("Count", count)] >+ content = "" >+ return 200, headers, content >+ else: >+ unique_id = id_token() >+ headers = [("Content-Type", "text/javascript"), >+ ("Cache-Control", "private, max-age=0, stale-while-revalidate=60"), >+ ("Unique-Id", unique_id)] >+ content = "report('{}')".format(unique_id) >+ return 200, headers, content >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..75a7732a566d4a6f573cc97fd3d1454657d47680 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/w3c-import.log >@@ -0,0 +1,19 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/web-platform-tests/wpt >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-css.py >+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-image.py >+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-script.py >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-css-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-css-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..8ac99405a7b89c13e5787eaf079ed6f1488e8c10 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-css-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS Cache returns stale resource >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-css.html b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-css.html >new file mode 100644 >index 0000000000000000000000000000000000000000..f56260fdb45c0c2c60b4d76f63a76389df818b11 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-css.html >@@ -0,0 +1,45 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Tests Stale While Revalidate works for css</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/utils.js"></script> >+<body> >+<script> >+ >+var request_token = token(); >+async_test(t => { >+ window.onload = t.step_func(() => { >+ t.step_timeout(() => { >+ assert_equals(window.getComputedStyle(document.body).getPropertyValue('background-color'), "rgb(0, 128, 0)"); >+ var link2 = document.createElement("link"); >+ link2.onload = t.step_func(() => { >+ assert_equals(window.getComputedStyle(document.body).getPropertyValue('background-color'), "rgb(0, 128, 0)"); >+ var checkResult = () => { >+ // We poll because we don't know when the revalidation will occur. >+ fetch("resources/stale-css.py?query&token=" + request_token).then(t.step_func((response) => { >+ var count = response.headers.get("Count"); >+ if (count == '2') { >+ t.done(); >+ } else { >+ t.step_timeout(checkResult, 25); >+ } >+ })); >+ }; >+ t.step_timeout(checkResult, 25); >+ }); >+ link2.rel = "stylesheet"; >+ link2.type = "text/css"; >+ link2.href = "resources/stale-css.py?token=" + request_token; >+ document.body.appendChild(link2); >+ }, 0); >+ }); >+}, 'Cache returns stale resource'); >+ >+var link = document.createElement("link"); >+link.rel = "stylesheet"; >+link.type = "text/css"; >+link.href = "resources/stale-css.py?token=" + request_token; >+document.body.appendChild(link); >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-image-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-image-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1e42014defd7191096c33cce5830ef7caa1a57a6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-image-expected.txt >@@ -0,0 +1,4 @@ >+ >+ >+PASS Cache returns stale resource >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-image.html b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-image.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0a08f81729de49985c6575e1a7a5fcb77d3a0ee2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-image.html >@@ -0,0 +1,49 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Tests Stale While Revalidate works for images</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/utils.js"></script> >+<body> >+<!-- >+Use a child document to load the second stale image into because >+an image loaded into the same document will skip cache-control headers. >+See: https://html.spec.whatwg.org/#the-list-of-available-images >+--> >+<iframe id="child" srcdoc=""></iframe> >+<script> >+ >+var request_token = token(); >+async_test(t => { >+ window.onload = t.step_func(() => { >+ t.step_timeout(() => { >+ assert_equals(document.getElementById("firstimage").width, 16, "Width is 16"); >+ var childDocument = document.getElementById('child').contentDocument; >+ var img2 = childDocument.createElement("img"); >+ img2.onload = t.step_func(() => { >+ assert_equals(img2.width, 16, "image dimension"); >+ var checkResult = () => { >+ // We poll because we don't know when the revalidation will occur. >+ fetch("resources/stale-image.py?query&token=" + request_token).then(t.step_func((response) => { >+ var count = response.headers.get("Count"); >+ if (count == '2') { >+ t.done(); >+ } else { >+ t.step_timeout(checkResult, 25); >+ } >+ })); >+ }; >+ t.step_timeout(checkResult, 25); >+ }); >+ img2.src = "resources/stale-image.py?token=" + request_token; >+ childDocument.body.appendChild(img2); >+ }, 0); >+ }); >+}, 'Cache returns stale resource'); >+ >+var img = document.createElement("img"); >+img.src = "resources/stale-image.py?token=" + request_token; >+img.id = "firstimage"; >+document.body.appendChild(img); >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-script-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-script-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..8ac99405a7b89c13e5787eaf079ed6f1488e8c10 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-script-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS Cache returns stale resource >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-script.html b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-script.html >new file mode 100644 >index 0000000000000000000000000000000000000000..68793e50056bc6053ea410d658aed373d19f9a41 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-script.html >@@ -0,0 +1,53 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Tests Stale While Revalidate works for scripts</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/utils.js"></script> >+<body> >+<script> >+var last_modified; >+var last_modified_count = 0; >+var request_token = token(); >+ >+// The script will call report via a uniquely generated ID on the subresource. >+// If it is a cache hit the ID will be the same and the test will pass. >+function report(mod) { >+ if (!last_modified) { >+ last_modified = mod; >+ last_modified_count = 1; >+ } else if (last_modified == mod) { >+ last_modified_count++; >+ } >+} >+ >+async_test(t => { >+ window.onload = t.step_func(() => { >+ step_timeout(() => { >+ var script = document.createElement("script"); >+ script.src = "resources/stale-script.py?token=" + request_token; >+ document.body.appendChild(script); >+ script.onload = t.step_func(() => { >+ assert_equals(last_modified_count, 2, "last modified"); >+ var checkResult = () => { >+ // We poll because we don't know when the revalidation will occur. >+ fetch("resources/stale-script.py?query&token=" + request_token).then(t.step_func((response) => { >+ var count = response.headers.get("Count"); >+ if (count == '2') { >+ t.done(); >+ } else { >+ t.step_timeout(checkResult, 25); >+ } >+ })); >+ }; >+ t.step_timeout(checkResult, 25); >+ }); >+ }, 0); >+ }); >+}, 'Cache returns stale resource'); >+ >+var script = document.createElement("script"); >+script.src = "resources/stale-script.py?token=" + request_token; >+document.body.appendChild(script); >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/sw-intercept.js b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/sw-intercept.js >new file mode 100644 >index 0000000000000000000000000000000000000000..dca7de51b0b8c5518276e70ae219b7bc8f869a95 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/sw-intercept.js >@@ -0,0 +1,14 @@ >+async function broadcast(msg) { >+ for (const client of await clients.matchAll()) { >+ client.postMessage(msg); >+ } >+} >+ >+self.addEventListener('fetch', event => { >+ event.waitUntil(broadcast(event.request.url)); >+ event.respondWith(fetch(event.request)); >+}); >+ >+self.addEventListener('activate', event => { >+ self.clients.claim(); >+}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..ab9dd06f846a7068fea2b828781ad75cc198e7a3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/w3c-import.log >@@ -0,0 +1,22 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/web-platform-tests/wpt >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https.html >+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch.html >+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-css.html >+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-image.html >+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-script.html >+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/sw-intercept.js >diff --git a/LayoutTests/platform/ios-wk1/TestExpectations b/LayoutTests/platform/ios-wk1/TestExpectations >index 5e64038ad8e67d69bc7139c9b7d9371be57b6cc7..7f483dfdb297792c2bef6c0da8ae51b3924f110c 100644 >--- a/LayoutTests/platform/ios-wk1/TestExpectations >+++ b/LayoutTests/platform/ios-wk1/TestExpectations >@@ -1998,3 +1998,6 @@ webkit.org/b/188762 fast/writing-mode/english-rl-text-with-spelling-marker.html > inspector/canvas/recording-html-2d.html > > webkit.org/b/159724 [ Debug ] imported/w3c/web-platform-tests/xhr/send-redirect-post-upload.htm [ Skip ] >+ >+# Stale-while-revalidate is not supported on WK1 >+imported/w3c/web-platform-tests/fetch/stale-while-revalidate [ Skip ] >diff --git a/LayoutTests/platform/mac-wk1/TestExpectations b/LayoutTests/platform/mac-wk1/TestExpectations >index b00cbd6e928d025bb36c364f4015a371a92e5ab5..8a6085cf04784b2d9156eb06c8165704bf9498bf 100644 >--- a/LayoutTests/platform/mac-wk1/TestExpectations >+++ b/LayoutTests/platform/mac-wk1/TestExpectations >@@ -791,3 +791,6 @@ webkit.org/b/199242 [ Debug ] http/tests/performance/performance-resource-timing > [ Mojave+ ] fast/images/animated-heics-verify.html [ Skip ] > > webkit.org/b/200002 [ Mojave+ Debug ] imported/blink/storage/indexeddb/blob-basics-metadata.html [ Timeout ] >+ >+# Stale-while-revalidate is not supported on WK1 >+imported/w3c/web-platform-tests/fetch/stale-while-revalidate [ Skip ]
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 201461
:
379546
|
379550
|
379563
|
380014
|
380309
|
380310
|
380325
|
380743
|
380744
|
380745
|
381807
|
381809
|
381813
|
381827
|
382942
|
383356
|
383373
|
383436