Title: [221403] trunk
Revision
221403
Author
commit-qu...@webkit.org
Date
2017-08-30 15:50:22 -0700 (Wed, 30 Aug 2017)

Log Message

[Cache API] Support cache names persistency
https://bugs.webkit.org/show_bug.cgi?id=175995

Patch by Youenn Fablet <you...@apple.com> on 2017-08-30
Reviewed by Alex Christensen.

Source/WebCore:

Test: http/tests/cache-storage/cache-persistency.https.html

Adding method to clear the memory representation of the cache storage.
Exposing it as internals so that layout tests can be used for testing persistency by combining clearing and private browsing mode.

Introducing ReadDisk and WriteDisk errors that are used by CacheStorage::Engine.

* Modules/cache/CacheStorageConnection.h:
(WebCore::CacheStorageConnection::clearMemoryRepresentation):
* Modules/cache/DOMCache.cpp:
(WebCore::DOMCache::errorToException):
* Modules/cache/DOMCache.h:
* testing/Internals.cpp:
(WebCore::Internals::clearCacheStorageMemoryRepresentation):
* testing/Internals.h:
* testing/Internals.idl:

Source/WebKit:

Adding disk read/write capacities to CacheStorage engine.
This is used to store per-origin cache names in a file.
Making Engine a thread safe refcounted object so that it does read/write in a background thread.

Introducing CacheStorage::Caches as the object managing the list of Cache objects for a given origin.
Caches will be responsible to do all the read/write operations for all of its caches.
It will be responsible for quota limitation as well.

Moving part of the logic from CacheStorage::Engine into CacheStorage::Caches.

CacheStorage::Engine is initialized asynchronously as it first creates a salt which is used
to obfuscate the names of the various files stored on disk.

In the same spirit, CacheStorage::Caches is initialized asynchronously as it needs to read from the disk the list of cache names.
Once read, the names will be stored in memory.
Added the possibility to clear this in-memory representation. This will be useful for testing.
This might also be useful to save memory when there is no more use of CacheStorage by web pages.

Introducing a new cacheStorageSubdirectoryName parameter for WebsiteDataStore so as to segment the different per session CacheStorageEngine
in direct sub folders of the main cacheStorageDirectory folder.

* CMakeLists.txt:
* NetworkProcess/cache/CacheStorageEngine.cpp:
(WebKit::CacheStorage::Engine::open):
(WebKit::CacheStorage::Engine::remove):
(WebKit::CacheStorage::Engine::retrieveCaches):
(WebKit::CacheStorage::Engine::retrieveRecords):
(WebKit::CacheStorage::Engine::initialize):
(WebKit::CacheStorage::Engine::readCachesFromDisk):
(WebKit::CacheStorage::Engine::cache):
(WebKit::CacheStorage::Engine::writeFile): Making use of default parameter to directly return to the main loop.
(WebKit::CacheStorage::Engine::readFile): Ditto.
(WebKit::CacheStorage::Engine::clearMemoryRepresentation):
* NetworkProcess/cache/CacheStorageEngine.h:
(WebKit::CacheStorage::Engine::rootPath const):
(WebKit::CacheStorage::Engine::salt const):
(WebKit::CacheStorage::Engine::nextCacheIdentifier):
* NetworkProcess/cache/CacheStorageEngineCaches.cpp: Added.
(WebKit::CacheStorage::cachesRootPath):
(WebKit::CacheStorage::cachesListFilename):
(WebKit::CacheStorage::Caches::Caches):
(WebKit::CacheStorage::Caches::initialize):
(WebKit::CacheStorage::Caches::find):
(WebKit::CacheStorage::Caches::open):
(WebKit::CacheStorage::Caches::remove):
(WebKit::CacheStorage::encodeCacheNames):
(WebKit::CacheStorage::decodeCachesNames):
(WebKit::CacheStorage::Caches::readCachesFromDisk):
(WebKit::CacheStorage::Caches::writeCachesToDisk):
(WebKit::CacheStorage::Caches::clearMemoryRepresentation):
(WebKit::CacheStorage::Caches::cacheInfos const):
* NetworkProcess/cache/CacheStorageEngineCaches.h: Added.
(WebKit::CacheStorage::Caches::create):
(WebKit::CacheStorage::Caches::isInitialized const):
(WebKit::CacheStorage::Caches::detach):
* NetworkProcess/cache/CacheStorageEngineConnection.cpp:
(WebKit::CacheStorageEngineConnection::clearMemoryRepresentation):
* NetworkProcess/cache/CacheStorageEngineConnection.h:
* NetworkProcess/cache/CacheStorageEngineConnection.messages.in:
* NetworkProcess/cache/NetworkCacheData.cpp:
(WebKit::NetworkCache::makeSalt):
* NetworkProcess/cache/NetworkCacheData.h:
* UIProcess/WebsiteData/WebsiteDataStore.h:
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/Cache/WebCacheStorageConnection.cpp:
(WebKit::WebCacheStorageConnection::clearMemoryRepresentation):
* WebProcess/Cache/WebCacheStorageConnection.h:

LayoutTests:

Putting these tests in http/tests folder so that they run in a different origin and so a different Caches than other tests.
Testing private browsing caching and clearing the memory representation would probably affect other cache+prviate browsing tests that would run in parallel.

* http/tests/cache-storage/cache-persistency.https-expected.txt: Added.
* http/tests/cache-storage/cache-persistency.https.html: Added.
* http/tests/cache-storage/resources/cache-persistency-iframe.html: Added.
* platform/ios-wk1/TestExpectations: Skipping new test on WK1.
* platform/mac-wk1/TestExpectations: Ditto.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (221402 => 221403)


--- trunk/LayoutTests/ChangeLog	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/LayoutTests/ChangeLog	2017-08-30 22:50:22 UTC (rev 221403)
@@ -1,3 +1,19 @@
+2017-08-30  Youenn Fablet  <you...@apple.com>
+
+        [Cache API] Support cache names persistency
+        https://bugs.webkit.org/show_bug.cgi?id=175995
+
+        Reviewed by Alex Christensen.
+
+        Putting these tests in http/tests folder so that they run in a different origin and so a different Caches than other tests.
+        Testing private browsing caching and clearing the memory representation would probably affect other cache+prviate browsing tests that would run in parallel.
+
+        * http/tests/cache-storage/cache-persistency.https-expected.txt: Added.
+        * http/tests/cache-storage/cache-persistency.https.html: Added.
+        * http/tests/cache-storage/resources/cache-persistency-iframe.html: Added.
+        * platform/ios-wk1/TestExpectations: Skipping new test on WK1.
+        * platform/mac-wk1/TestExpectations: Ditto.
+
 2017-08-30  Per Arne Vollan  <pvol...@apple.com>
 
         Update expectations for CSS regions tests after r220870.

Added: trunk/LayoutTests/http/tests/cache-storage/cache-persistency.https-expected.txt (0 => 221403)


--- trunk/LayoutTests/http/tests/cache-storage/cache-persistency.https-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/cache-storage/cache-persistency.https-expected.txt	2017-08-30 22:50:22 UTC (rev 221403)
@@ -0,0 +1,10 @@
+
+
+PASS Cleaning existing caches 
+PASS Clear memory representation and disable disk persistency 
+PASS Cleaning added caches from previous test 1 
+PASS Clear memory representation but keep disk persistency 
+PASS Cleaning added caches from previous test 2 
+PASS Adding/Removing caches and clearing in memory representation at various times 
+PASS Cleaning added caches 
+

Added: trunk/LayoutTests/http/tests/cache-storage/cache-persistency.https.html (0 => 221403)


--- trunk/LayoutTests/http/tests/cache-storage/cache-persistency.https.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/cache-storage/cache-persistency.https.html	2017-08-30 22:50:22 UTC (rev 221403)
@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Cache Storage: testing persistency</title>
+<script src=""
+<script src=""
+</head>
+<body>
+    <div id="check"></div>
+    <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");
+
+    promise_test(test => {
+        if (!window.internals || !window.testRunner)
+            return Promise.reject("Test requires internals");
+
+        testRunner.setPrivateBrowsingEnabled(true);
+
+        return new Promise((resolve, reject) => {
+            window.addEventListener("message", test.step_func((event) => {
+                if (event.data ="" "ready") {
+                    internals.clearCacheStorageMemoryRepresentation();
+                    check.innerHTML = "<iframe src=''></iframe>";
+                    return;
+                }
+                assert_true(event.data ="" false, "No cache object should be found");
+                testRunner.setPrivateBrowsingEnabled(false);
+                resolve();
+            }));
+            check.innerHTML = "<iframe src=''></iframe>";
+        })
+    }, "Clear memory representation and disable disk persistency");
+
+    promise_test(test => {
+        if (window.internals)
+            internals.clearCacheStorageMemoryRepresentation();
+        if (window.testRunner)
+            testRunner.setPrivateBrowsingEnabled(false);
+
+        return self.caches.keys().then(keys => {
+            var pending = [];
+            for (key of keys)
+                pending.push(self.caches.delete(keys[0]));
+            return Promise.all(pending);
+        });
+    }, "Cleaning added caches from previous test 1");
+
+    promise_test(test => {
+        if (!window.internals)
+            return Promise.reject("Test requires internals");
+
+        return new Promise((resolve, reject) => {
+            window.addEventListener("message", test.step_func((event) => {
+                if (event.data ="" "ready") {
+                    internals.clearCacheStorageMemoryRepresentation();
+                    check.innerHTML = "<iframe src=''></iframe>";
+                    return;
+                }
+                assert_true(event.data ="" true, "A cache object should be found");
+                resolve();
+            }));
+            check.innerHTML = "<iframe src=''></iframe>";
+        })
+    }, "Clear memory representation but keep disk persistency");
+
+    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 added caches from previous test 2");
+
+    promise_test(test => {
+        if (!window.internals)
+            return Promise.reject("Test requires internals");
+
+        return Promise.all([self.caches.open("test2"), self.caches.open("test1")]).then(() => {
+            return self.caches.keys()
+        }).then(keys => {
+            assert_array_equals(keys, ["test2", "test1"]);
+        }).then(() => {
+            internals.clearCacheStorageMemoryRepresentation();
+            return self.caches.keys();
+        }).then(keys => {
+            assert_array_equals(keys, ["test2", "test1"]);
+            return self.caches.delete("test2");
+        }).then(() => {
+            internals.clearCacheStorageMemoryRepresentation();
+            return self.caches.keys();
+        }).then(keys => {
+            assert_array_equals(keys, ["test1"]);
+        }).then(() => {
+            return self.caches.open("test2");
+        }).then(() => {
+            internals.clearCacheStorageMemoryRepresentation();
+            return self.caches.keys();
+        }).then(keys => {
+            assert_array_equals(keys, ["test1", "test2"]);
+        }).then(() => {
+            return Promise.all([self.caches.delete("test2"), self.caches.delete("test1")]);
+        }).then(() => {
+            internals.clearCacheStorageMemoryRepresentation();
+            return self.caches.keys();
+        }).then(keys => {
+            assert_array_equals(keys, []);
+        });
+    }, "Adding/Removing caches and clearing in memory representation at various times");
+
+    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 added caches");
+    </script>
+</body>
+</html>
+

Added: trunk/LayoutTests/http/tests/cache-storage/resources/cache-persistency-iframe.html (0 => 221403)


--- trunk/LayoutTests/http/tests/cache-storage/resources/cache-persistency-iframe.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/cache-storage/resources/cache-persistency-iframe.html	2017-08-30 22:50:22 UTC (rev 221403)
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<body>
+    <script>
+function doTest()
+{
+    if (window.location.hash === "#check") {
+        self.caches.keys().then(keys => {
+            window.parent.postMessage(keys.length === 1 && keys[0] === "testCacheName", "*");
+        });
+        return;
+    }
+
+    self.caches.open("testCacheName").then(() => {
+        window.parent.postMessage("ready", "*");
+    });
+}
+doTest();
+    </script>
+</body>
+</html>
+

Modified: trunk/LayoutTests/platform/ios-wk1/TestExpectations (221402 => 221403)


--- trunk/LayoutTests/platform/ios-wk1/TestExpectations	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/LayoutTests/platform/ios-wk1/TestExpectations	2017-08-30 22:50:22 UTC (rev 221403)
@@ -10,6 +10,7 @@
 # No service worker implementation for WK1
 imported/w3c/web-platform-tests/service-workers [ Skip ]
 http/wpt/cache-storage [ Skip ]
+http/tests/cache-storage [ Skip ]
 
 # Skip WebRTC for now in WK1
 imported/w3c/web-platform-tests/webrtc [ Skip ]

Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (221402 => 221403)


--- trunk/LayoutTests/platform/mac-wk1/TestExpectations	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations	2017-08-30 22:50:22 UTC (rev 221403)
@@ -94,6 +94,7 @@
 # No service worker implementation for WK1
 imported/w3c/web-platform-tests/service-workers [ Skip ]
 http/wpt/cache-storage [ Skip ]
+http/tests/cache-storage [ Skip ]
 
 # Skip WebRTC for now in WK1
 imported/w3c/web-platform-tests/webrtc [ Skip ]

Modified: trunk/Source/WebCore/ChangeLog (221402 => 221403)


--- trunk/Source/WebCore/ChangeLog	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebCore/ChangeLog	2017-08-30 22:50:22 UTC (rev 221403)
@@ -1,3 +1,27 @@
+2017-08-30  Youenn Fablet  <you...@apple.com>
+
+        [Cache API] Support cache names persistency
+        https://bugs.webkit.org/show_bug.cgi?id=175995
+
+        Reviewed by Alex Christensen.
+
+        Test: http/tests/cache-storage/cache-persistency.https.html
+
+        Adding method to clear the memory representation of the cache storage.
+        Exposing it as internals so that layout tests can be used for testing persistency by combining clearing and private browsing mode.
+
+        Introducing ReadDisk and WriteDisk errors that are used by CacheStorage::Engine.
+
+        * Modules/cache/CacheStorageConnection.h:
+        (WebCore::CacheStorageConnection::clearMemoryRepresentation):
+        * Modules/cache/DOMCache.cpp:
+        (WebCore::DOMCache::errorToException):
+        * Modules/cache/DOMCache.h:
+        * testing/Internals.cpp:
+        (WebCore::Internals::clearCacheStorageMemoryRepresentation):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2017-08-30  Matt Lewis  <jlew...@apple.com>
 
         Unreviewed, rolling out r221384.

Modified: trunk/Source/WebCore/Modules/cache/CacheStorageConnection.h (221402 => 221403)


--- trunk/Source/WebCore/Modules/cache/CacheStorageConnection.h	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebCore/Modules/cache/CacheStorageConnection.h	2017-08-30 22:50:22 UTC (rev 221403)
@@ -45,6 +45,9 @@
     void batchDeleteOperation(uint64_t cacheIdentifier, const ResourceRequest&, CacheQueryOptions&&, DOMCache::RecordIdentifiersCallback&&);
     void batchPutOperation(uint64_t cacheIdentifier, Vector<DOMCache::Record>&&, DOMCache::RecordIdentifiersCallback&&);
 
+    // Used only for testing purposes.
+    virtual void clearMemoryRepresentation(const String& /* origin */, DOMCache::CompletionCallback&& callback) { callback(DOMCache::Error::NotImplemented); }
+
 protected:
     CacheStorageConnection() =  default;
 

Modified: trunk/Source/WebCore/Modules/cache/DOMCache.cpp (221402 => 221403)


--- trunk/Source/WebCore/Modules/cache/DOMCache.cpp	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebCore/Modules/cache/DOMCache.cpp	2017-08-30 22:50:22 UTC (rev 221403)
@@ -40,6 +40,10 @@
     switch (error) {
     case Error::NotImplemented:
         return Exception { NotSupportedError, ASCIILiteral("Not implemented") };
+    case Error::ReadDisk:
+        return Exception { TypeError, ASCIILiteral("Failed reading data from the file system") };
+    case Error::WriteDisk:
+        return Exception { TypeError, ASCIILiteral("Failed writing data to the file system") };
     default:
         return Exception { TypeError, ASCIILiteral("Internal error") };
     }

Modified: trunk/Source/WebCore/Modules/cache/DOMCache.h (221402 => 221403)


--- trunk/Source/WebCore/Modules/cache/DOMCache.h	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebCore/Modules/cache/DOMCache.h	2017-08-30 22:50:22 UTC (rev 221403)
@@ -40,6 +40,8 @@
 
 enum class Error {
     NotImplemented,
+    ReadDisk,
+    WriteDisk,
     Internal
 };
 
@@ -94,6 +96,8 @@
     using values = EnumValues<
         WebCore::DOMCache::Error,
         WebCore::DOMCache::Error::NotImplemented,
+        WebCore::DOMCache::Error::ReadDisk,
+        WebCore::DOMCache::Error::WriteDisk,
         WebCore::DOMCache::Error::Internal
     >;
 };

Modified: trunk/Source/WebCore/testing/Internals.cpp (221402 => 221403)


--- trunk/Source/WebCore/testing/Internals.cpp	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebCore/testing/Internals.cpp	2017-08-30 22:50:22 UTC (rev 221403)
@@ -39,6 +39,8 @@
 #include "CSSMediaRule.h"
 #include "CSSStyleRule.h"
 #include "CSSSupportsRule.h"
+#include "CacheStorageConnection.h"
+#include "CacheStorageProvider.h"
 #include "CachedImage.h"
 #include "CachedResourceLoader.h"
 #include "Chrome.h"
@@ -4136,4 +4138,19 @@
     return emptyString();
 }
 
+void Internals::clearCacheStorageMemoryRepresentation()
+{
+    auto* document = contextDocument();
+    if (!document)
+        return;
+
+    if (!m_cacheStorageConnection) {
+        if (auto* page = contextDocument()->page())
+            m_cacheStorageConnection = page->cacheStorageProvider().createCacheStorageConnection(page->sessionID());
+        if (!m_cacheStorageConnection)
+            return;
+    }
+    m_cacheStorageConnection->clearMemoryRepresentation(document->securityOrigin().toString(), [](std::optional<DOMCache::Error>&&) { });
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/testing/Internals.h (221402 => 221403)


--- trunk/Source/WebCore/testing/Internals.h	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebCore/testing/Internals.h	2017-08-30 22:50:22 UTC (rev 221403)
@@ -43,6 +43,7 @@
 namespace WebCore {
 
 class AudioContext;
+class CacheStorageConnection;
 class DOMRect;
 class DOMRectList;
 class DOMURL;
@@ -598,6 +599,8 @@
 
     String audioSessionCategory() const;
 
+    void clearCacheStorageMemoryRepresentation();
+
 private:
     explicit Internals(Document&);
     Document* contextDocument() const;
@@ -618,6 +621,7 @@
 #endif
 
     std::unique_ptr<InspectorStubFrontend> m_inspectorFrontend;
+    RefPtr<CacheStorageConnection> m_cacheStorageConnection;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/testing/Internals.idl (221402 => 221403)


--- trunk/Source/WebCore/testing/Internals.idl	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebCore/testing/Internals.idl	2017-08-30 22:50:22 UTC (rev 221403)
@@ -544,5 +544,7 @@
     [Conditional=MEDIA_STREAM] void removeMediaStreamTrack(MediaStream stream, MediaStreamTrack track);
     [Conditional=MEDIA_STREAM] void simulateMediaStreamTrackCaptureSourceFailure(MediaStreamTrack track);
 
+    void clearCacheStorageMemoryRepresentation();
+
     DOMString audioSessionCategory();
 };

Modified: trunk/Source/WebKit/CMakeLists.txt (221402 => 221403)


--- trunk/Source/WebKit/CMakeLists.txt	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebKit/CMakeLists.txt	2017-08-30 22:50:22 UTC (rev 221403)
@@ -117,6 +117,7 @@
     NetworkProcess/PingLoad.cpp
 
     NetworkProcess/cache/CacheStorageEngine.cpp
+    NetworkProcess/cache/CacheStorageEngineCaches.cpp
     NetworkProcess/cache/CacheStorageEngineConnection.cpp
     NetworkProcess/cache/NetworkCache.cpp
     NetworkProcess/cache/NetworkCacheBlobStorage.cpp

Modified: trunk/Source/WebKit/ChangeLog (221402 => 221403)


--- trunk/Source/WebKit/ChangeLog	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebKit/ChangeLog	2017-08-30 22:50:22 UTC (rev 221403)
@@ -1,3 +1,78 @@
+2017-08-30  Youenn Fablet  <you...@apple.com>
+
+        [Cache API] Support cache names persistency
+        https://bugs.webkit.org/show_bug.cgi?id=175995
+
+        Reviewed by Alex Christensen.
+
+        Adding disk read/write capacities to CacheStorage engine.
+        This is used to store per-origin cache names in a file.
+        Making Engine a thread safe refcounted object so that it does read/write in a background thread.
+
+        Introducing CacheStorage::Caches as the object managing the list of Cache objects for a given origin.
+        Caches will be responsible to do all the read/write operations for all of its caches.
+        It will be responsible for quota limitation as well.
+
+        Moving part of the logic from CacheStorage::Engine into CacheStorage::Caches.
+
+        CacheStorage::Engine is initialized asynchronously as it first creates a salt which is used
+        to obfuscate the names of the various files stored on disk.
+
+        In the same spirit, CacheStorage::Caches is initialized asynchronously as it needs to read from the disk the list of cache names.
+        Once read, the names will be stored in memory.
+        Added the possibility to clear this in-memory representation. This will be useful for testing.
+        This might also be useful to save memory when there is no more use of CacheStorage by web pages.
+
+        Introducing a new cacheStorageSubdirectoryName parameter for WebsiteDataStore so as to segment the different per session CacheStorageEngine
+        in direct sub folders of the main cacheStorageDirectory folder.
+
+        * CMakeLists.txt:
+        * NetworkProcess/cache/CacheStorageEngine.cpp:
+        (WebKit::CacheStorage::Engine::open):
+        (WebKit::CacheStorage::Engine::remove):
+        (WebKit::CacheStorage::Engine::retrieveCaches):
+        (WebKit::CacheStorage::Engine::retrieveRecords):
+        (WebKit::CacheStorage::Engine::initialize):
+        (WebKit::CacheStorage::Engine::readCachesFromDisk):
+        (WebKit::CacheStorage::Engine::cache):
+        (WebKit::CacheStorage::Engine::writeFile): Making use of default parameter to directly return to the main loop.
+        (WebKit::CacheStorage::Engine::readFile): Ditto.
+        (WebKit::CacheStorage::Engine::clearMemoryRepresentation):
+        * NetworkProcess/cache/CacheStorageEngine.h:
+        (WebKit::CacheStorage::Engine::rootPath const):
+        (WebKit::CacheStorage::Engine::salt const):
+        (WebKit::CacheStorage::Engine::nextCacheIdentifier):
+        * NetworkProcess/cache/CacheStorageEngineCaches.cpp: Added.
+        (WebKit::CacheStorage::cachesRootPath):
+        (WebKit::CacheStorage::cachesListFilename):
+        (WebKit::CacheStorage::Caches::Caches):
+        (WebKit::CacheStorage::Caches::initialize):
+        (WebKit::CacheStorage::Caches::find):
+        (WebKit::CacheStorage::Caches::open):
+        (WebKit::CacheStorage::Caches::remove):
+        (WebKit::CacheStorage::encodeCacheNames):
+        (WebKit::CacheStorage::decodeCachesNames):
+        (WebKit::CacheStorage::Caches::readCachesFromDisk):
+        (WebKit::CacheStorage::Caches::writeCachesToDisk):
+        (WebKit::CacheStorage::Caches::clearMemoryRepresentation):
+        (WebKit::CacheStorage::Caches::cacheInfos const):
+        * NetworkProcess/cache/CacheStorageEngineCaches.h: Added.
+        (WebKit::CacheStorage::Caches::create):
+        (WebKit::CacheStorage::Caches::isInitialized const):
+        (WebKit::CacheStorage::Caches::detach):
+        * NetworkProcess/cache/CacheStorageEngineConnection.cpp:
+        (WebKit::CacheStorageEngineConnection::clearMemoryRepresentation):
+        * NetworkProcess/cache/CacheStorageEngineConnection.h:
+        * NetworkProcess/cache/CacheStorageEngineConnection.messages.in:
+        * NetworkProcess/cache/NetworkCacheData.cpp:
+        (WebKit::NetworkCache::makeSalt):
+        * NetworkProcess/cache/NetworkCacheData.h:
+        * UIProcess/WebsiteData/WebsiteDataStore.h:
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/Cache/WebCacheStorageConnection.cpp:
+        (WebKit::WebCacheStorageConnection::clearMemoryRepresentation):
+        * WebProcess/Cache/WebCacheStorageConnection.h:
+
 2017-08-30  Brady Eidson  <beid...@apple.com>
 
         Add "Identified" base class to replace a whole bunch of custom identifier generators.

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp (221402 => 221403)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp	2017-08-30 22:50:22 UTC (rev 221403)
@@ -84,42 +84,40 @@
             return;
         }
 
-        auto& caches = cachesOrError.value().get();
+        Caches& caches = cachesOrError.value();
 
-        auto position = caches.findMatching([&](const auto& item) { return item.name == cacheName; });
-        if (position == notFound) {
-            uint64_t cacheIdentifier = ++m_nextCacheIdentifier;
-            caches.append(Cache { cacheIdentifier, cacheName, Vector<Record>(), 0 });
-            writeCachesToDisk([cacheIdentifier, callback = WTFMove(callback)](std::optional<Error>&& error) {
-                if (error) {
-                    callback(makeUnexpected(error.value()));
-                    return;
-                }
-                callback(cacheIdentifier);
-            });
-        } else
-            callback(caches[position].identifier);
+        if (auto* cache = caches.find(cacheName)) {
+            callback(cache->identifier);
+            return;
+        }
 
+        caches.open(String { cacheName }, [callback = WTFMove(callback)](const CacheIdentifierOrError& result) mutable {
+            callback(result);
+        });
     });
 }
 
 void Engine::remove(uint64_t cacheIdentifier, CacheIdentifierCallback&& callback)
 {
-    std::optional<Cache> removedCache;
+    Caches* cachesToModify = nullptr;
     for (auto& caches : m_caches.values()) {
-        auto position = caches.findMatching([&](const auto& item) { return item.identifier == cacheIdentifier; });
-        if (position != notFound) {
-            removedCache = WTFMove(caches[position]);
-            caches.remove(position);
+        auto* cacheToRemove = caches->find(cacheIdentifier);
+        if (cacheToRemove) {
+            cachesToModify = caches.ptr();
             break;
         }
     }
-    if (!removedCache) {
-        callback(makeUnexpected(Error::Internal));
+    if (!cachesToModify) {
+        auto position = m_removedCaches.findMatching([&](const auto& item) { return item.identifier == cacheIdentifier; });
+        if (position == notFound) {
+            callback(makeUnexpected(Error::Internal));
+            return;
+        }
+        callback(cacheIdentifier);
         return;
     }
-    m_removedCaches.append(WTFMove(removedCache.value()));
-    writeCachesToDisk([cacheIdentifier, callback = WTFMove(callback)](std::optional<Error>&& error) {
+
+    cachesToModify->remove(cacheIdentifier, [cacheIdentifier, callback = WTFMove(callback)](std::optional<Error>&& error) {
         if (error) {
             callback(makeUnexpected(error.value()));
             return;
@@ -136,14 +134,7 @@
             return;
         }
 
-        auto& caches = cachesOrError.value().get();
-
-        Vector<CacheInfo> cachesInfo;
-        cachesInfo.reserveInitialCapacity(caches.size());
-        for (auto& cache : caches)
-            cachesInfo.uncheckedAppend(CacheInfo { cache.identifier, cache.name});
-
-        callback(WTFMove(cachesInfo));
+        callback(cachesOrError.value().get().cacheInfos());
     });
 }
 
@@ -159,7 +150,7 @@
 
         Vector<Record> copy;
         copy.reserveInitialCapacity(records.size());
-        for (auto& record : result.value().get().records)
+        for (auto& record : records)
             copy.uncheckedAppend(record.copy());
 
         callback(WTFMove(copy));
@@ -244,21 +235,62 @@
     });
 }
 
-void Engine::writeCachesToDisk(Function<void(std::optional<Error>&&)>&& callback)
+void Engine::initialize(Function<void(std::optional<Error>&&)>&& callback)
 {
-    // FIXME: Implement writing.
-    callback(std::nullopt);
+    if (m_salt) {
+        callback(std::nullopt);
+        return;
+    }
+
+    if (!shouldPersist()) {
+        m_salt = makeSalt();
+        callback(std::nullopt);
+        return;
+    }
+
+    String saltPath = WebCore::pathByAppendingComponent(m_rootPath, ASCIILiteral("salt"));
+    m_ioQueue->dispatch([protectedThis = makeRef(*this), this, callback = WTFMove(callback), saltPath = WTFMove(saltPath)] () mutable {
+        WebCore::makeAllDirectories(m_rootPath);
+        RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), this, salt = readOrMakeSalt(saltPath), callback = WTFMove(callback)]() mutable {
+            if (!salt) {
+                callback(Error::WriteDisk);
+                return;
+            }
+            m_salt = WTFMove(salt);
+            callback(std::nullopt);
+        });
+    });
 }
 
 void Engine::readCachesFromDisk(const String& origin, CachesCallback&& callback)
 {
-    // FIXME: Implement reading.
-
-    auto& caches = m_caches.ensure(origin, [] {
-        return Vector<Cache>();
+    auto& caches = m_caches.ensure(origin, [&origin, this] {
+        return Caches::create(*this, origin);
     }).iterator->value;
 
-    callback(std::reference_wrapper<Vector<Cache>> { caches });
+    if (caches->isInitialized()) {
+        callback(std::reference_wrapper<Caches> { caches.get() });
+        return;
+    }
+
+    initialize([this, origin, callback = WTFMove(callback)](std::optional<Error>&& error) mutable {
+        if (error) {
+            callback(makeUnexpected(error.value()));
+            return;
+        }
+
+        auto caches = m_caches.get(origin);
+        ASSERT(caches);
+
+        caches->initialize([callback = WTFMove(callback), caches](std::optional<Error>&& error) mutable {
+            if (error) {
+                callback(makeUnexpected(error.value()));
+                return;
+            }
+
+            callback(std::reference_wrapper<Caches> { *caches });
+        });
+    });
 }
 
 void Engine::readCache(uint64_t cacheIdentifier, CacheCallback&& callback)
@@ -288,11 +320,8 @@
 {
     Cache* result = nullptr;
     for (auto& caches : m_caches.values()) {
-        auto position = caches.findMatching([&](const auto& item) { return item.identifier == cacheIdentifier; });
-        if (position != notFound) {
-            result = &caches[position];
+        if ((result = caches->find(cacheIdentifier)))
             break;
-        }
     }
     if (!result) {
         auto position = m_removedCaches.findMatching([&](const auto& item) { return item.identifier == cacheIdentifier; });
@@ -322,17 +351,15 @@
         return;
     }
 
-    m_ioQueue->dispatch([this, protectedThis = makeRef(*this), callback = WTFMove(callback), data = "" filename = filename.isolatedCopy()] () mutable {
+    m_ioQueue->dispatch([callback = WTFMove(callback), data = "" filename = filename.isolatedCopy()] () mutable {
         auto channel = IOChannel::open(filename, IOChannel::Type::Create);
-        channel->write(0, data, m_ioQueue.get(), [callback = WTFMove(callback)](int error) mutable {
-            RunLoop::main().dispatch([callback = WTFMove(callback), error]() mutable {
-                if (error) {
-                    // FIXME: Use specific filesystem error.
-                    callback(Error::Internal);
-                    return;
-                }
-                callback(std::nullopt);
-            });
+        channel->write(0, data, nullptr, [callback = WTFMove(callback)](int error) mutable {
+            ASSERT(RunLoop::isMain());
+            if (error) {
+                callback(Error::WriteDisk);
+                return;
+            }
+            callback(std::nullopt);
         });
     });
 }
@@ -344,7 +371,7 @@
         return;
     }
 
-    m_ioQueue->dispatch([this, protectedThis = makeRef(*this), callback = WTFMove(callback), filename = filename.isolatedCopy()]() mutable {
+    m_ioQueue->dispatch([callback = WTFMove(callback), filename = filename.isolatedCopy()]() mutable {
         auto channel = IOChannel::open(filename, IOChannel::Type::Read);
         if (channel->fileDescriptor() < 0) {
             RunLoop::main().dispatch([callback = WTFMove(callback)]() mutable {
@@ -353,10 +380,10 @@
             return;
         }
 
-        channel->read(0, std::numeric_limits<size_t>::max(), m_ioQueue.get(), [callback = WTFMove(callback)](const Data& data, int error) mutable {
-            RunLoop::main().dispatch([callback = WTFMove(callback), data, error]() mutable {
-                callback(data, error);
-            });
+        channel->read(0, std::numeric_limits<size_t>::max(), nullptr, [callback = WTFMove(callback)](const Data& data, int error) mutable {
+            // FIXME: We should do the decoding in the background thread.
+            ASSERT(RunLoop::isMain());
+            callback(data, error);
         });
     });
 }
@@ -371,6 +398,15 @@
     });
 }
 
+void Engine::clearMemoryRepresentation(const String& origin)
+{
+    readCachesFromDisk(origin, [](CachesOrError&& result) {
+        if (!result.hasValue())
+            return;
+        result.value().get().clearMemoryRepresentation();
+    });
+}
+
 } // namespace CacheStorage
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.h (221402 => 221403)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.h	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.h	2017-08-30 22:50:22 UTC (rev 221403)
@@ -25,7 +25,7 @@
 
 #pragma once
 
-#include "CacheStorageEngineCache.h"
+#include "CacheStorageEngineCaches.h"
 #include "NetworkCacheData.h"
 #include <wtf/HashMap.h>
 #include <wtf/ThreadSafeRefCounted.h>
@@ -63,13 +63,19 @@
     void readFile(const String& filename, WTF::Function<void(const NetworkCache::Data&, int error)>&&);
     void removeFile(const String& filename);
 
+    const String& rootPath() const { return m_rootPath; }
+    const NetworkCache::Salt& salt() const { return m_salt.value(); }
+    uint64_t nextCacheIdentifier() { return ++m_nextCacheIdentifier; }
+
+    void clearMemoryRepresentation(const String& origin);
+
 private:
     static Engine& defaultEngine();
     explicit Engine(String&& rootPath);
 
-    void writeCachesToDisk(WebCore::DOMCache::CompletionCallback&&);
+    void initialize(Function<void(std::optional<WebCore::DOMCache::Error>&&)>&&);
 
-    using CachesOrError = Expected<std::reference_wrapper<Vector<Cache>>, WebCore::DOMCache::Error>;
+    using CachesOrError = Expected<std::reference_wrapper<Caches>, WebCore::DOMCache::Error>;
     using CachesCallback = WTF::Function<void(CachesOrError&&)>;
     void readCachesFromDisk(const String& origin, CachesCallback&&);
 
@@ -84,11 +90,12 @@
 
     Cache* cache(uint64_t cacheIdentifier);
 
-    HashMap<String, Vector<Cache>> m_caches;
+    HashMap<String, Ref<Caches>> m_caches;
     Vector<Cache> m_removedCaches;
     uint64_t m_nextCacheIdentifier { 0 };
     String m_rootPath;
     RefPtr<WorkQueue> m_ioQueue;
+    std::optional<NetworkCache::Salt> m_salt;
 };
 
 } // namespace CacheStorage

Added: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.cpp (0 => 221403)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.cpp	                        (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.cpp	2017-08-30 22:50:22 UTC (rev 221403)
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2017 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CacheStorageEngine.h"
+
+#include "NetworkCacheCoders.h"
+#include <wtf/text/StringBuilder.h>
+
+using namespace WebCore::DOMCache;
+using namespace WebKit::NetworkCache;
+
+namespace WebKit {
+
+namespace CacheStorage {
+
+static inline String cachesRootPath(Engine& engine, const String& origin)
+{
+    Key key(engine.rootPath(), { }, { }, origin, engine.salt());
+    return WebCore::pathByAppendingComponent(engine.rootPath(), key.partitionHashAsString());
+}
+
+static inline String cachesListFilename(const String& cachesRootPath)
+{
+    return WebCore::pathByAppendingComponent(cachesRootPath, ASCIILiteral("cacheslist"));
+}
+
+Caches::Caches(Engine& engine, const String& origin)
+    : m_engine(&engine)
+    , m_rootPath(cachesRootPath(engine, origin))
+{
+}
+
+void Caches::initialize(WebCore::DOMCache::CompletionCallback&& callback)
+{
+    if (m_isInitialized || !m_engine || !m_engine->shouldPersist()) {
+        callback(std::nullopt);
+        return;
+    }
+
+    if (m_storage) {
+        m_pendingInitializationCallbacks.append(WTFMove(callback));
+        return;
+    }
+
+    auto storage = Storage::open(m_rootPath, Storage::Mode::Normal);
+    if (!storage) {
+        callback(Error::WriteDisk);
+        return;
+    }
+    m_storage = storage.releaseNonNull();
+    readCachesFromDisk([this, callback = WTFMove(callback)](Expected<Vector<Cache>, Error>&& result) {
+        if (!result.hasValue()) {
+            callback(result.error());
+
+            auto pendingCallbacks = WTFMove(m_pendingInitializationCallbacks);
+            for (auto& callback : pendingCallbacks)
+                callback(result.error());
+            return;
+        }
+        m_caches = WTFMove(result.value());
+        m_isInitialized = true;
+        callback(std::nullopt);
+
+        auto pendingCallbacks = WTFMove(m_pendingInitializationCallbacks);
+        for (auto& callback : pendingCallbacks)
+            callback(std::nullopt);
+    });
+}
+
+Cache* Caches::find(const String& name)
+{
+    auto position = m_caches.findMatching([&](const auto& item) { return item.name == name; });
+    return (position != notFound) ? &m_caches[position] : nullptr;
+}
+
+Cache* Caches::find(uint64_t identifier)
+{
+    auto position = m_caches.findMatching([&](const auto& item) { return item.identifier == identifier; });
+    if (position != notFound)
+        return &m_caches[position];
+
+    position = m_removedCaches.findMatching([&](const auto& item) { return item.identifier == identifier; });
+    return (position != notFound) ? &m_removedCaches[position] : nullptr;
+}
+
+void Caches::open(String&& name, CacheIdentifierCallback&& callback)
+{
+    ASSERT(m_engine);
+
+    uint64_t cacheIdentifier = m_engine->nextCacheIdentifier();
+    m_caches.append(Cache { cacheIdentifier, WTFMove(name), { }, 0 });
+    writeCachesToDisk([callback = WTFMove(callback), cacheIdentifier](std::optional<Error>&& error) mutable {
+        if (error) {
+            callback(makeUnexpected(error.value()));
+            return;
+        }
+        callback(cacheIdentifier);
+    });
+}
+
+void Caches::remove(uint64_t identifier, CompletionCallback&& callback)
+{
+    ASSERT(m_engine);
+
+    auto position = m_caches.findMatching([&](const auto& item) { return item.identifier == identifier; });
+
+    ASSERT(position != notFound);
+
+    auto cache = WTFMove(m_caches[position]);
+    m_caches.remove(position);
+    m_removedCaches.append(WTFMove(cache));
+
+    writeCachesToDisk(WTFMove(callback));
+}
+
+static inline Data encodeCacheNames(const Vector<Cache>& caches)
+{
+    WTF::Persistence::Encoder encoder;
+
+    uint64_t size = caches.size();
+    encoder << size;
+    for (auto& cache : caches)
+        encoder << cache.name;
+
+    return Data { encoder.buffer(), encoder.bufferSize() };
+}
+
+static inline Expected<Vector<String>, Error> decodeCachesNames(const Data& data, int error)
+{
+    if (error)
+        return makeUnexpected(Error::ReadDisk);
+
+    WTF::Persistence::Decoder decoder(data.data(), data.size());
+    uint64_t count;
+    if (!decoder.decode(count))
+        return makeUnexpected(Error::ReadDisk);
+
+    Vector<String> names;
+    names.reserveInitialCapacity(count);
+    for (size_t index = 0; index < count; ++index) {
+        String name;
+        if (!decoder.decode(name))
+            return makeUnexpected(Error::ReadDisk);
+
+        names.uncheckedAppend(WTFMove(name));
+    }
+    return names;
+}
+
+void Caches::readCachesFromDisk(WTF::Function<void(Expected<Vector<Cache>, Error>&&)>&& callback)
+{
+    ASSERT(m_engine);
+    ASSERT(!m_isInitialized);
+    ASSERT(m_caches.isEmpty());
+
+    if (!m_engine->shouldPersist()) {
+        callback(Vector<Cache> { });
+        return;
+    }
+
+    auto filename = cachesListFilename(m_rootPath);
+    if (!WebCore::fileExists(filename)) {
+        callback(Vector<Cache> { });
+        return;
+    }
+
+    m_engine->readFile(filename, [protectedThis = makeRef(*this), this, callback = WTFMove(callback)](const Data& data, int error) mutable {
+        if (!m_engine) {
+            callback(Vector<Cache> { });
+            return;
+        }
+
+        auto result = decodeCachesNames(data, error);
+        if (!result.hasValue()) {
+            callback(makeUnexpected(result.error()));
+            return;
+        }
+        Vector<Cache> caches;
+        caches.reserveInitialCapacity(result.value().size());
+        for (auto& name : result.value())
+            caches.uncheckedAppend(Cache { m_engine->nextCacheIdentifier(), WTFMove(name), { }, 0 });
+
+        callback(WTFMove(caches));
+    });
+}
+
+void Caches::writeCachesToDisk(CompletionCallback&& callback)
+{
+    if (!m_engine->shouldPersist()) {
+        callback(std::nullopt);
+        return;
+    }
+
+    ASSERT(m_engine);
+
+    if (m_caches.isEmpty()) {
+        m_engine->removeFile(cachesListFilename(m_rootPath));
+        callback(std::nullopt);
+        return;
+    }
+
+    m_engine->writeFile(cachesListFilename(m_rootPath), encodeCacheNames(m_caches), [callback = WTFMove(callback)](std::optional<Error>&& error) mutable {
+        callback(WTFMove(error));
+    });
+}
+
+void Caches::clearMemoryRepresentation()
+{
+    m_caches.clear();
+    m_isInitialized = false;
+    m_storage = nullptr;
+}
+
+Vector<CacheInfo> Caches::cacheInfos() const
+{
+    Vector<CacheInfo> cacheInfos;
+    cacheInfos.reserveInitialCapacity(m_caches.size());
+    for (auto& cache : m_caches)
+        cacheInfos.uncheckedAppend(CacheInfo { cache.identifier, cache.name });
+    return cacheInfos;
+}
+
+} // namespace CacheStorage
+
+} // namespace WebKit

Copied: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.h (from rev 221402, trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.h) (0 => 221403)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.h	                        (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.h	2017-08-30 22:50:22 UTC (rev 221403)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CacheStorageEngineCache.h"
+#include "NetworkCacheStorage.h"
+
+namespace WebKit {
+
+namespace CacheStorage {
+
+class Engine;
+
+class Caches : public RefCounted<Caches> {
+public:
+    static Ref<Caches> create(Engine& engine, const String& origin) { return adoptRef(*new Caches { engine, origin }); }
+
+    void initialize(WebCore::DOMCache::CompletionCallback&&);
+
+    bool isInitialized() const { return m_isInitialized; }
+
+    Cache* find(const String& name);
+    Cache* find(uint64_t identifier);
+
+    void open(String&& name, WebCore::DOMCache::CacheIdentifierCallback&&);
+    void remove(uint64_t identifier, WebCore::DOMCache::CompletionCallback&&);
+
+    Vector<WebCore::DOMCache::CacheInfo> cacheInfos() const;
+
+    void clearMemoryRepresentation();
+    void detach() { m_engine = nullptr; }
+
+private:
+    Caches(Engine&, const String& rootPath);
+
+    void readCachesFromDisk(WTF::Function<void(Expected<Vector<Cache>, WebCore::DOMCache::Error>&&)>&&);
+    void writeCachesToDisk(WebCore::DOMCache::CompletionCallback&&);
+
+    bool m_isInitialized { false };
+    Engine* m_engine { nullptr };
+    String m_rootPath;
+    Vector<Cache> m_caches;
+    Vector<Cache> m_removedCaches;
+    RefPtr<NetworkCache::Storage> m_storage;
+    Vector<WebCore::DOMCache::CompletionCallback> m_pendingInitializationCallbacks;
+};
+
+} // namespace CacheStorage
+
+} // namespace WebKit

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.cpp (221402 => 221403)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.cpp	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.cpp	2017-08-30 22:50:22 UTC (rev 221403)
@@ -63,6 +63,11 @@
     });
 }
 
+void CacheStorageEngineConnection::clearMemoryRepresentation(PAL::SessionID sessionID, const String& origin)
+{
+    Engine::from(sessionID).clearMemoryRepresentation(origin);
+}
+
 void CacheStorageEngineConnection::records(PAL::SessionID sessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier)
 {
     Engine::from(sessionID).retrieveRecords(cacheIdentifier, [protectedThis = makeRef(*this), this, sessionID, requestIdentifier](RecordsOrError&& result) {

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.h (221402 => 221403)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.h	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.h	2017-08-30 22:50:22 UTC (rev 221403)
@@ -54,6 +54,8 @@
     void remove(PAL::SessionID, uint64_t removeRequestIdentifier, uint64_t cacheIdentifier);
     void caches(PAL::SessionID, uint64_t retrieveCachesIdentifier, const String& origin);
 
+    void clearMemoryRepresentation(PAL::SessionID, const String& origin);
+
     void records(PAL::SessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier);
     void deleteMatchingRecords(PAL::SessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier, WebCore::ResourceRequest&&, WebCore::CacheQueryOptions&&);
     void putRecords(PAL::SessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier, Vector<WebCore::DOMCache::Record>&&);

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


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.messages.in	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.messages.in	2017-08-30 22:50:22 UTC (rev 221403)
@@ -25,6 +25,8 @@
     Remove(PAL::SessionID sessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier);
     Caches(PAL::SessionID sessionID, uint64_t requestIdentifier, String origin);
 
+    ClearMemoryRepresentation(PAL::SessionID sessionID, String origin);
+
     Records(PAL::SessionID sessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier);
     DeleteMatchingRecords(PAL::SessionID sessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier, WebCore::ResourceRequest request, struct WebCore::CacheQueryOptions options);
     PutRecords(PAL::SessionID sessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier, Vector<WebCore::DOMCache::Record> record);

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheData.cpp (221402 => 221403)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheData.cpp	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheData.cpp	2017-08-30 22:50:22 UTC (rev 221403)
@@ -128,7 +128,7 @@
     return !memcmp(a.data(), b.data(), a.size());
 }
 
-static Salt makeSalt()
+Salt makeSalt()
 {
     Salt salt;
     static_assert(salt.size() == 8, "Salt size");

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheData.h (221402 => 221403)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheData.h	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheData.h	2017-08-30 22:50:22 UTC (rev 221403)
@@ -105,6 +105,7 @@
 
 using Salt = std::array<uint8_t, 8>;
 
+Salt makeSalt();
 std::optional<Salt> readOrMakeSalt(const String& path);
 SHA1::Digest computeSHA1(const Data&, const Salt&);
 

Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h (221402 => 221403)


--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h	2017-08-30 22:50:22 UTC (rev 221403)
@@ -69,6 +69,7 @@
 public:
     struct Configuration {
         String cacheStorageDirectory;
+        String cacheStorageSubdirectoryName;
         String networkCacheDirectory;
         String applicationCacheDirectory;
         String applicationCacheFlatFileSubdirectoryName;

Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (221402 => 221403)


--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2017-08-30 22:50:22 UTC (rev 221403)
@@ -891,6 +891,7 @@
 		413075B21DE85F580039EC69 /* LibWebRTCSocketFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 413075A61DE85EE70039EC69 /* LibWebRTCSocketFactory.h */; };
 		413075B31DE85F580039EC69 /* LibWebRTCProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 413075A71DE85EE70039EC69 /* LibWebRTCProvider.cpp */; };
 		413075B41DE85F580039EC69 /* LibWebRTCProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 413075A81DE85EE70039EC69 /* LibWebRTCProvider.h */; };
+		4135FBD11F4FB8090074C47B /* CacheStorageEngineCaches.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4135FBCF1F4FB7F20074C47B /* CacheStorageEngineCaches.cpp */; };
 		41897ECF1F415D620016FA42 /* WebCacheStorageConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41897ECE1F415D5C0016FA42 /* WebCacheStorageConnection.cpp */; };
 		41897ED01F415D650016FA42 /* WebCacheStorageProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41897ECC1F415D5C0016FA42 /* WebCacheStorageProvider.cpp */; };
 		41897ED11F415D680016FA42 /* WebCacheStorageConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 41897ECD1F415D5C0016FA42 /* WebCacheStorageConnection.h */; };
@@ -3162,6 +3163,8 @@
 		413075A61DE85EE70039EC69 /* LibWebRTCSocketFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LibWebRTCSocketFactory.h; path = Network/webrtc/LibWebRTCSocketFactory.h; sourceTree = "<group>"; };
 		413075A71DE85EE70039EC69 /* LibWebRTCProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = LibWebRTCProvider.cpp; path = Network/webrtc/LibWebRTCProvider.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
 		413075A81DE85EE70039EC69 /* LibWebRTCProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = LibWebRTCProvider.h; path = Network/webrtc/LibWebRTCProvider.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+		4135FBCF1F4FB7F20074C47B /* CacheStorageEngineCaches.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheStorageEngineCaches.cpp; sourceTree = "<group>"; };
+		4135FBD01F4FB7F20074C47B /* CacheStorageEngineCaches.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheStorageEngineCaches.h; sourceTree = "<group>"; };
 		41897ECB1F415D5C0016FA42 /* WebCacheStorageConnection.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = WebCacheStorageConnection.messages.in; sourceTree = "<group>"; };
 		41897ECC1F415D5C0016FA42 /* WebCacheStorageProvider.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebCacheStorageProvider.cpp; sourceTree = "<group>"; };
 		41897ECD1F415D5C0016FA42 /* WebCacheStorageConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebCacheStorageConnection.h; sourceTree = "<group>"; };
@@ -8201,6 +8204,8 @@
 				41897ED61F415D860016FA42 /* CacheStorageEngine.cpp */,
 				41897ED21F415D850016FA42 /* CacheStorageEngine.h */,
 				41FABD281F4DDFDC006A6C97 /* CacheStorageEngineCache.h */,
+				4135FBCF1F4FB7F20074C47B /* CacheStorageEngineCaches.cpp */,
+				4135FBD01F4FB7F20074C47B /* CacheStorageEngineCaches.h */,
 				41897ED31F415D850016FA42 /* CacheStorageEngineConnection.cpp */,
 				41897ED41F415D850016FA42 /* CacheStorageEngineConnection.h */,
 				41897ED51F415D850016FA42 /* CacheStorageEngineConnection.messages.in */,
@@ -9991,6 +9996,7 @@
 				E170876B16D6CA6900F99226 /* BlobRegistryProxy.cpp in Sources */,
 				BCF18638167D071E00A1A85A /* CacheModel.cpp in Sources */,
 				41897ED71F415D8A0016FA42 /* CacheStorageEngine.cpp in Sources */,
+				4135FBD11F4FB8090074C47B /* CacheStorageEngineCaches.cpp in Sources */,
 				41897ED91F415D8A0016FA42 /* CacheStorageEngineConnection.cpp in Sources */,
 				517CF0E3163A486C00C2950F /* CacheStorageEngineConnectionMessageReceiver.cpp in Sources */,
 				1AA2E51E12E4C05E00BC4966 /* CGUtilities.cpp in Sources */,

Modified: trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.cpp (221402 => 221403)


--- trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.cpp	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.cpp	2017-08-30 22:50:22 UTC (rev 221403)
@@ -86,6 +86,12 @@
     connection().send(Messages::CacheStorageEngineConnection::PutRecords(m_sessionID, requestIdentifier, cacheIdentifier, records), 0);
 }
 
+void WebCacheStorageConnection::clearMemoryRepresentation(const String& origin, CompletionCallback&& callback)
+{
+    connection().send(Messages::CacheStorageEngineConnection::ClearMemoryRepresentation(m_sessionID, origin), 0);
+    callback(std::nullopt);
+}
+
 void WebCacheStorageConnection::openCompleted(uint64_t requestIdentifier, const CacheIdentifierOrError& result)
 {
     CacheStorageConnection::openCompleted(requestIdentifier, result);

Modified: trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.h (221402 => 221403)


--- trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.h	2017-08-30 22:48:08 UTC (rev 221402)
+++ trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.h	2017-08-30 22:50:22 UTC (rev 221403)
@@ -60,6 +60,8 @@
     void doBatchDeleteOperation(uint64_t requestIdentifier, uint64_t cacheIdentifier, const WebCore::ResourceRequest&, WebCore::CacheQueryOptions&&) final;
     void doBatchPutOperation(uint64_t requestIdentifier, uint64_t cacheIdentifier, Vector<WebCore::DOMCache::Record>&&) final;
 
+    void clearMemoryRepresentation(const String& origin, WebCore::DOMCache::CompletionCallback&&) final;
+
     void openCompleted(uint64_t requestIdentifier, const WebCore::DOMCache::CacheIdentifierOrError&);
     void removeCompleted(uint64_t requestIdentifier, const WebCore::DOMCache::CacheIdentifierOrError&);
     void updateCaches(uint64_t requestIdentifier, WebCore::DOMCache::CacheInfosOrError&&);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to