Changeset 286601 in webkit
- Timestamp:
- Dec 7, 2021, 11:33:16 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 29 edited
-
Source/WTF/ChangeLog (modified) (1 diff)
-
Source/WTF/wtf/FileSystem.cpp (modified) (1 diff)
-
Source/WTF/wtf/FileSystem.h (modified) (2 diffs)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/Modules/filesystemaccess/FileSystemStorageConnection.h (modified) (1 diff)
-
Source/WebKit/CMakeLists.txt (modified) (1 diff)
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/DerivedSources-input.xcfilelist (modified) (1 diff)
-
Source/WebKit/DerivedSources-output.xcfilelist (modified) (3 diffs)
-
Source/WebKit/DerivedSources.make (modified) (1 diff)
-
Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp (modified) (1 diff)
-
Source/WebKit/NetworkProcess/NetworkProcess.cpp (modified) (5 diffs)
-
Source/WebKit/NetworkProcess/storage/FileSystemStorageHandle.h (modified) (1 diff)
-
Source/WebKit/NetworkProcess/storage/FileSystemStorageManager.cpp (modified) (3 diffs)
-
Source/WebKit/NetworkProcess/storage/FileSystemStorageManager.h (modified) (1 diff)
-
Source/WebKit/NetworkProcess/storage/NetworkStorageManager.cpp (modified) (7 diffs)
-
Source/WebKit/NetworkProcess/storage/NetworkStorageManager.h (modified) (3 diffs)
-
Source/WebKit/NetworkProcess/storage/OriginStorageManager.cpp (modified) (5 diffs)
-
Source/WebKit/NetworkProcess/storage/OriginStorageManager.h (modified) (3 diffs)
-
Source/WebKit/Shared/WebsiteData/WebsiteData.cpp (modified) (1 diff)
-
Source/WebKit/Shared/WebsiteData/WebsiteDataType.h (modified) (2 diffs)
-
Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataRecord.mm (modified) (2 diffs)
-
Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataRecordInternal.h (modified) (2 diffs)
-
Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataRecordPrivate.h (modified) (1 diff)
-
Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm (modified) (1 diff)
-
Source/WebKit/WebKit.xcodeproj/project.pbxproj (modified) (6 diffs)
-
Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp (modified) (2 diffs)
-
Source/WebKit/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.messages.in (added)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WTF/ChangeLog
r286569 r286601 1 2021-12-07 Sihui Liu <sihui_liu@apple.com> 2 3 Fetch and remove file system data via WKWebsiteDataStore 4 https://bugs.webkit.org/show_bug.cgi?id=233567 5 <rdar://problem/86029185> 6 7 Reviewed by Youenn Fablet. 8 9 * wtf/FileSystem.cpp: 10 (WTF::FileSystemImpl::readEntireFile): Read whole file content into a Vector. 11 (WTF::FileSystemImpl::deleteAllFilesModifiedSince): Recursively delete files and folders modified after 12 specified time in a directory. 13 * wtf/FileSystem.h: 14 1 15 2021-12-06 Ryan Haddad <ryanhaddad@apple.com> 2 16 -
trunk/Source/WTF/wtf/FileSystem.cpp
r286569 r286601 515 515 } 516 516 517 std::optional<Vector<uint8_t>> readEntireFile(PlatformFileHandle handle) 518 { 519 if (!FileSystem::isHandleValid(handle)) 520 return std::nullopt; 521 522 auto size = FileSystem::fileSize(handle).value_or(0); 523 if (!size) 524 return std::nullopt; 525 526 unsigned bytesToRead; 527 if (!WTF::convertSafely(size, bytesToRead)) 528 return std::nullopt; 529 530 Vector<uint8_t> buffer(bytesToRead); 531 unsigned totalBytesRead = FileSystem::readFromFile(handle, buffer.data(), buffer.size()); 532 if (totalBytesRead != bytesToRead) 533 return std::nullopt; 534 535 return buffer; 536 } 537 538 void deleteAllFilesModifiedSince(const String& directory, WallTime time) 539 { 540 // This function may delete directory folder. 541 if (time == -WallTime::infinity()) { 542 deleteNonEmptyDirectory(directory); 543 return; 544 } 545 546 auto children = listDirectory(directory); 547 for (auto& child : children) { 548 auto childPath = FileSystem::pathByAppendingComponent(directory, child); 549 auto childType = fileType(childPath); 550 if (!childType) 551 continue; 552 553 switch (*childType) { 554 case FileType::Regular: { 555 if (auto modificationTime = FileSystem::fileModificationTime(childPath); modificationTime && *modificationTime >= time) 556 deleteFile(childPath); 557 break; 558 } 559 case FileType::Directory: 560 deleteAllFilesModifiedSince(childPath, time); 561 deleteEmptyDirectory(childPath); 562 break; 563 case FileType::SymbolicLink: 564 break; 565 } 566 } 567 568 FileSystem::deleteEmptyDirectory(directory); 569 } 570 517 571 #if HAVE(STD_FILESYSTEM) || HAVE(STD_EXPERIMENTAL_FILESYSTEM) 518 572 -
trunk/Source/WTF/wtf/FileSystem.h
r286569 r286601 109 109 WTF_EXPORT_PRIVATE bool fileExists(const String&); 110 110 WTF_EXPORT_PRIVATE bool deleteFile(const String&); 111 WTF_EXPORT_PRIVATE void deleteAllFilesModifiedSince(const String&, WallTime); 111 112 WTF_EXPORT_PRIVATE bool deleteEmptyDirectory(const String&); 112 113 WTF_EXPORT_PRIVATE bool moveFile(const String& oldPath, const String& newPath); … … 147 148 using Salt = std::array<uint8_t, 8>; 148 149 WTF_EXPORT_PRIVATE std::optional<Salt> readOrMakeSalt(const String& path); 150 WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> readEntireFile(PlatformFileHandle); 149 151 150 152 // Prefix is what the filename should be prefixed with, not the full path. -
trunk/Source/WebCore/ChangeLog
r286599 r286601 1 2021-12-07 Sihui Liu <sihui_liu@apple.com> 2 3 Fetch and remove file system data via WKWebsiteDataStore 4 https://bugs.webkit.org/show_bug.cgi?id=233567 5 <rdar://problem/86029185> 6 7 Reviewed by Youenn Fablet. 8 9 * Modules/filesystemaccess/FileSystemStorageConnection.h: 10 1 11 2021-12-07 Antti Koivisto <antti@apple.com> 2 12 -
trunk/Source/WebCore/Modules/filesystemaccess/FileSystemStorageConnection.h
r286569 r286601 28 28 #include "FileSystemHandleIdentifier.h" 29 29 #include "FileSystemSyncAccessHandleIdentifier.h" 30 #include "ProcessQualified.h" 30 31 #include "ScriptExecutionContextIdentifier.h" 31 32 #include <wtf/CompletionHandler.h> -
trunk/Source/WebKit/CMakeLists.txt
r286569 r286601 311 311 WebProcess/WebCoreSupport/RemoteWebLockRegistry 312 312 WebProcess/WebCoreSupport/WebBroadcastChannelRegistry 313 WebProcess/WebCoreSupport/WebFileSystemStorageConnection 313 314 WebProcess/WebCoreSupport/WebSpeechRecognitionConnection 314 315 -
trunk/Source/WebKit/ChangeLog
r286596 r286601 1 2021-12-07 Sihui Liu <sihui_liu@apple.com> 2 3 Fetch and remove file system data via WKWebsiteDataStore 4 https://bugs.webkit.org/show_bug.cgi?id=233567 5 <rdar://problem/86029185> 6 7 Reviewed by Youenn Fablet. 8 9 Introduce a new WebsiteDataType value FileSystem for FileSystemAccess data. Network process now can fetch and 10 delete this type of data when fetching and deleteing website data (if FileSystem type is included in target 11 types). 12 13 To track origins that have FileSystem data, this patch introduces a new file named origin in the origin's 14 directory. This file will be created when OriginStorageManager is created. 15 16 To delete existing FileSystem data, network process finds origins that are requested to be deleted and have data 17 on disk, closes active access handles, and deletes the files. The origin file mentioned above will be deleted if 18 there is no other file left in the same directory, and empty directories will be deleted. 19 20 New API tests: FileSystemAccess.FetchAndRemoveData 21 FileSystemAccess.RemoveDataByModificationTime 22 FileSystemAccess.FetchDataForThirdParty 23 24 * CMakeLists.txt: 25 * DerivedSources-input.xcfilelist: 26 * DerivedSources-output.xcfilelist: 27 * DerivedSources.make: 28 * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp: 29 (WebKit::WebResourceLoadStatisticsStore::monitoredDataTypes): 30 * NetworkProcess/NetworkProcess.cpp: 31 (WebKit::NetworkProcess::fetchWebsiteData): 32 (WebKit::NetworkProcess::deleteWebsiteData): 33 (WebKit::NetworkProcess::deleteWebsiteDataForOrigins): 34 (WebKit::NetworkProcess::deleteAndRestrictWebsiteDataForRegistrableDomains): 35 (WebKit::NetworkProcess::registrableDomainsWithWebsiteData): 36 * NetworkProcess/storage/FileSystemStorageHandle.h: 37 (WebKit::FileSystemStorageHandle::activeSyncAccessHandle const): 38 * NetworkProcess/storage/FileSystemStorageManager.cpp: 39 (WebKit::FileSystemStorageManager::~FileSystemStorageManager): 40 (WebKit::FileSystemStorageManager::close): 41 * NetworkProcess/storage/FileSystemStorageManager.h: 42 * NetworkProcess/storage/NetworkStorageManager.cpp: 43 (WebKit::readOriginFromFile): 44 (WebKit::writeOriginToFileIfNecessary): 45 (WebKit::deleteOriginFileIfNecessary): 46 (WebKit::originDirectoryPath): 47 (WebKit::originFilePath): 48 (WebKit::NetworkStorageManager::localOriginStorageManager): 49 (WebKit::NetworkStorageManager::removeOriginStorageManagerIfPossible): 50 (WebKit::NetworkStorageManager::persist): 51 (WebKit::NetworkStorageManager::clearStorageForTesting): Only reset persisted state here as our test bot can run 52 tests in parallel. If one worker finishes a test and asks to clear storage, while another worker is running a 53 filesystem test; the test may fail as data is gone. (The workers are using the same network process.) 54 (WebKit::toWebsiteDataType): 55 (WebKit::NetworkStorageManager::forEachOriginDirectory): 56 (WebKit::NetworkStorageManager::fetchDataFromDisk): 57 (WebKit::NetworkStorageManager::fetchData): 58 (WebKit::NetworkStorageManager::deleteDataOnDisk): 59 (WebKit::NetworkStorageManager::deleteData): 60 (WebKit::NetworkStorageManager::deleteDataModifiedSince): 61 (WebKit::NetworkStorageManager::deleteDataForRegistrableDomains): 62 (WebKit::originPath): Deleted. 63 * NetworkProcess/storage/NetworkStorageManager.h: 64 * NetworkProcess/storage/OriginStorageManager.cpp: 65 (WebKit::OriginStorageManager::StorageBucket::toStorageIdentifier): 66 (WebKit::OriginStorageManager::StorageBucket::typeStoragePath const): 67 (WebKit::OriginStorageManager::StorageBucket::fileSystemStorageManager): 68 (WebKit::OriginStorageManager::StorageBucket::isActive): 69 (WebKit::OriginStorageManager::StorageBucket::deleteData): 70 (WebKit::OriginStorageManager::StorageBucket::deleteFileSystemStorageData): 71 (WebKit::OriginStorageManager::OriginStorageManager): 72 (WebKit::OriginStorageManager::fileSystemStorageManager): 73 (WebKit::OriginStorageManager::isActive): 74 (WebKit::OriginStorageManager::deleteData): 75 (WebKit::OriginStorageManager::setPersisted): 76 (WebKit::OriginStorageManager::persist): Deleted. 77 * NetworkProcess/storage/OriginStorageManager.h: 78 * Shared/WebsiteData/WebsiteData.cpp: 79 (WebKit::WebsiteData::ownerProcess): 80 * Shared/WebsiteData/WebsiteDataType.h: 81 * UIProcess/API/Cocoa/WKWebsiteDataRecord.mm: 82 (dataTypesToString): 83 * UIProcess/API/Cocoa/WKWebsiteDataRecordInternal.h: 84 (WebKit::toWebsiteDataType): 85 (WebKit::toWKWebsiteDataTypes): 86 * UIProcess/API/Cocoa/WKWebsiteDataRecordPrivate.h: 87 * UIProcess/API/Cocoa/WKWebsiteDataStore.mm: 88 (+[WKWebsiteDataStore _allWebsiteDataTypesIncludingPrivate]): 89 * WebKit.xcodeproj/project.pbxproj: 90 * WebProcess/Network/NetworkProcessConnection.cpp: 91 (WebKit::NetworkProcessConnection::didReceiveMessage): 92 * WebProcess/WebCoreSupport/WebFileSystemStorageConnection.messages.in: Added. 93 1 94 2021-12-07 Kimmo Kinnunen <kkinnunen@apple.com> 2 95 -
trunk/Source/WebKit/DerivedSources-input.xcfilelist
r286569 r286601 222 222 $(PROJECT_DIR)/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.messages.in 223 223 $(PROJECT_DIR)/WebProcess/WebCoreSupport/WebDeviceOrientationUpdateProvider.messages.in 224 $(PROJECT_DIR)/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.messages.in 224 225 $(PROJECT_DIR)/WebProcess/WebCoreSupport/WebSpeechRecognitionConnection.messages.in 225 226 $(PROJECT_DIR)/WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.messages.in -
trunk/Source/WebKit/DerivedSources-output.xcfilelist
r286569 r286601 1 1 # This file is generated by the generate-xcfilelists script. 2 <<<<<<< HEAD3 2 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/AudioCaptureSampleManagerMessageReceiver.cpp 4 3 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/AudioCaptureSampleManagerMessagesReplies.h … … 495 494 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/WebDeviceOrientationUpdateProviderProxyMessages.h 496 495 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/WebDeviceOrientationUpdateProviderProxyMessagesReplies.h 496 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/WebFileSystemStorageConnectionMessageReceiver.cpp 497 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/WebFileSystemStorageConnectionMessages.h 498 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/WebFileSystemStorageConnectionMessagesReplies.h 497 499 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/WebFullScreenManagerMessageReceiver.cpp 498 500 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/WebFullScreenManagerMessages.h … … 621 623 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/com.apple.WebKit.plugin-common.sb 622 624 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/com.apple.WebProcess.sb 625 <<<<<<< HEAD -
trunk/Source/WebKit/DerivedSources.make
r286569 r286601 223 223 WebProcess/WebCoreSupport/WebBroadcastChannelRegistry \ 224 224 WebProcess/WebCoreSupport/WebDeviceOrientationUpdateProvider \ 225 WebProcess/WebCoreSupport/WebFileSystemStorageConnection \ 225 226 WebProcess/WebCoreSupport/WebSpeechRecognitionConnection \ 226 227 WebProcess/Speech/SpeechRecognitionRealtimeMediaSourceManager \ -
trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp
r286569 r286601 75 75 WebsiteDataType::ServiceWorkerRegistrations, 76 76 #endif 77 WebsiteDataType::FileSystem, 77 78 })); 78 79 -
trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp
r286569 r286601 1556 1556 } 1557 1557 #endif 1558 1559 if (auto iterator = m_storageManagers.find(sessionID); iterator != m_storageManagers.end()) { 1560 iterator->value->fetchData(websiteDataTypes, [callbackAggregator](auto entries) mutable { 1561 callbackAggregator->m_websiteData.entries.appendVector(WTFMove(entries)); 1562 }); 1563 } 1558 1564 } 1559 1565 … … 1630 1636 } 1631 1637 #endif 1638 1639 if (auto iterator = m_storageManagers.find(sessionID); iterator != m_storageManagers.end()) 1640 iterator->value->deleteDataModifiedSince(websiteDataTypes, modifiedSince, [clearTasksHandler] { }); 1632 1641 } 1633 1642 … … 1736 1745 } 1737 1746 #endif 1747 1748 if (auto iterator = m_storageManagers.find(sessionID); iterator != m_storageManagers.end()) 1749 iterator->value->deleteData(websiteDataTypes, originDatas, [clearTasksHandler] { }); 1738 1750 1739 1751 if (auto* networkSession = this->networkSession(sessionID)) { … … 1960 1972 } 1961 1973 1974 if (auto iterator = m_storageManagers.find(sessionID); iterator != m_storageManagers.end()) { 1975 iterator->value->deleteDataForRegistrableDomains(websiteDataTypes, domainsToDeleteAllNonCookieWebsiteDataFor, [callbackAggregator](auto deletedDomains) mutable { 1976 for (auto domain : deletedDomains) 1977 callbackAggregator->m_domains.add(WTFMove(domain)); 1978 }); 1979 } 1980 1962 1981 auto dataTypesForUIProcess = WebsiteData::filter(websiteDataTypes, WebsiteDataProcessType::UI); 1963 1982 if (!dataTypesForUIProcess.isEmpty() && !domainsToDeleteAllNonCookieWebsiteDataFor.isEmpty()) { … … 2074 2093 callbackAggregator->m_websiteData.entries.appendVector(entries); 2075 2094 }); 2095 }); 2096 } 2097 2098 if (auto iterator = m_storageManagers.find(sessionID); iterator != m_storageManagers.end()) { 2099 iterator->value->fetchData(websiteDataTypes, [callbackAggregator](auto entries) mutable { 2100 callbackAggregator->m_websiteData.entries.appendVector(WTFMove(entries)); 2076 2101 }); 2077 2102 } -
trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageHandle.h
r286569 r286601 63 63 Expected<AccessHandleInfo, FileSystemStorageError> createSyncAccessHandle(); 64 64 std::optional<FileSystemStorageError> close(WebCore::FileSystemSyncAccessHandleIdentifier); 65 std::optional<WebCore::FileSystemSyncAccessHandleIdentifier> activeSyncAccessHandle() const { return m_activeSyncAccessHandle; } 65 66 66 67 private: -
trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageManager.cpp
r286569 r286601 29 29 #include "FileSystemStorageError.h" 30 30 #include "FileSystemStorageHandleRegistry.h" 31 #include "WebFileSystemStorageConnectionMessages.h" 31 32 32 33 namespace WebKit { … … 43 44 ASSERT(!RunLoop::isMain()); 44 45 45 for (auto identifier : m_handles.keys()) 46 m_registry.unregisterHandle(identifier); 46 close(); 47 47 } 48 48 … … 150 150 } 151 151 152 void FileSystemStorageManager::close() 153 { 154 ASSERT(!RunLoop::isMain()); 155 156 for (auto& [connectionID, identifiers] : m_handlesByConnection) { 157 for (auto identifier : identifiers) { 158 auto takenHandle = m_handles.take(identifier); 159 m_registry.unregisterHandle(identifier); 160 161 // Send message to web process to invalidate active sync access handle. 162 if (auto accessHandleIdentifier = takenHandle->activeSyncAccessHandle()) 163 IPC::Connection::send(connectionID, Messages::WebFileSystemStorageConnection::InvalidateAccessHandle(*accessHandleIdentifier), 0); 164 } 165 } 166 167 ASSERT(m_handles.isEmpty()); 168 m_handlesByConnection.clear(); 169 m_lockMap.clear(); 170 } 171 152 172 } // namespace WebKit -
trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageManager.h
r286569 r286601 50 50 51 51 private: 52 void close(); 53 52 54 String m_path; 53 55 FileSystemStorageHandleRegistry& m_registry; -
trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.cpp
r286569 r286601 32 32 #include "NetworkStorageManagerMessages.h" 33 33 #include "OriginStorageManager.h" 34 #include "WebsiteDataType.h" 34 35 #include <pal/crypto/CryptoDigest.h> 36 #include <wtf/Scope.h> 37 #include <wtf/persistence/PersistentDecoder.h> 38 #include <wtf/persistence/PersistentEncoder.h> 35 39 #include <wtf/text/Base64.h> 36 40 37 41 namespace WebKit { 42 43 static std::optional<WebCore::ClientOrigin> readOriginFromFile(const String& filePath) 44 { 45 ASSERT(!RunLoop::isMain()); 46 47 if (!FileSystem::fileExists(filePath)) 48 return std::nullopt; 49 50 auto originFileHandle = FileSystem::openFile(filePath, FileSystem::FileOpenMode::Read); 51 auto closeFile = makeScopeExit([&] { 52 FileSystem::closeFile(originFileHandle); 53 }); 54 55 if (!FileSystem::isHandleValid(originFileHandle)) 56 return std::nullopt; 57 58 auto originContent = FileSystem::readEntireFile(originFileHandle); 59 if (!originContent) 60 return std::nullopt; 61 62 WTF::Persistence::Decoder decoder({ originContent->data(), originContent->size() }); 63 std::optional<WebCore::ClientOrigin> origin; 64 decoder >> origin; 65 return origin; 66 } 67 68 static void writeOriginToFileIfNecessary(const String& filePath, const WebCore::ClientOrigin& origin) 69 { 70 if (FileSystem::fileExists(filePath)) 71 return; 72 73 FileSystem::makeAllDirectories(FileSystem::parentPath(filePath)); 74 auto originFileHandle = FileSystem::openFile(filePath, FileSystem::FileOpenMode::ReadWrite); 75 auto closeFile = makeScopeExit([&] { 76 FileSystem::closeFile(originFileHandle); 77 }); 78 79 if (!FileSystem::isHandleValid(originFileHandle)) { 80 LOG_ERROR("writeOriginToFileIfNecessary: Failed to open origin file"); 81 return; 82 } 83 84 WTF::Persistence::Encoder encoder; 85 encoder << origin; 86 FileSystem::writeToFile(originFileHandle, encoder.buffer(), encoder.bufferSize()); 87 } 88 89 static void deleteOriginFileIfNecessary(const String& filePath) 90 { 91 auto parentPath = FileSystem::parentPath(filePath); 92 auto children = FileSystem::listDirectory(parentPath); 93 if (children.size() == 1) 94 FileSystem::deleteFile(filePath); 95 } 38 96 39 97 Ref<NetworkStorageManager> NetworkStorageManager::create(PAL::SessionID sessionID, const String& path) … … 118 176 } 119 177 120 static String origin Path(const String& rootPath, const WebCore::ClientOrigin& origin, FileSystem::Salt salt)178 static String originDirectoryPath(const String& rootPath, const WebCore::ClientOrigin& origin, FileSystem::Salt salt) 121 179 { 122 180 if (rootPath.isEmpty()) … … 128 186 } 129 187 188 static String originFilePath(const String& directory) 189 { 190 return FileSystem::pathByAppendingComponent(directory, "origin"_s); 191 } 192 130 193 OriginStorageManager& NetworkStorageManager::localOriginStorageManager(const WebCore::ClientOrigin& origin) 131 194 { … … 133 196 134 197 return *m_localOriginStorageManagers.ensure(origin, [&] { 135 return makeUnique<OriginStorageManager>(originPath(m_path, origin, m_salt)); 198 auto originDirectory = originDirectoryPath(m_path, origin, m_salt); 199 writeOriginToFileIfNecessary(originFilePath(originDirectory), origin); 200 return makeUnique<OriginStorageManager>(WTFMove(originDirectory)); 136 201 }).iterator->value; 137 202 } 138 203 204 void NetworkStorageManager::removeOriginStorageManagerIfPossible(const WebCore::ClientOrigin& origin) 205 { 206 if (auto iterator = m_localOriginStorageManagers.find(origin); iterator != m_localOriginStorageManagers.end()) { 207 if (!iterator->value->isActive()) 208 m_localOriginStorageManagers.remove(iterator); 209 } 210 } 211 139 212 void NetworkStorageManager::persisted(const WebCore::ClientOrigin& origin, CompletionHandler<void(bool)>&& completionHandler) 140 213 { … … 148 221 ASSERT(!RunLoop::isMain()); 149 222 150 localOriginStorageManager(origin). persist();223 localOriginStorageManager(origin).setPersisted(true); 151 224 completionHandler(true); 152 225 } … … 157 230 158 231 m_queue->dispatch([this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)]() mutable { 159 m_localOriginStorageManagers.clear(); 160 m_sessionOriginStorageManagers.clear(); 232 // Reset persisted value. 233 for (auto& manager : m_localOriginStorageManagers.values()) 234 manager->setPersisted(false); 235 236 for (auto& manager : m_sessionOriginStorageManagers.values()) 237 manager->setPersisted(false); 161 238 162 239 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)]() mutable { … … 307 384 } 308 385 386 static std::optional<WebsiteDataType> toWebsiteDataType(const String& storageType) 387 { 388 if (storageType == "FileSystem") 389 return WebsiteDataType::FileSystem; 390 391 return std::nullopt; 392 } 393 394 void NetworkStorageManager::forEachOriginDirectory(const Function<void(const String&)>& apply) 395 { 396 for (auto& topOrigin : FileSystem::listDirectory(m_path)) { 397 auto topOriginDirectory = FileSystem::pathByAppendingComponent(m_path, topOrigin); 398 auto openingOrigins = FileSystem::listDirectory(topOriginDirectory); 399 if (openingOrigins.isEmpty()) { 400 FileSystem::deleteEmptyDirectory(topOriginDirectory); 401 continue; 402 } 403 404 for (auto& openingOrigin : openingOrigins) { 405 auto openingOriginDirectory = FileSystem::pathByAppendingComponent(topOriginDirectory, openingOrigin); 406 apply(openingOriginDirectory); 407 } 408 } 409 } 410 411 Vector<WebsiteData::Entry> NetworkStorageManager::fetchDataFromDisk(OptionSet<WebsiteDataType> targetTypes) 412 { 413 ASSERT(!RunLoop::isMain()); 414 415 HashMap<WebCore::SecurityOriginData, OptionSet<WebsiteDataType>> originTypes; 416 forEachOriginDirectory([&](auto directory) mutable { 417 auto origin = readOriginFromFile(originFilePath(directory)); 418 if (!origin) 419 return; 420 421 for (auto& storageType : FileSystem::listDirectory(directory)) { 422 if (auto type = toWebsiteDataType(storageType); type && targetTypes.contains(*type)) { 423 // Return both top origin and opening origin for this data. 424 originTypes.add(origin->clientOrigin, OptionSet<WebsiteDataType> { }).iterator->value.add(*type); 425 originTypes.add(origin->topOrigin, OptionSet<WebsiteDataType> { }).iterator->value.add(*type); 426 } 427 } 428 }); 429 430 Vector<WebsiteData::Entry> entries; 431 for (auto [origin, types] : originTypes) { 432 for (auto type : types) 433 entries.append({ WebsiteData::Entry { origin, type, 0 } }); 434 } 435 436 return entries; 437 } 438 439 void NetworkStorageManager::fetchData(OptionSet<WebsiteDataType> types, CompletionHandler<void(Vector<WebsiteData::Entry>&&)>&& completionHandler) 440 { 441 ASSERT(RunLoop::isMain()); 442 ASSERT(!m_closed); 443 444 m_queue->dispatch([this, protectedThis = Ref { *this }, types, completionHandler = WTFMove(completionHandler)]() mutable { 445 auto entries = fetchDataFromDisk(types); 446 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler), entries = crossThreadCopy(WTFMove(entries))]() mutable { 447 completionHandler(WTFMove(entries)); 448 }); 449 }); 450 } 451 452 Vector<WebCore::ClientOrigin> NetworkStorageManager::deleteDataOnDisk(OptionSet<WebsiteDataType> types, WallTime modifiedSinceTime, const Function<bool(const WebCore::ClientOrigin&)>& filter) 453 { 454 ASSERT(!RunLoop::isMain()); 455 456 Vector<WebCore::ClientOrigin> deletedOrigins; 457 forEachOriginDirectory([&](auto directory) mutable { 458 auto filePath = originFilePath(directory); 459 auto origin = readOriginFromFile(filePath); 460 if (!origin) { 461 // If origin cannot be retrieved, but we are asked to remove data for all origins, remove it. 462 RELEASE_LOG_ERROR(Storage, "NetworkStorageManager::deleteDataOnDisk failed to read origin from '%s'", filePath.utf8().data()); 463 if (filter(WebCore::ClientOrigin { })) { 464 auto tempOriginStorageManager = makeUnique<OriginStorageManager>(String { directory }); 465 tempOriginStorageManager->deleteData(types, modifiedSinceTime); 466 deleteOriginFileIfNecessary(filePath); 467 FileSystem::deleteEmptyDirectory(directory); 468 } 469 return; 470 } 471 472 if (!filter(*origin)) 473 return; 474 475 deletedOrigins.append(*origin); 476 localOriginStorageManager(*origin).deleteData(types, modifiedSinceTime); 477 removeOriginStorageManagerIfPossible(*origin); 478 deleteOriginFileIfNecessary(filePath); 479 FileSystem::deleteEmptyDirectory(directory); 480 }); 481 482 return deletedOrigins; 483 } 484 485 void NetworkStorageManager::deleteData(OptionSet<WebsiteDataType> types, const Vector<WebCore::SecurityOriginData>& origins, CompletionHandler<void()>&& completionHandler) 486 { 487 ASSERT(RunLoop::isMain()); 488 ASSERT(!m_closed); 489 490 m_queue->dispatch([this, protectedThis = Ref { *this }, types, origins = crossThreadCopy(origins), completionHandler = WTFMove(completionHandler)]() mutable { 491 HashSet<WebCore::SecurityOriginData> originSet; 492 originSet.reserveInitialCapacity(origins.size()); 493 for (auto origin : origins) 494 originSet.add(WTFMove(origin)); 495 496 deleteDataOnDisk(types, -WallTime::infinity(), [&originSet](auto origin) { 497 return originSet.contains(origin.topOrigin) || originSet.contains(origin.clientOrigin); 498 }); 499 500 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)]() mutable { 501 completionHandler(); 502 }); 503 }); 504 } 505 506 void NetworkStorageManager::deleteDataModifiedSince(OptionSet<WebsiteDataType> types, WallTime modifiedSinceTime, CompletionHandler<void()>&& completionHandler) 507 { 508 ASSERT(RunLoop::isMain()); 509 ASSERT(!m_closed); 510 511 m_queue->dispatch([this, protectedThis = Ref { *this }, types, modifiedSinceTime, completionHandler = WTFMove(completionHandler)]() mutable { 512 deleteDataOnDisk(types, modifiedSinceTime, [](auto&) { 513 return true; 514 }); 515 516 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)]() mutable { 517 completionHandler(); 518 }); 519 }); 520 } 521 522 void NetworkStorageManager::deleteDataForRegistrableDomains(OptionSet<WebsiteDataType> types, const Vector<WebCore::RegistrableDomain>& domains, CompletionHandler<void(HashSet<WebCore::RegistrableDomain>&&)>&& completionHandler) 523 { 524 ASSERT(RunLoop::isMain()); 525 ASSERT(!m_closed); 526 527 m_queue->dispatch([this, protectedThis = Ref { *this }, types, domains = crossThreadCopy(domains), completionHandler = WTFMove(completionHandler)]() mutable { 528 auto deletedOrigins = deleteDataOnDisk(types, -WallTime::infinity(), [&domains](auto& origin) { 529 auto domain = WebCore::RegistrableDomain::uncheckedCreateFromHost(origin.clientOrigin.host); 530 return domains.contains(domain); 531 }); 532 533 HashSet<WebCore::RegistrableDomain> deletedDomains; 534 for (auto origin : deletedOrigins) { 535 auto domain = WebCore::RegistrableDomain::uncheckedCreateFromHost(origin.clientOrigin.host); 536 deletedDomains.add(domain); 537 } 538 539 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler), domains = crossThreadCopy(WTFMove(deletedDomains))]() mutable { 540 completionHandler(WTFMove(domains)); 541 }); 542 }); 543 } 544 309 545 } // namespace WebKit 310 546 -
trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.h
r286569 r286601 29 29 #include "FileSystemStorageError.h" 30 30 #include "OriginStorageManager.h" 31 #include "WebsiteData.h" 31 32 #include <WebCore/ClientOrigin.h> 32 33 #include <WebCore/FileSystemHandleIdentifier.h> 33 34 #include <WebCore/FileSystemSyncAccessHandleIdentifier.h> 34 35 #include <pal/SessionID.h> 36 #include <wtf/Forward.h> 35 37 36 38 namespace IPC { … … 56 58 void close(); 57 59 void clearStorageForTesting(CompletionHandler<void()>&&); 60 void fetchData(OptionSet<WebsiteDataType>, CompletionHandler<void(Vector<WebsiteData::Entry>&&)>&&); 61 void deleteData(OptionSet<WebsiteDataType>, const Vector<WebCore::SecurityOriginData>&, CompletionHandler<void()>&&); 62 void deleteDataModifiedSince(OptionSet<WebsiteDataType>, WallTime, CompletionHandler<void()>&&); 63 void deleteDataForRegistrableDomains(OptionSet<WebsiteDataType>, const Vector<WebCore::RegistrableDomain>&, CompletionHandler<void(HashSet<WebCore::RegistrableDomain>&&)>&&); 58 64 59 65 private: … … 61 67 ~NetworkStorageManager(); 62 68 OriginStorageManager& localOriginStorageManager(const WebCore::ClientOrigin&); 69 void removeOriginStorageManagerIfPossible(const WebCore::ClientOrigin&); 63 70 FileSystemStorageHandleRegistry& fileSystemStorageHandleRegistry(); 71 72 void forEachOriginDirectory(const Function<void(const String&)>&); 73 Vector<WebsiteData::Entry> fetchDataFromDisk(OptionSet<WebsiteDataType>); 74 Vector<WebCore::ClientOrigin> deleteDataOnDisk(OptionSet<WebsiteDataType>, WallTime, const Function<bool(const WebCore::ClientOrigin&)>&); 64 75 65 76 // IPC::MessageReceiver (implemented by generated code) -
trunk/Source/WebKit/NetworkProcess/storage/OriginStorageManager.cpp
r286569 r286601 52 52 } 53 53 54 String typeStoragePath(const String& storageIdentifier) const 54 enum class StorageType : uint8_t { 55 FileSystem, 56 }; 57 58 static String toStorageIdentifier(StorageType type) 55 59 { 56 return m_rootPath.isEmpty() ? emptyString() : FileSystem::pathByAppendingComponent(m_rootPath, storageIdentifier); 60 switch (type) { 61 case StorageType::FileSystem: 62 return "FileSystem"_s; 63 default: 64 break; 65 } 66 ASSERT_NOT_REACHED(); 67 return ""_s; 68 } 69 70 String typeStoragePath(StorageType type) const 71 { 72 auto storageIdentifier = toStorageIdentifier(type); 73 if (m_rootPath.isEmpty() || storageIdentifier.isEmpty()) 74 return emptyString(); 75 76 return FileSystem::pathByAppendingComponent(m_rootPath, storageIdentifier); 57 77 } 58 78 … … 60 80 { 61 81 if (!m_fileSystemStorageManager) 62 m_fileSystemStorageManager = makeUnique<FileSystemStorageManager>(typeStoragePath( "FileSystem"), registry);82 m_fileSystemStorageManager = makeUnique<FileSystemStorageManager>(typeStoragePath(StorageType::FileSystem), registry); 63 83 64 84 return *m_fileSystemStorageManager; 65 85 } 66 86 87 bool isActive() 88 { 89 return !!m_fileSystemStorageManager; 90 } 91 92 void deleteData(OptionSet<WebsiteDataType> types, WallTime modifiedSinceTime) 93 { 94 if (types.contains(WebsiteDataType::FileSystem)) 95 deleteFileSystemStorageData(modifiedSinceTime); 96 } 97 67 98 private: 99 void deleteFileSystemStorageData(WallTime modifiedSinceTime) 100 { 101 m_fileSystemStorageManager = nullptr; 102 103 auto fileSystemStoragePath = typeStoragePath(StorageType::FileSystem); 104 FileSystem::deleteAllFilesModifiedSince(fileSystemStoragePath, modifiedSinceTime); 105 } 106 68 107 String m_rootPath; 69 108 String m_identifier; … … 75 114 : m_path(WTFMove(path)) 76 115 { 116 ASSERT(!RunLoop::isMain()); 77 117 } 78 118 … … 93 133 } 94 134 95 void OriginStorageManager::persist()96 {97 m_persisted = true;98 defaultBucket().setMode(StorageBucketMode::Persistent);99 }100 101 135 FileSystemStorageManager& OriginStorageManager::fileSystemStorageManager(FileSystemStorageHandleRegistry& registry) 102 136 { … … 104 138 } 105 139 140 bool OriginStorageManager::isActive() 141 { 142 return defaultBucket().isActive(); 143 } 144 145 void OriginStorageManager::deleteData(OptionSet<WebsiteDataType> types, WallTime modifiedSince) 146 { 147 ASSERT(!RunLoop::isMain()); 148 defaultBucket().deleteData(types, modifiedSince); 149 } 150 151 void OriginStorageManager::setPersisted(bool value) 152 { 153 ASSERT(!RunLoop::isMain()); 154 155 m_persisted = value; 156 defaultBucket().setMode(value ? StorageBucketMode::Persistent : StorageBucketMode::BestEffort); 157 } 158 106 159 } // namespace WebKit 107 160 -
trunk/Source/WebKit/NetworkProcess/storage/OriginStorageManager.h
r286569 r286601 29 29 #include <wtf/text/WTFString.h> 30 30 31 namespace WebCore { 32 struct ClientOrigin; 33 } 34 31 35 namespace WebKit { 32 36 33 37 class FileSystemStorageHandleRegistry; 34 38 class FileSystemStorageManager; 39 enum class WebsiteDataType : uint32_t; 35 40 36 41 class OriginStorageManager { … … 42 47 void connectionClosed(IPC::Connection::UniqueID); 43 48 bool persisted() const { return m_persisted; } 44 void persist();49 void setPersisted(bool value); 45 50 FileSystemStorageManager& fileSystemStorageManager(FileSystemStorageHandleRegistry&); 51 bool isActive(); 52 void deleteData(OptionSet<WebsiteDataType>, WallTime); 46 53 47 54 private: … … 49 56 class StorageBucket; 50 57 StorageBucket& defaultBucket(); 58 59 void createOriginFileIfNecessary(const WebCore::ClientOrigin&); 60 void deleteOriginFileIfNecessary(); 51 61 52 62 std::unique_ptr<StorageBucket> m_defaultBucket; -
trunk/Source/WebKit/Shared/WebsiteData/WebsiteData.cpp
r286569 r286601 130 130 return WebsiteDataProcessType::Network; 131 131 #endif 132 case WebsiteDataType::FileSystem: 133 return WebsiteDataProcessType::Network; 132 134 } 133 135 -
trunk/Source/WebKit/Shared/WebsiteData/WebsiteDataType.h
r286569 r286601 53 53 AlternativeServices = 1 << 18, 54 54 #endif 55 FileSystem = 1 << 19, 55 56 }; 56 57 … … 80 81 WebKit::WebsiteDataType::DOMCache, 81 82 WebKit::WebsiteDataType::DeviceIdHashSalt, 82 WebKit::WebsiteDataType::PrivateClickMeasurements 83 WebKit::WebsiteDataType::PrivateClickMeasurements, 83 84 #if HAVE(CFNETWORK_ALTERNATIVE_SERVICE) 84 , WebKit::WebsiteDataType::AlternativeServices85 WebKit::WebsiteDataType::AlternativeServices, 85 86 #endif 87 WebKit::WebsiteDataType::FileSystem 86 88 >; 87 89 }; -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataRecord.mm
r286569 r286601 52 52 NSString * const _WKWebsiteDataTypePrivateClickMeasurements = @"_WKWebsiteDataTypePrivateClickMeasurements"; 53 53 NSString * const _WKWebsiteDataTypeAlternativeServices = @"_WKWebsiteDataTypeAlternativeServices"; 54 NSString * const _WKWebsiteDataTypeFileSystem = @"_WKWebsiteDataTypeFileSystem"; 54 55 55 56 #if PLATFORM(MAC) … … 111 112 if ([dataTypes containsObject:_WKWebsiteDataTypeAlternativeServices]) 112 113 [array addObject:@"Alternative Services"]; 114 if ([dataTypes containsObject:_WKWebsiteDataTypeFileSystem]) 115 [array addObject:@"File System"]; 113 116 114 117 return [array componentsJoinedByString:@", "]; -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataRecordInternal.h
r286569 r286601 78 78 return WebsiteDataType::AlternativeServices; 79 79 #endif 80 if ([websiteDataType isEqualToString:_WKWebsiteDataTypeFileSystem]) 81 return WebsiteDataType::FileSystem; 80 82 return std::nullopt; 81 83 } … … 135 137 [wkWebsiteDataTypes addObject:_WKWebsiteDataTypeAlternativeServices]; 136 138 #endif 139 if (websiteDataTypes.contains(WebsiteDataType::FileSystem)) 140 [wkWebsiteDataTypes addObject:_WKWebsiteDataTypeFileSystem]; 137 141 138 142 return wkWebsiteDataTypes; -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataRecordPrivate.h
r286569 r286601 38 38 WK_EXTERN NSString * const _WKWebsiteDataTypePrivateClickMeasurements WK_API_AVAILABLE(macos(12.0), ios(15.0)); 39 39 WK_EXTERN NSString * const _WKWebsiteDataTypeAlternativeServices WK_API_AVAILABLE(macos(11.0), ios(14.0)); 40 WK_EXTERN NSString * const _WKWebsiteDataTypeFileSystem WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); 40 41 41 42 #if !TARGET_OS_IPHONE -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
r286569 r286601 249 249 _WKWebsiteDataTypeAdClickAttributions, 250 250 _WKWebsiteDataTypePrivateClickMeasurements, 251 _WKWebsiteDataTypeAlternativeServices 251 _WKWebsiteDataTypeAlternativeServices, 252 _WKWebsiteDataTypeFileSystem 252 253 #if !TARGET_OS_IPHONE 253 254 , _WKWebsiteDataTypePlugInData -
trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj
r286596 r286601 1505 1505 93D6B7B925534A170058DD3A /* WKSpeechRecognitionPermissionCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D6B7B725534A110058DD3A /* WKSpeechRecognitionPermissionCallback.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1506 1506 93E6A4EE1BC5DD3900F8A0E7 /* _WKHitTestResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 93E6A4ED1BC5DD3900F8A0E7 /* _WKHitTestResult.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1507 93E799852756FA550074008A /* WebFileSystemStorageConnectionMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93E799822756FA540074008A /* WebFileSystemStorageConnectionMessageReceiver.cpp */; }; 1508 93E799872756FAB40074008A /* WebFileSystemStorageConnectionMessagesReplies.h in Headers */ = {isa = PBXBuildFile; fileRef = 93E799832756FA540074008A /* WebFileSystemStorageConnectionMessagesReplies.h */; }; 1509 93E799882756FAC20074008A /* WebFileSystemStorageConnectionMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 93E799812756FA530074008A /* WebFileSystemStorageConnectionMessages.h */; }; 1507 1510 93F549B41E3174B7000E7239 /* WKSnapshotConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F549B31E3174B7000E7239 /* WKSnapshotConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1508 1511 950F2880252414EA00B74F1C /* WKMouseDeviceObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 950F287E252414E900B74F1C /* WKMouseDeviceObserver.h */; }; … … 5324 5327 93D6B7B825534A120058DD3A /* WKSpeechRecognitionPermissionCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKSpeechRecognitionPermissionCallback.cpp; sourceTree = "<group>"; }; 5325 5328 93E6A4ED1BC5DD3900F8A0E7 /* _WKHitTestResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKHitTestResult.h; sourceTree = "<group>"; }; 5329 93E7997E2756F6700074008A /* WebFileSystemStorageConnection.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebFileSystemStorageConnection.messages.in; sourceTree = "<group>"; }; 5330 93E799812756FA530074008A /* WebFileSystemStorageConnectionMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebFileSystemStorageConnectionMessages.h; sourceTree = "<group>"; }; 5331 93E799822756FA540074008A /* WebFileSystemStorageConnectionMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebFileSystemStorageConnectionMessageReceiver.cpp; sourceTree = "<group>"; }; 5332 93E799832756FA540074008A /* WebFileSystemStorageConnectionMessagesReplies.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebFileSystemStorageConnectionMessagesReplies.h; sourceTree = "<group>"; }; 5326 5333 93F549B31E3174B7000E7239 /* WKSnapshotConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKSnapshotConfiguration.h; sourceTree = "<group>"; }; 5327 5334 93F549B51E3174DA000E7239 /* WKSnapshotConfiguration.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKSnapshotConfiguration.mm; sourceTree = "<group>"; }; … … 10629 10636 9354242B2703BDCB005CA72C /* WebFileSystemStorageConnection.cpp */, 10630 10637 9354242A2703BDCB005CA72C /* WebFileSystemStorageConnection.h */, 10638 93E7997E2756F6700074008A /* WebFileSystemStorageConnection.messages.in */, 10631 10639 BC111A58112F4FBB00337BAB /* WebFrameLoaderClient.cpp */, 10632 10640 BC032D6A10F4378D0058C15A /* WebFrameLoaderClient.h */, … … 12106 12114 E3866B042399979C00F88FE9 /* WebDeviceOrientationUpdateProviderProxyMessageReceiver.cpp */, 12107 12115 E3866B052399979C00F88FE9 /* WebDeviceOrientationUpdateProviderProxyMessages.h */, 12116 93E799822756FA540074008A /* WebFileSystemStorageConnectionMessageReceiver.cpp */, 12117 93E799812756FA530074008A /* WebFileSystemStorageConnectionMessages.h */, 12118 93E799832756FA540074008A /* WebFileSystemStorageConnectionMessagesReplies.h */, 12108 12119 CD73BA48131ACD8E00EEDED2 /* WebFullScreenManagerMessageReceiver.cpp */, 12109 12120 CD73BA49131ACD8E00EEDED2 /* WebFullScreenManagerMessages.h */, … … 13352 13363 BC111B5D112F629800337BAB /* WebEventFactory.h in Headers */, 13353 13364 9354242C2703BDCB005CA72C /* WebFileSystemStorageConnection.h in Headers */, 13365 93E799882756FAC20074008A /* WebFileSystemStorageConnectionMessages.h in Headers */, 13366 93E799872756FAB40074008A /* WebFileSystemStorageConnectionMessagesReplies.h in Headers */, 13354 13367 1A90C1EE1264FD50003E44D4 /* WebFindOptions.h in Headers */, 13355 13368 BCE469541214E6CB000B98EB /* WebFormClient.h in Headers */, … … 15480 15493 E3866B092399A2D500F88FE9 /* WebDeviceOrientationUpdateProviderProxyMessageReceiver.cpp in Sources */, 15481 15494 2D92A789212B6AB100F493FD /* WebEvent.cpp in Sources */, 15495 93E799852756FA550074008A /* WebFileSystemStorageConnectionMessageReceiver.cpp in Sources */, 15482 15496 CD73BA4E131ACDB700EEDED2 /* WebFullScreenManagerMessageReceiver.cpp in Sources */, 15483 15497 CD73BA47131ACC9A00EEDED2 /* WebFullScreenManagerProxyMessageReceiver.cpp in Sources */, -
trunk/Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp
r286569 r286601 38 38 #include "WebCookieJar.h" 39 39 #include "WebCoreArgumentCoders.h" 40 #include "WebFileSystemStorageConnection.h" 41 #include "WebFileSystemStorageConnectionMessages.h" 40 42 #include "WebFrame.h" 41 43 #include "WebIDBConnectionToServer.h" … … 120 122 return; 121 123 } 124 if (decoder.messageReceiverName() == Messages::WebFileSystemStorageConnection::messageReceiverName()) { 125 WebProcess::singleton().fileSystemStorageConnection().didReceiveMessage(connection, decoder); 126 return; 127 } 122 128 123 129 #if USE(LIBWEBRTC) -
trunk/Tools/ChangeLog
r286600 r286601 1 2021-12-07 Sihui Liu <sihui_liu@apple.com> 2 3 Fetch and remove file system data via WKWebsiteDataStore 4 https://bugs.webkit.org/show_bug.cgi?id=233567 5 <rdar://problem/86029185> 6 7 Reviewed by Youenn Fablet. 8 9 * TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm: 10 1 11 2021-12-07 Jonathan Bedard <jbedard@apple.com> 2 12 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm
r286569 r286601 30 30 #import "DeprecatedGlobalValues.h" 31 31 #import "PlatformUtilities.h" 32 #import "TestUIDelegate.h" 32 33 #import "TestURLSchemeHandler.h" 33 34 #import "TestWKWebView.h" … … 35 36 #import <WebKit/WKWebViewConfigurationPrivate.h> 36 37 #import <WebKit/WKWebViewPrivate.h> 38 #import <WebKit/WKWebsiteDataRecordPrivate.h> 37 39 38 40 @interface FileSystemAccessMessageHandler : NSObject <WKScriptMessageHandler> … … 49 51 @end 50 52 51 static NSString * mainFrameString = @"<script> \53 static NSString *workerFrameString = @"<script> \ 52 54 function start() { \ 53 55 var worker = new Worker('worker.js'); \ … … 116 118 117 119 auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]); 118 [webView loadHTMLString: mainFrameString baseURL:[NSURL URLWithString:@"webkit://webkit.org"]];120 [webView loadHTMLString:workerFrameString baseURL:[NSURL URLWithString:@"webkit://webkit.org"]]; 119 121 TestWebKitAPI::Util::run(&receivedScriptMessage); 120 122 receivedScriptMessage = false; … … 127 129 128 130 auto secondWebView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]); 129 [secondWebView loadHTMLString: mainFrameString baseURL:[NSURL URLWithString:@"webkit://webkit.org"]];131 [secondWebView loadHTMLString:workerFrameString baseURL:[NSURL URLWithString:@"webkit://webkit.org"]]; 130 132 TestWebKitAPI::Util::run(&receivedScriptMessage); 131 133 receivedScriptMessage = false; … … 169 171 170 172 auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]); 171 [webView loadHTMLString: mainFrameString baseURL:[NSURL URLWithString:@"webkit://webkit.org"]];173 [webView loadHTMLString:workerFrameString baseURL:[NSURL URLWithString:@"webkit://webkit.org"]]; 172 174 TestWebKitAPI::Util::run(&receivedScriptMessage); 173 175 receivedScriptMessage = false; … … 259 261 } 260 262 263 static NSString *testString = @"<script> \ 264 async function open(shouldCreateFile) \ 265 { \ 266 try { \ 267 var rootHandle = await navigator.storage.getDirectory(); \ 268 var fileHandle = await rootHandle.getFileHandle('file-system-access.txt', { 'create' : shouldCreateFile }); \ 269 window.webkit.messageHandlers.testHandler.postMessage('file is opened'); \ 270 } catch(err) { \ 271 window.webkit.messageHandlers.testHandler.postMessage('error: ' + err.name + ' - ' + err.message); \ 272 } \ 273 } \ 274 open(true); \ 275 </script>"; 276 277 TEST(FileSystemAccess, FetchAndRemoveData) 278 { 279 auto handler = adoptNS([[FileSystemAccessMessageHandler alloc] init]); 280 auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 281 [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"]; 282 auto websiteDataStore = [configuration websiteDataStore]; 283 auto types = [NSSet setWithObject:_WKWebsiteDataTypeFileSystem]; 284 285 // Remove existing data. 286 done = false; 287 [websiteDataStore removeDataOfTypes:types modifiedSince:[NSDate distantPast] completionHandler:^ { 288 done = true; 289 }]; 290 TestWebKitAPI::Util::run(&done); 291 292 auto preferences = [configuration preferences]; 293 preferences._fileSystemAccessEnabled = YES; 294 preferences._storageAPIEnabled = YES; 295 auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]); 296 [webView loadHTMLString:testString baseURL:[NSURL URLWithString:@"https://webkit.org"]]; 297 TestWebKitAPI::Util::run(&receivedScriptMessage); 298 receivedScriptMessage = false; 299 EXPECT_WK_STREQ(@"file is opened", [lastScriptMessage body]); 300 301 // Fetch data and remove it by origin. 302 done = false; 303 [websiteDataStore fetchDataRecordsOfTypes:types completionHandler:^(NSArray<WKWebsiteDataRecord *> *records) { 304 EXPECT_EQ(records.count, 1u); 305 auto record = [records objectAtIndex:0]; 306 EXPECT_STREQ("webkit.org", [record.displayName UTF8String]); 307 308 // Remove data. 309 [websiteDataStore removeDataOfTypes:types forDataRecords:records completionHandler:^{ 310 done = true; 311 }]; 312 }]; 313 TestWebKitAPI::Util::run(&done); 314 315 // Fetch data after removal. 316 done = false; 317 [websiteDataStore fetchDataRecordsOfTypes:types completionHandler:^(NSArray<WKWebsiteDataRecord *> *records) { 318 EXPECT_EQ(records.count, 0u); 319 done = true; 320 }]; 321 322 // File cannot be opened after data removal. 323 [webView evaluateJavaScript:@"open(false)" completionHandler:nil]; 324 TestWebKitAPI::Util::run(&receivedScriptMessage); 325 receivedScriptMessage = false; 326 EXPECT_WK_STREQ(@"error: NotFoundError - The object can not be found here.", [lastScriptMessage body]); 327 } 328 329 TEST(FileSystemAccess, RemoveDataByModificationTime) 330 { 331 auto handler = adoptNS([[FileSystemAccessMessageHandler alloc] init]); 332 auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 333 [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"]; 334 auto preferences = [configuration preferences]; 335 preferences._fileSystemAccessEnabled = YES; 336 preferences._storageAPIEnabled = YES; 337 auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]); 338 [webView loadHTMLString:testString baseURL:[NSURL URLWithString:@"https://webkit.org"]]; 339 TestWebKitAPI::Util::run(&receivedScriptMessage); 340 receivedScriptMessage = false; 341 EXPECT_WK_STREQ(@"file is opened", [lastScriptMessage body]); 342 343 auto websiteDataStore = [configuration websiteDataStore]; 344 auto types = [NSSet setWithObject:_WKWebsiteDataTypeFileSystem]; 345 done = false; 346 __block NSUInteger recordsCount; 347 [websiteDataStore fetchDataRecordsOfTypes:types completionHandler:^(NSArray<WKWebsiteDataRecord *> *records) { 348 recordsCount = records.count; 349 EXPECT_GT(recordsCount, 0u); 350 done = true; 351 }]; 352 TestWebKitAPI::Util::run(&done); 353 354 done = false; 355 [websiteDataStore removeDataOfTypes:types modifiedSince:[NSDate now] completionHandler:^ { 356 [websiteDataStore fetchDataRecordsOfTypes:types completionHandler:^(NSArray<WKWebsiteDataRecord *> *records) { 357 recordsCount = records.count; 358 EXPECT_EQ(records.count, recordsCount); 359 done = true; 360 }]; 361 }]; 362 TestWebKitAPI::Util::run(&done); 363 364 done = false; 365 [websiteDataStore removeDataOfTypes:types modifiedSince:[NSDate distantPast] completionHandler:^ { 366 [websiteDataStore fetchDataRecordsOfTypes:types completionHandler:^(NSArray<WKWebsiteDataRecord *> *records) { 367 EXPECT_EQ(records.count, 0u); 368 done = true; 369 }]; 370 }]; 371 TestWebKitAPI::Util::run(&done); 372 } 373 374 static NSString *mainFrameString = @"<script> \ 375 function postResult(event) \ 376 { \ 377 window.webkit.messageHandlers.testHandler.postMessage(event.data); \ 378 } \ 379 addEventListener('message', postResult, false); \ 380 </script> \ 381 <iframe src='https://127.0.0.1:9091/'>"; 382 383 static const char* frameBytes = R"TESTRESOURCE( 384 <script> 385 function postMessage(message) 386 { 387 parent.postMessage(message, '*'); 388 } 389 async function open() 390 { 391 try { 392 var rootHandle = await navigator.storage.getDirectory(); 393 var fileHandle = await rootHandle.getFileHandle('file-system-access.txt', { 'create' : true }); 394 postMessage('file is opened'); 395 } catch(err) { 396 postMessage('error: ' + err.name + ' - ' + err.message); 397 } 398 } 399 open(); 400 </script> 401 )TESTRESOURCE"; 402 403 TEST(FileSystemAccess, FetchDataForThirdParty) 404 { 405 TestWebKitAPI::HTTPServer server({ 406 { "/", { frameBytes } }, 407 }, TestWebKitAPI::HTTPServer::Protocol::Https, nullptr, nullptr, 9091); 408 409 auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 410 auto handler = adoptNS([[FileSystemAccessMessageHandler alloc] init]); 411 [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"]; 412 auto preferences = [configuration preferences]; 413 preferences._fileSystemAccessEnabled = YES; 414 preferences._storageAPIEnabled = YES; 415 416 auto websiteDataStore = [configuration websiteDataStore]; 417 auto types = [NSSet setWithObject:_WKWebsiteDataTypeFileSystem]; 418 done = false; 419 [websiteDataStore removeDataOfTypes:types modifiedSince:[NSDate distantPast] completionHandler:^ { 420 done = true; 421 }]; 422 TestWebKitAPI::Util::run(&done); 423 424 auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]); 425 auto navigationDelegate = adoptNS([TestNavigationDelegate new]); 426 [navigationDelegate setDidReceiveAuthenticationChallenge:^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^callback)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) { 427 EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust); 428 callback(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); 429 }]; 430 [navigationDelegate setDecidePolicyForNavigationAction:[&](WKNavigationAction *action, void (^decisionHandler)(WKNavigationActionPolicy)) { 431 decisionHandler(WKNavigationActionPolicyAllow); 432 }]; 433 [webView setNavigationDelegate:navigationDelegate.get()]; 434 435 [webView loadHTMLString:mainFrameString baseURL:[NSURL URLWithString:@"https://webkit.org"]]; 436 TestWebKitAPI::Util::run(&receivedScriptMessage); 437 receivedScriptMessage = false; 438 EXPECT_WK_STREQ(@"file is opened", [lastScriptMessage body]); 439 440 done = false; 441 [websiteDataStore fetchDataRecordsOfTypes:types completionHandler:^(NSArray<WKWebsiteDataRecord *> *records) { 442 // Should return both opening origin and top origin. 443 EXPECT_EQ(records.count, 2u); 444 auto sortFunction = ^(WKWebsiteDataRecord *record1, WKWebsiteDataRecord *record2){ 445 return [record1.displayName compare:record2.displayName]; 446 }; 447 auto sortedRecords = [records sortedArrayUsingComparator:sortFunction]; 448 EXPECT_WK_STREQ(@"127.0.0.1", [sortedRecords objectAtIndex:0].displayName); 449 EXPECT_WK_STREQ(@"webkit.org", [sortedRecords objectAtIndex:1].displayName); 450 done = true; 451 }]; 452 TestWebKitAPI::Util::run(&done); 453 } 454 261 455 #endif // USE(APPLE_INTERNAL_SDK)
Note:
See TracChangeset
for help on using the changeset viewer.