Changeset 232410 in webkit
- Timestamp:
- Jun 1, 2018 1:13:08 PM (6 years ago)
- Location:
- trunk/Source
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r232394 r232410 1 2018-06-01 Sihui Liu <sihui_liu@apple.com> 2 3 Stop using StorageTracker.db in LocalStorageDatabaseTracker 4 https://bugs.webkit.org/show_bug.cgi?id=186104 5 6 Reviewed by Geoffrey Garen. 7 8 No behavior change. 9 10 * platform/sql/SQLiteFileSystem.h: 11 1 12 2018-06-01 Zalan Bujtas <zalan@apple.com> 2 13 -
trunk/Source/WebCore/platform/sql/SQLiteFileSystem.h
r218799 r232410 58 58 // path - The directory. 59 59 // fileName - The file name. 60 static String appendDatabaseFileNameToPath(const String& path, const String& fileName);60 WEBCORE_EXPORT static String appendDatabaseFileNameToPath(const String& path, const String& fileName); 61 61 62 62 // Makes sure the given directory exists, by creating all missing directories … … 64 64 // 65 65 // path - The directory. 66 static bool ensureDatabaseDirectoryExists(const String& path);66 WEBCORE_EXPORT static bool ensureDatabaseDirectoryExists(const String& path); 67 67 68 68 // If 'checkPathOnly' is false, then this method only checks if the given file exists. … … 98 98 99 99 static long long getDatabaseFileSize(const String& fileName); 100 static double databaseCreationTime(const String& fileName);101 static double databaseModificationTime(const String& fileName);100 WEBCORE_EXPORT static double databaseCreationTime(const String& fileName); 101 WEBCORE_EXPORT static double databaseModificationTime(const String& fileName); 102 102 103 103 private: -
trunk/Source/WebKit/ChangeLog
r232397 r232410 1 2018-06-01 Sihui Liu <sihui_liu@apple.com> 2 3 Stop using StorageTracker.db in LocalStorageDatabaseTracker 4 https://bugs.webkit.org/show_bug.cgi?id=186104 5 6 Reviewed by Geoffrey Garen. 7 8 Stop using StorageTracker.db and stop caching origins in LocalStorageDatabaseTracker for efficiency 9 and simplicity. Since functions in LocalStorageDatabaseTracker are not frequently called, we get 10 little benefits from caching origins. 11 12 * Platform/Logging.h: 13 * UIProcess/API/C/WKKeyValueStorageManager.cpp: 14 (WKKeyValueStorageManagerGetStorageDetailsByOrigin): 15 * UIProcess/WebStorage/LocalStorageDatabaseTracker.cpp: 16 (WebKit::LocalStorageDatabaseTracker::LocalStorageDatabaseTracker): 17 (WebKit::LocalStorageDatabaseTracker::didOpenDatabaseWithOrigin): 18 (WebKit::LocalStorageDatabaseTracker::deleteDatabaseWithOrigin): 19 (WebKit::LocalStorageDatabaseTracker::deleteAllDatabases): 20 (WebKit::LocalStorageDatabaseTracker::databasesModifiedSince): 21 (WebKit::LocalStorageDatabaseTracker::origins const): 22 (WebKit::LocalStorageDatabaseTracker::originDetails): 23 (WebKit::LocalStorageDatabaseTracker::databasePath const): 24 (WebKit::fileCreationTime): Deleted. 25 (WebKit::fileModificationTime): Deleted. 26 (WebKit::LocalStorageDatabaseTracker::trackerDatabasePath const): Deleted. 27 (WebKit::LocalStorageDatabaseTracker::openTrackerDatabase): Deleted. 28 (WebKit::LocalStorageDatabaseTracker::importOriginIdentifiers): Deleted. 29 (WebKit::LocalStorageDatabaseTracker::updateTrackerDatabaseFromLocalStorageDatabaseFiles): Deleted. 30 (WebKit::LocalStorageDatabaseTracker::addDatabaseWithOriginIdentifier): Deleted. 31 (WebKit::LocalStorageDatabaseTracker::removeDatabaseWithOriginIdentifier): Deleted. 32 (WebKit::LocalStorageDatabaseTracker::pathForDatabaseWithOriginIdentifier): Deleted. 33 * UIProcess/WebStorage/LocalStorageDatabaseTracker.h: 34 * UIProcess/WebStorage/StorageManager.h: 35 1 36 2018-06-01 Michael Catanzaro <mcatanzaro@igalia.com> 2 37 -
trunk/Source/WebKit/Platform/Logging.h
r230834 r232410 53 53 M(Layers) \ 54 54 M(Loading) \ 55 M(LocalStorageDatabaseTracker) \ 55 56 M(MouseHandling) \ 56 57 M(Network) \ -
trunk/Source/WebKit/UIProcess/API/C/WKKeyValueStorageManager.cpp
r229979 r232410 103 103 detailsMap.set(toImpl(WKKeyValueStorageManagerGetOriginKey())->string(), origin); 104 104 if (originDetails.creationTime) 105 detailsMap.set(toImpl(WKKeyValueStorageManagerGetCreationTimeKey())->string(), API::Double::create(originDetails.creationTime. value_or(0)));105 detailsMap.set(toImpl(WKKeyValueStorageManagerGetCreationTimeKey())->string(), API::Double::create(originDetails.creationTime.secondsSinceEpoch().value())); 106 106 if (originDetails.modificationTime) 107 detailsMap.set(toImpl(WKKeyValueStorageManagerGetModificationTimeKey())->string(), API::Double::create(originDetails.modificationTime. value_or(0)));107 detailsMap.set(toImpl(WKKeyValueStorageManagerGetModificationTimeKey())->string(), API::Double::create(originDetails.modificationTime.secondsSinceEpoch().value())); 108 108 109 109 result.uncheckedAppend(API::Dictionary::create(WTFMove(detailsMap))); -
trunk/Source/WebKit/UIProcess/WebStorage/LocalStorageDatabaseTracker.cpp
r231837 r232410 27 27 #include "LocalStorageDatabaseTracker.h" 28 28 29 #include "Logging.h" 29 30 #include <WebCore/FileSystem.h> 30 31 #include <WebCore/SQLiteFileSystem.h> 31 32 #include <WebCore/SQLiteStatement.h> 32 #include <WebCore/SecurityOrigin.h>33 #include <WebCore/SecurityOriginData.h>34 33 #include <WebCore/TextEncoding.h> 35 34 #include <wtf/MainThread.h> … … 57 56 58 57 m_queue->dispatch([protectedThis = makeRef(*this)]() mutable { 59 protectedThis->importOriginIdentifiers(); 58 // Delete legacy storageTracker database file. 59 SQLiteFileSystem::deleteDatabaseFile(protectedThis->databasePath("StorageTracker.db")); 60 60 }); 61 61 } … … 72 72 void LocalStorageDatabaseTracker::didOpenDatabaseWithOrigin(const SecurityOriginData& securityOrigin) 73 73 { 74 addDatabaseWithOriginIdentifier(securityOrigin.databaseIdentifier(), databasePath(securityOrigin));74 // FIXME: Tell clients that the origin was added. 75 75 } 76 76 77 77 void LocalStorageDatabaseTracker::deleteDatabaseWithOrigin(const SecurityOriginData& securityOrigin) 78 78 { 79 removeDatabaseWithOriginIdentifier(securityOrigin.databaseIdentifier()); 79 auto path = databasePath(securityOrigin); 80 if (!path.isEmpty()) 81 SQLiteFileSystem::deleteDatabaseFile(path); 82 83 // FIXME: Tell clients that the origin was removed. 80 84 } 81 85 82 86 void LocalStorageDatabaseTracker::deleteAllDatabases() 83 87 { 84 m_origins.clear(); 85 86 openTrackerDatabase(SkipIfNonExistent); 87 if (!m_database.isOpen()) 88 return; 89 90 SQLiteStatement statement(m_database, "SELECT origin, path FROM Origins"); 91 if (statement.prepare() != SQLITE_OK) { 92 LOG_ERROR("Failed to prepare statement."); 93 return; 94 } 95 96 int result; 97 while ((result = statement.step()) == SQLITE_ROW) { 98 FileSystem::deleteFile(statement.getColumnText(1)); 88 auto paths = FileSystem::listDirectory(m_localStorageDirectory, "*.localstorage"); 89 for (auto path : paths) { 90 SQLiteFileSystem::deleteDatabaseFile(path); 99 91 100 92 // FIXME: Call out to the client. 101 93 } 102 94 103 if (result != SQLITE_DONE) 104 LOG_ERROR("Failed to read in all origins from the database."); 105 106 if (m_database.isOpen()) 107 m_database.close(); 108 109 if (!FileSystem::deleteFile(trackerDatabasePath())) { 110 // In the case where it is not possible to delete the database file (e.g some other program 111 // like a virus scanner is accessing it), make sure to remove all entries. 112 openTrackerDatabase(SkipIfNonExistent); 113 if (!m_database.isOpen()) 114 return; 115 116 SQLiteStatement deleteStatement(m_database, "DELETE FROM Origins"); 117 if (deleteStatement.prepare() != SQLITE_OK) { 118 LOG_ERROR("Unable to prepare deletion of all origins"); 119 return; 120 } 121 if (!deleteStatement.executeCommand()) { 122 LOG_ERROR("Unable to execute deletion of all origins"); 123 return; 124 } 125 } 126 127 FileSystem::deleteEmptyDirectory(m_localStorageDirectory); 128 } 129 130 static std::optional<time_t> fileCreationTime(const String& filePath) 131 { 132 time_t time; 133 return FileSystem::getFileCreationTime(filePath, time) ? time : std::optional<time_t>(std::nullopt); 134 } 135 136 static std::optional<time_t> fileModificationTime(const String& filePath) 137 { 138 time_t time; 139 if (!FileSystem::getFileModificationTime(filePath, time)) 140 return std::nullopt; 141 142 return time; 95 SQLiteFileSystem::deleteEmptyDatabaseDirectory(m_localStorageDirectory); 143 96 } 144 97 145 98 Vector<SecurityOriginData> LocalStorageDatabaseTracker::databasesModifiedSince(WallTime time) 146 99 { 147 ASSERT(!RunLoop::isMain()); 148 importOriginIdentifiers(); 149 Vector<String> originIdentifiersModified; 100 Vector<SecurityOriginData> databaseOriginsModified; 101 auto databaseOrigins = origins(); 150 102 151 for ( const String& origin : m_origins) {152 String filePath = pathForDatabaseWithOriginIdentifier(origin);103 for (auto origin : databaseOrigins) { 104 auto path = databasePath(origin); 153 105 154 auto modificationTime = FileSystem::getFileModificationTime(filePath);155 if ( !modificationTime || modificationTime.value()>= time)156 originIdentifiersModified.append(origin);106 auto modificationTime = WallTime::fromRawSeconds(SQLiteFileSystem::databaseModificationTime(path)); 107 if (modificationTime >= time) 108 databaseOriginsModified.append(origin); 157 109 } 158 159 Vector<SecurityOriginData> databaseOriginsModified; 160 databaseOriginsModified.reserveInitialCapacity(originIdentifiersModified.size()); 161 162 for (const auto& originIdentifier : originIdentifiersModified) { 163 if (auto origin = SecurityOriginData::fromDatabaseIdentifier(originIdentifier)) 164 databaseOriginsModified.uncheckedAppend(*origin); 165 else 166 ASSERT_NOT_REACHED(); 167 } 168 110 169 111 return databaseOriginsModified; 170 112 } … … 172 114 Vector<SecurityOriginData> LocalStorageDatabaseTracker::origins() const 173 115 { 174 Vector<SecurityOriginData> origins; 175 origins.reserveInitialCapacity(m_origins.size()); 176 177 for (const String& originIdentifier : m_origins) { 178 if (auto origin = SecurityOriginData::fromDatabaseIdentifier(originIdentifier)) 179 origins.uncheckedAppend(*origin); 116 Vector<SecurityOriginData> databaseOrigins; 117 auto paths = FileSystem::listDirectory(m_localStorageDirectory, "*.localstorage"); 118 119 for (auto path : paths) { 120 auto filename = FileSystem::pathGetFileName(path); 121 auto originIdentifier = filename.substring(0, filename.length() - strlen(".localstorage")); 122 auto origin = SecurityOriginData::fromDatabaseIdentifier(originIdentifier); 123 if (origin) 124 databaseOrigins.append(origin.value()); 180 125 else 181 ASSERT_NOT_REACHED();126 RELEASE_LOG_ERROR(LocalStorageDatabaseTracker, "Unable to extract origin from path %s", path.utf8().data()); 182 127 } 183 128 184 return origins;129 return databaseOrigins; 185 130 } 186 131 … … 188 133 { 189 134 Vector<OriginDetails> result; 190 result.reserveInitialCapacity(m_origins.size()); 135 auto databaseOrigins = origins(); 136 result.reserveInitialCapacity(databaseOrigins.size()); 191 137 192 for ( const String& origin : m_origins) {193 String filePath = pathForDatabaseWithOriginIdentifier(origin);138 for (auto origin : databaseOrigins) { 139 String path = databasePath(origin); 194 140 195 141 OriginDetails details; 196 details.originIdentifier = origin. isolatedCopy();197 details.creationTime = fileCreationTime(filePath);198 details.modificationTime = fileModificationTime(filePath);142 details.originIdentifier = origin.databaseIdentifier(); 143 details.creationTime = WallTime::fromRawSeconds(SQLiteFileSystem::databaseCreationTime(path)); 144 details.modificationTime = WallTime::fromRawSeconds(SQLiteFileSystem::databaseModificationTime(path)); 199 145 result.uncheckedAppend(details); 200 146 } … … 205 151 String LocalStorageDatabaseTracker::databasePath(const String& filename) const 206 152 { 207 if (! FileSystem::makeAllDirectories(m_localStorageDirectory)) {153 if (!SQLiteFileSystem::ensureDatabaseDirectoryExists(m_localStorageDirectory)) { 208 154 LOG_ERROR("Unable to create LocalStorage database path %s", m_localStorageDirectory.utf8().data()); 209 155 return String(); … … 214 160 #endif 215 161 216 return FileSystem::pathByAppendingComponent(m_localStorageDirectory, filename); 217 } 218 219 String LocalStorageDatabaseTracker::trackerDatabasePath() const 220 { 221 return databasePath("StorageTracker.db"); 222 } 223 224 void LocalStorageDatabaseTracker::openTrackerDatabase(DatabaseOpeningStrategy openingStrategy) 225 { 226 if (m_database.isOpen()) 227 return; 228 229 String databasePath = trackerDatabasePath(); 230 231 if (!FileSystem::fileExists(databasePath) && openingStrategy == SkipIfNonExistent) 232 return; 233 234 if (!m_database.open(databasePath)) { 235 LOG_ERROR("Failed to open databasePath %s.", databasePath.ascii().data()); 236 return; 237 } 238 239 // Since a WorkQueue isn't bound to a specific thread, we have to disable threading checks 240 // even though we never access the database from different threads simultaneously. 241 m_database.disableThreadingChecks(); 242 243 if (m_database.tableExists("Origins")) 244 return; 245 246 if (!m_database.executeCommand("CREATE TABLE Origins (origin TEXT UNIQUE ON CONFLICT REPLACE, path TEXT);")) 247 LOG_ERROR("Failed to create Origins table."); 248 } 249 250 void LocalStorageDatabaseTracker::importOriginIdentifiers() 251 { 252 openTrackerDatabase(SkipIfNonExistent); 253 254 if (m_database.isOpen()) { 255 SQLiteStatement statement(m_database, "SELECT origin FROM Origins"); 256 if (statement.prepare() != SQLITE_OK) { 257 LOG_ERROR("Failed to prepare statement."); 258 return; 259 } 260 261 int result; 262 263 while ((result = statement.step()) == SQLITE_ROW) 264 m_origins.add(statement.getColumnText(0)); 265 266 if (result != SQLITE_DONE) { 267 LOG_ERROR("Failed to read in all origins from the database."); 268 return; 269 } 270 } 271 272 updateTrackerDatabaseFromLocalStorageDatabaseFiles(); 273 } 274 275 void LocalStorageDatabaseTracker::updateTrackerDatabaseFromLocalStorageDatabaseFiles() 276 { 277 Vector<String> paths = FileSystem::listDirectory(m_localStorageDirectory, "*.localstorage"); 278 279 HashSet<String> origins(m_origins); 280 HashSet<String> originsFromLocalStorageDatabaseFiles; 281 282 for (size_t i = 0; i < paths.size(); ++i) { 283 const String& path = paths[i]; 284 285 if (!path.endsWith(".localstorage")) 286 continue; 287 288 String filename = FileSystem::pathGetFileName(path); 289 290 String originIdentifier = filename.substring(0, filename.length() - strlen(".localstorage")); 291 292 if (!m_origins.contains(originIdentifier)) 293 addDatabaseWithOriginIdentifier(originIdentifier, path); 294 295 originsFromLocalStorageDatabaseFiles.add(originIdentifier); 296 } 297 298 for (auto it = origins.begin(), end = origins.end(); it != end; ++it) { 299 const String& originIdentifier = *it; 300 if (origins.contains(originIdentifier)) 301 continue; 302 303 removeDatabaseWithOriginIdentifier(originIdentifier); 304 } 305 } 306 307 void LocalStorageDatabaseTracker::addDatabaseWithOriginIdentifier(const String& originIdentifier, const String& databasePath) 308 { 309 openTrackerDatabase(CreateIfNonExistent); 310 if (!m_database.isOpen()) 311 return; 312 313 SQLiteStatement statement(m_database, "INSERT INTO Origins VALUES (?, ?)"); 314 if (statement.prepare() != SQLITE_OK) { 315 LOG_ERROR("Unable to establish origin '%s' in the tracker", originIdentifier.utf8().data()); 316 return; 317 } 318 319 statement.bindText(1, originIdentifier); 320 statement.bindText(2, databasePath); 321 322 if (statement.step() != SQLITE_DONE) 323 LOG_ERROR("Unable to establish origin '%s' in the tracker", originIdentifier.utf8().data()); 324 325 m_origins.add(originIdentifier); 326 327 // FIXME: Tell clients that the origin was added. 328 } 329 330 void LocalStorageDatabaseTracker::removeDatabaseWithOriginIdentifier(const String& originIdentifier) 331 { 332 openTrackerDatabase(SkipIfNonExistent); 333 if (!m_database.isOpen()) 334 return; 335 336 String path = pathForDatabaseWithOriginIdentifier(originIdentifier); 337 if (path.isEmpty()) 338 return; 339 340 SQLiteStatement deleteStatement(m_database, "DELETE FROM Origins where origin=?"); 341 if (deleteStatement.prepare() != SQLITE_OK) { 342 LOG_ERROR("Unable to prepare deletion of origin '%s'", originIdentifier.ascii().data()); 343 return; 344 } 345 deleteStatement.bindText(1, originIdentifier); 346 if (!deleteStatement.executeCommand()) { 347 LOG_ERROR("Unable to execute deletion of origin '%s'", originIdentifier.ascii().data()); 348 return; 349 } 350 351 SQLiteFileSystem::deleteDatabaseFile(path); 352 353 m_origins.remove(originIdentifier); 354 if (m_origins.isEmpty()) { 355 // There are no origins left; delete the tracker database. 356 m_database.close(); 357 SQLiteFileSystem::deleteDatabaseFile(trackerDatabasePath()); 358 FileSystem::deleteEmptyDirectory(m_localStorageDirectory); 359 } 360 361 // FIXME: Tell clients that the origin was removed. 362 } 363 364 String LocalStorageDatabaseTracker::pathForDatabaseWithOriginIdentifier(const String& originIdentifier) 365 { 366 if (!m_database.isOpen()) 367 return String(); 368 369 SQLiteStatement pathStatement(m_database, "SELECT path FROM Origins WHERE origin=?"); 370 if (pathStatement.prepare() != SQLITE_OK) { 371 LOG_ERROR("Unable to prepare selection of path for origin '%s'", originIdentifier.utf8().data()); 372 return String(); 373 } 374 375 pathStatement.bindText(1, originIdentifier); 376 377 int result = pathStatement.step(); 378 if (result != SQLITE_ROW) 379 return String(); 380 381 return pathStatement.getColumnText(0); 162 return SQLiteFileSystem::appendDatabaseFileNameToPath(m_localStorageDirectory, filename); 382 163 } 383 164 -
trunk/Source/WebKit/UIProcess/WebStorage/LocalStorageDatabaseTracker.h
r231837 r232410 26 26 #pragma once 27 27 28 #include <WebCore/S QLiteDatabase.h>28 #include <WebCore/SecurityOriginData.h> 29 29 #include <wtf/HashSet.h> 30 30 #include <wtf/Optional.h> … … 35 35 #include <wtf/text/StringHash.h> 36 36 #include <wtf/text/WTFString.h> 37 38 namespace WebCore {39 class SecurityOrigin;40 struct SecurityOriginData;41 }42 37 43 38 namespace WebKit { … … 63 58 struct OriginDetails { 64 59 String originIdentifier; 65 std::optional<time_t>creationTime;66 std::optional<time_t>modificationTime;60 WallTime creationTime; 61 WallTime modificationTime; 67 62 }; 68 63 Vector<OriginDetails> originDetails(); … … 72 67 73 68 String databasePath(const String& filename) const; 74 String trackerDatabasePath() const;75 69 76 70 enum DatabaseOpeningStrategy { … … 78 72 SkipIfNonExistent 79 73 }; 80 void openTrackerDatabase(DatabaseOpeningStrategy);81 82 void importOriginIdentifiers();83 void updateTrackerDatabaseFromLocalStorageDatabaseFiles();84 85 void addDatabaseWithOriginIdentifier(const String& originIdentifier, const String& databasePath);86 void removeDatabaseWithOriginIdentifier(const String& originIdentifier);87 String pathForDatabaseWithOriginIdentifier(const String& originIdentifier);88 74 89 75 RefPtr<WorkQueue> m_queue; 90 76 String m_localStorageDirectory; 91 92 WebCore::SQLiteDatabase m_database;93 HashSet<String> m_origins;94 77 95 78 #if PLATFORM(IOS) -
trunk/Source/WebKit/UIProcess/WebStorage/StorageManager.h
r229979 r232410 28 28 #include "Connection.h" 29 29 #include "LocalStorageDatabaseTracker.h" 30 #include <WebCore/SecurityOriginData.h>31 #include <WebCore/SecurityOriginHash.h>32 30 #include <wtf/Forward.h> 33 31 #include <wtf/Function.h>
Note: See TracChangeset
for help on using the changeset viewer.