LocalStorageDatabaseTracker.cpp [plain text]
#include "config.h"
#include "LocalStorageDatabaseTracker.h"
#include "Logging.h"
#include <WebCore/FileSystem.h>
#include <WebCore/SQLiteFileSystem.h>
#include <WebCore/SQLiteStatement.h>
#include <WebCore/TextEncoding.h>
#include <wtf/MainThread.h>
#include <wtf/RunLoop.h>
#include <wtf/WorkQueue.h>
#include <wtf/text/CString.h>
using namespace WebCore;
namespace WebKit {
Ref<LocalStorageDatabaseTracker> LocalStorageDatabaseTracker::create(Ref<WorkQueue>&& queue, const String& localStorageDirectory)
{
return adoptRef(*new LocalStorageDatabaseTracker(WTFMove(queue), localStorageDirectory));
}
LocalStorageDatabaseTracker::LocalStorageDatabaseTracker(Ref<WorkQueue>&& queue, const String& localStorageDirectory)
: m_queue(WTFMove(queue))
, m_localStorageDirectory(localStorageDirectory.isolatedCopy())
{
ASSERT(!m_localStorageDirectory.isEmpty());
UTF8Encoding();
m_queue->dispatch([protectedThis = makeRef(*this)]() mutable {
SQLiteFileSystem::deleteDatabaseFile(protectedThis->databasePath("StorageTracker.db"));
});
}
LocalStorageDatabaseTracker::~LocalStorageDatabaseTracker()
{
}
String LocalStorageDatabaseTracker::databasePath(const SecurityOriginData& securityOrigin) const
{
return databasePath(securityOrigin.databaseIdentifier() + ".localstorage");
}
void LocalStorageDatabaseTracker::didOpenDatabaseWithOrigin(const SecurityOriginData& securityOrigin)
{
}
void LocalStorageDatabaseTracker::deleteDatabaseWithOrigin(const SecurityOriginData& securityOrigin)
{
auto path = databasePath(securityOrigin);
if (!path.isEmpty())
SQLiteFileSystem::deleteDatabaseFile(path);
}
void LocalStorageDatabaseTracker::deleteAllDatabases()
{
auto paths = FileSystem::listDirectory(m_localStorageDirectory, "*.localstorage");
for (auto path : paths) {
SQLiteFileSystem::deleteDatabaseFile(path);
}
SQLiteFileSystem::deleteEmptyDatabaseDirectory(m_localStorageDirectory);
}
Vector<SecurityOriginData> LocalStorageDatabaseTracker::databasesModifiedSince(WallTime time)
{
Vector<SecurityOriginData> databaseOriginsModified;
auto databaseOrigins = origins();
for (auto origin : databaseOrigins) {
auto path = databasePath(origin);
auto modificationTime = WallTime::fromRawSeconds(SQLiteFileSystem::databaseModificationTime(path));
if (modificationTime >= time)
databaseOriginsModified.append(origin);
}
return databaseOriginsModified;
}
Vector<SecurityOriginData> LocalStorageDatabaseTracker::origins() const
{
Vector<SecurityOriginData> databaseOrigins;
auto paths = FileSystem::listDirectory(m_localStorageDirectory, "*.localstorage");
for (auto path : paths) {
auto filename = FileSystem::pathGetFileName(path);
auto originIdentifier = filename.substring(0, filename.length() - strlen(".localstorage"));
auto origin = SecurityOriginData::fromDatabaseIdentifier(originIdentifier);
if (origin)
databaseOrigins.append(origin.value());
else
RELEASE_LOG_ERROR(LocalStorageDatabaseTracker, "Unable to extract origin from path %s", path.utf8().data());
}
return databaseOrigins;
}
Vector<LocalStorageDatabaseTracker::OriginDetails> LocalStorageDatabaseTracker::originDetails()
{
Vector<OriginDetails> result;
auto databaseOrigins = origins();
result.reserveInitialCapacity(databaseOrigins.size());
for (auto origin : databaseOrigins) {
String path = databasePath(origin);
OriginDetails details;
details.originIdentifier = origin.databaseIdentifier();
details.creationTime = WallTime::fromRawSeconds(SQLiteFileSystem::databaseCreationTime(path));
details.modificationTime = WallTime::fromRawSeconds(SQLiteFileSystem::databaseModificationTime(path));
result.uncheckedAppend(details);
}
return result;
}
String LocalStorageDatabaseTracker::databasePath(const String& filename) const
{
if (!SQLiteFileSystem::ensureDatabaseDirectoryExists(m_localStorageDirectory)) {
LOG_ERROR("Unable to create LocalStorage database path %s", m_localStorageDirectory.utf8().data());
return String();
}
#if PLATFORM(IOS)
platformMaybeExcludeFromBackup();
#endif
return SQLiteFileSystem::appendDatabaseFileNameToPath(m_localStorageDirectory, filename);
}
}