Title: [226481] trunk
Revision
226481
Author
commit-qu...@webkit.org
Date
2018-01-05 17:56:23 -0800 (Fri, 05 Jan 2018)

Log Message

Implement Cache API partitioning based on ClientOrigin
https://bugs.webkit.org/show_bug.cgi?id=181240

Patch by Youenn Fablet <you...@apple.com> on 2018-01-05
Reviewed by Alex Christensen.

Source/WebCore:

Covered by updated tests.

Previously, cache storage was partitioned according the origin of the client, represented as a String.
We now partition according both client and top origins, represented as a ClientOrigin

Minor refactoring to use more makePendingActivity.
Added support for IPC serialization of ClientOrigin.
Added SecurityOriginData::toString which is used by WebKit2 Cache Storage implementation.

* Modules/cache/CacheStorageConnection.cpp:
(WebCore::CacheStorageConnection::open):
(WebCore::CacheStorageConnection::retrieveCaches):
* Modules/cache/CacheStorageConnection.h:
(WebCore::CacheStorageConnection::clearMemoryRepresentation):
(WebCore::CacheStorageConnection::doOpen):
(WebCore::CacheStorageConnection::doRetrieveCaches):
* Modules/cache/DOMCacheStorage.cpp:
(WebCore::DOMCacheStorage::origin const):
(WebCore::DOMCacheStorage::retrieveCaches):
(WebCore::DOMCacheStorage::open):
(WebCore::DOMCacheStorage::remove):
* Modules/cache/DOMCacheStorage.h:
* Modules/cache/WorkerCacheStorageConnection.cpp:
(WebCore::WorkerCacheStorageConnection::doOpen):
(WebCore::WorkerCacheStorageConnection::doRetrieveCaches):
* Modules/cache/WorkerCacheStorageConnection.h:
* page/ClientOrigin.h:
(WebCore::ClientOrigin::isolatedCopy const):
(WebCore::ClientOrigin::encode const):
(WebCore::ClientOrigin::decode):
* page/SecurityOriginData.cpp:
(WebCore::SecurityOriginData::toString const):
(WebCore::SecurityOriginData::debugString const): Deleted.
* page/SecurityOriginData.h:
(WebCore::SecurityOriginData::debugString const):
* testing/Internals.cpp:
(WebCore::Internals::clearCacheStorageMemoryRepresentation):

Source/WebKit:

open and retrieveCaches now take a ClientOrigin instead of a String.
Updated cache filesystem path computation to take both client origin and top origin.

When clearing an origin, caches whose client origin or top origin matches the origin are cleared.
Caches are added to the web site data of their client origin with their corresponding cache size.
Caches are added to the web site data of their top origin with a size equal to 0.

Updated memory representation dumping used for test to include both top and client origins.

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::deleteWebsiteDataForOrigins):
* NetworkProcess/cache/CacheStorageEngine.cpp:
(WebKit::CacheStorage::Engine::cachesRootPath):
(WebKit::CacheStorage::Engine::open):
(WebKit::CacheStorage::Engine::remove):
(WebKit::CacheStorage::Engine::retrieveCaches):
(WebKit::CacheStorage::Engine::readCachesFromDisk):
(WebKit::CacheStorage::Engine::removeCaches):
(WebKit::CacheStorage::Engine::fetchEntries):
(WebKit::CacheStorage::Engine::clearCachesForOrigin):
(WebKit::CacheStorage::Engine::clearMemoryRepresentation):
(WebKit::CacheStorage::Engine::representation):
* NetworkProcess/cache/CacheStorageEngine.h:
* NetworkProcess/cache/CacheStorageEngineCache.cpp:
(WebKit::CacheStorage::Cache::Cache):
* NetworkProcess/cache/CacheStorageEngineCaches.cpp:
(WebKit::CacheStorage::Caches::retrieveOriginFromDirectory):
(WebKit::CacheStorage::Caches::Caches):
(WebKit::CacheStorage::Caches::storeOrigin):
(WebKit::CacheStorage::Caches::readOrigin):
(WebKit::CacheStorage::Caches::open):
* NetworkProcess/cache/CacheStorageEngineCaches.h:
(WebKit::CacheStorage::Caches::create):
(WebKit::CacheStorage::Caches::origin const):
* NetworkProcess/cache/CacheStorageEngineConnection.cpp:
(WebKit::CacheStorageEngineConnection::open):
(WebKit::CacheStorageEngineConnection::caches):
(WebKit::CacheStorageEngineConnection::clearMemoryRepresentation):
* NetworkProcess/cache/CacheStorageEngineConnection.h:
* NetworkProcess/cache/CacheStorageEngineConnection.messages.in:
* WebProcess/Cache/WebCacheStorageConnection.cpp:
(WebKit::WebCacheStorageConnection::doOpen):
(WebKit::WebCacheStorageConnection::doRetrieveCaches):
(WebKit::WebCacheStorageConnection::clearMemoryRepresentation):
* WebProcess/Cache/WebCacheStorageConnection.h:

LayoutTests:

Beefing up test to ensure that client and top origins are taken into consideration.

* http/tests/cache-storage/cache-origins.https-expected.txt:
* http/tests/cache-storage/cache-origins.https.html:
* http/tests/cache-storage/cache-clearing-origin.https-expected.txt:
* http/tests/cache-storage/cache-clearing-origin.https.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (226480 => 226481)


--- trunk/LayoutTests/ChangeLog	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/LayoutTests/ChangeLog	2018-01-06 01:56:23 UTC (rev 226481)
@@ -1,3 +1,17 @@
+2018-01-05  Youenn Fablet  <you...@apple.com>
+
+        Implement Cache API partitioning based on ClientOrigin
+        https://bugs.webkit.org/show_bug.cgi?id=181240
+
+        Reviewed by Alex Christensen.
+
+        Beefing up test to ensure that client and top origins are taken into consideration.
+
+        * http/tests/cache-storage/cache-origins.https-expected.txt:
+        * http/tests/cache-storage/cache-origins.https.html:
+        * http/tests/cache-storage/cache-clearing-origin.https-expected.txt:
+        * http/tests/cache-storage/cache-clearing-origin.https.html:
+
 2017-12-21  Ryan Haddad  <ryanhad...@apple.com>
 
         Mark fast/workers/worker-terminate.html as flaky.

Modified: trunk/LayoutTests/http/tests/cache-storage/cache-clearing-origin.https-expected.txt (226480 => 226481)


--- trunk/LayoutTests/http/tests/cache-storage/cache-clearing-origin.https-expected.txt	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/LayoutTests/http/tests/cache-storage/cache-clearing-origin.https-expected.txt	2018-01-06 01:56:23 UTC (rev 226481)
@@ -1,4 +1,7 @@
 
-PASS Cleaning existing caches 
+
+PASS Create a cache storage from localhost and clear it 
 PASS Clearing disk cache of a given origin 
+PASS Validating cache representation before clearing 
+PASS Validating cache representation after clearing 
 

Modified: trunk/LayoutTests/http/tests/cache-storage/cache-clearing-origin.https.html (226480 => 226481)


--- trunk/LayoutTests/http/tests/cache-storage/cache-clearing-origin.https.html	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/LayoutTests/http/tests/cache-storage/cache-clearing-origin.https.html	2018-01-06 01:56:23 UTC (rev 226481)
@@ -7,15 +7,45 @@
 </head>
 <body>
     <script>
-promise_test(test => {
-    return self.caches.keys().then(keys => {
-        var pending = [];
-        for (key of keys)
-            pending.push(self.caches.delete(keys[0]));
-        return Promise.all(pending);
-    });
-}, "Cleaning existing caches");
+function compareClientOrigins(a, b)
+{
+    if (a.origin.clientOrigin < b.clientOrigin)
+        return 1;
+    if (a.origin.clientOrigin > b.origin.clientOrigin)
+        return -1;
+    return 0;
+}
 
+promise_test(() => {
+    if (!window.internals || !window.testRunner)
+        return Promise.reject("Test requires internals and test runner");
+
+    return new Promise((resolve, reject) => {
+        var counter = 0;
+        window.addEventListener("message", async (event) => {
+            var representation = JSON.parse(await internals.cacheStorageEngineRepresentation());
+            test(() => {
+                representation.sort(compareClientOrigins);
+                var cache = representation[0].origin.clientOrigin === "https://localhost:8443"
+                assert_equals(representation[0].origin.topOrigin, "https://127.0.0.1:8443", "top origin of cache 1");
+                assert_equals(representation[0].origin.clientOrigin, "https://localhost:8443", "client origin of cache 1");
+                assert_array_equals(representation[0].caches.persistent, ["cache1"]);
+            }, "Validating cache representation before clearing");
+
+            testRunner.clearDOMCache('https://localhost:8443');
+
+            representation = JSON.parse(await internals.cacheStorageEngineRepresentation());
+            test(() => {
+                representation.sort(compareClientOrigins);
+                assert_equals(representation[0].origin.topOrigin, "https://127.0.0.1:8443", "top origin of cache 1");
+                assert_equals(representation[0].origin.clientOrigin, "https://localhost:8443", "client origin of cache 1");
+                assert_array_equals(representation[0].caches.persistent, []);
+            }, "Validating cache representation after clearing");
+            resolve();
+        });
+    })
+}, "Create a cache storage from localhost and clear it");
+
 promise_test(async test => {
     var cache = await self.caches.open("test-cache-records-persistency");
     await cache.put("https://example.com/foo", new Response("body", { statusText: "status" }));
@@ -44,5 +74,6 @@
     assert_equals(keys.length, 0, "records should be empty");
 }, 'Clearing disk cache of a given origin');
     </script>
+    <iframe src=""
 </body>
 </html>

Modified: trunk/LayoutTests/http/tests/cache-storage/cache-origins.https-expected.txt (226480 => 226481)


--- trunk/LayoutTests/http/tests/cache-storage/cache-origins.https-expected.txt	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/LayoutTests/http/tests/cache-storage/cache-origins.https-expected.txt	2018-01-06 01:56:23 UTC (rev 226481)
@@ -1,5 +1,7 @@
   
 
 PASS Create a cache storage and look at the representation 
-PASS Caches from different origins should not mix 
+PASS Verifying that two caches are created on two different client origins 
+PASS Verifying that caches are clustered per client origin. 
+PASS Verifying that clearing caches for an origin will clear both top origin and client origin caches. 
 

Modified: trunk/LayoutTests/http/tests/cache-storage/cache-origins.https.html (226480 => 226481)


--- trunk/LayoutTests/http/tests/cache-storage/cache-origins.https.html	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/LayoutTests/http/tests/cache-storage/cache-origins.https.html	2018-01-06 01:56:23 UTC (rev 226481)
@@ -8,28 +8,54 @@
 <body>
     <script>
 
-    function checkCaches(name) {
-        promise_test(() => {
-            return self.caches.keys().then(keys => {
-                assert_true(keys.indexOf("cache1") !== -1, "Should have cache1");
-                assert_true(keys.indexOf("cache2") === -1, "Should not have cache1");
-            });
-        }, name);
+    async function checkCachesAfterClearingMemoryRepresentation(name) {
+        await internals.clearCacheStorageMemoryRepresentation();
+        var keys = await self.caches.keys();
+        test(() => {
+            assert_true(keys.indexOf("cache1") !== -1, "Should have cache1");
+            assert_true(keys.indexOf("cache2") === -1, "Should not have cache2");
+        }, "Verifying that caches are clustered per client origin.");
     }
 
+    async function checkCachesAfterClearingOrigins() {
+        testRunner.clearDOMCache('https://127.0.0.1:8443');
+        var representation = JSON.parse(await internals.cacheStorageEngineRepresentation());
+        test(() => {
+            assert_equals(representation[0].origin.topOrigin, "https://127.0.0.1:8443", "top origin of cache 1");
+            assert_equals(representation[1].origin.topOrigin, "https://127.0.0.1:8443", "top origin of cache 2");
+            assert_equals(representation[0].origin.clientOrigin, "https://127.0.0.1:8443", "client origin of cache 1");
+            assert_equals(representation[1].origin.clientOrigin, "https://localhost:8443", "client origin of cache 2");
+            assert_array_equals(representation[0].caches.persistent, []);
+            assert_array_equals(representation[1].caches.persistent, []);
+        }, "Verifying that clearing caches for an origin will clear both top origin and client origin caches.");
+    }
+
+    async function checkCacheRepresentation() {
+        var representation = JSON.parse(await internals.cacheStorageEngineRepresentation());
+        test(() => {
+            assert_equals(representation[0].origin.topOrigin, "https://127.0.0.1:8443", "top origin of cache 1");
+            assert_equals(representation[1].origin.topOrigin, "https://127.0.0.1:8443", "top origin of cache 2");
+            assert_equals(representation[0].origin.clientOrigin, "https://127.0.0.1:8443", "client origin of cache 1");
+            assert_equals(representation[1].origin.clientOrigin, "https://localhost:8443", "client origin of cache 2");
+            assert_array_equals(representation[0].caches.persistent, ["cache1"]);
+            assert_array_equals(representation[1].caches.persistent, ["cache2"]);
+        }, "Verifying that two caches are created on two different client origins");
+    }
+
     promise_test(test => {
-        if (!window.internals)
-            return Promise.reject("Test requires internals");
+        if (!window.internals || !window.testRunner)
+            return Promise.reject("Test requires internals and test runner");
 
         return new Promise((resolve, reject) => {
             var counter = 0;
-            window.addEventListener("message", test.step_func((event) => {
+            window.addEventListener("message", test.step_func(async (event) => {
                 if (++counter <= 1)
                     return;
-                internals.clearCacheStorageMemoryRepresentation().then(() => {
-                    checkCaches("Caches from different origins should not mix");
-                    resolve();
-                });
+
+                await checkCacheRepresentation();
+                await checkCachesAfterClearingMemoryRepresentation();
+                await checkCachesAfterClearingOrigins();
+                resolve();
             }));
         })
     }, "Create a cache storage and look at the representation");
@@ -40,4 +66,3 @@
     </div>
 </body>
 </html>
-

Modified: trunk/LayoutTests/http/tests/cache-storage/cache-representation.https.html (226480 => 226481)


--- trunk/LayoutTests/http/tests/cache-storage/cache-representation.https.html	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/LayoutTests/http/tests/cache-storage/cache-representation.https.html	2018-01-06 01:56:23 UTC (rev 226481)
@@ -15,6 +15,7 @@
     function checkCaches(hasPersistent, hasRemoved, name, value) {
         test(() => {
             var results = JSON.parse(value);
+            assert_equals(results.length, 1);
             var caches = results[0].caches;
             assert_equals(!!caches["persistent"].length, hasPersistent, "persistent");
             assert_equals(!!caches["removed"].length, hasRemoved, "removed");

Modified: trunk/Source/WebCore/ChangeLog (226480 => 226481)


--- trunk/Source/WebCore/ChangeLog	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebCore/ChangeLog	2018-01-06 01:56:23 UTC (rev 226481)
@@ -1,3 +1,48 @@
+2018-01-05  Youenn Fablet  <you...@apple.com>
+
+        Implement Cache API partitioning based on ClientOrigin
+        https://bugs.webkit.org/show_bug.cgi?id=181240
+
+        Reviewed by Alex Christensen.
+
+        Covered by updated tests.
+
+        Previously, cache storage was partitioned according the origin of the client, represented as a String.
+        We now partition according both client and top origins, represented as a ClientOrigin
+
+        Minor refactoring to use more makePendingActivity.
+        Added support for IPC serialization of ClientOrigin.
+        Added SecurityOriginData::toString which is used by WebKit2 Cache Storage implementation.
+
+        * Modules/cache/CacheStorageConnection.cpp:
+        (WebCore::CacheStorageConnection::open):
+        (WebCore::CacheStorageConnection::retrieveCaches):
+        * Modules/cache/CacheStorageConnection.h:
+        (WebCore::CacheStorageConnection::clearMemoryRepresentation):
+        (WebCore::CacheStorageConnection::doOpen):
+        (WebCore::CacheStorageConnection::doRetrieveCaches):
+        * Modules/cache/DOMCacheStorage.cpp:
+        (WebCore::DOMCacheStorage::origin const):
+        (WebCore::DOMCacheStorage::retrieveCaches):
+        (WebCore::DOMCacheStorage::open):
+        (WebCore::DOMCacheStorage::remove):
+        * Modules/cache/DOMCacheStorage.h:
+        * Modules/cache/WorkerCacheStorageConnection.cpp:
+        (WebCore::WorkerCacheStorageConnection::doOpen):
+        (WebCore::WorkerCacheStorageConnection::doRetrieveCaches):
+        * Modules/cache/WorkerCacheStorageConnection.h:
+        * page/ClientOrigin.h:
+        (WebCore::ClientOrigin::isolatedCopy const):
+        (WebCore::ClientOrigin::encode const):
+        (WebCore::ClientOrigin::decode):
+        * page/SecurityOriginData.cpp:
+        (WebCore::SecurityOriginData::toString const):
+        (WebCore::SecurityOriginData::debugString const): Deleted.
+        * page/SecurityOriginData.h:
+        (WebCore::SecurityOriginData::debugString const):
+        * testing/Internals.cpp:
+        (WebCore::Internals::clearCacheStorageMemoryRepresentation):
+
 2018-01-05  Wenson Hsieh  <wenson_hs...@apple.com>
 
         [Attachment Support] Add a way to write blob data to a file URL from the UI process

Modified: trunk/Source/WebCore/Modules/cache/CacheStorageConnection.cpp (226480 => 226481)


--- trunk/Source/WebCore/Modules/cache/CacheStorageConnection.cpp	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebCore/Modules/cache/CacheStorageConnection.cpp	2018-01-06 01:56:23 UTC (rev 226481)
@@ -33,7 +33,7 @@
 namespace WebCore {
 using namespace WebCore::DOMCacheEngine;
 
-void CacheStorageConnection::open(const String& origin, const String& cacheName, CacheIdentifierCallback&& callback)
+void CacheStorageConnection::open(const ClientOrigin& origin, const String& cacheName, CacheIdentifierCallback&& callback)
 {
     uint64_t requestIdentifier = ++m_lastRequestIdentifier;
     m_openAndRemoveCachePendingRequests.add(requestIdentifier, WTFMove(callback));
@@ -49,7 +49,7 @@
     doRemove(requestIdentifier, cacheIdentifier);
 }
 
-void CacheStorageConnection::retrieveCaches(const String& origin, uint64_t updateCounter, CacheInfosCallback&& callback)
+void CacheStorageConnection::retrieveCaches(const ClientOrigin& origin, uint64_t updateCounter, CacheInfosCallback&& callback)
 {
     uint64_t requestIdentifier = ++m_lastRequestIdentifier;
     m_retrieveCachesPendingRequests.add(requestIdentifier, WTFMove(callback));

Modified: trunk/Source/WebCore/Modules/cache/CacheStorageConnection.h (226480 => 226481)


--- trunk/Source/WebCore/Modules/cache/CacheStorageConnection.h	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebCore/Modules/cache/CacheStorageConnection.h	2018-01-06 01:56:23 UTC (rev 226481)
@@ -32,6 +32,7 @@
 
 namespace WebCore {
 
+struct ClientOrigin;
 class FetchResponse;
 
 class CacheStorageConnection : public ThreadSafeRefCounted<CacheStorageConnection> {
@@ -39,9 +40,9 @@
     static Ref<CacheStorageConnection> create() { return adoptRef(*new CacheStorageConnection()); }
     virtual ~CacheStorageConnection() = default;
 
-    void open(const String& origin, const String& cacheName, DOMCacheEngine::CacheIdentifierCallback&&);
+    void open(const ClientOrigin&, const String& cacheName, DOMCacheEngine::CacheIdentifierCallback&&);
     void remove(uint64_t cacheIdentifier, DOMCacheEngine::CacheIdentifierCallback&&);
-    void retrieveCaches(const String& origin, uint64_t updateCounter, DOMCacheEngine::CacheInfosCallback&&);
+    void retrieveCaches(const ClientOrigin&, uint64_t updateCounter, DOMCacheEngine::CacheInfosCallback&&);
 
     void retrieveRecords(uint64_t cacheIdentifier, const URL&, DOMCacheEngine::RecordsCallback&&);
     void batchDeleteOperation(uint64_t cacheIdentifier, const ResourceRequest&, CacheQueryOptions&&, DOMCacheEngine::RecordIdentifiersCallback&&);
@@ -52,7 +53,7 @@
     virtual void dereference(uint64_t /* cacheIdentifier */) { }
 
     // Used only for testing purposes.
-    virtual void clearMemoryRepresentation(const String& /* origin */, DOMCacheEngine::CompletionCallback&& callback) { callback(DOMCacheEngine::Error::NotImplemented); }
+    virtual void clearMemoryRepresentation(const ClientOrigin&, DOMCacheEngine::CompletionCallback&& callback) { callback(DOMCacheEngine::Error::NotImplemented); }
     virtual void engineRepresentation(WTF::Function<void(const String&)>&& callback) { callback(String { }); }
 
 protected:
@@ -67,9 +68,9 @@
     WEBCORE_EXPORT void putRecordsCompleted(uint64_t requestIdentifier, DOMCacheEngine::RecordIdentifiersOrError&&);
 
 private:
-    virtual void doOpen(uint64_t requestIdentifier, const String& /* origin */, const String& /* cacheName */) { openCompleted(requestIdentifier, makeUnexpected(DOMCacheEngine::Error::NotImplemented)); }
+    virtual void doOpen(uint64_t requestIdentifier, const ClientOrigin&, const String& /* cacheName */) { openCompleted(requestIdentifier, makeUnexpected(DOMCacheEngine::Error::NotImplemented)); }
     virtual void doRemove(uint64_t requestIdentifier, uint64_t /* cacheIdentifier */) { removeCompleted(requestIdentifier, makeUnexpected(DOMCacheEngine::Error::NotImplemented)); }
-    virtual void doRetrieveCaches(uint64_t requestIdentifier, const String& /* origin */, uint64_t /* updateCounter */) { updateCaches(requestIdentifier, { }); }
+    virtual void doRetrieveCaches(uint64_t requestIdentifier, const ClientOrigin&, uint64_t /* updateCounter */) { updateCaches(requestIdentifier, { }); }
 
     virtual void doRetrieveRecords(uint64_t requestIdentifier, uint64_t /* cacheIdentifier */, const URL& /* url */) { updateRecords(requestIdentifier, { }); }
     virtual void doBatchDeleteOperation(uint64_t requestIdentifier, uint64_t /* cacheIdentifier */, const ResourceRequest&, CacheQueryOptions&&) { deleteRecordsCompleted(requestIdentifier, makeUnexpected(DOMCacheEngine::Error::NotImplemented)); }

Modified: trunk/Source/WebCore/Modules/cache/DOMCacheStorage.cpp (226480 => 226481)


--- trunk/Source/WebCore/Modules/cache/DOMCacheStorage.cpp	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebCore/Modules/cache/DOMCacheStorage.cpp	2018-01-06 01:56:23 UTC (rev 226481)
@@ -27,6 +27,7 @@
 #include "DOMCacheStorage.h"
 
 #include "CacheQueryOptions.h"
+#include "ClientOrigin.h"
 #include "JSDOMCache.h"
 #include "JSFetchResponse.h"
 #include "ScriptExecutionContext.h"
@@ -42,11 +43,13 @@
     suspendIfNeeded();
 }
 
-String DOMCacheStorage::origin() const
+std::optional<ClientOrigin> DOMCacheStorage::origin() const
 {
-    // FIXME: Do we really need to check for origin being null?
     auto* origin = scriptExecutionContext() ? scriptExecutionContext()->securityOrigin() : nullptr;
-    return origin ? origin->toString() : String();
+    if (!origin)
+        return std::nullopt;
+
+    return ClientOrigin { SecurityOriginData::fromSecurityOrigin(scriptExecutionContext()->topOrigin()), SecurityOriginData::fromSecurityOrigin(*origin) };
 }
 
 static void doSequentialMatch(size_t index, Vector<Ref<DOMCache>>&& caches, DOMCache::RequestInfo&& info, CacheQueryOptions&& options, DOMCache::MatchCallback&& completionHandler)
@@ -135,12 +138,11 @@
 
 void DOMCacheStorage::retrieveCaches(WTF::Function<void(std::optional<Exception>&&)>&& callback)
 {
-    String origin = this->origin();
-    if (origin.isNull())
+    auto origin = this->origin();
+    if (!origin)
         return;
 
-    setPendingActivity(this);
-    m_connection->retrieveCaches(origin, m_updateCounter, [this, callback = WTFMove(callback)](CacheInfosOrError&& result) mutable {
+    m_connection->retrieveCaches(*origin, m_updateCounter, [this, callback = WTFMove(callback), pendingActivity = makePendingActivity(*this)](CacheInfosOrError&& result) mutable {
         if (!m_isStopped) {
             if (!result.has_value()) {
                 callback(DOMCacheEngine::errorToException(result.error()));
@@ -158,7 +160,6 @@
             }
             callback(std::nullopt);
         }
-        unsetPendingActivity(this);
     });
 }
 
@@ -177,33 +178,32 @@
             promise.reject(WTFMove(exception.value()));
             return;
         }
+        doOpen(name, WTFMove(promise));
+    });
+}
 
-        auto position = m_caches.findMatching([&](auto& item) { return item->name() == name; });
-        if (position != notFound) {
-            auto& cache = m_caches[position];
-            promise.resolve(DOMCache::create(*scriptExecutionContext(), String { cache->name() }, cache->identifier(), m_connection.copyRef()));
-            return;
-        }
+void DOMCacheStorage::doOpen(const String& name, DOMPromiseDeferred<IDLInterface<DOMCache>>&& promise)
+{
+    auto position = m_caches.findMatching([&](auto& item) { return item->name() == name; });
+    if (position != notFound) {
+        auto& cache = m_caches[position];
+        promise.resolve(DOMCache::create(*scriptExecutionContext(), String { cache->name() }, cache->identifier(), m_connection.copyRef()));
+        return;
+    }
 
-        String origin = this->origin();
-        ASSERT(!origin.isNull());
+    m_connection->open(*origin(), name, [this, name, promise = WTFMove(promise), pendingActivity = makePendingActivity(*this)](const CacheIdentifierOrError& result) mutable {
+        if (!m_isStopped) {
+            if (!result.has_value())
+                promise.reject(DOMCacheEngine::errorToException(result.error()));
+            else {
+                if (result.value().hadStorageError)
+                    logConsolePersistencyError(scriptExecutionContext(), name);
 
-        setPendingActivity(this);
-        m_connection->open(origin, name, [this, name, promise = WTFMove(promise)](const CacheIdentifierOrError& result) mutable {
-            if (!m_isStopped) {
-                if (!result.has_value())
-                    promise.reject(DOMCacheEngine::errorToException(result.error()));
-                else {
-                    if (result.value().hadStorageError)
-                        logConsolePersistencyError(scriptExecutionContext(), name);
-
-                    auto cache = DOMCache::create(*scriptExecutionContext(), String { name }, result.value().identifier, m_connection.copyRef());
-                    promise.resolve(cache);
-                    m_caches.append(WTFMove(cache));
-                }
+                auto cache = DOMCache::create(*scriptExecutionContext(), String { name }, result.value().identifier, m_connection.copyRef());
+                promise.resolve(cache);
+                m_caches.append(WTFMove(cache));
             }
-            unsetPendingActivity(this);
-        });
+        }
     });
 }
 
@@ -214,31 +214,30 @@
             promise.reject(WTFMove(exception.value()));
             return;
         }
+        doRemove(name, WTFMove(promise));
+    });
+}
 
-        auto position = m_caches.findMatching([&](auto& item) { return item->name() == name; });
-        if (position == notFound) {
-            promise.resolve(false);
-            return;
-        }
+void DOMCacheStorage::doRemove(const String& name, DOMPromiseDeferred<IDLBoolean>&& promise)
+{
+    auto position = m_caches.findMatching([&](auto& item) { return item->name() == name; });
+    if (position == notFound) {
+        promise.resolve(false);
+        return;
+    }
 
-        String origin = this->origin();
-        ASSERT(!origin.isNull());
-
-        setPendingActivity(this);
-        m_connection->remove(m_caches[position]->identifier(), [this, name, promise = WTFMove(promise)](const CacheIdentifierOrError& result) mutable {
-            if (!m_isStopped) {
-                if (!result.has_value())
-                    promise.reject(DOMCacheEngine::errorToException(result.error()));
-                else {
-                    if (result.value().hadStorageError)
-                        logConsolePersistencyError(scriptExecutionContext(), name);
-                    promise.resolve(true);
-                }
+    m_connection->remove(m_caches[position]->identifier(), [this, name, promise = WTFMove(promise), pendingActivity = makePendingActivity(*this)](const CacheIdentifierOrError& result) mutable {
+        if (!m_isStopped) {
+            if (!result.has_value())
+                promise.reject(DOMCacheEngine::errorToException(result.error()));
+            else {
+                if (result.value().hadStorageError)
+                    logConsolePersistencyError(scriptExecutionContext(), name);
+                promise.resolve(true);
             }
-            unsetPendingActivity(this);
-        });
-        m_caches.remove(position);
+        }
     });
+    m_caches.remove(position);
 }
 
 void DOMCacheStorage::keys(KeysPromise&& promise)

Modified: trunk/Source/WebCore/Modules/cache/DOMCacheStorage.h (226480 => 226481)


--- trunk/Source/WebCore/Modules/cache/DOMCacheStorage.h	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebCore/Modules/cache/DOMCacheStorage.h	2018-01-06 01:56:23 UTC (rev 226481)
@@ -52,9 +52,11 @@
     const char* activeDOMObjectName() const final;
     bool canSuspendForDocumentSuspension() const final;
 
+    void doOpen(const String& name, DOMPromiseDeferred<IDLInterface<DOMCache>>&&);
+    void doRemove(const String&, DOMPromiseDeferred<IDLBoolean>&&);
     void retrieveCaches(WTF::Function<void(std::optional<Exception>&&)>&&);
     Ref<DOMCache> findCacheOrCreate(DOMCacheEngine::CacheInfo&&);
-    String origin() const;
+    std::optional<ClientOrigin> origin() const;
 
     Vector<Ref<DOMCache>> m_caches;
     uint64_t m_updateCounter { 0 };

Modified: trunk/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.cpp (226480 => 226481)


--- trunk/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.cpp	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.cpp	2018-01-06 01:56:23 UTC (rev 226481)
@@ -109,7 +109,7 @@
         callOnMainThread([mainThreadConnection = WTFMove(m_mainThreadConnection)]() mutable { });
 }
 
-void WorkerCacheStorageConnection::doOpen(uint64_t requestIdentifier, const String& origin, const String& cacheName)
+void WorkerCacheStorageConnection::doOpen(uint64_t requestIdentifier, const ClientOrigin& origin, const String& cacheName)
 {
     callOnMainThread([workerThread = makeRef(m_scope.thread()), mainThreadConnection = m_mainThreadConnection, requestIdentifier, origin = origin.isolatedCopy(), cacheName = cacheName.isolatedCopy()] () mutable {
         mainThreadConnection->open(origin, cacheName, [workerThread = WTFMove(workerThread), requestIdentifier] (const CacheIdentifierOrError& result) mutable {
@@ -132,7 +132,7 @@
     });
 }
 
-void WorkerCacheStorageConnection::doRetrieveCaches(uint64_t requestIdentifier, const String& origin, uint64_t updateCounter)
+void WorkerCacheStorageConnection::doRetrieveCaches(uint64_t requestIdentifier, const ClientOrigin& origin, uint64_t updateCounter)
 {
     callOnMainThread([workerThread = makeRef(m_scope.thread()), mainThreadConnection = m_mainThreadConnection, requestIdentifier, origin = origin.isolatedCopy(), updateCounter] () mutable {
         mainThreadConnection->retrieveCaches(origin, updateCounter, [workerThread = WTFMove(workerThread), requestIdentifier] (CacheInfosOrError&& result) mutable {

Modified: trunk/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.h (226480 => 226481)


--- trunk/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.h	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.h	2018-01-06 01:56:23 UTC (rev 226481)
@@ -42,9 +42,9 @@
     explicit WorkerCacheStorageConnection(WorkerGlobalScope&);
 
     // WebCore::CacheStorageConnection.
-    void doOpen(uint64_t requestIdentifier, const String& origin, const String& cacheName) final;
+    void doOpen(uint64_t requestIdentifier, const ClientOrigin&, const String& cacheName) final;
     void doRemove(uint64_t requestIdentifier, uint64_t cacheIdentifier) final;
-    void doRetrieveCaches(uint64_t requestIdentifier, const String& origin, uint64_t updateCounter) final;
+    void doRetrieveCaches(uint64_t requestIdentifier, const ClientOrigin&, uint64_t updateCounter) final;
 
     void doRetrieveRecords(uint64_t requestIdentifier, uint64_t cacheIdentifier, const URL&) final;
 

Modified: trunk/Source/WebCore/page/ClientOrigin.h (226480 => 226481)


--- trunk/Source/WebCore/page/ClientOrigin.h	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebCore/page/ClientOrigin.h	2018-01-06 01:56:23 UTC (rev 226481)
@@ -36,6 +36,11 @@
     unsigned hash() const;
     bool operator==(const ClientOrigin&) const;
 
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<ClientOrigin> decode(Decoder&);
+
+    ClientOrigin isolatedCopy() const;
+
     SecurityOriginData topOrigin;
     SecurityOriginData clientOrigin;
 };
@@ -54,6 +59,31 @@
     return topOrigin == other.topOrigin && clientOrigin == other.clientOrigin;
 }
 
+inline ClientOrigin ClientOrigin::isolatedCopy() const
+{
+    return { topOrigin.isolatedCopy(), clientOrigin.isolatedCopy() };
+}
+
+template<class Encoder> inline void ClientOrigin::encode(Encoder& encoder) const
+{
+    encoder << topOrigin;
+    encoder << clientOrigin;
+}
+
+template<class Decoder> inline std::optional<ClientOrigin> ClientOrigin::decode(Decoder& decoder)
+{
+    std::optional<SecurityOriginData> topOrigin;
+    std::optional<SecurityOriginData> clientOrigin;
+    decoder >> topOrigin;
+    if (!topOrigin)
+        return std::nullopt;
+    decoder >> clientOrigin;
+    if (!clientOrigin)
+        return std::nullopt;
+
+    return ClientOrigin { WTFMove(*topOrigin), WTFMove(*clientOrigin) };
+}
+
 } // namespace WebCore
 
 namespace WTF {

Modified: trunk/Source/WebCore/page/SecurityOriginData.cpp (226480 => 226481)


--- trunk/Source/WebCore/page/SecurityOriginData.cpp	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebCore/page/SecurityOriginData.cpp	2018-01-06 01:56:23 UTC (rev 226481)
@@ -48,12 +48,10 @@
     return securityOriginData;
 }
 
-#if !LOG_DISABLED
-String SecurityOriginData::debugString() const
+String SecurityOriginData::toString() const
 {
     return makeString(protocol, "://", host, ":", String::number(port.value_or(0)));
 }
-#endif
 
 SecurityOriginData SecurityOriginData::fromFrame(Frame* frame)
 {

Modified: trunk/Source/WebCore/page/SecurityOriginData.h (226480 => 226481)


--- trunk/Source/WebCore/page/SecurityOriginData.h	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebCore/page/SecurityOriginData.h	2018-01-06 01:56:23 UTC (rev 226481)
@@ -77,8 +77,10 @@
         return protocol.isHashTableDeletedValue();
     }
     
+    WEBCORE_EXPORT String toString() const;
+
 #if !LOG_DISABLED
-    WEBCORE_EXPORT String debugString() const;
+    String debugString() const { return toString(); }
 #endif
 };
 

Modified: trunk/Source/WebCore/testing/Internals.cpp (226480 => 226481)


--- trunk/Source/WebCore/testing/Internals.cpp	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebCore/testing/Internals.cpp	2018-01-06 01:56:23 UTC (rev 226481)
@@ -45,6 +45,7 @@
 #include "CachedImage.h"
 #include "CachedResourceLoader.h"
 #include "Chrome.h"
+#include "ClientOrigin.h"
 #include "ComposedTreeIterator.h"
 #include "Cursor.h"
 #include "DOMRect.h"
@@ -4248,7 +4249,7 @@
         if (!m_cacheStorageConnection)
             return;
     }
-    m_cacheStorageConnection->clearMemoryRepresentation(document->securityOrigin().toString(), [promise = WTFMove(promise)](std::optional<DOMCacheEngine::Error>&& result) mutable {
+    m_cacheStorageConnection->clearMemoryRepresentation(ClientOrigin { SecurityOriginData::fromSecurityOrigin(document->topOrigin()), SecurityOriginData::fromSecurityOrigin(document->securityOrigin()) }, [promise = WTFMove(promise)] (auto && result) mutable {
         ASSERT_UNUSED(result, !result);
         promise.resolve();
     });

Modified: trunk/Source/WebKit/ChangeLog (226480 => 226481)


--- trunk/Source/WebKit/ChangeLog	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebKit/ChangeLog	2018-01-06 01:56:23 UTC (rev 226481)
@@ -1,3 +1,56 @@
+2018-01-05  Youenn Fablet  <you...@apple.com>
+
+        Implement Cache API partitioning based on ClientOrigin
+        https://bugs.webkit.org/show_bug.cgi?id=181240
+
+        Reviewed by Alex Christensen.
+
+        open and retrieveCaches now take a ClientOrigin instead of a String.
+        Updated cache filesystem path computation to take both client origin and top origin.
+
+        When clearing an origin, caches whose client origin or top origin matches the origin are cleared.
+        Caches are added to the web site data of their client origin with their corresponding cache size.
+        Caches are added to the web site data of their top origin with a size equal to 0.
+
+        Updated memory representation dumping used for test to include both top and client origins.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::deleteWebsiteDataForOrigins):
+        * NetworkProcess/cache/CacheStorageEngine.cpp:
+        (WebKit::CacheStorage::Engine::cachesRootPath):
+        (WebKit::CacheStorage::Engine::open):
+        (WebKit::CacheStorage::Engine::remove):
+        (WebKit::CacheStorage::Engine::retrieveCaches):
+        (WebKit::CacheStorage::Engine::readCachesFromDisk):
+        (WebKit::CacheStorage::Engine::removeCaches):
+        (WebKit::CacheStorage::Engine::fetchEntries):
+        (WebKit::CacheStorage::Engine::clearCachesForOrigin):
+        (WebKit::CacheStorage::Engine::clearMemoryRepresentation):
+        (WebKit::CacheStorage::Engine::representation):
+        * NetworkProcess/cache/CacheStorageEngine.h:
+        * NetworkProcess/cache/CacheStorageEngineCache.cpp:
+        (WebKit::CacheStorage::Cache::Cache):
+        * NetworkProcess/cache/CacheStorageEngineCaches.cpp:
+        (WebKit::CacheStorage::Caches::retrieveOriginFromDirectory):
+        (WebKit::CacheStorage::Caches::Caches):
+        (WebKit::CacheStorage::Caches::storeOrigin):
+        (WebKit::CacheStorage::Caches::readOrigin):
+        (WebKit::CacheStorage::Caches::open):
+        * NetworkProcess/cache/CacheStorageEngineCaches.h:
+        (WebKit::CacheStorage::Caches::create):
+        (WebKit::CacheStorage::Caches::origin const):
+        * NetworkProcess/cache/CacheStorageEngineConnection.cpp:
+        (WebKit::CacheStorageEngineConnection::open):
+        (WebKit::CacheStorageEngineConnection::caches):
+        (WebKit::CacheStorageEngineConnection::clearMemoryRepresentation):
+        * NetworkProcess/cache/CacheStorageEngineConnection.h:
+        * NetworkProcess/cache/CacheStorageEngineConnection.messages.in:
+        * WebProcess/Cache/WebCacheStorageConnection.cpp:
+        (WebKit::WebCacheStorageConnection::doOpen):
+        (WebKit::WebCacheStorageConnection::doRetrieveCaches):
+        (WebKit::WebCacheStorageConnection::clearMemoryRepresentation):
+        * WebProcess/Cache/WebCacheStorageConnection.h:
+
 2018-01-05  Megan Gardner  <megan_gard...@apple.com>
 
         Show Keyboard when re-launching WKWebView with a previously focused element

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (226480 => 226481)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2018-01-06 01:56:23 UTC (rev 226481)
@@ -531,10 +531,8 @@
     });
 
     if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) {
-        for (auto& originData : originDatas) {
-            auto origin = originData.securityOrigin()->toString();
-            CacheStorage::Engine::from(sessionID).clearCachesForOrigin(origin, clearTasksHandler);
-        }
+        for (auto& originData : originDatas)
+            CacheStorage::Engine::from(sessionID).clearCachesForOrigin(originData, clearTasksHandler);
     }
 
     if (websiteDataTypes.contains(WebsiteDataType::DiskCache) && !sessionID.isEphemeral())

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp (226480 => 226481)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp	2018-01-06 01:56:23 UTC (rev 226481)
@@ -52,13 +52,13 @@
     return map;
 }
 
-String Engine::cachesRootPath(const String& origin)
+String Engine::cachesRootPath(const WebCore::ClientOrigin& origin)
 {
     if (!shouldPersist())
         return { };
 
-    Key key(origin, { }, { }, { }, salt());
-    return WebCore::FileSystem::pathByAppendingComponent(rootPath(), key.partitionHashAsString());
+    Key key(origin.topOrigin.toString(), origin.clientOrigin.toString(), { }, { }, salt());
+    return WebCore::FileSystem::pathByAppendingComponent(rootPath(), key.hashAsString());
 }
 
 Engine::~Engine()
@@ -100,7 +100,7 @@
         m_ioQueue = WorkQueue::create("com.apple.WebKit.CacheStorageEngine.serialBackground", WorkQueue::Type::Serial, WorkQueue::QOS::Background);
 }
 
-void Engine::open(const String& origin, const String& cacheName, CacheIdentifierCallback&& callback)
+void Engine::open(const WebCore::ClientOrigin& origin, const String& cacheName, CacheIdentifierCallback&& callback)
 {
     readCachesFromDisk(origin, [cacheName, callback = WTFMove(callback)](CachesOrError&& cachesOrError) mutable {
         if (!cachesOrError.has_value()) {
@@ -118,7 +118,7 @@
     for (auto& caches : m_caches.values()) {
         auto* cacheToRemove = caches->find(cacheIdentifier);
         if (cacheToRemove) {
-            cachesToModify = caches.ptr();
+            cachesToModify = caches.get();
             break;
         }
     }
@@ -130,7 +130,7 @@
     cachesToModify->remove(cacheIdentifier, WTFMove(callback));
 }
 
-void Engine::retrieveCaches(const String& origin, uint64_t updateCounter, CacheInfosCallback&& callback)
+void Engine::retrieveCaches(const WebCore::ClientOrigin& origin, uint64_t updateCounter, CacheInfosCallback&& callback)
 {
     readCachesFromDisk(origin, [updateCounter, callback = WTFMove(callback)](CachesOrError&& cachesOrError) mutable {
         if (!cachesOrError.has_value()) {
@@ -203,15 +203,16 @@
     });
 }
 
-void Engine::readCachesFromDisk(const String& origin, CachesCallback&& callback)
+void Engine::readCachesFromDisk(const WebCore::ClientOrigin& origin, CachesCallback&& callback)
 {
     initialize([this, origin, callback = WTFMove(callback)](std::optional<Error>&& error) mutable {
         auto& caches = m_caches.ensure(origin, [&origin, this] {
-            return Caches::create(*this, String { origin }, cachesRootPath(origin), NetworkProcess::singleton().cacheStoragePerOriginQuota());
+            auto path = cachesRootPath(origin);
+            return Caches::create(*this, WebCore::ClientOrigin { origin }, WTFMove(path), NetworkProcess::singleton().cacheStoragePerOriginQuota());
         }).iterator->value;
 
         if (caches->isInitialized()) {
-            callback(std::reference_wrapper<Caches> { caches.get() });
+            callback(std::reference_wrapper<Caches> { *caches });
             return;
         }
 
@@ -226,7 +227,7 @@
                 return;
             }
 
-            callback(std::reference_wrapper<Caches> { caches.get() });
+            callback(std::reference_wrapper<Caches> { *caches });
         });
     });
 }
@@ -322,12 +323,6 @@
     });
 }
 
-void Engine::removeCaches(const String& origin)
-{
-    ASSERT(m_caches.contains(origin));
-    m_caches.remove(origin);
-}
-
 class ReadOriginsTaskCounter : public RefCounted<ReadOriginsTaskCounter> {
 public:
     static Ref<ReadOriginsTaskCounter> create(WTF::CompletionHandler<void(Vector<WebsiteData::Entry>)>&& callback)
@@ -359,7 +354,7 @@
 {
     if (!shouldPersist()) {
         auto entries = WTF::map(m_caches, [] (auto& pair) {
-            return WebsiteData::Entry { pair.value->origin(), WebsiteDataType::DOMCache, 0 };
+            return WebsiteData::Entry { pair.value->origin().clientOrigin, WebsiteDataType::DOMCache, 0 };
         });
         completionHandler(WTFMove(entries));
         return;
@@ -369,22 +364,22 @@
     for (auto& folderPath : WebCore::FileSystem::listDirectory(m_rootPath, "*")) {
         if (!WebCore::FileSystem::fileIsDirectory(folderPath, WebCore::FileSystem::ShouldFollowSymbolicLinks::No))
             continue;
-        Caches::retrieveOriginFromDirectory(folderPath, *m_ioQueue, [protectedThis = makeRef(*this), shouldComputeSize, taskCounter = taskCounter.copyRef()] (std::optional<WebCore::SecurityOriginData>&& origin) mutable {
+        Caches::retrieveOriginFromDirectory(folderPath, *m_ioQueue, [protectedThis = makeRef(*this), shouldComputeSize, taskCounter = taskCounter.copyRef()] (auto&& origin) mutable {
             ASSERT(RunLoop::isMain());
             if (!origin)
                 return;
 
             if (!shouldComputeSize) {
-                taskCounter->addOrigin(WTFMove(origin.value()), 0);
+                taskCounter->addOrigin(WTFMove(origin->topOrigin), 0);
+                taskCounter->addOrigin(WTFMove(origin->clientOrigin), 0);
                 return;
             }
 
-            auto cacheOrigin = origin->securityOrigin()->toString();
-            protectedThis->readCachesFromDisk(cacheOrigin, [origin = WTFMove(origin.value()), taskCounter = WTFMove(taskCounter)] (CachesOrError&& result) mutable {
+            protectedThis->readCachesFromDisk(origin.value(), [origin = origin.value(), taskCounter = WTFMove(taskCounter)] (CachesOrError&& result) mutable {
                 if (!result.has_value())
                     return;
-                taskCounter->addOrigin(WTFMove(origin), result.value().get().storageSize());
-
+                taskCounter->addOrigin(WTFMove(origin.topOrigin), 0);
+                taskCounter->addOrigin(WTFMove(origin.clientOrigin), result.value().get().storageSize());
             });
         });
     }
@@ -406,22 +401,33 @@
     });
 }
 
-void Engine::clearCachesForOrigin(const String& origin, CallbackAggregator& taskHandler)
+void Engine::clearCachesForOrigin(const WebCore::SecurityOriginData& origin, CallbackAggregator& taskHandler)
 {
-    if (auto caches = m_caches.get(origin)) {
-        caches->clear([taskHandler = makeRef(taskHandler)] { });
-        return;
+    for (auto& keyValue : m_caches) {
+        if (keyValue.key.topOrigin == origin || keyValue.key.clientOrigin == origin)
+            keyValue.value->clear([taskHandler = makeRef(taskHandler)] { });
     }
 
     if (!shouldPersist())
         return;
 
-    m_ioQueue->dispatch([filename = cachesRootPath(origin), taskHandler = makeRef(taskHandler)] {
-        deleteDirectoryRecursively(filename);
-    });
+    for (auto& folderPath : WebCore::FileSystem::listDirectory(m_rootPath, "*")) {
+        if (!WebCore::FileSystem::fileIsDirectory(folderPath, WebCore::FileSystem::ShouldFollowSymbolicLinks::No))
+            continue;
+        Caches::retrieveOriginFromDirectory(folderPath, *m_ioQueue, [this, protectedThis = makeRef(*this), origin, taskHandler = makeRef(taskHandler)] (std::optional<WebCore::ClientOrigin>&& folderOrigin) mutable {
+            if (!folderOrigin)
+                return;
+            if (folderOrigin->topOrigin != origin && folderOrigin->clientOrigin != origin)
+                return;
+
+            m_ioQueue->dispatch([path = cachesRootPath(*folderOrigin), taskHandler = WTFMove(taskHandler)] {
+                deleteDirectoryRecursively(path);
+            });
+        });
+    }
 }
 
-void Engine::clearMemoryRepresentation(const String& origin, WebCore::DOMCacheEngine::CompletionCallback&& callback)
+void Engine::clearMemoryRepresentation(const WebCore::ClientOrigin& origin, WebCore::DOMCacheEngine::CompletionCallback&& callback)
 {
     readCachesFromDisk(origin, [callback = WTFMove(callback)](CachesOrError&& result) {
         if (!result.has_value()) {
@@ -469,9 +475,11 @@
             builder.append(",");
         isFirst = false;
 
-        builder.append("\n{ \"origin\" : \"");
-        builder.append(keyValue.key);
-        builder.append("\", \"caches\" : ");
+        builder.append("\n{ \"origin\" : { \"topOrigin\" : \"");
+        builder.append(keyValue.key.topOrigin.toString());
+        builder.append("\", \"clientOrigin\": \"");
+        builder.append(keyValue.key.clientOrigin.toString());
+        builder.append("\" }, \"caches\" : ");
         keyValue.value->appendRepresentation(builder);
         builder.append("}");
     }

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.h (226480 => 226481)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.h	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.h	2018-01-06 01:56:23 UTC (rev 226481)
@@ -28,6 +28,7 @@
 #include "CacheStorageEngineCaches.h"
 #include "NetworkCacheData.h"
 #include "WebsiteData.h"
+#include <WebCore/ClientOrigin.h>
 #include <wtf/HashMap.h>
 #include <wtf/ThreadSafeRefCounted.h>
 #include <wtf/WorkQueue.h>
@@ -63,9 +64,9 @@
 
     bool shouldPersist() const { return !!m_ioQueue;}
 
-    void open(const String& origin, const String& cacheName, WebCore::DOMCacheEngine::CacheIdentifierCallback&&);
+    void open(const WebCore::ClientOrigin&, const String& cacheName, WebCore::DOMCacheEngine::CacheIdentifierCallback&&);
     void remove(uint64_t cacheIdentifier, WebCore::DOMCacheEngine::CacheIdentifierCallback&&);
-    void retrieveCaches(const String& origin, uint64_t updateCounter, WebCore::DOMCacheEngine::CacheInfosCallback&&);
+    void retrieveCaches(const WebCore::ClientOrigin&, uint64_t updateCounter, WebCore::DOMCacheEngine::CacheInfosCallback&&);
 
     void retrieveRecords(uint64_t cacheIdentifier, WebCore::URL&&, WebCore::DOMCacheEngine::RecordsCallback&&);
     void putRecords(uint64_t cacheIdentifier, Vector<WebCore::DOMCacheEngine::Record>&&, WebCore::DOMCacheEngine::RecordIdentifiersCallback&&);
@@ -82,19 +83,17 @@
     const NetworkCache::Salt& salt() const { return m_salt.value(); }
     uint64_t nextCacheIdentifier() { return ++m_nextCacheIdentifier; }
 
-    void removeCaches(const String& origin);
-
-    void clearMemoryRepresentation(const String& origin, WebCore::DOMCacheEngine::CompletionCallback&&);
+    void clearMemoryRepresentation(const WebCore::ClientOrigin&, WebCore::DOMCacheEngine::CompletionCallback&&);
     String representation();
 
     void clearAllCaches(WTF::CallbackAggregator&);
-    void clearCachesForOrigin(const String& origin, WTF::CallbackAggregator&);
+    void clearCachesForOrigin(const WebCore::SecurityOriginData&, WTF::CallbackAggregator&);
 
 private:
     static Engine& defaultEngine();
     explicit Engine(String&& rootPath);
 
-    String cachesRootPath(const String& origin);
+    String cachesRootPath(const WebCore::ClientOrigin&);
 
     void fetchEntries(bool /* shouldComputeSize */, WTF::CompletionHandler<void(Vector<WebsiteData::Entry>)>&&);
 
@@ -102,7 +101,7 @@
 
     using CachesOrError = Expected<std::reference_wrapper<Caches>, WebCore::DOMCacheEngine::Error>;
     using CachesCallback = WTF::Function<void(CachesOrError&&)>;
-    void readCachesFromDisk(const String& origin, CachesCallback&&);
+    void readCachesFromDisk(const WebCore::ClientOrigin&, CachesCallback&&);
 
     using CacheOrError = Expected<std::reference_wrapper<Cache>, WebCore::DOMCacheEngine::Error>;
     using CacheCallback = WTF::Function<void(CacheOrError&&)>;
@@ -110,7 +109,7 @@
 
     Cache* cache(uint64_t cacheIdentifier);
 
-    HashMap<String, Ref<Caches>> m_caches;
+    HashMap<WebCore::ClientOrigin, RefPtr<Caches>> m_caches;
     uint64_t m_nextCacheIdentifier { 0 };
     String m_rootPath;
     RefPtr<WorkQueue> m_ioQueue;

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.cpp (226480 => 226481)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.cpp	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.cpp	2018-01-06 01:56:23 UTC (rev 226481)
@@ -50,7 +50,7 @@
     return WebCore::FileSystem::pathByAppendingComponent(cachesRootPath, ASCIILiteral("origin"));
 }
 
-void Caches::retrieveOriginFromDirectory(const String& folderPath, WorkQueue& queue, WTF::CompletionHandler<void(std::optional<WebCore::SecurityOriginData>&&)>&& completionHandler)
+void Caches::retrieveOriginFromDirectory(const String& folderPath, WorkQueue& queue, WTF::CompletionHandler<void(std::optional<WebCore::ClientOrigin>&&)>&& completionHandler)
 {
     queue.dispatch([completionHandler = WTFMove(completionHandler), folderPath = folderPath.isolatedCopy()]() mutable {
         if (!WebCore::FileSystem::fileExists(cachesListFilename(folderPath))) {
@@ -72,9 +72,9 @@
     });
 }
 
-Caches::Caches(Engine& engine, String&& origin, String&& rootPath, uint64_t quota)
+Caches::Caches(Engine& engine, WebCore::ClientOrigin&& origin, String&& rootPath, uint64_t quota)
     : m_engine(&engine)
-    , m_origin(WebCore::SecurityOriginData::fromSecurityOrigin(WebCore::SecurityOrigin::createFromString(origin)))
+    , m_origin(WTFMove(origin))
     , m_rootPath(WTFMove(rootPath))
     , m_quota(quota)
 {
@@ -83,27 +83,36 @@
 void Caches::storeOrigin(CompletionCallback&& completionHandler)
 {
     WTF::Persistence::Encoder encoder;
-    encoder << m_origin.protocol;
-    encoder << m_origin.host;
-    encoder << m_origin.port;
+    encoder << m_origin.topOrigin.protocol;
+    encoder << m_origin.topOrigin.host;
+    encoder << m_origin.topOrigin.port;
+    encoder << m_origin.clientOrigin.protocol;
+    encoder << m_origin.clientOrigin.host;
+    encoder << m_origin.clientOrigin.port;
     m_engine->writeFile(cachesOriginFilename(m_rootPath), Data { encoder.buffer(), encoder.bufferSize() }, [protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] (std::optional<Error>&& error) mutable {
         completionHandler(WTFMove(error));
     });
 }
 
-std::optional<WebCore::SecurityOriginData> Caches::readOrigin(const Data& data)
+std::optional<WebCore::ClientOrigin> Caches::readOrigin(const Data& data)
 {
     // FIXME: We should be able to use modern decoders for persistent data.
-    WebCore::SecurityOriginData origin;
+    WebCore::SecurityOriginData topOrigin, clientOrigin;
     WTF::Persistence::Decoder decoder(data.data(), data.size());
 
-    if (!decoder.decode(origin.protocol))
+    if (!decoder.decode(topOrigin.protocol))
         return std::nullopt;
-    if (!decoder.decode(origin.host))
+    if (!decoder.decode(topOrigin.host))
         return std::nullopt;
-    if (!decoder.decode(origin.port))
+    if (!decoder.decode(topOrigin.port))
         return std::nullopt;
-    return WTFMove(origin);
+    if (!decoder.decode(clientOrigin.protocol))
+        return std::nullopt;
+    if (!decoder.decode(clientOrigin.host))
+        return std::nullopt;
+    if (!decoder.decode(clientOrigin.port))
+        return std::nullopt;
+    return WebCore::ClientOrigin { WTFMove(topOrigin), WTFMove(clientOrigin) };
 }
 
 void Caches::initialize(WebCore::DOMCacheEngine::CompletionCallback&& callback)

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.h (226480 => 226481)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.h	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.h	2018-01-06 01:56:23 UTC (rev 226481)
@@ -27,7 +27,7 @@
 
 #include "CacheStorageEngineCache.h"
 #include "NetworkCacheStorage.h"
-#include <WebCore/SecurityOriginData.h>
+#include <WebCore/ClientOrigin.h>
 #include <wtf/CompletionHandler.h>
 
 namespace WebKit {
@@ -38,9 +38,9 @@
 
 class Caches : public RefCounted<Caches> {
 public:
-    static Ref<Caches> create(Engine& engine, String&& origin, String&& rootPath, uint64_t quota) { return adoptRef(*new Caches { engine, WTFMove(origin), WTFMove(rootPath), quota }); }
+    static Ref<Caches> create(Engine& engine, WebCore::ClientOrigin&& origin, String&& rootPath, uint64_t quota) { return adoptRef(*new Caches { engine, WTFMove(origin), WTFMove(rootPath), quota }); }
 
-    static void retrieveOriginFromDirectory(const String& folderPath, WorkQueue&, WTF::CompletionHandler<void(std::optional<WebCore::SecurityOriginData>&&)>&&);
+    static void retrieveOriginFromDirectory(const String& folderPath, WorkQueue&, WTF::CompletionHandler<void(std::optional<WebCore::ClientOrigin>&&)>&&);
 
     void initialize(WebCore::DOMCacheEngine::CompletionCallback&&);
     void open(const String& name, WebCore::DOMCacheEngine::CacheIdentifierCallback&&);
@@ -66,7 +66,7 @@
     void removeRecord(const RecordInformation&);
 
     const NetworkCache::Salt& salt() const;
-    const WebCore::SecurityOriginData& origin() const { return m_origin; }
+    const WebCore::ClientOrigin& origin() const { return m_origin; }
 
     bool shouldPersist() const { return !m_rootPath.isNull(); }
 
@@ -76,7 +76,7 @@
     uint64_t storageSize() const;
 
 private:
-    Caches(Engine&, String&& origin, String&& rootPath, uint64_t quota);
+    Caches(Engine&, WebCore::ClientOrigin&&, String&& rootPath, uint64_t quota);
 
     void initializeSize(WebCore::DOMCacheEngine::CompletionCallback&&);
     void readCachesFromDisk(WTF::Function<void(Expected<Vector<Cache>, WebCore::DOMCacheEngine::Error>&&)>&&);
@@ -83,7 +83,7 @@
     void writeCachesToDisk(WebCore::DOMCacheEngine::CompletionCallback&&);
 
     void storeOrigin(WebCore::DOMCacheEngine::CompletionCallback&&);
-    static std::optional<WebCore::SecurityOriginData> readOrigin(const NetworkCache::Data&);
+    static std::optional<WebCore::ClientOrigin> readOrigin(const NetworkCache::Data&);
 
     Cache* find(const String& name);
 
@@ -93,7 +93,7 @@
     bool m_isInitialized { false };
     Engine* m_engine { nullptr };
     uint64_t m_updateCounter { 0 };
-    WebCore::SecurityOriginData m_origin;
+    WebCore::ClientOrigin m_origin;
     String m_rootPath;
     uint64_t m_quota { 0 };
     uint64_t m_size { 0 };

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.cpp (226480 => 226481)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.cpp	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.cpp	2018-01-06 01:56:23 UTC (rev 226481)
@@ -53,7 +53,7 @@
     }
 }
 
-void CacheStorageEngineConnection::open(PAL::SessionID sessionID, uint64_t requestIdentifier, const String& origin, const String& cacheName)
+void CacheStorageEngineConnection::open(PAL::SessionID sessionID, uint64_t requestIdentifier, const WebCore::ClientOrigin& origin, const String& cacheName)
 {
     Engine::from(sessionID).open(origin, cacheName, [connection = makeRef(m_connection.connection()), sessionID, requestIdentifier](const CacheIdentifierOrError& result) {
         connection->send(Messages::WebCacheStorageConnection::OpenCompleted(requestIdentifier, result), sessionID.sessionID());
@@ -67,7 +67,7 @@
     });
 }
 
-void CacheStorageEngineConnection::caches(PAL::SessionID sessionID, uint64_t requestIdentifier, const String& origin, uint64_t updateCounter)
+void CacheStorageEngineConnection::caches(PAL::SessionID sessionID, uint64_t requestIdentifier, const WebCore::ClientOrigin& origin, uint64_t updateCounter)
 {
     Engine::from(sessionID).retrieveCaches(origin, updateCounter, [connection = makeRef(m_connection.connection()), sessionID, origin, requestIdentifier](CacheInfosOrError&& result) {
         connection->send(Messages::WebCacheStorageConnection::UpdateCaches(requestIdentifier, result), sessionID.sessionID());
@@ -127,7 +127,7 @@
     references.remove(referenceResult);
 }
 
-void CacheStorageEngineConnection::clearMemoryRepresentation(PAL::SessionID sessionID, uint64_t requestIdentifier, const String& origin)
+void CacheStorageEngineConnection::clearMemoryRepresentation(PAL::SessionID sessionID, uint64_t requestIdentifier, const WebCore::ClientOrigin& origin)
 {
     Engine::from(sessionID).clearMemoryRepresentation(origin, [connection = makeRef(m_connection.connection()), sessionID, requestIdentifier] (std::optional<Error>&& error) {
         connection->send(Messages::WebCacheStorageConnection::ClearMemoryRepresentationCompleted(requestIdentifier, error), sessionID.sessionID());

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.h (226480 => 226481)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.h	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.h	2018-01-06 01:56:23 UTC (rev 226481)
@@ -50,9 +50,9 @@
 private:
     explicit CacheStorageEngineConnection(NetworkConnectionToWebProcess&);
 
-    void open(PAL::SessionID, uint64_t openRequestIdentifier, const String& origin, const String& cacheName);
+    void open(PAL::SessionID, uint64_t openRequestIdentifier, const WebCore::ClientOrigin&, const String& cacheName);
     void remove(PAL::SessionID, uint64_t removeRequestIdentifier, uint64_t cacheIdentifier);
-    void caches(PAL::SessionID, uint64_t retrieveCachesIdentifier, const String& origin, uint64_t updateCounter);
+    void caches(PAL::SessionID, uint64_t retrieveCachesIdentifier, const WebCore::ClientOrigin&, uint64_t updateCounter);
 
     void retrieveRecords(PAL::SessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier, WebCore::URL&&);
     void deleteMatchingRecords(PAL::SessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier, WebCore::ResourceRequest&&, WebCore::CacheQueryOptions&&);
@@ -61,7 +61,7 @@
     void reference(PAL::SessionID, uint64_t cacheIdentifier);
     void dereference(PAL::SessionID, uint64_t cacheIdentifier);
 
-    void clearMemoryRepresentation(PAL::SessionID, uint64_t requestIdentifier, const String& origin);
+    void clearMemoryRepresentation(PAL::SessionID, uint64_t requestIdentifier, const WebCore::ClientOrigin&);
     void engineRepresentation(PAL::SessionID, uint64_t requestIdentifier);
 
     NetworkConnectionToWebProcess& m_connection;

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.messages.in (226480 => 226481)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.messages.in	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.messages.in	2018-01-06 01:56:23 UTC (rev 226481)
@@ -24,11 +24,11 @@
     Reference(PAL::SessionID sessionID, uint64_t cacheIdentifier);
     Dereference(PAL::SessionID sessionID, uint64_t cacheIdentifier);
 
-    Open(PAL::SessionID sessionID, uint64_t requestIdentifier, String origin, String cacheName);
+    Open(PAL::SessionID sessionID, uint64_t requestIdentifier, struct WebCore::ClientOrigin origin, String cacheName);
     Remove(PAL::SessionID sessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier);
-    Caches(PAL::SessionID sessionID, uint64_t requestIdentifier, String origin, uint64_t updateCounter);
+    Caches(PAL::SessionID sessionID, uint64_t requestIdentifier, struct WebCore::ClientOrigin origin, uint64_t updateCounter);
 
-    ClearMemoryRepresentation(PAL::SessionID sessionID, uint64_t requestIdentifier, String origin);
+    ClearMemoryRepresentation(PAL::SessionID sessionID, uint64_t requestIdentifier, struct WebCore::ClientOrigin origin);
     EngineRepresentation(PAL::SessionID sessionID, uint64_t requestIdentifier);
 
     RetrieveRecords(PAL::SessionID sessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier, WebCore::URL url);

Modified: trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.cpp (226480 => 226481)


--- trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.cpp	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.cpp	2018-01-06 01:56:23 UTC (rev 226481)
@@ -56,7 +56,7 @@
     return WebProcess::singleton().ensureNetworkProcessConnection().connection();
 }
 
-void WebCacheStorageConnection::doOpen(uint64_t requestIdentifier, const String& origin, const String& cacheName)
+void WebCacheStorageConnection::doOpen(uint64_t requestIdentifier, const WebCore::ClientOrigin& origin, const String& cacheName)
 {
     connection().send(Messages::CacheStorageEngineConnection::Open(m_sessionID, requestIdentifier, origin, cacheName), 0);
 }
@@ -66,7 +66,7 @@
     connection().send(Messages::CacheStorageEngineConnection::Remove(m_sessionID, requestIdentifier, cacheIdentifier), 0);
 }
 
-void WebCacheStorageConnection::doRetrieveCaches(uint64_t requestIdentifier, const String& origin, uint64_t updateCounter)
+void WebCacheStorageConnection::doRetrieveCaches(uint64_t requestIdentifier, const WebCore::ClientOrigin& origin, uint64_t updateCounter)
 {
     connection().send(Messages::CacheStorageEngineConnection::Caches(m_sessionID, requestIdentifier, origin, updateCounter), 0);
 }
@@ -126,7 +126,7 @@
     CacheStorageConnection::putRecordsCompleted(requestIdentifier, WTFMove(result));
 }
 
-void WebCacheStorageConnection::clearMemoryRepresentation(const String& origin, CompletionCallback&& callback)
+void WebCacheStorageConnection::clearMemoryRepresentation(const WebCore::ClientOrigin& origin, CompletionCallback&& callback)
 {
     uint64_t requestIdentifier = ++m_engineRepresentationNextIdentifier;
     m_clearRepresentationCallbacks.set(requestIdentifier, WTFMove(callback));

Modified: trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.h (226480 => 226481)


--- trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.h	2018-01-06 01:53:44 UTC (rev 226480)
+++ trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.h	2018-01-06 01:56:23 UTC (rev 226481)
@@ -52,9 +52,9 @@
     IPC::Connection& connection();
 
     // WebCore::CacheStorageConnection
-    void doOpen(uint64_t requestIdentifier, const String& origin, const String& cacheName) final;
+    void doOpen(uint64_t requestIdentifier, const WebCore::ClientOrigin&, const String& cacheName) final;
     void doRemove(uint64_t requestIdentifier, uint64_t cacheIdentifier) final;
-    void doRetrieveCaches(uint64_t requestIdentifier, const String& origin, uint64_t updateCounter) final;
+    void doRetrieveCaches(uint64_t requestIdentifier, const WebCore::ClientOrigin&, uint64_t updateCounter) final;
 
     void doRetrieveRecords(uint64_t requestIdentifier, uint64_t cacheIdentifier, const WebCore::URL&) final;
     void doBatchDeleteOperation(uint64_t requestIdentifier, uint64_t cacheIdentifier, const WebCore::ResourceRequest&, WebCore::CacheQueryOptions&&) final;
@@ -63,7 +63,7 @@
     void reference(uint64_t cacheIdentifier) final;
     void dereference(uint64_t cacheIdentifier) final;
 
-    void clearMemoryRepresentation(const String& origin, WebCore::DOMCacheEngine::CompletionCallback&&) final;
+    void clearMemoryRepresentation(const WebCore::ClientOrigin&, WebCore::DOMCacheEngine::CompletionCallback&&) final;
     void engineRepresentation(WTF::Function<void(const String&)>&&) final;
 
     void openCompleted(uint64_t requestIdentifier, const WebCore::DOMCacheEngine::CacheIdentifierOrError&);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to