Changeset 286507 in webkit
- Timestamp:
- Dec 3, 2021, 12:17:15 PM (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) (1 diff)
-
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) (5 diffs)
-
Source/WebKit/NetworkProcess/storage/NetworkStorageManager.h (modified) (3 diffs)
-
Source/WebKit/NetworkProcess/storage/OriginStorageManager.cpp (modified) (4 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
r286504 r286507 1 2021-12-03 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 6 Reviewed by Youenn Fablet. 7 8 * wtf/FileSystem.cpp: 9 (WTF::FileSystemImpl::readEntireFile): Read whole file content into a Vector. 10 (WTF::FileSystemImpl::deleteAllFilesModifiedSince): Recursively delete files and folders modified after 11 specified time in a directory. 12 * wtf/FileSystem.h: 13 1 14 2021-12-03 Tim Horton <timothy_horton@apple.com> 2 15 -
trunk/Source/WTF/wtf/FileSystem.cpp
r281694 r286507 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
r284156 r286507 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
r286500 r286507 1 2021-12-03 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 6 Reviewed by Youenn Fablet. 7 8 * Modules/filesystemaccess/FileSystemStorageConnection.h: 9 1 10 2021-12-03 Alan Bujtas <zalan@apple.com> 2 11 -
trunk/Source/WebCore/Modules/filesystemaccess/FileSystemStorageConnection.h
r286414 r286507 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
r286455 r286507 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
r286505 r286507 1 2021-12-03 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 6 Reviewed by Youenn Fablet. 7 8 Introduce a new WebsiteDataType value FileSystem for FileSystemAccess data. Network process now can fetch and 9 delete this type of data when fetching and deleteing website data (if FileSystem type is included in target 10 types). 11 12 To track origins that have FileSystem data, this patch introduces a new file named origin in the origin's 13 directory. This file will be created when OriginStorageManager is created. 14 15 To delete existing FileSystem data, network process finds origins that are requested to be deleted and have data 16 on disk, closes active access handles, and deletes the files. The origin file mentioned above will be deleted if 17 there is no other file left in the same directory, and empty directories will be deleted. 18 19 New API tests: FileSystemAccess.FetchAndRemoveData 20 FileSystemAccess.RemoveDataByModificationTime 21 FileSystemAccess.FetchDataForThirdParty 22 23 * CMakeLists.txt: 24 * DerivedSources-input.xcfilelist: 25 * DerivedSources-output.xcfilelist: 26 * DerivedSources.make: 27 * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp: 28 (WebKit::WebResourceLoadStatisticsStore::monitoredDataTypes): 29 * NetworkProcess/NetworkProcess.cpp: 30 (WebKit::NetworkProcess::fetchWebsiteData): 31 (WebKit::NetworkProcess::deleteWebsiteData): 32 (WebKit::NetworkProcess::deleteWebsiteDataForOrigins): 33 (WebKit::NetworkProcess::deleteAndRestrictWebsiteDataForRegistrableDomains): 34 (WebKit::NetworkProcess::registrableDomainsWithWebsiteData): 35 * NetworkProcess/storage/FileSystemStorageHandle.h: 36 (WebKit::FileSystemStorageHandle::activeSyncAccessHandle const): 37 * NetworkProcess/storage/FileSystemStorageManager.cpp: 38 (WebKit::FileSystemStorageManager::~FileSystemStorageManager): 39 (WebKit::FileSystemStorageManager::close): 40 * NetworkProcess/storage/FileSystemStorageManager.h: 41 * NetworkProcess/storage/NetworkStorageManager.cpp: 42 (WebKit::readOriginFromFile): 43 (WebKit::writeOriginToFileIfNecessary): 44 (WebKit::deleteOriginFileIfNecessary): 45 (WebKit::originDirectoryPath): 46 (WebKit::originFilePath): 47 (WebKit::NetworkStorageManager::localOriginStorageManager): 48 (WebKit::NetworkStorageManager::removeOriginStorageManagerIfPossible): 49 (WebKit::toWebsiteDataType): 50 (WebKit::NetworkStorageManager::forEachOriginDirectory): 51 (WebKit::NetworkStorageManager::fetchDataFromDisk): 52 (WebKit::NetworkStorageManager::fetchData): 53 (WebKit::NetworkStorageManager::deleteDataOnDisk): 54 (WebKit::NetworkStorageManager::deleteData): 55 (WebKit::NetworkStorageManager::deleteDataModifiedSince): 56 (WebKit::NetworkStorageManager::deleteDataForRegistrableDomains): 57 (WebKit::originPath): Deleted. 58 * NetworkProcess/storage/NetworkStorageManager.h: 59 * NetworkProcess/storage/OriginStorageManager.cpp: 60 (WebKit::OriginStorageManager::StorageBucket::toStorageIdentifier): 61 (WebKit::OriginStorageManager::StorageBucket::typeStoragePath const): 62 (WebKit::OriginStorageManager::StorageBucket::fileSystemStorageManager): 63 (WebKit::OriginStorageManager::StorageBucket::isActive): 64 (WebKit::OriginStorageManager::StorageBucket::deleteData): 65 (WebKit::OriginStorageManager::StorageBucket::deleteFileSystemStorageData): 66 (WebKit::OriginStorageManager::OriginStorageManager): 67 (WebKit::OriginStorageManager::isActive): 68 (WebKit::OriginStorageManager::deleteData): 69 * NetworkProcess/storage/OriginStorageManager.h: 70 * Shared/WebsiteData/WebsiteData.cpp: 71 (WebKit::WebsiteData::ownerProcess): 72 * Shared/WebsiteData/WebsiteDataType.h: 73 * UIProcess/API/Cocoa/WKWebsiteDataRecord.mm: 74 (dataTypesToString): 75 * UIProcess/API/Cocoa/WKWebsiteDataRecordInternal.h: 76 (WebKit::toWebsiteDataType): 77 (WebKit::toWKWebsiteDataTypes): 78 * UIProcess/API/Cocoa/WKWebsiteDataRecordPrivate.h: 79 * UIProcess/API/Cocoa/WKWebsiteDataStore.mm: 80 (+[WKWebsiteDataStore _allWebsiteDataTypesIncludingPrivate]): 81 * WebKit.xcodeproj/project.pbxproj: 82 * WebProcess/Network/NetworkProcessConnection.cpp: 83 (WebKit::NetworkProcessConnection::didReceiveMessage): 84 * WebProcess/WebCoreSupport/WebFileSystemStorageConnection.messages.in: Added. 85 1 86 2021-12-03 Chris Dumez <cdumez@apple.com> 2 87 -
trunk/Source/WebKit/DerivedSources-input.xcfilelist
r286455 r286507 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
r286455 r286507 494 494 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/WebDeviceOrientationUpdateProviderProxyMessages.h 495 495 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/WebDeviceOrientationUpdateProviderProxyMessagesReplies.h 496 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/WebFileSystemStorageConnectionMessageReceiver.cpp 497 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/WebFileSystemStorageConnectionMessages.h 498 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/WebFileSystemStorageConnectionMessagesReplies.h 496 499 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/WebFullScreenManagerMessageReceiver.cpp 497 500 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/WebFullScreenManagerMessages.h -
trunk/Source/WebKit/DerivedSources.make
r286455 r286507 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
r285047 r286507 75 75 WebsiteDataType::ServiceWorkerRegistrations, 76 76 #endif 77 WebsiteDataType::FileSystem, 77 78 })); 78 79 -
trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp
r286484 r286507 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
r285566 r286507 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
r285041 r286507 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
r285041 r286507 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
r285912 r286507 31 31 #include "NetworkStorageManagerMessages.h" 32 32 #include "OriginStorageManager.h" 33 #include "WebsiteDataType.h" 33 34 #include <pal/crypto/CryptoDigest.h> 35 #include <wtf/Scope.h> 36 #include <wtf/persistence/PersistentDecoder.h> 37 #include <wtf/persistence/PersistentEncoder.h> 34 38 #include <wtf/text/Base64.h> 35 39 36 40 namespace WebKit { 41 42 static std::optional<WebCore::ClientOrigin> readOriginFromFile(const String& filePath) 43 { 44 ASSERT(!RunLoop::isMain()); 45 46 if (!FileSystem::fileExists(filePath)) 47 return std::nullopt; 48 49 auto originFileHandle = FileSystem::openFile(filePath, FileSystem::FileOpenMode::Read); 50 auto closeFile = makeScopeExit([&] { 51 FileSystem::closeFile(originFileHandle); 52 }); 53 54 if (!FileSystem::isHandleValid(originFileHandle)) 55 return std::nullopt; 56 57 auto originContent = FileSystem::readEntireFile(originFileHandle); 58 if (!originContent) 59 return std::nullopt; 60 61 WTF::Persistence::Decoder decoder({ originContent->data(), originContent->size() }); 62 std::optional<WebCore::ClientOrigin> origin; 63 decoder >> origin; 64 return origin; 65 } 66 67 static void writeOriginToFileIfNecessary(const String& filePath, const WebCore::ClientOrigin& origin) 68 { 69 if (FileSystem::fileExists(filePath)) 70 return; 71 72 FileSystem::makeAllDirectories(FileSystem::parentPath(filePath)); 73 auto originFileHandle = FileSystem::openFile(filePath, FileSystem::FileOpenMode::ReadWrite); 74 auto closeFile = makeScopeExit([&] { 75 FileSystem::closeFile(originFileHandle); 76 }); 77 78 if (!FileSystem::isHandleValid(originFileHandle)) { 79 LOG_ERROR("writeOriginToFileIfNecessary: Failed to open origin file"); 80 return; 81 } 82 83 WTF::Persistence::Encoder encoder; 84 encoder << origin; 85 FileSystem::writeToFile(originFileHandle, encoder.buffer(), encoder.bufferSize()); 86 } 87 88 static void deleteOriginFileIfNecessary(const String& filePath) 89 { 90 auto parentPath = FileSystem::parentPath(filePath); 91 auto children = FileSystem::listDirectory(parentPath); 92 if (children.size() == 1) 93 FileSystem::deleteFile(filePath); 94 } 37 95 38 96 Ref<NetworkStorageManager> NetworkStorageManager::create(PAL::SessionID sessionID, const String& path) … … 117 175 } 118 176 119 static String origin Path(const String& rootPath, const WebCore::ClientOrigin& origin, FileSystem::Salt salt)177 static String originDirectoryPath(const String& rootPath, const WebCore::ClientOrigin& origin, FileSystem::Salt salt) 120 178 { 121 179 if (rootPath.isEmpty()) … … 127 185 } 128 186 187 static String originFilePath(const String& directory) 188 { 189 return FileSystem::pathByAppendingComponent(directory, "origin"_s); 190 } 191 129 192 OriginStorageManager& NetworkStorageManager::localOriginStorageManager(const WebCore::ClientOrigin& origin) 130 193 { … … 132 195 133 196 return *m_localOriginStorageManagers.ensure(origin, [&] { 134 return makeUnique<OriginStorageManager>(originPath(m_path, origin, m_salt)); 197 auto originDirectory = originDirectoryPath(m_path, origin, m_salt); 198 writeOriginToFileIfNecessary(originFilePath(originDirectory), origin); 199 return makeUnique<OriginStorageManager>(WTFMove(originDirectory)); 135 200 }).iterator->value; 201 } 202 203 void NetworkStorageManager::removeOriginStorageManagerIfPossible(const WebCore::ClientOrigin& origin) 204 { 205 if (auto iterator = m_localOriginStorageManagers.find(origin); iterator != m_localOriginStorageManagers.end()) { 206 if (!iterator->value->isActive()) 207 m_localOriginStorageManagers.remove(iterator); 208 } 136 209 } 137 210 … … 306 379 } 307 380 381 static std::optional<WebsiteDataType> toWebsiteDataType(const String& storageType) 382 { 383 if (storageType == "FileSystem") 384 return WebsiteDataType::FileSystem; 385 386 return std::nullopt; 387 } 388 389 void NetworkStorageManager::forEachOriginDirectory(const Function<void(const String&)>& apply) 390 { 391 for (auto& topOrigin : FileSystem::listDirectory(m_path)) { 392 auto topOriginDirectory = FileSystem::pathByAppendingComponent(m_path, topOrigin); 393 auto openingOrigins = FileSystem::listDirectory(topOriginDirectory); 394 if (openingOrigins.isEmpty()) { 395 FileSystem::deleteEmptyDirectory(topOriginDirectory); 396 continue; 397 } 398 399 for (auto& openingOrigin : openingOrigins) { 400 auto openingOriginDirectory = FileSystem::pathByAppendingComponent(topOriginDirectory, openingOrigin); 401 apply(openingOriginDirectory); 402 } 403 } 404 } 405 406 Vector<WebsiteData::Entry> NetworkStorageManager::fetchDataFromDisk(OptionSet<WebsiteDataType> targetTypes) 407 { 408 ASSERT(!RunLoop::isMain()); 409 410 HashMap<WebCore::SecurityOriginData, OptionSet<WebsiteDataType>> originTypes; 411 forEachOriginDirectory([&](auto directory) mutable { 412 auto origin = readOriginFromFile(originFilePath(directory)); 413 if (!origin) 414 return; 415 416 for (auto& storageType : FileSystem::listDirectory(directory)) { 417 if (auto type = toWebsiteDataType(storageType); type && targetTypes.contains(*type)) { 418 // Return both top origin and opening origin for this data. 419 originTypes.add(origin->clientOrigin, OptionSet<WebsiteDataType> { }).iterator->value.add(*type); 420 originTypes.add(origin->topOrigin, OptionSet<WebsiteDataType> { }).iterator->value.add(*type); 421 } 422 } 423 }); 424 425 Vector<WebsiteData::Entry> entries; 426 for (auto [origin, types] : originTypes) { 427 for (auto type : types) 428 entries.append({ WebsiteData::Entry { origin, type, 0 } }); 429 } 430 431 return entries; 432 } 433 434 void NetworkStorageManager::fetchData(OptionSet<WebsiteDataType> types, CompletionHandler<void(Vector<WebsiteData::Entry>&&)>&& completionHandler) 435 { 436 ASSERT(RunLoop::isMain()); 437 ASSERT(!m_closed); 438 439 m_queue->dispatch([this, protectedThis = Ref { *this }, types, completionHandler = WTFMove(completionHandler)]() mutable { 440 auto entries = fetchDataFromDisk(types); 441 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler), entries = crossThreadCopy(WTFMove(entries))]() mutable { 442 completionHandler(WTFMove(entries)); 443 }); 444 }); 445 } 446 447 Vector<WebCore::ClientOrigin> NetworkStorageManager::deleteDataOnDisk(OptionSet<WebsiteDataType> types, WallTime modifiedSinceTime, const Function<bool(const WebCore::ClientOrigin&)>& filter) 448 { 449 ASSERT(!RunLoop::isMain()); 450 451 Vector<WebCore::ClientOrigin> deletedOrigins; 452 forEachOriginDirectory([&](auto directory) mutable { 453 auto filePath = originFilePath(directory); 454 auto origin = readOriginFromFile(filePath); 455 if (!origin) { 456 // If origin cannot be retrieved, but we are asked to remove data for all origins, remove it. 457 RELEASE_LOG_ERROR(Storage, "NetworkStorageManager::deleteDataOnDisk failed to read origin from '%s'", filePath.utf8().data()); 458 if (filter(WebCore::ClientOrigin { })) { 459 FileSystem::deleteAllFilesModifiedSince(directory, modifiedSinceTime); 460 FileSystem::deleteEmptyDirectory(directory); 461 } 462 return; 463 } 464 465 if (!filter(*origin)) 466 return; 467 468 deletedOrigins.append(*origin); 469 localOriginStorageManager(*origin).deleteData(types, modifiedSinceTime); 470 removeOriginStorageManagerIfPossible(*origin); 471 deleteOriginFileIfNecessary(filePath); 472 FileSystem::deleteEmptyDirectory(directory); 473 }); 474 475 return deletedOrigins; 476 } 477 478 void NetworkStorageManager::deleteData(OptionSet<WebsiteDataType> types, const Vector<WebCore::SecurityOriginData>& origins, CompletionHandler<void()>&& completionHandler) 479 { 480 ASSERT(RunLoop::isMain()); 481 ASSERT(!m_closed); 482 483 m_queue->dispatch([this, protectedThis = Ref { *this }, types, origins = crossThreadCopy(origins), completionHandler = WTFMove(completionHandler)]() mutable { 484 HashSet<WebCore::SecurityOriginData> originSet; 485 originSet.reserveInitialCapacity(origins.size()); 486 for (auto origin : origins) 487 originSet.add(WTFMove(origin)); 488 489 deleteDataOnDisk(types, -WallTime::infinity(), [&originSet](auto origin) { 490 return originSet.contains(origin.topOrigin) || originSet.contains(origin.clientOrigin); 491 }); 492 493 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)]() mutable { 494 completionHandler(); 495 }); 496 }); 497 } 498 499 void NetworkStorageManager::deleteDataModifiedSince(OptionSet<WebsiteDataType> types, WallTime modifiedSinceTime, CompletionHandler<void()>&& completionHandler) 500 { 501 ASSERT(RunLoop::isMain()); 502 ASSERT(!m_closed); 503 504 m_queue->dispatch([this, protectedThis = Ref { *this }, types, modifiedSinceTime, completionHandler = WTFMove(completionHandler)]() mutable { 505 deleteDataOnDisk(types, modifiedSinceTime, [](auto&) { 506 return true; 507 }); 508 509 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)]() mutable { 510 completionHandler(); 511 }); 512 }); 513 } 514 515 void NetworkStorageManager::deleteDataForRegistrableDomains(OptionSet<WebsiteDataType> types, const Vector<WebCore::RegistrableDomain>& domains, CompletionHandler<void(HashSet<WebCore::RegistrableDomain>&&)>&& completionHandler) 516 { 517 ASSERT(RunLoop::isMain()); 518 ASSERT(!m_closed); 519 520 m_queue->dispatch([this, protectedThis = Ref { *this }, types, domains = crossThreadCopy(domains), completionHandler = WTFMove(completionHandler)]() mutable { 521 auto deletedOrigins = deleteDataOnDisk(types, -WallTime::infinity(), [&domains](auto& origin) { 522 auto domain = WebCore::RegistrableDomain::uncheckedCreateFromHost(origin.clientOrigin.host); 523 return domains.contains(domain); 524 }); 525 526 HashSet<WebCore::RegistrableDomain> deletedDomains; 527 for (auto origin : deletedOrigins) { 528 auto domain = WebCore::RegistrableDomain::uncheckedCreateFromHost(origin.clientOrigin.host); 529 deletedDomains.add(domain); 530 } 531 532 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler), domains = crossThreadCopy(WTFMove(deletedDomains))]() mutable { 533 completionHandler(WTFMove(domains)); 534 }); 535 }); 536 } 537 308 538 } // namespace WebKit 309 539 -
trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.h
r285912 r286507 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
r283029 r286507 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 FileSystem::deleteNonEmptyDirectory(m_rootPath); 98 } 99 67 100 private: 101 void deleteFileSystemStorageData(WallTime modifiedSinceTime) 102 { 103 m_fileSystemStorageManager = nullptr; 104 105 auto fileSystemStoragePath = typeStoragePath(StorageType::FileSystem); 106 FileSystem::deleteAllFilesModifiedSince(fileSystemStoragePath, modifiedSinceTime); 107 } 108 68 109 String m_rootPath; 69 110 String m_identifier; … … 75 116 : m_path(WTFMove(path)) 76 117 { 118 ASSERT(!RunLoop::isMain()); 77 119 } 78 120 … … 104 146 } 105 147 148 bool OriginStorageManager::isActive() 149 { 150 return defaultBucket().isActive(); 151 } 152 153 void OriginStorageManager::deleteData(OptionSet<WebsiteDataType> types, WallTime modifiedSince) 154 { 155 ASSERT(!RunLoop::isMain()); 156 defaultBucket().deleteData(types, modifiedSince); 157 } 158 106 159 } // namespace WebKit 107 160 -
trunk/Source/WebKit/NetworkProcess/storage/OriginStorageManager.h
r283271 r286507 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 { … … 44 49 void persist(); 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
r285047 r286507 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
r285047 r286507 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
r276880 r286507 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
r285047 r286507 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
r279089 r286507 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
r285121 r286507 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
r286487 r286507 1500 1500 93D6B7B925534A170058DD3A /* WKSpeechRecognitionPermissionCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D6B7B725534A110058DD3A /* WKSpeechRecognitionPermissionCallback.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1501 1501 93E6A4EE1BC5DD3900F8A0E7 /* _WKHitTestResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 93E6A4ED1BC5DD3900F8A0E7 /* _WKHitTestResult.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1502 93E799852756FA550074008A /* WebFileSystemStorageConnectionMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93E799822756FA540074008A /* WebFileSystemStorageConnectionMessageReceiver.cpp */; }; 1503 93E799872756FAB40074008A /* WebFileSystemStorageConnectionMessagesReplies.h in Headers */ = {isa = PBXBuildFile; fileRef = 93E799832756FA540074008A /* WebFileSystemStorageConnectionMessagesReplies.h */; }; 1504 93E799882756FAC20074008A /* WebFileSystemStorageConnectionMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 93E799812756FA530074008A /* WebFileSystemStorageConnectionMessages.h */; }; 1502 1505 93F549B41E3174B7000E7239 /* WKSnapshotConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F549B31E3174B7000E7239 /* WKSnapshotConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1503 1506 950F2880252414EA00B74F1C /* WKMouseDeviceObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 950F287E252414E900B74F1C /* WKMouseDeviceObserver.h */; }; … … 5302 5305 93D6B7B825534A120058DD3A /* WKSpeechRecognitionPermissionCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKSpeechRecognitionPermissionCallback.cpp; sourceTree = "<group>"; }; 5303 5306 93E6A4ED1BC5DD3900F8A0E7 /* _WKHitTestResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKHitTestResult.h; sourceTree = "<group>"; }; 5307 93E7997E2756F6700074008A /* WebFileSystemStorageConnection.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebFileSystemStorageConnection.messages.in; sourceTree = "<group>"; }; 5308 93E799812756FA530074008A /* WebFileSystemStorageConnectionMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebFileSystemStorageConnectionMessages.h; sourceTree = "<group>"; }; 5309 93E799822756FA540074008A /* WebFileSystemStorageConnectionMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebFileSystemStorageConnectionMessageReceiver.cpp; sourceTree = "<group>"; }; 5310 93E799832756FA540074008A /* WebFileSystemStorageConnectionMessagesReplies.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebFileSystemStorageConnectionMessagesReplies.h; sourceTree = "<group>"; }; 5304 5311 93F549B31E3174B7000E7239 /* WKSnapshotConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKSnapshotConfiguration.h; sourceTree = "<group>"; }; 5305 5312 93F549B51E3174DA000E7239 /* WKSnapshotConfiguration.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKSnapshotConfiguration.mm; sourceTree = "<group>"; }; … … 10583 10590 9354242B2703BDCB005CA72C /* WebFileSystemStorageConnection.cpp */, 10584 10591 9354242A2703BDCB005CA72C /* WebFileSystemStorageConnection.h */, 10592 93E7997E2756F6700074008A /* WebFileSystemStorageConnection.messages.in */, 10585 10593 BC111A58112F4FBB00337BAB /* WebFrameLoaderClient.cpp */, 10586 10594 BC032D6A10F4378D0058C15A /* WebFrameLoaderClient.h */, … … 12060 12068 E3866B042399979C00F88FE9 /* WebDeviceOrientationUpdateProviderProxyMessageReceiver.cpp */, 12061 12069 E3866B052399979C00F88FE9 /* WebDeviceOrientationUpdateProviderProxyMessages.h */, 12070 93E799822756FA540074008A /* WebFileSystemStorageConnectionMessageReceiver.cpp */, 12071 93E799812756FA530074008A /* WebFileSystemStorageConnectionMessages.h */, 12072 93E799832756FA540074008A /* WebFileSystemStorageConnectionMessagesReplies.h */, 12062 12073 CD73BA48131ACD8E00EEDED2 /* WebFullScreenManagerMessageReceiver.cpp */, 12063 12074 CD73BA49131ACD8E00EEDED2 /* WebFullScreenManagerMessages.h */, … … 13307 13318 BC111B5D112F629800337BAB /* WebEventFactory.h in Headers */, 13308 13319 9354242C2703BDCB005CA72C /* WebFileSystemStorageConnection.h in Headers */, 13320 93E799882756FAC20074008A /* WebFileSystemStorageConnectionMessages.h in Headers */, 13321 93E799872756FAB40074008A /* WebFileSystemStorageConnectionMessagesReplies.h in Headers */, 13309 13322 1A90C1EE1264FD50003E44D4 /* WebFindOptions.h in Headers */, 13310 13323 BCE469541214E6CB000B98EB /* WebFormClient.h in Headers */, … … 15403 15416 E3866B092399A2D500F88FE9 /* WebDeviceOrientationUpdateProviderProxyMessageReceiver.cpp in Sources */, 15404 15417 2D92A789212B6AB100F493FD /* WebEvent.cpp in Sources */, 15418 93E799852756FA550074008A /* WebFileSystemStorageConnectionMessageReceiver.cpp in Sources */, 15405 15419 CD73BA4E131ACDB700EEDED2 /* WebFullScreenManagerMessageReceiver.cpp in Sources */, 15406 15420 CD73BA47131ACC9A00EEDED2 /* WebFullScreenManagerProxyMessageReceiver.cpp in Sources */, -
trunk/Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp
r282712 r286507 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
r286505 r286507 1 2021-12-03 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 6 Reviewed by Youenn Fablet. 7 8 * TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm: 9 1 10 2021-12-03 Chris Dumez <cdumez@apple.com> 2 11 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm
r286414 r286507 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.