void IDBServer::performCloseAndDeleteDatabasesForOrigins(const Vector<SecurityOriginData>& origins, uint64_t callbackID) { if (!m_databaseDirectoryPath.isEmpty()) { for (const auto& origin : origins) { String originPath = FileSystem::pathByAppendingComponent(m_databaseDirectoryPath, origin.databaseIdentifier()); removeAllDatabasesForOriginPath(originPath, -WallTime::infinity()); for (const auto& topOriginPath : FileSystem::listDirectory(m_databaseDirectoryPath, "*")) { originPath = FileSystem::pathByAppendingComponent(topOriginPath, origin.databaseIdentifier()); removeAllDatabasesForOriginPath(originPath, -WallTime::infinity()); } } } postDatabaseTaskReply(createCrossThreadTask(*this, &IDBServer::didPerformCloseAndDeleteDatabases, callbackID)); }
void DatabaseProcess::deleteAllIndexedDatabaseEntries() { if (m_indexedDatabaseDirectory.isEmpty()) return; Vector<String> originPaths = listDirectory(m_indexedDatabaseDirectory, "*"); for (auto& originPath : originPaths) removeAllDatabasesForOriginPath(originPath, std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max()); }
void DatabaseProcess::deleteIndexedDatabaseEntriesModifiedBetweenDates(double startDate, double endDate) { if (m_indexedDatabaseDirectory.isEmpty()) return; Vector<String> originPaths = listDirectory(m_indexedDatabaseDirectory, "*"); for (auto& originPath : originPaths) removeAllDatabasesForOriginPath(originPath, startDate, endDate); }
void DatabaseProcess::deleteIndexedDatabaseEntriesModifiedSince(std::chrono::system_clock::time_point modifiedSince) { if (m_indexedDatabaseDirectory.isEmpty()) return; Vector<String> originPaths = listDirectory(m_indexedDatabaseDirectory, "*"); for (auto& originPath : originPaths) removeAllDatabasesForOriginPath(originPath, modifiedSince); }
void IDBServer::performCloseAndDeleteDatabasesModifiedSince(std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID) { if (!m_databaseDirectoryPath.isEmpty()) { Vector<String> originPaths = listDirectory(m_databaseDirectoryPath, "*"); for (auto& originPath : originPaths) removeAllDatabasesForOriginPath(originPath, modifiedSince); } postDatabaseTaskReply(createCrossThreadTask(*this, &IDBServer::didPerformCloseAndDeleteDatabases, callbackID)); }
void DatabaseProcess::deleteIndexedDatabaseEntriesForOrigin(const SecurityOriginData& originData) { if (m_indexedDatabaseDirectory.isEmpty()) return; RefPtr<SecurityOrigin> origin = originData.securityOrigin(); String databaseIdentifier = origin->databaseIdentifier(); String originPath = pathByAppendingComponent(m_indexedDatabaseDirectory, databaseIdentifier); removeAllDatabasesForOriginPath(originPath, std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max()); }
void DatabaseProcess::deleteIndexedDatabaseEntriesForOrigins(const Vector<RefPtr<WebCore::SecurityOrigin>>& securityOrigins) { if (m_indexedDatabaseDirectory.isEmpty()) return; for (const auto& securityOrigin : securityOrigins) { String originPath = pathByAppendingComponent(m_indexedDatabaseDirectory, securityOrigin->databaseIdentifier()); removeAllDatabasesForOriginPath(originPath, std::chrono::system_clock::time_point::min()); } }
void IDBServer::performCloseAndDeleteDatabasesForOrigins(const Vector<SecurityOriginData>& origins, uint64_t callbackID) { if (!m_databaseDirectoryPath.isEmpty()) { for (const auto& origin : origins) { String originPath = pathByAppendingComponent(m_databaseDirectoryPath, origin.securityOrigin()->databaseIdentifier()); removeAllDatabasesForOriginPath(originPath, std::chrono::system_clock::time_point::min()); } } postDatabaseTaskReply(createCrossThreadTask(*this, &IDBServer::didPerformCloseAndDeleteDatabases, callbackID)); }
static void removeAllDatabasesForOriginPath(const String& originPath, WallTime modifiedSince) { LOG(IndexedDB, "removeAllDatabasesForOriginPath with originPath %s", originPath.utf8().data()); Vector<String> databasePaths = FileSystem::listDirectory(originPath, "*"); for (auto& databasePath : databasePaths) { if (FileSystem::fileIsDirectory(databasePath, FileSystem::ShouldFollowSymbolicLinks::No)) removeAllDatabasesForOriginPath(databasePath, modifiedSince); String databaseFile = FileSystem::pathByAppendingComponent(databasePath, "IndexedDB.sqlite3"); if (modifiedSince > -WallTime::infinity() && FileSystem::fileExists(databaseFile)) { auto modificationTime = FileSystem::getFileModificationTime(databaseFile); if (!modificationTime) continue; if (modificationTime.value() < modifiedSince) continue; } // Deleting this database means we need to delete all files that represent it. // This includes: // - The directory itself, which is named after the database. // - IndexedDB.sqlite3 and related SQLite files. // - Blob files that we stored in the directory. // // To be conservative, we should *not* try to delete files that are unexpected; // We should only delete files we think we put there. // // IndexedDB blob files are named "N.blob" where N is a decimal integer, // so those are the only blob files we should be trying to delete. for (auto& blobPath : FileSystem::listDirectory(databasePath, "[0-9]*.blob")) { // Globbing can't give us only filenames starting with 1-or-more digits. // The above globbing gives us files that start with a digit and ends with ".blob", but there might be non-digits in between. // We need to validate that each filename contains only digits before deleting it, as any other files are not ones we put there. String filename = FileSystem::pathGetFileName(blobPath); auto filenameLength = filename.length(); ASSERT(filenameLength >= 6); ASSERT(filename.endsWith(".blob")); if (filename.length() < 6) continue; if (!filename.endsWith(".blob")) continue; bool validFilename = true; for (unsigned i = 0; i < filenameLength - 5; ++i) { if (!isASCIIDigit(filename[i])) { validFilename = false; break; } } if (validFilename) FileSystem::deleteFile(blobPath); } // Now delete IndexedDB.sqlite3 and related SQLite files. SQLiteFileSystem::deleteDatabaseFile(databaseFile); // And finally, if we can, delete the empty directory. FileSystem::deleteEmptyDirectory(databasePath); } // If no databases remain for this origin, we can delete the origin directory as well. FileSystem::deleteEmptyDirectory(originPath); }