Title: [286507] trunk
Revision
286507
Author
[email protected]
Date
2021-12-03 12:17:15 -0800 (Fri, 03 Dec 2021)

Log Message

Fetch and remove file system data via WKWebsiteDataStore
https://bugs.webkit.org/show_bug.cgi?id=233567

Reviewed by Youenn Fablet.

Source/WebCore:

* Modules/filesystemaccess/FileSystemStorageConnection.h:

Source/WebKit:

Introduce a new WebsiteDataType value FileSystem for FileSystemAccess data. Network process now can fetch and
delete this type of data when fetching and deleteing website data (if FileSystem type is included in target
types).

To track origins that have FileSystem data, this patch introduces a new file named origin in the origin's
directory. This file will be created when OriginStorageManager is created.

To delete existing FileSystem data, network process finds origins that are requested to be deleted and have data
on disk, closes active access handles, and deletes the files. The origin file mentioned above will be deleted if
there is no other file left in the same directory, and empty directories will be deleted.

New API tests: FileSystemAccess.FetchAndRemoveData
               FileSystemAccess.RemoveDataByModificationTime
               FileSystemAccess.FetchDataForThirdParty

* CMakeLists.txt:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:
(WebKit::WebResourceLoadStatisticsStore::monitoredDataTypes):
* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::fetchWebsiteData):
(WebKit::NetworkProcess::deleteWebsiteData):
(WebKit::NetworkProcess::deleteWebsiteDataForOrigins):
(WebKit::NetworkProcess::deleteAndRestrictWebsiteDataForRegistrableDomains):
(WebKit::NetworkProcess::registrableDomainsWithWebsiteData):
* NetworkProcess/storage/FileSystemStorageHandle.h:
(WebKit::FileSystemStorageHandle::activeSyncAccessHandle const):
* NetworkProcess/storage/FileSystemStorageManager.cpp:
(WebKit::FileSystemStorageManager::~FileSystemStorageManager):
(WebKit::FileSystemStorageManager::close):
* NetworkProcess/storage/FileSystemStorageManager.h:
* NetworkProcess/storage/NetworkStorageManager.cpp:
(WebKit::readOriginFromFile):
(WebKit::writeOriginToFileIfNecessary):
(WebKit::deleteOriginFileIfNecessary):
(WebKit::originDirectoryPath):
(WebKit::originFilePath):
(WebKit::NetworkStorageManager::localOriginStorageManager):
(WebKit::NetworkStorageManager::removeOriginStorageManagerIfPossible):
(WebKit::toWebsiteDataType):
(WebKit::NetworkStorageManager::forEachOriginDirectory):
(WebKit::NetworkStorageManager::fetchDataFromDisk):
(WebKit::NetworkStorageManager::fetchData):
(WebKit::NetworkStorageManager::deleteDataOnDisk):
(WebKit::NetworkStorageManager::deleteData):
(WebKit::NetworkStorageManager::deleteDataModifiedSince):
(WebKit::NetworkStorageManager::deleteDataForRegistrableDomains):
(WebKit::originPath): Deleted.
* NetworkProcess/storage/NetworkStorageManager.h:
* NetworkProcess/storage/OriginStorageManager.cpp:
(WebKit::OriginStorageManager::StorageBucket::toStorageIdentifier):
(WebKit::OriginStorageManager::StorageBucket::typeStoragePath const):
(WebKit::OriginStorageManager::StorageBucket::fileSystemStorageManager):
(WebKit::OriginStorageManager::StorageBucket::isActive):
(WebKit::OriginStorageManager::StorageBucket::deleteData):
(WebKit::OriginStorageManager::StorageBucket::deleteFileSystemStorageData):
(WebKit::OriginStorageManager::OriginStorageManager):
(WebKit::OriginStorageManager::isActive):
(WebKit::OriginStorageManager::deleteData):
* NetworkProcess/storage/OriginStorageManager.h:
* Shared/WebsiteData/WebsiteData.cpp:
(WebKit::WebsiteData::ownerProcess):
* Shared/WebsiteData/WebsiteDataType.h:
* UIProcess/API/Cocoa/WKWebsiteDataRecord.mm:
(dataTypesToString):
* UIProcess/API/Cocoa/WKWebsiteDataRecordInternal.h:
(WebKit::toWebsiteDataType):
(WebKit::toWKWebsiteDataTypes):
* UIProcess/API/Cocoa/WKWebsiteDataRecordPrivate.h:
* UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
(+[WKWebsiteDataStore _allWebsiteDataTypesIncludingPrivate]):
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/Network/NetworkProcessConnection.cpp:
(WebKit::NetworkProcessConnection::didReceiveMessage):
* WebProcess/WebCoreSupport/WebFileSystemStorageConnection.messages.in: Added.

Source/WTF:

* wtf/FileSystem.cpp:
(WTF::FileSystemImpl::readEntireFile): Read whole file content into a Vector.
(WTF::FileSystemImpl::deleteAllFilesModifiedSince): Recursively delete files and folders modified after
specified time in a directory.
* wtf/FileSystem.h:

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (286506 => 286507)


--- trunk/Source/WTF/ChangeLog	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WTF/ChangeLog	2021-12-03 20:17:15 UTC (rev 286507)
@@ -1,3 +1,16 @@
+2021-12-03  Sihui Liu  <[email protected]>
+
+        Fetch and remove file system data via WKWebsiteDataStore
+        https://bugs.webkit.org/show_bug.cgi?id=233567
+
+        Reviewed by Youenn Fablet.
+
+        * wtf/FileSystem.cpp:
+        (WTF::FileSystemImpl::readEntireFile): Read whole file content into a Vector.
+        (WTF::FileSystemImpl::deleteAllFilesModifiedSince): Recursively delete files and folders modified after 
+        specified time in a directory.
+        * wtf/FileSystem.h:
+
 2021-12-03  Tim Horton  <[email protected]>
 
         Enable Momentum Event Generator by default

Modified: trunk/Source/WTF/wtf/FileSystem.cpp (286506 => 286507)


--- trunk/Source/WTF/wtf/FileSystem.cpp	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WTF/wtf/FileSystem.cpp	2021-12-03 20:17:15 UTC (rev 286507)
@@ -514,6 +514,60 @@
     return salt;
 }
 
+std::optional<Vector<uint8_t>> readEntireFile(PlatformFileHandle handle)
+{
+    if (!FileSystem::isHandleValid(handle))
+        return std::nullopt;
+
+    auto size = FileSystem::fileSize(handle).value_or(0);
+    if (!size)
+        return std::nullopt;
+
+    unsigned bytesToRead;
+    if (!WTF::convertSafely(size, bytesToRead))
+        return std::nullopt;
+
+    Vector<uint8_t> buffer(bytesToRead);
+    unsigned totalBytesRead = FileSystem::readFromFile(handle, buffer.data(), buffer.size());
+    if (totalBytesRead != bytesToRead)
+        return std::nullopt;
+
+    return buffer;
+}
+
+void deleteAllFilesModifiedSince(const String& directory, WallTime time)
+{
+    // This function may delete directory folder.
+    if (time == -WallTime::infinity()) {
+        deleteNonEmptyDirectory(directory);
+        return;
+    }
+
+    auto children = listDirectory(directory);
+    for (auto& child : children) {
+        auto childPath = FileSystem::pathByAppendingComponent(directory, child);
+        auto childType = fileType(childPath);
+        if (!childType)
+            continue;
+
+        switch (*childType) {
+        case FileType::Regular: {
+            if (auto modificationTime = FileSystem::fileModificationTime(childPath); modificationTime && *modificationTime >= time)
+                deleteFile(childPath);
+            break;
+        }
+        case FileType::Directory:
+            deleteAllFilesModifiedSince(childPath, time);
+            deleteEmptyDirectory(childPath);
+            break;
+        case FileType::SymbolicLink:
+            break;
+        }
+    }
+
+    FileSystem::deleteEmptyDirectory(directory);
+}
+
 #if HAVE(STD_FILESYSTEM) || HAVE(STD_EXPERIMENTAL_FILESYSTEM)
 
 bool deleteEmptyDirectory(const String& path)

Modified: trunk/Source/WTF/wtf/FileSystem.h (286506 => 286507)


--- trunk/Source/WTF/wtf/FileSystem.h	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WTF/wtf/FileSystem.h	2021-12-03 20:17:15 UTC (rev 286507)
@@ -108,6 +108,7 @@
 
 WTF_EXPORT_PRIVATE bool fileExists(const String&);
 WTF_EXPORT_PRIVATE bool deleteFile(const String&);
+WTF_EXPORT_PRIVATE void deleteAllFilesModifiedSince(const String&, WallTime);
 WTF_EXPORT_PRIVATE bool deleteEmptyDirectory(const String&);
 WTF_EXPORT_PRIVATE bool moveFile(const String& oldPath, const String& newPath);
 WTF_EXPORT_PRIVATE std::optional<uint64_t> fileSize(const String&); // Follows symlinks.
@@ -146,6 +147,7 @@
 
 using Salt = std::array<uint8_t, 8>;
 WTF_EXPORT_PRIVATE std::optional<Salt> readOrMakeSalt(const String& path);
+WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> readEntireFile(PlatformFileHandle);
 
 // Prefix is what the filename should be prefixed with, not the full path.
 WTF_EXPORT_PRIVATE String openTemporaryFile(const String& prefix, PlatformFileHandle&, const String& suffix = { });

Modified: trunk/Source/WebCore/ChangeLog (286506 => 286507)


--- trunk/Source/WebCore/ChangeLog	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebCore/ChangeLog	2021-12-03 20:17:15 UTC (rev 286507)
@@ -1,3 +1,12 @@
+2021-12-03  Sihui Liu  <[email protected]>
+
+        Fetch and remove file system data via WKWebsiteDataStore
+        https://bugs.webkit.org/show_bug.cgi?id=233567
+
+        Reviewed by Youenn Fablet.
+
+        * Modules/filesystemaccess/FileSystemStorageConnection.h:
+
 2021-12-03  Alan Bujtas  <[email protected]>
 
         [LFC][IFC] Set the first/last box flag on the (bidi fragmented) inline box type of display boxes

Modified: trunk/Source/WebCore/Modules/filesystemaccess/FileSystemStorageConnection.h (286506 => 286507)


--- trunk/Source/WebCore/Modules/filesystemaccess/FileSystemStorageConnection.h	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebCore/Modules/filesystemaccess/FileSystemStorageConnection.h	2021-12-03 20:17:15 UTC (rev 286507)
@@ -27,6 +27,7 @@
 
 #include "FileSystemHandleIdentifier.h"
 #include "FileSystemSyncAccessHandleIdentifier.h"
+#include "ProcessQualified.h"
 #include "ScriptExecutionContextIdentifier.h"
 #include <wtf/CompletionHandler.h>
 #include <wtf/FileSystem.h>

Modified: trunk/Source/WebKit/CMakeLists.txt (286506 => 286507)


--- trunk/Source/WebKit/CMakeLists.txt	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/CMakeLists.txt	2021-12-03 20:17:15 UTC (rev 286507)
@@ -310,6 +310,7 @@
 
     WebProcess/WebCoreSupport/RemoteWebLockRegistry
     WebProcess/WebCoreSupport/WebBroadcastChannelRegistry
+    WebProcess/WebCoreSupport/WebFileSystemStorageConnection
     WebProcess/WebCoreSupport/WebSpeechRecognitionConnection
 
     WebProcess/WebPage/DrawingArea

Modified: trunk/Source/WebKit/ChangeLog (286506 => 286507)


--- trunk/Source/WebKit/ChangeLog	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/ChangeLog	2021-12-03 20:17:15 UTC (rev 286507)
@@ -1,3 +1,88 @@
+2021-12-03  Sihui Liu  <[email protected]>
+
+        Fetch and remove file system data via WKWebsiteDataStore
+        https://bugs.webkit.org/show_bug.cgi?id=233567
+
+        Reviewed by Youenn Fablet.
+
+        Introduce a new WebsiteDataType value FileSystem for FileSystemAccess data. Network process now can fetch and 
+        delete this type of data when fetching and deleteing website data (if FileSystem type is included in target
+        types).
+
+        To track origins that have FileSystem data, this patch introduces a new file named origin in the origin's 
+        directory. This file will be created when OriginStorageManager is created.
+
+        To delete existing FileSystem data, network process finds origins that are requested to be deleted and have data 
+        on disk, closes active access handles, and deletes the files. The origin file mentioned above will be deleted if 
+        there is no other file left in the same directory, and empty directories will be deleted.
+
+        New API tests: FileSystemAccess.FetchAndRemoveData
+                       FileSystemAccess.RemoveDataByModificationTime
+                       FileSystemAccess.FetchDataForThirdParty
+
+        * CMakeLists.txt:
+        * DerivedSources-input.xcfilelist:
+        * DerivedSources-output.xcfilelist:
+        * DerivedSources.make:
+        * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:
+        (WebKit::WebResourceLoadStatisticsStore::monitoredDataTypes):
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::fetchWebsiteData):
+        (WebKit::NetworkProcess::deleteWebsiteData):
+        (WebKit::NetworkProcess::deleteWebsiteDataForOrigins):
+        (WebKit::NetworkProcess::deleteAndRestrictWebsiteDataForRegistrableDomains):
+        (WebKit::NetworkProcess::registrableDomainsWithWebsiteData):
+        * NetworkProcess/storage/FileSystemStorageHandle.h:
+        (WebKit::FileSystemStorageHandle::activeSyncAccessHandle const):
+        * NetworkProcess/storage/FileSystemStorageManager.cpp:
+        (WebKit::FileSystemStorageManager::~FileSystemStorageManager):
+        (WebKit::FileSystemStorageManager::close):
+        * NetworkProcess/storage/FileSystemStorageManager.h:
+        * NetworkProcess/storage/NetworkStorageManager.cpp:
+        (WebKit::readOriginFromFile):
+        (WebKit::writeOriginToFileIfNecessary):
+        (WebKit::deleteOriginFileIfNecessary):
+        (WebKit::originDirectoryPath):
+        (WebKit::originFilePath):
+        (WebKit::NetworkStorageManager::localOriginStorageManager):
+        (WebKit::NetworkStorageManager::removeOriginStorageManagerIfPossible):
+        (WebKit::toWebsiteDataType):
+        (WebKit::NetworkStorageManager::forEachOriginDirectory):
+        (WebKit::NetworkStorageManager::fetchDataFromDisk):
+        (WebKit::NetworkStorageManager::fetchData):
+        (WebKit::NetworkStorageManager::deleteDataOnDisk):
+        (WebKit::NetworkStorageManager::deleteData):
+        (WebKit::NetworkStorageManager::deleteDataModifiedSince):
+        (WebKit::NetworkStorageManager::deleteDataForRegistrableDomains):
+        (WebKit::originPath): Deleted.
+        * NetworkProcess/storage/NetworkStorageManager.h:
+        * NetworkProcess/storage/OriginStorageManager.cpp:
+        (WebKit::OriginStorageManager::StorageBucket::toStorageIdentifier):
+        (WebKit::OriginStorageManager::StorageBucket::typeStoragePath const):
+        (WebKit::OriginStorageManager::StorageBucket::fileSystemStorageManager):
+        (WebKit::OriginStorageManager::StorageBucket::isActive):
+        (WebKit::OriginStorageManager::StorageBucket::deleteData):
+        (WebKit::OriginStorageManager::StorageBucket::deleteFileSystemStorageData):
+        (WebKit::OriginStorageManager::OriginStorageManager):
+        (WebKit::OriginStorageManager::isActive):
+        (WebKit::OriginStorageManager::deleteData):
+        * NetworkProcess/storage/OriginStorageManager.h:
+        * Shared/WebsiteData/WebsiteData.cpp:
+        (WebKit::WebsiteData::ownerProcess):
+        * Shared/WebsiteData/WebsiteDataType.h:
+        * UIProcess/API/Cocoa/WKWebsiteDataRecord.mm:
+        (dataTypesToString):
+        * UIProcess/API/Cocoa/WKWebsiteDataRecordInternal.h:
+        (WebKit::toWebsiteDataType):
+        (WebKit::toWKWebsiteDataTypes):
+        * UIProcess/API/Cocoa/WKWebsiteDataRecordPrivate.h:
+        * UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
+        (+[WKWebsiteDataStore _allWebsiteDataTypesIncludingPrivate]):
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/Network/NetworkProcessConnection.cpp:
+        (WebKit::NetworkProcessConnection::didReceiveMessage):
+        * WebProcess/WebCoreSupport/WebFileSystemStorageConnection.messages.in: Added.
+
 2021-12-03  Chris Dumez  <[email protected]>
 
         Follow-up to r286479 to add API test and address issues found by the test

Modified: trunk/Source/WebKit/DerivedSources-input.xcfilelist (286506 => 286507)


--- trunk/Source/WebKit/DerivedSources-input.xcfilelist	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/DerivedSources-input.xcfilelist	2021-12-03 20:17:15 UTC (rev 286507)
@@ -221,6 +221,7 @@
 $(PROJECT_DIR)/WebProcess/WebCoreSupport/RemoteWebLockRegistry.messages.in
 $(PROJECT_DIR)/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.messages.in
 $(PROJECT_DIR)/WebProcess/WebCoreSupport/WebDeviceOrientationUpdateProvider.messages.in
+$(PROJECT_DIR)/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.messages.in
 $(PROJECT_DIR)/WebProcess/WebCoreSupport/WebSpeechRecognitionConnection.messages.in
 $(PROJECT_DIR)/WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.messages.in
 $(PROJECT_DIR)/WebProcess/WebPage/DrawingArea.messages.in

Modified: trunk/Source/WebKit/DerivedSources-output.xcfilelist (286506 => 286507)


--- trunk/Source/WebKit/DerivedSources-output.xcfilelist	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/DerivedSources-output.xcfilelist	2021-12-03 20:17:15 UTC (rev 286507)
@@ -493,6 +493,9 @@
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/WebDeviceOrientationUpdateProviderProxyMessageReceiver.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/WebDeviceOrientationUpdateProviderProxyMessages.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/WebDeviceOrientationUpdateProviderProxyMessagesReplies.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/WebFileSystemStorageConnectionMessageReceiver.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/WebFileSystemStorageConnectionMessages.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/WebFileSystemStorageConnectionMessagesReplies.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/WebFullScreenManagerMessageReceiver.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/WebFullScreenManagerMessages.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/WebFullScreenManagerMessagesReplies.h

Modified: trunk/Source/WebKit/DerivedSources.make (286506 => 286507)


--- trunk/Source/WebKit/DerivedSources.make	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/DerivedSources.make	2021-12-03 20:17:15 UTC (rev 286507)
@@ -222,6 +222,7 @@
 	WebProcess/WebCoreSupport/RemoteWebLockRegistry \
 	WebProcess/WebCoreSupport/WebBroadcastChannelRegistry \
 	WebProcess/WebCoreSupport/WebDeviceOrientationUpdateProvider \
+	WebProcess/WebCoreSupport/WebFileSystemStorageConnection \
 	WebProcess/WebCoreSupport/WebSpeechRecognitionConnection \
 	WebProcess/Speech/SpeechRecognitionRealtimeMediaSourceManager \
 	WebProcess/Storage/WebSWContextManagerConnection \

Modified: trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp (286506 => 286507)


--- trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp	2021-12-03 20:17:15 UTC (rev 286507)
@@ -74,6 +74,7 @@
 #if ENABLE(SERVICE_WORKER)
         WebsiteDataType::ServiceWorkerRegistrations,
 #endif
+        WebsiteDataType::FileSystem,
     }));
 
     ASSERT(RunLoop::isMain());

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (286506 => 286507)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2021-12-03 20:17:15 UTC (rev 286507)
@@ -1555,6 +1555,12 @@
         }
     }
 #endif
+
+    if (auto iterator = m_storageManagers.find(sessionID); iterator != m_storageManagers.end()) {
+        iterator->value->fetchData(websiteDataTypes, [callbackAggregator](auto entries) mutable {
+            callbackAggregator->m_websiteData.entries.appendVector(WTFMove(entries));
+        });
+    }
 }
 
 void NetworkProcess::deleteWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, WallTime modifiedSince, CompletionHandler<void()>&& completionHandler)
@@ -1629,6 +1635,9 @@
             networkSession->clearAlternativeServices(modifiedSince);
     }
 #endif
+
+    if (auto iterator = m_storageManagers.find(sessionID); iterator != m_storageManagers.end())
+        iterator->value->deleteDataModifiedSince(websiteDataTypes, modifiedSince, [clearTasksHandler] { });
 }
 
 static void clearDiskCacheEntries(NetworkCache::Cache* cache, const Vector<SecurityOriginData>& origins, CompletionHandler<void()>&& completionHandler)
@@ -1736,6 +1745,9 @@
     }
 #endif
 
+    if (auto iterator = m_storageManagers.find(sessionID); iterator != m_storageManagers.end())
+        iterator->value->deleteData(websiteDataTypes, originDatas, [clearTasksHandler] { });
+
     if (auto* networkSession = this->networkSession(sessionID)) {
         HashSet<WebCore::RegistrableDomain> domainsToDeleteNetworkDataFor;
         for (auto& originData : originDatas)
@@ -1959,6 +1971,13 @@
         });
     }
 
+    if (auto iterator = m_storageManagers.find(sessionID); iterator != m_storageManagers.end()) {
+        iterator->value->deleteDataForRegistrableDomains(websiteDataTypes, domainsToDeleteAllNonCookieWebsiteDataFor, [callbackAggregator](auto deletedDomains) mutable {
+            for (auto domain : deletedDomains)
+                callbackAggregator->m_domains.add(WTFMove(domain));
+        });
+    }
+
     auto dataTypesForUIProcess = WebsiteData::filter(websiteDataTypes, WebsiteDataProcessType::UI);
     if (!dataTypesForUIProcess.isEmpty() && !domainsToDeleteAllNonCookieWebsiteDataFor.isEmpty()) {
         CompletionHandler<void(const HashSet<RegistrableDomain>&)> completionHandler = [callbackAggregator] (const HashSet<RegistrableDomain>& domains) {
@@ -2075,6 +2094,12 @@
             });
         });
     }
+
+    if (auto iterator = m_storageManagers.find(sessionID); iterator != m_storageManagers.end()) {
+        iterator->value->fetchData(websiteDataTypes, [callbackAggregator](auto entries) mutable {
+            callbackAggregator->m_websiteData.entries.appendVector(WTFMove(entries));
+        });
+    }
 }
 #endif // ENABLE(INTELLIGENT_TRACKING_PREVENTION)
 

Modified: trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageHandle.h (286506 => 286507)


--- trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageHandle.h	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageHandle.h	2021-12-03 20:17:15 UTC (rev 286507)
@@ -62,6 +62,7 @@
     using AccessHandleInfo = std::pair<WebCore::FileSystemSyncAccessHandleIdentifier, IPC::SharedFileHandle>;
     Expected<AccessHandleInfo, FileSystemStorageError> createSyncAccessHandle();
     std::optional<FileSystemStorageError> close(WebCore::FileSystemSyncAccessHandleIdentifier);
+    std::optional<WebCore::FileSystemSyncAccessHandleIdentifier> activeSyncAccessHandle() const { return m_activeSyncAccessHandle; }
 
 private:
     Expected<WebCore::FileSystemHandleIdentifier, FileSystemStorageError> requestCreateHandle(IPC::Connection::UniqueID, Type, String&& name, bool createIfNecessary);

Modified: trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageManager.cpp (286506 => 286507)


--- trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageManager.cpp	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageManager.cpp	2021-12-03 20:17:15 UTC (rev 286507)
@@ -28,6 +28,7 @@
 
 #include "FileSystemStorageError.h"
 #include "FileSystemStorageHandleRegistry.h"
+#include "WebFileSystemStorageConnectionMessages.h"
 
 namespace WebKit {
 
@@ -42,8 +43,7 @@
 {
     ASSERT(!RunLoop::isMain());
 
-    for (auto identifier : m_handles.keys())
-        m_registry.unregisterHandle(identifier);
+    close();
 }
 
 Expected<WebCore::FileSystemHandleIdentifier, FileSystemStorageError> FileSystemStorageManager::createHandle(IPC::Connection::UniqueID connection, FileSystemStorageHandle::Type type, String&& path, String&& name, bool createIfNecessary)
@@ -149,4 +149,24 @@
     return false;
 }
 
+void FileSystemStorageManager::close()
+{
+    ASSERT(!RunLoop::isMain());
+
+    for (auto& [connectionID, identifiers] : m_handlesByConnection) {
+        for (auto identifier : identifiers) {
+            auto takenHandle = m_handles.take(identifier);
+            m_registry.unregisterHandle(identifier);
+
+            // Send message to web process to invalidate active sync access handle.
+            if (auto accessHandleIdentifier = takenHandle->activeSyncAccessHandle())
+                IPC::Connection::send(connectionID, Messages::WebFileSystemStorageConnection::InvalidateAccessHandle(*accessHandleIdentifier), 0);
+        }
+    }
+
+    ASSERT(m_handles.isEmpty());
+    m_handlesByConnection.clear();
+    m_lockMap.clear();
+}
+
 } // namespace WebKit

Modified: trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageManager.h (286506 => 286507)


--- trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageManager.h	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageManager.h	2021-12-03 20:17:15 UTC (rev 286507)
@@ -49,6 +49,8 @@
     bool releaseLockForFile(const String& path, WebCore::FileSystemHandleIdentifier);
 
 private:
+    void close();
+
     String m_path;
     FileSystemStorageHandleRegistry& m_registry;
     HashMap<IPC::Connection::UniqueID, HashSet<WebCore::FileSystemHandleIdentifier>> m_handlesByConnection;

Modified: trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.cpp (286506 => 286507)


--- trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.cpp	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.cpp	2021-12-03 20:17:15 UTC (rev 286507)
@@ -30,11 +30,69 @@
 #include "FileSystemStorageManager.h"
 #include "NetworkStorageManagerMessages.h"
 #include "OriginStorageManager.h"
+#include "WebsiteDataType.h"
 #include <pal/crypto/CryptoDigest.h>
+#include <wtf/Scope.h>
+#include <wtf/persistence/PersistentDecoder.h>
+#include <wtf/persistence/PersistentEncoder.h>
 #include <wtf/text/Base64.h>
 
 namespace WebKit {
 
+static std::optional<WebCore::ClientOrigin> readOriginFromFile(const String& filePath)
+{
+    ASSERT(!RunLoop::isMain());
+
+    if (!FileSystem::fileExists(filePath))
+        return std::nullopt;
+
+    auto originFileHandle = FileSystem::openFile(filePath, FileSystem::FileOpenMode::Read);
+    auto closeFile = makeScopeExit([&] {
+        FileSystem::closeFile(originFileHandle);
+    });
+
+    if (!FileSystem::isHandleValid(originFileHandle))
+        return std::nullopt;
+
+    auto originContent = FileSystem::readEntireFile(originFileHandle);
+    if (!originContent)
+        return std::nullopt;
+
+    WTF::Persistence::Decoder decoder({ originContent->data(), originContent->size() });
+    std::optional<WebCore::ClientOrigin> origin;
+    decoder >> origin;
+    return origin;
+}
+
+static void writeOriginToFileIfNecessary(const String& filePath, const WebCore::ClientOrigin& origin)
+{
+    if (FileSystem::fileExists(filePath))
+        return;
+
+    FileSystem::makeAllDirectories(FileSystem::parentPath(filePath));
+    auto originFileHandle = FileSystem::openFile(filePath, FileSystem::FileOpenMode::ReadWrite);
+    auto closeFile = makeScopeExit([&] {
+        FileSystem::closeFile(originFileHandle);
+    });
+
+    if (!FileSystem::isHandleValid(originFileHandle)) {
+        LOG_ERROR("writeOriginToFileIfNecessary: Failed to open origin file");
+        return;
+    }
+
+    WTF::Persistence::Encoder encoder;
+    encoder << origin;
+    FileSystem::writeToFile(originFileHandle, encoder.buffer(), encoder.bufferSize());
+}
+
+static void deleteOriginFileIfNecessary(const String& filePath)
+{
+    auto parentPath = FileSystem::parentPath(filePath);
+    auto children = FileSystem::listDirectory(parentPath);
+    if (children.size() == 1)
+        FileSystem::deleteFile(filePath);
+}
+
 Ref<NetworkStorageManager> NetworkStorageManager::create(PAL::SessionID sessionID, const String& path)
 {
     return adoptRef(*new NetworkStorageManager(sessionID, path));
@@ -116,7 +174,7 @@
     return base64URLEncodeToString(hash.data(), hash.size());
 }
 
-static String originPath(const String& rootPath, const WebCore::ClientOrigin& origin, FileSystem::Salt salt)
+static String originDirectoryPath(const String& rootPath, const WebCore::ClientOrigin& origin, FileSystem::Salt salt)
 {
     if (rootPath.isEmpty())
         return rootPath;
@@ -126,15 +184,30 @@
     return FileSystem::pathByAppendingComponents(rootPath, { encodedTopOrigin, encodedOpeningOrigin });
 }
 
+static String originFilePath(const String& directory)
+{
+    return FileSystem::pathByAppendingComponent(directory, "origin"_s);
+}
+
 OriginStorageManager& NetworkStorageManager::localOriginStorageManager(const WebCore::ClientOrigin& origin)
 {
     ASSERT(!RunLoop::isMain());
 
     return *m_localOriginStorageManagers.ensure(origin, [&] {
-        return makeUnique<OriginStorageManager>(originPath(m_path, origin, m_salt));
+        auto originDirectory = originDirectoryPath(m_path, origin, m_salt);
+        writeOriginToFileIfNecessary(originFilePath(originDirectory), origin);
+        return makeUnique<OriginStorageManager>(WTFMove(originDirectory));
     }).iterator->value;
 }
 
+void NetworkStorageManager::removeOriginStorageManagerIfPossible(const WebCore::ClientOrigin& origin)
+{
+    if (auto iterator = m_localOriginStorageManagers.find(origin); iterator != m_localOriginStorageManagers.end()) {
+        if (!iterator->value->isActive())
+            m_localOriginStorageManagers.remove(iterator);
+    }
+}
+
 void NetworkStorageManager::persisted(const WebCore::ClientOrigin& origin, CompletionHandler<void(bool)>&& completionHandler)
 {
     ASSERT(!RunLoop::isMain());
@@ -305,5 +378,162 @@
     completionHandler(handle->getHandle(connection.uniqueID(), WTFMove(name)));
 }
 
+static std::optional<WebsiteDataType> toWebsiteDataType(const String& storageType)
+{
+    if (storageType == "FileSystem")
+        return WebsiteDataType::FileSystem;
+
+    return std::nullopt;
+}
+
+void NetworkStorageManager::forEachOriginDirectory(const Function<void(const String&)>& apply)
+{
+    for (auto& topOrigin : FileSystem::listDirectory(m_path)) {
+        auto topOriginDirectory = FileSystem::pathByAppendingComponent(m_path, topOrigin);
+        auto openingOrigins = FileSystem::listDirectory(topOriginDirectory);
+        if (openingOrigins.isEmpty()) {
+            FileSystem::deleteEmptyDirectory(topOriginDirectory);
+            continue;
+        }
+
+        for (auto& openingOrigin : openingOrigins) {
+            auto openingOriginDirectory = FileSystem::pathByAppendingComponent(topOriginDirectory, openingOrigin);
+            apply(openingOriginDirectory);
+        }
+    }
+}
+
+Vector<WebsiteData::Entry> NetworkStorageManager::fetchDataFromDisk(OptionSet<WebsiteDataType> targetTypes)
+{
+    ASSERT(!RunLoop::isMain());
+
+    HashMap<WebCore::SecurityOriginData, OptionSet<WebsiteDataType>> originTypes;
+    forEachOriginDirectory([&](auto directory) mutable {
+        auto origin = readOriginFromFile(originFilePath(directory));
+        if (!origin)
+            return;
+
+        for (auto& storageType : FileSystem::listDirectory(directory)) {
+            if (auto type = toWebsiteDataType(storageType); type && targetTypes.contains(*type)) {
+                // Return both top origin and opening origin for this data.
+                originTypes.add(origin->clientOrigin, OptionSet<WebsiteDataType> { }).iterator->value.add(*type);
+                originTypes.add(origin->topOrigin, OptionSet<WebsiteDataType> { }).iterator->value.add(*type);
+            }
+        }
+    });
+
+    Vector<WebsiteData::Entry> entries;
+    for (auto [origin, types] : originTypes) {
+        for (auto type : types)
+            entries.append({ WebsiteData::Entry { origin, type, 0 } });
+    }
+
+    return entries;
+}
+
+void NetworkStorageManager::fetchData(OptionSet<WebsiteDataType> types, CompletionHandler<void(Vector<WebsiteData::Entry>&&)>&& completionHandler)
+{
+    ASSERT(RunLoop::isMain());
+    ASSERT(!m_closed);
+
+    m_queue->dispatch([this, protectedThis = Ref { *this }, types, completionHandler = WTFMove(completionHandler)]() mutable {
+        auto entries = fetchDataFromDisk(types);
+        RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler), entries = crossThreadCopy(WTFMove(entries))]() mutable {
+            completionHandler(WTFMove(entries));
+        });
+    });
+}
+
+Vector<WebCore::ClientOrigin> NetworkStorageManager::deleteDataOnDisk(OptionSet<WebsiteDataType> types, WallTime modifiedSinceTime, const Function<bool(const WebCore::ClientOrigin&)>& filter)
+{
+    ASSERT(!RunLoop::isMain());
+
+    Vector<WebCore::ClientOrigin> deletedOrigins;
+    forEachOriginDirectory([&](auto directory) mutable {
+        auto filePath = originFilePath(directory);
+        auto origin = readOriginFromFile(filePath);
+        if (!origin) {
+            // If origin cannot be retrieved, but we are asked to remove data for all origins, remove it.
+            RELEASE_LOG_ERROR(Storage, "NetworkStorageManager::deleteDataOnDisk failed to read origin from '%s'", filePath.utf8().data());
+            if (filter(WebCore::ClientOrigin { })) {
+                FileSystem::deleteAllFilesModifiedSince(directory, modifiedSinceTime);
+                FileSystem::deleteEmptyDirectory(directory);
+            }
+            return;
+        }
+
+        if (!filter(*origin))
+            return;
+
+        deletedOrigins.append(*origin);
+        localOriginStorageManager(*origin).deleteData(types, modifiedSinceTime);
+        removeOriginStorageManagerIfPossible(*origin);
+        deleteOriginFileIfNecessary(filePath);
+        FileSystem::deleteEmptyDirectory(directory);
+    });
+
+    return deletedOrigins;
+}
+
+void NetworkStorageManager::deleteData(OptionSet<WebsiteDataType> types, const Vector<WebCore::SecurityOriginData>& origins, CompletionHandler<void()>&& completionHandler)
+{
+    ASSERT(RunLoop::isMain());
+    ASSERT(!m_closed);
+
+    m_queue->dispatch([this, protectedThis = Ref { *this }, types, origins = crossThreadCopy(origins), completionHandler = WTFMove(completionHandler)]() mutable {
+        HashSet<WebCore::SecurityOriginData> originSet;
+        originSet.reserveInitialCapacity(origins.size());
+        for (auto origin : origins)
+            originSet.add(WTFMove(origin));
+
+        deleteDataOnDisk(types, -WallTime::infinity(), [&originSet](auto origin) {
+            return originSet.contains(origin.topOrigin) || originSet.contains(origin.clientOrigin);
+        });
+
+        RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)]() mutable {
+            completionHandler();
+        });
+    });
+}
+
+void NetworkStorageManager::deleteDataModifiedSince(OptionSet<WebsiteDataType> types, WallTime modifiedSinceTime, CompletionHandler<void()>&& completionHandler)
+{
+    ASSERT(RunLoop::isMain());
+    ASSERT(!m_closed);
+
+    m_queue->dispatch([this, protectedThis = Ref { *this }, types, modifiedSinceTime, completionHandler = WTFMove(completionHandler)]() mutable {
+        deleteDataOnDisk(types, modifiedSinceTime, [](auto&) {
+            return true;
+        });
+
+        RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)]() mutable {
+            completionHandler();
+        });
+    });
+}
+
+void NetworkStorageManager::deleteDataForRegistrableDomains(OptionSet<WebsiteDataType> types, const Vector<WebCore::RegistrableDomain>& domains, CompletionHandler<void(HashSet<WebCore::RegistrableDomain>&&)>&& completionHandler)
+{
+    ASSERT(RunLoop::isMain());
+    ASSERT(!m_closed);
+
+    m_queue->dispatch([this, protectedThis = Ref { *this }, types, domains = crossThreadCopy(domains), completionHandler = WTFMove(completionHandler)]() mutable {
+        auto deletedOrigins = deleteDataOnDisk(types, -WallTime::infinity(), [&domains](auto& origin) {
+            auto domain = WebCore::RegistrableDomain::uncheckedCreateFromHost(origin.clientOrigin.host);
+            return domains.contains(domain);
+        });
+
+        HashSet<WebCore::RegistrableDomain> deletedDomains;
+        for (auto origin : deletedOrigins) {
+            auto domain = WebCore::RegistrableDomain::uncheckedCreateFromHost(origin.clientOrigin.host);
+            deletedDomains.add(domain);
+        }
+
+        RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler), domains = crossThreadCopy(WTFMove(deletedDomains))]() mutable {
+            completionHandler(WTFMove(domains));
+        });
+    });
+}
+
 } // namespace WebKit
 

Modified: trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.h (286506 => 286507)


--- trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.h	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.h	2021-12-03 20:17:15 UTC (rev 286507)
@@ -28,10 +28,12 @@
 #include "Connection.h"
 #include "FileSystemStorageError.h"
 #include "OriginStorageManager.h"
+#include "WebsiteData.h"
 #include <WebCore/ClientOrigin.h>
 #include <WebCore/FileSystemHandleIdentifier.h>
 #include <WebCore/FileSystemSyncAccessHandleIdentifier.h>
 #include <pal/SessionID.h>
+#include <wtf/Forward.h>
 
 namespace IPC {
 class SharedFileHandle;
@@ -55,13 +57,22 @@
     PAL::SessionID sessionID() const { return m_sessionID; }
     void close();
     void clearStorageForTesting(CompletionHandler<void()>&&);
+    void fetchData(OptionSet<WebsiteDataType>, CompletionHandler<void(Vector<WebsiteData::Entry>&&)>&&);
+    void deleteData(OptionSet<WebsiteDataType>, const Vector<WebCore::SecurityOriginData>&, CompletionHandler<void()>&&);
+    void deleteDataModifiedSince(OptionSet<WebsiteDataType>, WallTime, CompletionHandler<void()>&&);
+    void deleteDataForRegistrableDomains(OptionSet<WebsiteDataType>, const Vector<WebCore::RegistrableDomain>&, CompletionHandler<void(HashSet<WebCore::RegistrableDomain>&&)>&&);
 
 private:
     NetworkStorageManager(PAL::SessionID, const String& path);
     ~NetworkStorageManager();
     OriginStorageManager& localOriginStorageManager(const WebCore::ClientOrigin&);
+    void removeOriginStorageManagerIfPossible(const WebCore::ClientOrigin&);
     FileSystemStorageHandleRegistry& fileSystemStorageHandleRegistry();
 
+    void forEachOriginDirectory(const Function<void(const String&)>&);
+    Vector<WebsiteData::Entry> fetchDataFromDisk(OptionSet<WebsiteDataType>);
+    Vector<WebCore::ClientOrigin> deleteDataOnDisk(OptionSet<WebsiteDataType>, WallTime, const Function<bool(const WebCore::ClientOrigin&)>&);
+
     // IPC::MessageReceiver (implemented by generated code)
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&);
 

Modified: trunk/Source/WebKit/NetworkProcess/storage/OriginStorageManager.cpp (286506 => 286507)


--- trunk/Source/WebKit/NetworkProcess/storage/OriginStorageManager.cpp	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/NetworkProcess/storage/OriginStorageManager.cpp	2021-12-03 20:17:15 UTC (rev 286507)
@@ -51,20 +51,61 @@
             m_fileSystemStorageManager->connectionClosed(connection);
     }
 
-    String typeStoragePath(const String& storageIdentifier) const
+    enum class StorageType : uint8_t {
+        FileSystem,
+    };
+
+    static String toStorageIdentifier(StorageType type)
     {
-        return m_rootPath.isEmpty() ? emptyString() : FileSystem::pathByAppendingComponent(m_rootPath, storageIdentifier);
+        switch (type) {
+        case StorageType::FileSystem:
+            return "FileSystem"_s;
+        default:
+            break;
+        }
+        ASSERT_NOT_REACHED();
+        return ""_s;
     }
 
+    String typeStoragePath(StorageType type) const
+    {
+        auto storageIdentifier = toStorageIdentifier(type);
+        if (m_rootPath.isEmpty() || storageIdentifier.isEmpty())
+            return emptyString();
+
+        return FileSystem::pathByAppendingComponent(m_rootPath, storageIdentifier);
+    }
+
     FileSystemStorageManager& fileSystemStorageManager(FileSystemStorageHandleRegistry& registry)
     {
         if (!m_fileSystemStorageManager)
-            m_fileSystemStorageManager = makeUnique<FileSystemStorageManager>(typeStoragePath("FileSystem"), registry);
+            m_fileSystemStorageManager = makeUnique<FileSystemStorageManager>(typeStoragePath(StorageType::FileSystem), registry);
 
         return *m_fileSystemStorageManager;
     }
 
+    bool isActive()
+    {
+        return !!m_fileSystemStorageManager;
+    }
+
+    void deleteData(OptionSet<WebsiteDataType> types, WallTime modifiedSinceTime)
+    {
+        if (types.contains(WebsiteDataType::FileSystem))
+            deleteFileSystemStorageData(modifiedSinceTime);
+
+        FileSystem::deleteNonEmptyDirectory(m_rootPath);
+    }
+
 private:
+    void deleteFileSystemStorageData(WallTime modifiedSinceTime)
+    {
+        m_fileSystemStorageManager = nullptr;
+
+        auto fileSystemStoragePath = typeStoragePath(StorageType::FileSystem);
+        FileSystem::deleteAllFilesModifiedSince(fileSystemStoragePath, modifiedSinceTime);
+    }
+
     String m_rootPath;
     String m_identifier;
     StorageBucketMode m_mode { StorageBucketMode::BestEffort };
@@ -74,6 +115,7 @@
 OriginStorageManager::OriginStorageManager(String&& path)
     : m_path(WTFMove(path))
 {
+    ASSERT(!RunLoop::isMain());
 }
 
 OriginStorageManager::~OriginStorageManager() = default;
@@ -103,5 +145,16 @@
     return defaultBucket().fileSystemStorageManager(registry);
 }
 
+bool OriginStorageManager::isActive()
+{
+    return defaultBucket().isActive();
+}
+
+void OriginStorageManager::deleteData(OptionSet<WebsiteDataType> types, WallTime modifiedSince)
+{
+    ASSERT(!RunLoop::isMain());
+    defaultBucket().deleteData(types, modifiedSince);
+}
+
 } // namespace WebKit
 

Modified: trunk/Source/WebKit/NetworkProcess/storage/OriginStorageManager.h (286506 => 286507)


--- trunk/Source/WebKit/NetworkProcess/storage/OriginStorageManager.h	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/NetworkProcess/storage/OriginStorageManager.h	2021-12-03 20:17:15 UTC (rev 286507)
@@ -28,10 +28,15 @@
 #include "Connection.h"
 #include <wtf/text/WTFString.h>
 
+namespace WebCore {
+struct ClientOrigin;
+}
+
 namespace WebKit {
 
 class FileSystemStorageHandleRegistry;
 class FileSystemStorageManager;
+enum class WebsiteDataType : uint32_t;
 
 class OriginStorageManager {
     WTF_MAKE_FAST_ALLOCATED;
@@ -43,6 +48,8 @@
     bool persisted() const { return m_persisted; }
     void persist();
     FileSystemStorageManager& fileSystemStorageManager(FileSystemStorageHandleRegistry&);
+    bool isActive();
+    void deleteData(OptionSet<WebsiteDataType>, WallTime);
 
 private:
     enum class StorageBucketMode : bool;
@@ -49,6 +56,9 @@
     class StorageBucket;
     StorageBucket& defaultBucket();
 
+    void createOriginFileIfNecessary(const WebCore::ClientOrigin&);
+    void deleteOriginFileIfNecessary();
+
     std::unique_ptr<StorageBucket> m_defaultBucket;
     String m_path;
     bool m_persisted { false };

Modified: trunk/Source/WebKit/Shared/WebsiteData/WebsiteData.cpp (286506 => 286507)


--- trunk/Source/WebKit/Shared/WebsiteData/WebsiteData.cpp	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/Shared/WebsiteData/WebsiteData.cpp	2021-12-03 20:17:15 UTC (rev 286507)
@@ -129,6 +129,8 @@
     case WebsiteDataType::AlternativeServices:
         return WebsiteDataProcessType::Network;
 #endif
+    case WebsiteDataType::FileSystem:
+        return WebsiteDataProcessType::Network;
     }
 
     RELEASE_ASSERT_NOT_REACHED();

Modified: trunk/Source/WebKit/Shared/WebsiteData/WebsiteDataType.h (286506 => 286507)


--- trunk/Source/WebKit/Shared/WebsiteData/WebsiteDataType.h	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/Shared/WebsiteData/WebsiteDataType.h	2021-12-03 20:17:15 UTC (rev 286507)
@@ -52,6 +52,7 @@
 #if HAVE(CFNETWORK_ALTERNATIVE_SERVICE)
     AlternativeServices = 1 << 18,
 #endif
+    FileSystem = 1 << 19,
 };
 
 } // namespace WebKit
@@ -79,10 +80,11 @@
 #endif
         WebKit::WebsiteDataType::DOMCache,
         WebKit::WebsiteDataType::DeviceIdHashSalt,
-        WebKit::WebsiteDataType::PrivateClickMeasurements
+        WebKit::WebsiteDataType::PrivateClickMeasurements,
 #if HAVE(CFNETWORK_ALTERNATIVE_SERVICE)
-        , WebKit::WebsiteDataType::AlternativeServices
+        WebKit::WebsiteDataType::AlternativeServices,
 #endif
+        WebKit::WebsiteDataType::FileSystem
     >;
 };
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataRecord.mm (286506 => 286507)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataRecord.mm	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataRecord.mm	2021-12-03 20:17:15 UTC (rev 286507)
@@ -51,6 +51,7 @@
 NSString * const _WKWebsiteDataTypeAdClickAttributions = @"_WKWebsiteDataTypeAdClickAttributions";
 NSString * const _WKWebsiteDataTypePrivateClickMeasurements = @"_WKWebsiteDataTypePrivateClickMeasurements";
 NSString * const _WKWebsiteDataTypeAlternativeServices = @"_WKWebsiteDataTypeAlternativeServices";
+NSString * const _WKWebsiteDataTypeFileSystem = @"_WKWebsiteDataTypeFileSystem";
 
 #if PLATFORM(MAC)
 NSString * const _WKWebsiteDataTypePlugInData = @"_WKWebsiteDataTypePlugInData";
@@ -110,6 +111,8 @@
         [array addObject:@"Private Click Measurements"];
     if ([dataTypes containsObject:_WKWebsiteDataTypeAlternativeServices])
         [array addObject:@"Alternative Services"];
+    if ([dataTypes containsObject:_WKWebsiteDataTypeFileSystem])
+        [array addObject:@"File System"];
 
     return [array componentsJoinedByString:@", "];
 }

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataRecordInternal.h (286506 => 286507)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataRecordInternal.h	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataRecordInternal.h	2021-12-03 20:17:15 UTC (rev 286507)
@@ -77,6 +77,8 @@
     if ([websiteDataType isEqualToString:_WKWebsiteDataTypeAlternativeServices])
         return WebsiteDataType::AlternativeServices;
 #endif
+    if ([websiteDataType isEqualToString:_WKWebsiteDataTypeFileSystem])
+        return WebsiteDataType::FileSystem;
     return std::nullopt;
 }
 
@@ -134,6 +136,8 @@
     if (websiteDataTypes.contains(WebsiteDataType::AlternativeServices))
         [wkWebsiteDataTypes addObject:_WKWebsiteDataTypeAlternativeServices];
 #endif
+    if (websiteDataTypes.contains(WebsiteDataType::FileSystem))
+        [wkWebsiteDataTypes addObject:_WKWebsiteDataTypeFileSystem];
 
     return wkWebsiteDataTypes;
 }

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataRecordPrivate.h (286506 => 286507)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataRecordPrivate.h	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataRecordPrivate.h	2021-12-03 20:17:15 UTC (rev 286507)
@@ -37,6 +37,7 @@
 WK_EXTERN NSString * const _WKWebsiteDataTypeAdClickAttributions WK_API_AVAILABLE(macos(10.15), ios(13.0));
 WK_EXTERN NSString * const _WKWebsiteDataTypePrivateClickMeasurements WK_API_AVAILABLE(macos(12.0), ios(15.0));
 WK_EXTERN NSString * const _WKWebsiteDataTypeAlternativeServices WK_API_AVAILABLE(macos(11.0), ios(14.0));
+WK_EXTERN NSString * const _WKWebsiteDataTypeFileSystem WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 #if !TARGET_OS_IPHONE
 WK_EXTERN NSString * const _WKWebsiteDataTypePlugInData WK_API_AVAILABLE(macos(10.11));

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm (286506 => 286507)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm	2021-12-03 20:17:15 UTC (rev 286507)
@@ -248,7 +248,8 @@
             _WKWebsiteDataTypeCredentials,
             _WKWebsiteDataTypeAdClickAttributions,
             _WKWebsiteDataTypePrivateClickMeasurements,
-            _WKWebsiteDataTypeAlternativeServices
+            _WKWebsiteDataTypeAlternativeServices,
+            _WKWebsiteDataTypeFileSystem
 #if !TARGET_OS_IPHONE
             , _WKWebsiteDataTypePlugInData
 #endif

Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (286506 => 286507)


--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-12-03 20:17:15 UTC (rev 286507)
@@ -1499,6 +1499,9 @@
 		93D6B7B5255268D70058DD3A /* SpeechRecognitionPermissionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D6B7B2255268A20058DD3A /* SpeechRecognitionPermissionManager.h */; };
 		93D6B7B925534A170058DD3A /* WKSpeechRecognitionPermissionCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D6B7B725534A110058DD3A /* WKSpeechRecognitionPermissionCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		93E6A4EE1BC5DD3900F8A0E7 /* _WKHitTestResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 93E6A4ED1BC5DD3900F8A0E7 /* _WKHitTestResult.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		93E799852756FA550074008A /* WebFileSystemStorageConnectionMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93E799822756FA540074008A /* WebFileSystemStorageConnectionMessageReceiver.cpp */; };
+		93E799872756FAB40074008A /* WebFileSystemStorageConnectionMessagesReplies.h in Headers */ = {isa = PBXBuildFile; fileRef = 93E799832756FA540074008A /* WebFileSystemStorageConnectionMessagesReplies.h */; };
+		93E799882756FAC20074008A /* WebFileSystemStorageConnectionMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 93E799812756FA530074008A /* WebFileSystemStorageConnectionMessages.h */; };
 		93F549B41E3174B7000E7239 /* WKSnapshotConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F549B31E3174B7000E7239 /* WKSnapshotConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		950F2880252414EA00B74F1C /* WKMouseDeviceObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 950F287E252414E900B74F1C /* WKMouseDeviceObserver.h */; };
 		9565083926D87A2B00E15CB7 /* AppleMediaServicesSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 9565083726D87A2B00E15CB7 /* AppleMediaServicesSPI.h */; };
@@ -5301,6 +5304,10 @@
 		93D6B7B725534A110058DD3A /* WKSpeechRecognitionPermissionCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKSpeechRecognitionPermissionCallback.h; sourceTree = "<group>"; };
 		93D6B7B825534A120058DD3A /* WKSpeechRecognitionPermissionCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKSpeechRecognitionPermissionCallback.cpp; sourceTree = "<group>"; };
 		93E6A4ED1BC5DD3900F8A0E7 /* _WKHitTestResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKHitTestResult.h; sourceTree = "<group>"; };
+		93E7997E2756F6700074008A /* WebFileSystemStorageConnection.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebFileSystemStorageConnection.messages.in; sourceTree = "<group>"; };
+		93E799812756FA530074008A /* WebFileSystemStorageConnectionMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebFileSystemStorageConnectionMessages.h; sourceTree = "<group>"; };
+		93E799822756FA540074008A /* WebFileSystemStorageConnectionMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebFileSystemStorageConnectionMessageReceiver.cpp; sourceTree = "<group>"; };
+		93E799832756FA540074008A /* WebFileSystemStorageConnectionMessagesReplies.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebFileSystemStorageConnectionMessagesReplies.h; sourceTree = "<group>"; };
 		93F549B31E3174B7000E7239 /* WKSnapshotConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKSnapshotConfiguration.h; sourceTree = "<group>"; };
 		93F549B51E3174DA000E7239 /* WKSnapshotConfiguration.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKSnapshotConfiguration.mm; sourceTree = "<group>"; };
 		950F287E252414E900B74F1C /* WKMouseDeviceObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKMouseDeviceObserver.h; path = ios/WKMouseDeviceObserver.h; sourceTree = "<group>"; };
@@ -10582,6 +10589,7 @@
 				BC032D6810F4378D0058C15A /* WebEditorClient.h */,
 				9354242B2703BDCB005CA72C /* WebFileSystemStorageConnection.cpp */,
 				9354242A2703BDCB005CA72C /* WebFileSystemStorageConnection.h */,
+				93E7997E2756F6700074008A /* WebFileSystemStorageConnection.messages.in */,
 				BC111A58112F4FBB00337BAB /* WebFrameLoaderClient.cpp */,
 				BC032D6A10F4378D0058C15A /* WebFrameLoaderClient.h */,
 				BC1BE1DF12D54A410004A228 /* WebGeolocationClient.cpp */,
@@ -12059,6 +12067,9 @@
 				E3866B072399979D00F88FE9 /* WebDeviceOrientationUpdateProviderMessages.h */,
 				E3866B042399979C00F88FE9 /* WebDeviceOrientationUpdateProviderProxyMessageReceiver.cpp */,
 				E3866B052399979C00F88FE9 /* WebDeviceOrientationUpdateProviderProxyMessages.h */,
+				93E799822756FA540074008A /* WebFileSystemStorageConnectionMessageReceiver.cpp */,
+				93E799812756FA530074008A /* WebFileSystemStorageConnectionMessages.h */,
+				93E799832756FA540074008A /* WebFileSystemStorageConnectionMessagesReplies.h */,
 				CD73BA48131ACD8E00EEDED2 /* WebFullScreenManagerMessageReceiver.cpp */,
 				CD73BA49131ACD8E00EEDED2 /* WebFullScreenManagerMessages.h */,
 				CD73BA45131ACC8800EEDED2 /* WebFullScreenManagerProxyMessageReceiver.cpp */,
@@ -13306,6 +13317,8 @@
 				BC032DBB10F4380F0058C15A /* WebEventConversion.h in Headers */,
 				BC111B5D112F629800337BAB /* WebEventFactory.h in Headers */,
 				9354242C2703BDCB005CA72C /* WebFileSystemStorageConnection.h in Headers */,
+				93E799882756FAC20074008A /* WebFileSystemStorageConnectionMessages.h in Headers */,
+				93E799872756FAB40074008A /* WebFileSystemStorageConnectionMessagesReplies.h in Headers */,
 				1A90C1EE1264FD50003E44D4 /* WebFindOptions.h in Headers */,
 				BCE469541214E6CB000B98EB /* WebFormClient.h in Headers */,
 				BCE469561214E6CB000B98EB /* WebFormSubmissionListenerProxy.h in Headers */,
@@ -15402,6 +15415,7 @@
 				E3866AE52397400400F88FE9 /* WebDeviceOrientationUpdateProviderProxy.mm in Sources */,
 				E3866B092399A2D500F88FE9 /* WebDeviceOrientationUpdateProviderProxyMessageReceiver.cpp in Sources */,
 				2D92A789212B6AB100F493FD /* WebEvent.cpp in Sources */,
+				93E799852756FA550074008A /* WebFileSystemStorageConnectionMessageReceiver.cpp in Sources */,
 				CD73BA4E131ACDB700EEDED2 /* WebFullScreenManagerMessageReceiver.cpp in Sources */,
 				CD73BA47131ACC9A00EEDED2 /* WebFullScreenManagerProxyMessageReceiver.cpp in Sources */,
 				BC0E606112D6BA910012A72A /* WebGeolocationManagerMessageReceiver.cpp in Sources */,

Modified: trunk/Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp (286506 => 286507)


--- trunk/Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp	2021-12-03 20:17:15 UTC (rev 286507)
@@ -37,6 +37,8 @@
 #include "WebCacheStorageProvider.h"
 #include "WebCookieJar.h"
 #include "WebCoreArgumentCoders.h"
+#include "WebFileSystemStorageConnection.h"
+#include "WebFileSystemStorageConnectionMessages.h"
 #include "WebFrame.h"
 #include "WebIDBConnectionToServer.h"
 #include "WebIDBConnectionToServerMessages.h"
@@ -119,6 +121,10 @@
             storageAreaMap->didReceiveMessage(connection, decoder);
         return;
     }
+    if (decoder.messageReceiverName() == Messages::WebFileSystemStorageConnection::messageReceiverName()) {
+        WebProcess::singleton().fileSystemStorageConnection().didReceiveMessage(connection, decoder);
+        return;
+    }
 
 #if USE(LIBWEBRTC)
     if (decoder.messageReceiverName() == Messages::WebRTCMonitor::messageReceiverName()) {

Added: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.messages.in (0 => 286507)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.messages.in	                        (rev 0)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.messages.in	2021-12-03 20:17:15 UTC (rev 286507)
@@ -0,0 +1,25 @@
+# Copyright (C) 2021 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.
+
+messages -> WebFileSystemStorageConnection NotRefCounted {
+    InvalidateAccessHandle(WebCore::FileSystemSyncAccessHandleIdentifier identifier)
+}

Modified: trunk/Tools/ChangeLog (286506 => 286507)


--- trunk/Tools/ChangeLog	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Tools/ChangeLog	2021-12-03 20:17:15 UTC (rev 286507)
@@ -1,3 +1,12 @@
+2021-12-03  Sihui Liu  <[email protected]>
+
+        Fetch and remove file system data via WKWebsiteDataStore
+        https://bugs.webkit.org/show_bug.cgi?id=233567
+
+        Reviewed by Youenn Fablet.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm:
+
 2021-12-03  Chris Dumez  <[email protected]>
 
         Follow-up to r286479 to add API test and address issues found by the test

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm (286506 => 286507)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm	2021-12-03 19:52:04 UTC (rev 286506)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm	2021-12-03 20:17:15 UTC (rev 286507)
@@ -29,11 +29,13 @@
 
 #import "DeprecatedGlobalValues.h"
 #import "PlatformUtilities.h"
+#import "TestUIDelegate.h"
 #import "TestURLSchemeHandler.h"
 #import "TestWKWebView.h"
 #import <WebKit/WKPreferencesPrivate.h>
 #import <WebKit/WKWebViewConfigurationPrivate.h>
 #import <WebKit/WKWebViewPrivate.h>
+#import <WebKit/WKWebsiteDataRecordPrivate.h>
 
 @interface FileSystemAccessMessageHandler : NSObject <WKScriptMessageHandler>
 @end
@@ -48,7 +50,7 @@
 
 @end
 
-static NSString *mainFrameString = @"<script> \
+static NSString *workerFrameString = @"<script> \
     function start() { \
         var worker = new Worker('worker.js'); \
         worker._onmessage_ = function(event) { \
@@ -115,7 +117,7 @@
     [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webkit"];
 
     auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
-    [webView loadHTMLString:mainFrameString baseURL:[NSURL URLWithString:@"webkit://webkit.org"]];
+    [webView loadHTMLString:workerFrameString baseURL:[NSURL URLWithString:@"webkit://webkit.org"]];
     TestWebKitAPI::Util::run(&receivedScriptMessage);
     receivedScriptMessage = false;
     EXPECT_WK_STREQ(@"page is loaded", [lastScriptMessage body]);
@@ -126,7 +128,7 @@
     EXPECT_WK_STREQ(@"success: write 10 bytes", [lastScriptMessage body]);
 
     auto secondWebView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
-    [secondWebView loadHTMLString:mainFrameString baseURL:[NSURL URLWithString:@"webkit://webkit.org"]];
+    [secondWebView loadHTMLString:workerFrameString baseURL:[NSURL URLWithString:@"webkit://webkit.org"]];
     TestWebKitAPI::Util::run(&receivedScriptMessage);
     receivedScriptMessage = false;
     EXPECT_WK_STREQ(@"page is loaded", [lastScriptMessage body]);
@@ -168,7 +170,7 @@
     [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webkit"];
 
     auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
-    [webView loadHTMLString:mainFrameString baseURL:[NSURL URLWithString:@"webkit://webkit.org"]];
+    [webView loadHTMLString:workerFrameString baseURL:[NSURL URLWithString:@"webkit://webkit.org"]];
     TestWebKitAPI::Util::run(&receivedScriptMessage);
     receivedScriptMessage = false;
     EXPECT_WK_STREQ(@"page is loaded", [lastScriptMessage body]);
@@ -258,4 +260,196 @@
     EXPECT_WK_STREQ(@"file is opened", [lastScriptMessage body]);
 }
 
+static NSString *testString = @"<script> \
+    async function open(shouldCreateFile) \
+    { \
+        try { \
+            var rootHandle = await navigator.storage.getDirectory(); \
+            var fileHandle = await rootHandle.getFileHandle('file-system-access.txt', { 'create' : shouldCreateFile }); \
+            window.webkit.messageHandlers.testHandler.postMessage('file is opened'); \
+        } catch(err) { \
+            window.webkit.messageHandlers.testHandler.postMessage('error: ' + err.name + ' - ' + err.message); \
+        } \
+    } \
+    open(true); \
+    </script>";
+
+TEST(FileSystemAccess, FetchAndRemoveData)
+{
+    auto handler = adoptNS([[FileSystemAccessMessageHandler alloc] init]);
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"];
+    auto websiteDataStore = [configuration websiteDataStore];
+    auto types = [NSSet setWithObject:_WKWebsiteDataTypeFileSystem];
+
+    // Remove existing data.
+    done = false;
+    [websiteDataStore removeDataOfTypes:types modifiedSince:[NSDate distantPast] completionHandler:^ {
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+
+    auto preferences = [configuration preferences];
+    preferences._fileSystemAccessEnabled = YES;
+    preferences._storageAPIEnabled = YES;
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
+    [webView loadHTMLString:testString baseURL:[NSURL URLWithString:@"https://webkit.org"]];
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    receivedScriptMessage = false;
+    EXPECT_WK_STREQ(@"file is opened", [lastScriptMessage body]);
+
+    // Fetch data and remove it by origin.
+    done = false;
+    [websiteDataStore fetchDataRecordsOfTypes:types completionHandler:^(NSArray<WKWebsiteDataRecord *> *records) {
+        EXPECT_EQ(records.count, 1u);
+        auto record = [records objectAtIndex:0];
+        EXPECT_STREQ("webkit.org", [record.displayName UTF8String]);
+
+        // Remove data.
+        [websiteDataStore removeDataOfTypes:types forDataRecords:records completionHandler:^{
+            done = true;
+        }];
+    }];
+    TestWebKitAPI::Util::run(&done);
+
+    // Fetch data after removal.
+    done = false;
+    [websiteDataStore fetchDataRecordsOfTypes:types completionHandler:^(NSArray<WKWebsiteDataRecord *> *records) {
+        EXPECT_EQ(records.count, 0u);
+        done = true;
+    }];
+
+    // File cannot be opened after data removal.
+    [webView evaluateJavaScript:@"open(false)" completionHandler:nil];
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    receivedScriptMessage = false;
+    EXPECT_WK_STREQ(@"error: NotFoundError - The object can not be found here.", [lastScriptMessage body]);
+}
+
+TEST(FileSystemAccess, RemoveDataByModificationTime)
+{
+    auto handler = adoptNS([[FileSystemAccessMessageHandler alloc] init]);
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"];
+    auto preferences = [configuration preferences];
+    preferences._fileSystemAccessEnabled = YES;
+    preferences._storageAPIEnabled = YES;
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
+    [webView loadHTMLString:testString baseURL:[NSURL URLWithString:@"https://webkit.org"]];
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    receivedScriptMessage = false;
+    EXPECT_WK_STREQ(@"file is opened", [lastScriptMessage body]);
+
+    auto websiteDataStore = [configuration websiteDataStore];
+    auto types = [NSSet setWithObject:_WKWebsiteDataTypeFileSystem];
+    done = false;
+    __block NSUInteger recordsCount;
+    [websiteDataStore fetchDataRecordsOfTypes:types completionHandler:^(NSArray<WKWebsiteDataRecord *> *records) {
+        recordsCount = records.count;
+        EXPECT_GT(recordsCount, 0u);
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+
+    done = false;
+    [websiteDataStore removeDataOfTypes:types modifiedSince:[NSDate now] completionHandler:^ {
+        [websiteDataStore fetchDataRecordsOfTypes:types completionHandler:^(NSArray<WKWebsiteDataRecord *> *records) {
+            recordsCount = records.count;
+            EXPECT_EQ(records.count, recordsCount);
+            done = true;
+        }];
+    }];
+    TestWebKitAPI::Util::run(&done);
+
+    done = false;
+    [websiteDataStore removeDataOfTypes:types modifiedSince:[NSDate distantPast] completionHandler:^ {
+        [websiteDataStore fetchDataRecordsOfTypes:types completionHandler:^(NSArray<WKWebsiteDataRecord *> *records) {
+            EXPECT_EQ(records.count, 0u);
+            done = true;
+        }];
+    }];
+    TestWebKitAPI::Util::run(&done);
+}
+
+static NSString *mainFrameString = @"<script> \
+    function postResult(event) \
+    { \
+        window.webkit.messageHandlers.testHandler.postMessage(event.data); \
+    } \
+    addEventListener('message', postResult, false); \
+    </script> \
+    <iframe src=''>";
+
+static const char* frameBytes = R"TESTRESOURCE(
+<script>
+function postMessage(message)
+{
+    parent.postMessage(message, '*');
+}
+async function open()
+{
+    try {
+        var rootHandle = await navigator.storage.getDirectory();
+        var fileHandle = await rootHandle.getFileHandle('file-system-access.txt', { 'create' : true });
+        postMessage('file is opened');
+    } catch(err) {
+        postMessage('error: ' + err.name + ' - ' + err.message);
+    }
+}
+open();
+</script>
+)TESTRESOURCE";
+
+TEST(FileSystemAccess, FetchDataForThirdParty)
+{
+    TestWebKitAPI::HTTPServer server({
+        { "/", { frameBytes } },
+    }, TestWebKitAPI::HTTPServer::Protocol::Https, nullptr, nullptr, 9091);
+
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto handler = adoptNS([[FileSystemAccessMessageHandler alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"];
+    auto preferences = [configuration preferences];
+    preferences._fileSystemAccessEnabled = YES;
+    preferences._storageAPIEnabled = YES;
+
+    auto websiteDataStore = [configuration websiteDataStore];
+    auto types = [NSSet setWithObject:_WKWebsiteDataTypeFileSystem];
+    done = false;
+    [websiteDataStore removeDataOfTypes:types modifiedSince:[NSDate distantPast] completionHandler:^ {
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
+    auto navigationDelegate = adoptNS([TestNavigationDelegate new]);
+    [navigationDelegate setDidReceiveAuthenticationChallenge:^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^callback)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
+        EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
+        callback(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
+    }];
+    [navigationDelegate setDecidePolicyForNavigationAction:[&](WKNavigationAction *action, void (^decisionHandler)(WKNavigationActionPolicy)) {
+        decisionHandler(WKNavigationActionPolicyAllow);
+    }];
+    [webView setNavigationDelegate:navigationDelegate.get()];
+
+    [webView loadHTMLString:mainFrameString baseURL:[NSURL URLWithString:@"https://webkit.org"]];
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    receivedScriptMessage = false;
+    EXPECT_WK_STREQ(@"file is opened", [lastScriptMessage body]);
+
+    done = false;
+    [websiteDataStore fetchDataRecordsOfTypes:types completionHandler:^(NSArray<WKWebsiteDataRecord *> *records) {
+        // Should return both opening origin and top origin.
+        EXPECT_EQ(records.count, 2u);
+        auto sortFunction = ^(WKWebsiteDataRecord *record1, WKWebsiteDataRecord *record2){
+            return [record1.displayName compare:record2.displayName];
+        };
+        auto sortedRecords = [records sortedArrayUsingComparator:sortFunction];
+        EXPECT_WK_STREQ(@"127.0.0.1", [sortedRecords objectAtIndex:0].displayName);
+        EXPECT_WK_STREQ(@"webkit.org", [sortedRecords objectAtIndex:1].displayName);
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+}
+
 #endif // USE(APPLE_INTERNAL_SDK)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to