diff options
Diffstat (limited to 'Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp')
-rw-r--r-- | Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp | 517 |
1 files changed, 245 insertions, 272 deletions
diff --git a/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp b/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp index e5751ac59..b6b9d7a7c 100644 --- a/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp +++ b/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp @@ -31,13 +31,14 @@ #include "ApplicationCacheHost.h" #include "ApplicationCacheResource.h" #include "FileSystem.h" -#include "NotImplemented.h" #include "SQLiteDatabaseTracker.h" #include "SQLiteStatement.h" #include "SQLiteTransaction.h" #include "SecurityOrigin.h" +#include "SecurityOriginData.h" #include "URL.h" #include "UUID.h" +#include <wtf/NeverDestroyed.h> #include <wtf/StdLibExtras.h> #include <wtf/StringExtras.h> #include <wtf/text/CString.h> @@ -45,16 +46,13 @@ namespace WebCore { -static const char flatFileSubdirectory[] = "ApplicationCache"; - template <class T> class StorageIDJournal { public: ~StorageIDJournal() { - size_t size = m_records.size(); - for (size_t i = 0; i < size; ++i) - m_records[i].restore(); + for (auto& record : m_records) + record.restore(); } void add(T* resource, unsigned storageID) @@ -70,7 +68,7 @@ public: private: class Record { public: - Record() : m_resource(0), m_storageID(0) { } + Record() : m_resource(nullptr), m_storageID(0) { } Record(T* resource, unsigned storageID) : m_resource(resource), m_storageID(storageID) { } void restore() @@ -105,59 +103,55 @@ ApplicationCacheGroup* ApplicationCacheStorage::loadCacheGroup(const URL& manife openDatabase(false); if (!m_database.isOpen()) - return 0; + return nullptr; SQLiteStatement statement(m_database, "SELECT id, manifestURL, newestCache FROM CacheGroups WHERE newestCache IS NOT NULL AND manifestURL=?"); - if (statement.prepare() != SQLResultOk) - return 0; + if (statement.prepare() != SQLITE_OK) + return nullptr; statement.bindText(1, manifestURL); int result = statement.step(); - if (result == SQLResultDone) - return 0; + if (result == SQLITE_DONE) + return nullptr; - if (result != SQLResultRow) { + if (result != SQLITE_ROW) { LOG_ERROR("Could not load cache group, error \"%s\"", m_database.lastErrorMsg()); - return 0; + return nullptr; } unsigned newestCacheStorageID = static_cast<unsigned>(statement.getColumnInt64(2)); - RefPtr<ApplicationCache> cache = loadCache(newestCacheStorageID); + auto cache = loadCache(newestCacheStorageID); if (!cache) - return 0; + return nullptr; - ApplicationCacheGroup* group = new ApplicationCacheGroup(manifestURL); - - group->setStorageID(static_cast<unsigned>(statement.getColumnInt64(0))); - group->setNewestCache(cache.release()); - - return group; + auto& group = *new ApplicationCacheGroup(*this, manifestURL); + group.setStorageID(static_cast<unsigned>(statement.getColumnInt64(0))); + group.setNewestCache(cache.releaseNonNull()); + return &group; } ApplicationCacheGroup* ApplicationCacheStorage::findOrCreateCacheGroup(const URL& manifestURL) { ASSERT(!manifestURL.hasFragmentIdentifier()); - CacheGroupMap::AddResult result = m_cachesInMemory.add(manifestURL, nullptr); - + auto result = m_cachesInMemory.add(manifestURL, nullptr); if (!result.isNewEntry) { ASSERT(result.iterator->value); return result.iterator->value; } // Look up the group in the database - ApplicationCacheGroup* group = loadCacheGroup(manifestURL); + auto* group = loadCacheGroup(manifestURL); // If the group was not found we need to create it if (!group) { - group = new ApplicationCacheGroup(manifestURL); + group = new ApplicationCacheGroup(*this, manifestURL); m_cacheHostSet.add(urlHostHash(manifestURL)); } - + result.iterator->value = group; - return group; } @@ -185,10 +179,10 @@ void ApplicationCacheStorage::loadManifestHostHashes() // Fetch the host hashes. SQLiteStatement statement(m_database, "SELECT manifestHostHash FROM CacheGroups"); - if (statement.prepare() != SQLResultOk) + if (statement.prepare() != SQLITE_OK) return; - while (statement.step() == SQLResultRow) + while (statement.step() == SQLITE_ROW) m_cacheHostSet.add(static_cast<unsigned>(statement.getColumnInt64(0))); } @@ -200,7 +194,7 @@ ApplicationCacheGroup* ApplicationCacheStorage::cacheGroupForURL(const URL& url) // Hash the host name and see if there's a manifest with the same host. if (!m_cacheHostSet.contains(urlHostHash(url))) - return 0; + return nullptr; // Check if a cache already exists in memory. for (const auto& group : m_cachesInMemory.values()) { @@ -220,17 +214,17 @@ ApplicationCacheGroup* ApplicationCacheStorage::cacheGroupForURL(const URL& url) } if (!m_database.isOpen()) - return 0; + return nullptr; SQLiteTransactionInProgressAutoCounter transactionCounter; // Check the database. Look for all cache groups with a newest cache. SQLiteStatement statement(m_database, "SELECT id, manifestURL, newestCache FROM CacheGroups WHERE newestCache IS NOT NULL"); - if (statement.prepare() != SQLResultOk) - return 0; + if (statement.prepare() != SQLITE_OK) + return nullptr; int result; - while ((result = statement.step()) == SQLResultRow) { + while ((result = statement.step()) == SQLITE_ROW) { URL manifestURL = URL(ParsedURLString, statement.getColumnText(1)); if (m_cachesInMemory.contains(manifestURL)) @@ -242,30 +236,28 @@ ApplicationCacheGroup* ApplicationCacheStorage::cacheGroupForURL(const URL& url) // We found a cache group that matches. Now check if the newest cache has a resource with // a matching URL. unsigned newestCacheID = static_cast<unsigned>(statement.getColumnInt64(2)); - RefPtr<ApplicationCache> cache = loadCache(newestCacheID); + auto cache = loadCache(newestCacheID); if (!cache) continue; - ApplicationCacheResource* resource = cache->resourceForURL(url); + auto* resource = cache->resourceForURL(url); if (!resource) continue; if (resource->type() & ApplicationCacheResource::Foreign) continue; - ApplicationCacheGroup* group = new ApplicationCacheGroup(manifestURL); - - group->setStorageID(static_cast<unsigned>(statement.getColumnInt64(0))); - group->setNewestCache(cache.release()); - - m_cachesInMemory.set(group->manifestURL(), group); - - return group; + auto& group = *new ApplicationCacheGroup(*this, manifestURL); + group.setStorageID(static_cast<unsigned>(statement.getColumnInt64(0))); + group.setNewestCache(cache.releaseNonNull()); + m_cachesInMemory.set(group.manifestURL(), &group); + + return &group; } - if (result != SQLResultDone) + if (result != SQLITE_DONE) LOG_ERROR("Could not load cache group, error \"%s\"", m_database.lastErrorMsg()); - return 0; + return nullptr; } ApplicationCacheGroup* ApplicationCacheStorage::fallbackCacheGroupForURL(const URL& url) @@ -275,10 +267,7 @@ ApplicationCacheGroup* ApplicationCacheStorage::fallbackCacheGroupForURL(const U ASSERT(!url.hasFragmentIdentifier()); // Check if an appropriate cache already exists in memory. - CacheGroupMap::const_iterator end = m_cachesInMemory.end(); - for (CacheGroupMap::const_iterator it = m_cachesInMemory.begin(); it != end; ++it) { - ApplicationCacheGroup* group = it->value; - + for (auto* group : m_cachesInMemory.values()) { ASSERT(!group->isObsolete()); if (ApplicationCache* cache = group->newestCache()) { @@ -294,15 +283,15 @@ ApplicationCacheGroup* ApplicationCacheStorage::fallbackCacheGroupForURL(const U } if (!m_database.isOpen()) - return 0; + return nullptr; // Check the database. Look for all cache groups with a newest cache. SQLiteStatement statement(m_database, "SELECT id, manifestURL, newestCache FROM CacheGroups WHERE newestCache IS NOT NULL"); - if (statement.prepare() != SQLResultOk) - return 0; + if (statement.prepare() != SQLITE_OK) + return nullptr; int result; - while ((result = statement.step()) == SQLResultRow) { + while ((result = statement.step()) == SQLITE_ROW) { URL manifestURL = URL(ParsedURLString, statement.getColumnText(1)); if (m_cachesInMemory.contains(manifestURL)) @@ -315,7 +304,7 @@ ApplicationCacheGroup* ApplicationCacheStorage::fallbackCacheGroupForURL(const U // We found a cache group that matches. Now check if the newest cache has a resource with // a matching fallback namespace. unsigned newestCacheID = static_cast<unsigned>(statement.getColumnInt64(2)); - RefPtr<ApplicationCache> cache = loadCache(newestCacheID); + auto cache = loadCache(newestCacheID); URL fallbackURL; if (cache->isURLInOnlineWhitelist(url)) @@ -325,57 +314,48 @@ ApplicationCacheGroup* ApplicationCacheStorage::fallbackCacheGroupForURL(const U if (cache->resourceForURL(fallbackURL)->type() & ApplicationCacheResource::Foreign) continue; - ApplicationCacheGroup* group = new ApplicationCacheGroup(manifestURL); - - group->setStorageID(static_cast<unsigned>(statement.getColumnInt64(0))); - group->setNewestCache(cache.release()); - - m_cachesInMemory.set(group->manifestURL(), group); - - return group; + auto& group = *new ApplicationCacheGroup(*this, manifestURL); + group.setStorageID(static_cast<unsigned>(statement.getColumnInt64(0))); + group.setNewestCache(cache.releaseNonNull()); + + m_cachesInMemory.set(group.manifestURL(), &group); + + return &group; } - if (result != SQLResultDone) + if (result != SQLITE_DONE) LOG_ERROR("Could not load cache group, error \"%s\"", m_database.lastErrorMsg()); - return 0; + return nullptr; } -void ApplicationCacheStorage::cacheGroupDestroyed(ApplicationCacheGroup* group) +void ApplicationCacheStorage::cacheGroupDestroyed(ApplicationCacheGroup& group) { - if (group->isObsolete()) { - ASSERT(!group->storageID()); - ASSERT(m_cachesInMemory.get(group->manifestURL()) != group); + if (group.isObsolete()) { + ASSERT(!group.storageID()); + ASSERT(m_cachesInMemory.get(group.manifestURL()) != &group); return; } - ASSERT(m_cachesInMemory.get(group->manifestURL()) == group); + ASSERT(m_cachesInMemory.get(group.manifestURL()) == &group); - m_cachesInMemory.remove(group->manifestURL()); + m_cachesInMemory.remove(group.manifestURL()); // If the cache group is half-created, we don't want it in the saved set (as it is not stored in database). - if (!group->storageID()) - m_cacheHostSet.remove(urlHostHash(group->manifestURL())); + if (!group.storageID()) + m_cacheHostSet.remove(urlHostHash(group.manifestURL())); } -void ApplicationCacheStorage::cacheGroupMadeObsolete(ApplicationCacheGroup* group) +void ApplicationCacheStorage::cacheGroupMadeObsolete(ApplicationCacheGroup& group) { - ASSERT(m_cachesInMemory.get(group->manifestURL()) == group); - ASSERT(m_cacheHostSet.contains(urlHostHash(group->manifestURL()))); + ASSERT(m_cachesInMemory.get(group.manifestURL()) == &group); + ASSERT(m_cacheHostSet.contains(urlHostHash(group.manifestURL()))); - if (ApplicationCache* newestCache = group->newestCache()) + if (auto* newestCache = group.newestCache()) remove(newestCache); - m_cachesInMemory.remove(group->manifestURL()); - m_cacheHostSet.remove(urlHostHash(group->manifestURL())); -} - -void ApplicationCacheStorage::setCacheDirectory(const String& cacheDirectory) -{ - ASSERT(m_cacheDirectory.isNull()); - ASSERT(!cacheDirectory.isNull()); - - m_cacheDirectory = cacheDirectory; + m_cachesInMemory.remove(group.manifestURL()); + m_cacheHostSet.remove(urlHostHash(group.manifestURL())); } const String& ApplicationCacheStorage::cacheDirectory() const @@ -441,7 +421,7 @@ void ApplicationCacheStorage::setDefaultOriginQuota(int64_t quota) m_defaultOriginQuota = quota; } -bool ApplicationCacheStorage::calculateQuotaForOrigin(const SecurityOrigin* origin, int64_t& quota) +bool ApplicationCacheStorage::calculateQuotaForOrigin(const SecurityOrigin& origin, int64_t& quota) { SQLiteTransactionInProgressAutoCounter transactionCounter; @@ -449,14 +429,14 @@ bool ApplicationCacheStorage::calculateQuotaForOrigin(const SecurityOrigin* orig // Using the count to determine if a record existed or not is a safe way to determine // if a quota of 0 is real, from the record, or from null. SQLiteStatement statement(m_database, "SELECT COUNT(quota), quota FROM Origins WHERE origin=?"); - if (statement.prepare() != SQLResultOk) + if (statement.prepare() != SQLITE_OK) return false; - statement.bindText(1, origin->databaseIdentifier()); + statement.bindText(1, SecurityOriginData::fromSecurityOrigin(origin).databaseIdentifier()); int result = statement.step(); // Return the quota, or if it was null the default. - if (result == SQLResultRow) { + if (result == SQLITE_ROW) { bool wasNoRecord = statement.getColumnInt64(0) == 0; quota = wasNoRecord ? m_defaultOriginQuota : statement.getColumnInt64(1); return true; @@ -477,13 +457,13 @@ bool ApplicationCacheStorage::calculateUsageForOrigin(const SecurityOrigin* orig " INNER JOIN Origins ON CacheGroups.origin = Origins.origin" " INNER JOIN Caches ON CacheGroups.id = Caches.cacheGroup" " WHERE Origins.origin=?"); - if (statement.prepare() != SQLResultOk) + if (statement.prepare() != SQLITE_OK) return false; - statement.bindText(1, origin->databaseIdentifier()); + statement.bindText(1, SecurityOriginData::fromSecurityOrigin(*origin).databaseIdentifier()); int result = statement.step(); - if (result == SQLResultRow) { + if (result == SQLITE_ROW) { usage = statement.getColumnInt64(0); return true; } @@ -492,7 +472,7 @@ bool ApplicationCacheStorage::calculateUsageForOrigin(const SecurityOrigin* orig return false; } -bool ApplicationCacheStorage::calculateRemainingSizeForOriginExcludingCache(const SecurityOrigin* origin, ApplicationCache* cache, int64_t& remainingSize) +bool ApplicationCacheStorage::calculateRemainingSizeForOriginExcludingCache(const SecurityOrigin& origin, ApplicationCache* cache, int64_t& remainingSize) { SQLiteTransactionInProgressAutoCounter transactionCounter; @@ -520,17 +500,17 @@ bool ApplicationCacheStorage::calculateRemainingSizeForOriginExcludingCache(cons } SQLiteStatement statement(m_database, query); - if (statement.prepare() != SQLResultOk) + if (statement.prepare() != SQLITE_OK) return false; - statement.bindText(1, origin->databaseIdentifier()); + statement.bindText(1, SecurityOriginData::fromSecurityOrigin(origin).databaseIdentifier()); if (excludingCacheIdentifier != 0) statement.bindInt64(2, excludingCacheIdentifier); int result = statement.step(); // If the count was 0 that then we have to query the origin table directly // for its quota. Otherwise we can use the calculated value. - if (result == SQLResultRow) { + if (result == SQLITE_ROW) { int64_t numberOfCaches = statement.getColumnInt64(0); if (numberOfCaches == 0) calculateQuotaForOrigin(origin, remainingSize); @@ -555,11 +535,11 @@ bool ApplicationCacheStorage::storeUpdatedQuotaForOrigin(const SecurityOrigin* o return false; SQLiteStatement updateStatement(m_database, "UPDATE Origins SET quota=? WHERE origin=?"); - if (updateStatement.prepare() != SQLResultOk) + if (updateStatement.prepare() != SQLITE_OK) return false; updateStatement.bindInt64(1, quota); - updateStatement.bindText(2, origin->databaseIdentifier()); + updateStatement.bindText(2, SecurityOriginData::fromSecurityOrigin(*origin).databaseIdentifier()); return executeStatement(updateStatement); } @@ -590,7 +570,9 @@ void ApplicationCacheStorage::verifySchemaVersion() if (version == schemaVersion) return; - deleteTables(); + // Version will be 0 if we just created an empty file. Trying to delete tables would cause errors, because they don't exist yet. + if (version) + deleteTables(); // Update user version. SQLiteTransaction setDatabaseVersion(m_database); @@ -601,7 +583,7 @@ void ApplicationCacheStorage::verifySchemaVersion() ASSERT_UNUSED(unusedNumBytes, static_cast<int>(sizeof(userVersionSQL)) >= unusedNumBytes); SQLiteStatement statement(m_database, userVersionSQL); - if (statement.prepare() != SQLResultOk) + if (statement.prepare() != SQLITE_OK) return; executeStatement(statement); @@ -701,19 +683,19 @@ bool ApplicationCacheStorage::store(ApplicationCacheGroup* group, GroupStorageID deleteCacheGroupRecord(group->manifestURL()); SQLiteStatement statement(m_database, "INSERT INTO CacheGroups (manifestHostHash, manifestURL, origin) VALUES (?, ?, ?)"); - if (statement.prepare() != SQLResultOk) + if (statement.prepare() != SQLITE_OK) return false; statement.bindInt64(1, urlHostHash(group->manifestURL())); statement.bindText(2, group->manifestURL()); - statement.bindText(3, group->origin()->databaseIdentifier()); + statement.bindText(3, SecurityOriginData::fromSecurityOrigin(group->origin()).databaseIdentifier()); if (!executeStatement(statement)) return false; unsigned groupStorageID = static_cast<unsigned>(m_database.lastInsertRowID()); - if (!ensureOriginRecord(group->origin())) + if (!ensureOriginRecord(&group->origin())) return false; group->setStorageID(groupStorageID); @@ -729,7 +711,7 @@ bool ApplicationCacheStorage::store(ApplicationCache* cache, ResourceStorageIDJo ASSERT(storageIDJournal); SQLiteStatement statement(m_database, "INSERT INTO Caches (cacheGroup, size) VALUES (?, ?)"); - if (statement.prepare() != SQLResultOk) + if (statement.prepare() != SQLITE_OK) return false; statement.bindInt64(1, cache->group()->storageID()); @@ -741,28 +723,24 @@ bool ApplicationCacheStorage::store(ApplicationCache* cache, ResourceStorageIDJo unsigned cacheStorageID = static_cast<unsigned>(m_database.lastInsertRowID()); // Store all resources - { - ApplicationCache::ResourceMap::const_iterator end = cache->end(); - for (ApplicationCache::ResourceMap::const_iterator it = cache->begin(); it != end; ++it) { - unsigned oldStorageID = it->value->storageID(); - if (!store(it->value.get(), cacheStorageID)) - return false; + for (auto& resource : cache->resources().values()) { + unsigned oldStorageID = resource->storageID(); + if (!store(resource.get(), cacheStorageID)) + return false; - // Storing the resource succeeded. Log its old storageID in case - // it needs to be restored later. - storageIDJournal->add(it->value.get(), oldStorageID); - } + // Storing the resource succeeded. Log its old storageID in case + // it needs to be restored later. + storageIDJournal->add(resource.get(), oldStorageID); } // Store the online whitelist const Vector<URL>& onlineWhitelist = cache->onlineWhitelist(); { - size_t whitelistSize = onlineWhitelist.size(); - for (size_t i = 0; i < whitelistSize; ++i) { + for (auto& whitelistURL : onlineWhitelist) { SQLiteStatement statement(m_database, "INSERT INTO CacheWhitelistURLs (url, cache) VALUES (?, ?)"); statement.prepare(); - statement.bindText(1, onlineWhitelist[i]); + statement.bindText(1, whitelistURL); statement.bindInt64(2, cacheStorageID); if (!executeStatement(statement)) @@ -785,13 +763,12 @@ bool ApplicationCacheStorage::store(ApplicationCache* cache, ResourceStorageIDJo // Store fallback URLs. const FallbackURLVector& fallbackURLs = cache->fallbackURLs(); { - size_t fallbackCount = fallbackURLs.size(); - for (size_t i = 0; i < fallbackCount; ++i) { + for (auto& fallbackURL : fallbackURLs) { SQLiteStatement statement(m_database, "INSERT INTO FallbackURLs (namespace, fallbackURL, cache) VALUES (?, ?, ?)"); statement.prepare(); - statement.bindText(1, fallbackURLs[i].first); - statement.bindText(2, fallbackURLs[i].second); + statement.bindText(1, fallbackURL.first); + statement.bindText(2, fallbackURL.second); statement.bindInt64(3, cacheStorageID); if (!executeStatement(statement)) @@ -817,7 +794,7 @@ bool ApplicationCacheStorage::store(ApplicationCacheResource* resource, unsigned // First, insert the data SQLiteStatement dataStatement(m_database, "INSERT INTO CacheResourceData (data, path) VALUES (?, ?)"); - if (dataStatement.prepare() != SQLResultOk) + if (dataStatement.prepare() != SQLITE_OK) return false; @@ -827,12 +804,12 @@ bool ApplicationCacheStorage::store(ApplicationCacheResource* resource, unsigned else if (shouldStoreResourceAsFlatFile(resource)) { // First, check to see if creating the flat file would violate the maximum total quota. We don't need // to check the per-origin quota here, as it was already checked in storeNewestCache(). - if (m_database.totalSize() + flatFileAreaSize() + resource->data()->size() > m_maximumSize) { + if (m_database.totalSize() + flatFileAreaSize() + resource->data().size() > m_maximumSize) { m_isMaximumSizeReached = true; return false; } - String flatFileDirectory = pathByAppendingComponent(m_cacheDirectory, flatFileSubdirectory); + String flatFileDirectory = pathByAppendingComponent(m_cacheDirectory, m_flatFileSubdirectoryName); makeAllDirectories(flatFileDirectory); String extension; @@ -850,8 +827,8 @@ bool ApplicationCacheStorage::store(ApplicationCacheResource* resource, unsigned resource->setPath(fullPath); dataStatement.bindText(2, path); } else { - if (resource->data()->size()) - dataStatement.bindBlob(1, resource->data()->data(), resource->data()->size()); + if (resource->data().size()) + dataStatement.bindBlob(1, resource->data().data(), resource->data().size()); } if (!dataStatement.executeCommand()) { @@ -869,18 +846,17 @@ bool ApplicationCacheStorage::store(ApplicationCacheResource* resource, unsigned // Serialize the headers StringBuilder stringBuilder; - HTTPHeaderMap::const_iterator end = resource->response().httpHeaderFields().end(); - for (HTTPHeaderMap::const_iterator it = resource->response().httpHeaderFields().begin(); it!= end; ++it) { - stringBuilder.append(it->key); + for (const auto& header : resource->response().httpHeaderFields()) { + stringBuilder.append(header.key); stringBuilder.append(':'); - stringBuilder.append(it->value); + stringBuilder.append(header.value); stringBuilder.append('\n'); } String headers = stringBuilder.toString(); SQLiteStatement resourceStatement(m_database, "INSERT INTO CacheResources (url, statusCode, responseURL, headers, data, mimeType, textEncodingName) VALUES (?, ?, ?, ?, ?, ?, ?)"); - if (resourceStatement.prepare() != SQLResultOk) + if (resourceStatement.prepare() != SQLITE_OK) return false; // The same ApplicationCacheResource are used in ApplicationCacheResource::size() @@ -901,7 +877,7 @@ bool ApplicationCacheStorage::store(ApplicationCacheResource* resource, unsigned // Finally, insert the cache entry SQLiteStatement entryStatement(m_database, "INSERT INTO CacheEntries (cache, type, resource) VALUES (?, ?, ?)"); - if (entryStatement.prepare() != SQLResultOk) + if (entryStatement.prepare() != SQLITE_OK) return false; entryStatement.bindInt64(1, cacheStorageID); @@ -915,7 +891,7 @@ bool ApplicationCacheStorage::store(ApplicationCacheResource* resource, unsigned // release the resource's data and free up a potentially large amount // of memory: if (!fullPath.isEmpty()) - resource->data()->clear(); + resource->data().clear(); resource->setStorageID(resourceId); return true; @@ -930,7 +906,7 @@ bool ApplicationCacheStorage::storeUpdatedType(ApplicationCacheResource* resourc // First, insert the data SQLiteStatement entryStatement(m_database, "UPDATE CacheEntries SET type=? WHERE resource=?"); - if (entryStatement.prepare() != SQLResultOk) + if (entryStatement.prepare() != SQLITE_OK) return false; entryStatement.bindInt64(1, resource->type()); @@ -963,7 +939,7 @@ bool ApplicationCacheStorage::store(ApplicationCacheResource* resource, Applicat // A resource was added to the cache. Update the total data size for the cache. SQLiteStatement sizeUpdateStatement(m_database, "UPDATE Caches SET size=size+? WHERE id=?"); - if (sizeUpdateStatement.prepare() != SQLResultOk) + if (sizeUpdateStatement.prepare() != SQLITE_OK) return false; sizeUpdateStatement.bindInt64(1, resource->estimatedSizeInStorage()); @@ -980,10 +956,10 @@ bool ApplicationCacheStorage::ensureOriginRecord(const SecurityOrigin* origin) { ASSERT(SQLiteDatabaseTracker::hasTransactionInProgress()); SQLiteStatement insertOriginStatement(m_database, "INSERT INTO Origins (origin, quota) VALUES (?, ?)"); - if (insertOriginStatement.prepare() != SQLResultOk) + if (insertOriginStatement.prepare() != SQLITE_OK) return false; - insertOriginStatement.bindText(1, origin->databaseIdentifier()); + insertOriginStatement.bindText(1, SecurityOriginData::fromSecurityOrigin(*origin).databaseIdentifier()); insertOriginStatement.bindInt64(2, m_defaultOriginQuota); if (!executeStatement(insertOriginStatement)) return false; @@ -995,7 +971,7 @@ bool ApplicationCacheStorage::checkOriginQuota(ApplicationCacheGroup* group, App { // Check if the oldCache with the newCache would reach the per-origin quota. int64_t remainingSpaceInOrigin; - const SecurityOrigin* origin = group->origin(); + auto& origin = group->origin(); if (calculateRemainingSizeForOriginExcludingCache(origin, oldCache, remainingSpaceInOrigin)) { if (remainingSpaceInOrigin < newCache->estimatedSizeInStorage()) { int64_t quota; @@ -1013,7 +989,7 @@ bool ApplicationCacheStorage::checkOriginQuota(ApplicationCacheGroup* group, App return true; } -bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group, ApplicationCache* oldCache, FailureReason& failureReason) +bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup& group, ApplicationCache* oldCache, FailureReason& failureReason) { openDatabase(true); @@ -1029,24 +1005,24 @@ bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group, App // Check if this would reach the per-origin quota. int64_t totalSpaceNeededIgnored; - if (!checkOriginQuota(group, oldCache, group->newestCache(), totalSpaceNeededIgnored)) { + if (!checkOriginQuota(&group, oldCache, group.newestCache(), totalSpaceNeededIgnored)) { failureReason = OriginQuotaReached; return false; } GroupStorageIDJournal groupStorageIDJournal; - if (!group->storageID()) { + if (!group.storageID()) { // Store the group - if (!store(group, &groupStorageIDJournal)) { + if (!store(&group, &groupStorageIDJournal)) { checkForMaxSizeReached(); failureReason = isMaximumSizeReached() ? TotalQuotaReached : DiskOrOperationFailure; return false; } } - ASSERT(group->newestCache()); - ASSERT(!group->isObsolete()); - ASSERT(!group->newestCache()->storageID()); + ASSERT(group.newestCache()); + ASSERT(!group.isObsolete()); + ASSERT(!group.newestCache()->storageID()); // Log the storageID changes to the in-memory resource objects. The journal // object will roll them back automatically in case a database operation @@ -1054,7 +1030,7 @@ bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group, App ResourceStorageIDJournal resourceStorageIDJournal; // Store the newest cache - if (!store(group->newestCache(), &resourceStorageIDJournal)) { + if (!store(group.newestCache(), &resourceStorageIDJournal)) { checkForMaxSizeReached(); failureReason = isMaximumSizeReached() ? TotalQuotaReached : DiskOrOperationFailure; return false; @@ -1063,13 +1039,13 @@ bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group, App // Update the newest cache in the group. SQLiteStatement statement(m_database, "UPDATE CacheGroups SET newestCache=? WHERE id=?"); - if (statement.prepare() != SQLResultOk) { + if (statement.prepare() != SQLITE_OK) { failureReason = DiskOrOperationFailure; return false; } - statement.bindInt64(1, group->newestCache()->storageID()); - statement.bindInt64(2, group->storageID()); + statement.bindInt64(1, group.newestCache()->storageID()); + statement.bindInt64(2, group.storageID()); if (!executeStatement(statement)) { failureReason = DiskOrOperationFailure; @@ -1082,22 +1058,24 @@ bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group, App return true; } -bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group) +bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup& group) { // Ignore the reason for failing, just attempt the store. FailureReason ignoredFailureReason; - return storeNewestCache(group, 0, ignoredFailureReason); + return storeNewestCache(group, nullptr, ignoredFailureReason); } -template <typename CharacterType> -static inline void parseHeader(const CharacterType* header, size_t headerLength, ResourceResponse& response) +template<typename CharacterType> +static inline void parseHeader(const CharacterType* header, unsigned headerLength, ResourceResponse& response) { - size_t pos = find(header, headerLength, ':'); - ASSERT(pos != notFound); - - AtomicString headerName = AtomicString(header, pos); - String headerValue = String(header + pos + 1, headerLength - pos - 1); - + ASSERT(find(header, headerLength, ':') != notFound); + unsigned colonPosition = find(header, headerLength, ':'); + + // Save memory by putting the header names into atomic strings so each is stored only once, + // even though the setHTTPHeaderField function does not require an atomic string. + AtomicString headerName { header, colonPosition }; + String headerValue { header + colonPosition + 1, headerLength - colonPosition - 1 }; + response.setHTTPHeaderField(headerName, headerValue); } @@ -1124,25 +1102,25 @@ static inline void parseHeaders(const String& headers, ResourceResponse& respons } } -PassRefPtr<ApplicationCache> ApplicationCacheStorage::loadCache(unsigned storageID) +RefPtr<ApplicationCache> ApplicationCacheStorage::loadCache(unsigned storageID) { ASSERT(SQLiteDatabaseTracker::hasTransactionInProgress()); SQLiteStatement cacheStatement(m_database, "SELECT url, statusCode, type, mimeType, textEncodingName, headers, CacheResourceData.data, CacheResourceData.path FROM CacheEntries INNER JOIN CacheResources ON CacheEntries.resource=CacheResources.id " "INNER JOIN CacheResourceData ON CacheResourceData.id=CacheResources.data WHERE CacheEntries.cache=?"); - if (cacheStatement.prepare() != SQLResultOk) { + if (cacheStatement.prepare() != SQLITE_OK) { LOG_ERROR("Could not prepare cache statement, error \"%s\"", m_database.lastErrorMsg()); - return 0; + return nullptr; } cacheStatement.bindInt64(1, storageID); - RefPtr<ApplicationCache> cache = ApplicationCache::create(); + auto cache = ApplicationCache::create(); - String flatFileDirectory = pathByAppendingComponent(m_cacheDirectory, flatFileSubdirectory); + String flatFileDirectory = pathByAppendingComponent(m_cacheDirectory, m_flatFileSubdirectoryName); int result; - while ((result = cacheStatement.step()) == SQLResultRow) { + while ((result = cacheStatement.step()) == SQLITE_ROW) { URL url(ParsedURLString, cacheStatement.getColumnText(0)); int httpStatusCode = cacheStatement.getColumnInt(1); @@ -1152,7 +1130,7 @@ PassRefPtr<ApplicationCache> ApplicationCacheStorage::loadCache(unsigned storage Vector<char> blob; cacheStatement.getColumnBlobAsVector(6, blob); - RefPtr<SharedBuffer> data = SharedBuffer::adoptVector(blob); + auto data = SharedBuffer::adoptVector(blob); String path = cacheStatement.getColumnText(7); long long size = 0; @@ -1166,21 +1144,21 @@ PassRefPtr<ApplicationCache> ApplicationCacheStorage::loadCache(unsigned storage String mimeType = cacheStatement.getColumnText(3); String textEncodingName = cacheStatement.getColumnText(4); - ResourceResponse response(url, mimeType, size, textEncodingName, ""); + ResourceResponse response(url, mimeType, size, textEncodingName); response.setHTTPStatusCode(httpStatusCode); String headers = cacheStatement.getColumnText(5); parseHeaders(headers, response); - RefPtr<ApplicationCacheResource> resource = ApplicationCacheResource::create(url, response, type, data.release(), path); + auto resource = ApplicationCacheResource::create(url, response, type, WTFMove(data), path); if (type & ApplicationCacheResource::Manifest) - cache->setManifestResource(resource.release()); + cache->setManifestResource(WTFMove(resource)); else - cache->addResource(resource.release()); + cache->addResource(WTFMove(resource)); } - if (result != SQLResultDone) + if (result != SQLITE_DONE) LOG_ERROR("Could not load cache resources, error \"%s\"", m_database.lastErrorMsg()); if (!cache->manifestResource()) { @@ -1190,52 +1168,52 @@ PassRefPtr<ApplicationCache> ApplicationCacheStorage::loadCache(unsigned storage // Load the online whitelist SQLiteStatement whitelistStatement(m_database, "SELECT url FROM CacheWhitelistURLs WHERE cache=?"); - if (whitelistStatement.prepare() != SQLResultOk) - return 0; + if (whitelistStatement.prepare() != SQLITE_OK) + return nullptr; whitelistStatement.bindInt64(1, storageID); Vector<URL> whitelist; - while ((result = whitelistStatement.step()) == SQLResultRow) + while ((result = whitelistStatement.step()) == SQLITE_ROW) whitelist.append(URL(ParsedURLString, whitelistStatement.getColumnText(0))); - if (result != SQLResultDone) + if (result != SQLITE_DONE) LOG_ERROR("Could not load cache online whitelist, error \"%s\"", m_database.lastErrorMsg()); cache->setOnlineWhitelist(whitelist); // Load online whitelist wildcard flag. SQLiteStatement whitelistWildcardStatement(m_database, "SELECT wildcard FROM CacheAllowsAllNetworkRequests WHERE cache=?"); - if (whitelistWildcardStatement.prepare() != SQLResultOk) - return 0; + if (whitelistWildcardStatement.prepare() != SQLITE_OK) + return nullptr; whitelistWildcardStatement.bindInt64(1, storageID); result = whitelistWildcardStatement.step(); - if (result != SQLResultRow) + if (result != SQLITE_ROW) LOG_ERROR("Could not load cache online whitelist wildcard flag, error \"%s\"", m_database.lastErrorMsg()); cache->setAllowsAllNetworkRequests(whitelistWildcardStatement.getColumnInt64(0)); - if (whitelistWildcardStatement.step() != SQLResultDone) + if (whitelistWildcardStatement.step() != SQLITE_DONE) LOG_ERROR("Too many rows for online whitelist wildcard flag"); // Load fallback URLs. SQLiteStatement fallbackStatement(m_database, "SELECT namespace, fallbackURL FROM FallbackURLs WHERE cache=?"); - if (fallbackStatement.prepare() != SQLResultOk) - return 0; + if (fallbackStatement.prepare() != SQLITE_OK) + return nullptr; fallbackStatement.bindInt64(1, storageID); FallbackURLVector fallbackURLs; - while ((result = fallbackStatement.step()) == SQLResultRow) + while ((result = fallbackStatement.step()) == SQLITE_ROW) fallbackURLs.append(std::make_pair(URL(ParsedURLString, fallbackStatement.getColumnText(0)), URL(ParsedURLString, fallbackStatement.getColumnText(1)))); - if (result != SQLResultDone) + if (result != SQLITE_DONE) LOG_ERROR("Could not load fallback URLs, error \"%s\"", m_database.lastErrorMsg()); cache->setFallbackURLs(fallbackURLs); cache->setStorageID(storageID); - return cache.release(); + return WTFMove(cache); } void ApplicationCacheStorage::remove(ApplicationCache* cache) @@ -1254,7 +1232,7 @@ void ApplicationCacheStorage::remove(ApplicationCache* cache) // All associated data will be deleted by database triggers. SQLiteStatement statement(m_database, "DELETE FROM Caches WHERE id=?"); - if (statement.prepare() != SQLResultOk) + if (statement.prepare() != SQLITE_OK) return; statement.bindInt64(1, cache->storageID()); @@ -1265,7 +1243,7 @@ void ApplicationCacheStorage::remove(ApplicationCache* cache) if (cache->group()->newestCache() == cache) { // Currently, there are no triggers on the cache group, which is why the cache had to be removed separately above. SQLiteStatement groupStatement(m_database, "DELETE FROM CacheGroups WHERE id=?"); - if (groupStatement.prepare() != SQLResultOk) + if (groupStatement.prepare() != SQLITE_OK) return; groupStatement.bindInt64(1, cache->group()->storageID()); @@ -1294,10 +1272,9 @@ void ApplicationCacheStorage::empty() // Clear the storage IDs for the caches in memory. // The caches will still work, but cached resources will not be saved to disk // until a cache update process has been initiated. - CacheGroupMap::const_iterator end = m_cachesInMemory.end(); - for (CacheGroupMap::const_iterator it = m_cachesInMemory.begin(); it != end; ++it) - it->value->clearStorageID(); - + for (auto* group : m_cachesInMemory.values()) + group->clearStorageID(); + checkForDeletedResources(); } @@ -1313,7 +1290,7 @@ bool ApplicationCacheStorage::shouldStoreResourceAsFlatFile(ApplicationCacheReso || resource->response().mimeType().startsWith("video/", false); } -bool ApplicationCacheStorage::writeDataToUniqueFileInDirectory(SharedBuffer* data, const String& directory, String& path, const String& fileExtension) +bool ApplicationCacheStorage::writeDataToUniqueFileInDirectory(SharedBuffer& data, const String& directory, String& path, const String& fileExtension) { String fullPath; @@ -1332,10 +1309,10 @@ bool ApplicationCacheStorage::writeDataToUniqueFileInDirectory(SharedBuffer* dat if (!handle) return false; - int64_t writtenBytes = writeToFile(handle, data->data(), data->size()); + int64_t writtenBytes = writeToFile(handle, data.data(), data.size()); closeFile(handle); - if (writtenBytes != static_cast<int64_t>(data->size())) { + if (writtenBytes != static_cast<int64_t>(data.size())) { deleteFile(fullPath); return false; } @@ -1343,45 +1320,7 @@ bool ApplicationCacheStorage::writeDataToUniqueFileInDirectory(SharedBuffer* dat return true; } -bool ApplicationCacheStorage::storeCopyOfCache(const String& cacheDirectory, ApplicationCacheHost* cacheHost) -{ - SQLiteTransactionInProgressAutoCounter transactionCounter; - - ApplicationCache* cache = cacheHost->applicationCache(); - if (!cache) - return true; - - // Create a new cache. - RefPtr<ApplicationCache> cacheCopy = ApplicationCache::create(); - - cacheCopy->setOnlineWhitelist(cache->onlineWhitelist()); - cacheCopy->setFallbackURLs(cache->fallbackURLs()); - - // Traverse the cache and add copies of all resources. - ApplicationCache::ResourceMap::const_iterator end = cache->end(); - for (ApplicationCache::ResourceMap::const_iterator it = cache->begin(); it != end; ++it) { - ApplicationCacheResource* resource = it->value.get(); - - RefPtr<ApplicationCacheResource> resourceCopy = ApplicationCacheResource::create(resource->url(), resource->response(), resource->type(), resource->data(), resource->path()); - - cacheCopy->addResource(resourceCopy.release()); - } - - // Now create a new cache group. - OwnPtr<ApplicationCacheGroup> groupCopy(adoptPtr(new ApplicationCacheGroup(cache->group()->manifestURL(), true))); - - groupCopy->setNewestCache(cacheCopy); - - ApplicationCacheStorage copyStorage; - copyStorage.setCacheDirectory(cacheDirectory); - - // Empty the cache in case something was there before. - copyStorage.empty(); - - return copyStorage.storeNewestCache(groupCopy.get()); -} - -bool ApplicationCacheStorage::manifestURLs(Vector<URL>* urls) +bool ApplicationCacheStorage::getManifestURLs(Vector<URL>* urls) { SQLiteTransactionInProgressAutoCounter transactionCounter; @@ -1392,10 +1331,10 @@ bool ApplicationCacheStorage::manifestURLs(Vector<URL>* urls) SQLiteStatement selectURLs(m_database, "SELECT manifestURL FROM CacheGroups"); - if (selectURLs.prepare() != SQLResultOk) + if (selectURLs.prepare() != SQLITE_OK) return false; - while (selectURLs.step() == SQLResultRow) + while (selectURLs.step() == SQLITE_ROW) urls->append(URL(ParsedURLString, selectURLs.getColumnText(0))); return true; @@ -1411,16 +1350,16 @@ bool ApplicationCacheStorage::cacheGroupSize(const String& manifestURL, int64_t* return false; SQLiteStatement statement(m_database, "SELECT sum(Caches.size) FROM Caches INNER JOIN CacheGroups ON Caches.cacheGroup=CacheGroups.id WHERE CacheGroups.manifestURL=?"); - if (statement.prepare() != SQLResultOk) + if (statement.prepare() != SQLITE_OK) return false; statement.bindText(1, manifestURL); int result = statement.step(); - if (result == SQLResultDone) + if (result == SQLITE_DONE) return false; - if (result != SQLResultRow) { + if (result != SQLITE_ROW) { LOG_ERROR("Could not get the size of the cache group, error \"%s\"", m_database.lastErrorMsg()); return false; } @@ -1433,23 +1372,23 @@ bool ApplicationCacheStorage::deleteCacheGroupRecord(const String& manifestURL) { ASSERT(SQLiteDatabaseTracker::hasTransactionInProgress()); SQLiteStatement idStatement(m_database, "SELECT id FROM CacheGroups WHERE manifestURL=?"); - if (idStatement.prepare() != SQLResultOk) + if (idStatement.prepare() != SQLITE_OK) return false; idStatement.bindText(1, manifestURL); int result = idStatement.step(); - if (result != SQLResultRow) + if (result != SQLITE_ROW) return false; int64_t groupId = idStatement.getColumnInt64(0); SQLiteStatement cacheStatement(m_database, "DELETE FROM Caches WHERE cacheGroup=?"); - if (cacheStatement.prepare() != SQLResultOk) + if (cacheStatement.prepare() != SQLITE_OK) return false; SQLiteStatement groupStatement(m_database, "DELETE FROM CacheGroups WHERE id=?"); - if (groupStatement.prepare() != SQLResultOk) + if (groupStatement.prepare() != SQLITE_OK) return false; cacheStatement.bindInt64(1, groupId); @@ -1464,10 +1403,11 @@ bool ApplicationCacheStorage::deleteCacheGroup(const String& manifestURL) SQLiteTransactionInProgressAutoCounter transactionCounter; SQLiteTransaction deleteTransaction(m_database); + // Check to see if the group is in memory. - ApplicationCacheGroup* group = m_cachesInMemory.get(manifestURL); + auto* group = m_cachesInMemory.get(manifestURL); if (group) - cacheGroupMadeObsolete(group); + cacheGroupMadeObsolete(*group); else { // The cache group is not in memory, so remove it from the disk. openDatabase(false); @@ -1480,9 +1420,9 @@ bool ApplicationCacheStorage::deleteCacheGroup(const String& manifestURL) } deleteTransaction.commit(); - + checkForDeletedResources(); - + return true; } @@ -1499,7 +1439,7 @@ void ApplicationCacheStorage::vacuumDatabaseFile() void ApplicationCacheStorage::checkForMaxSizeReached() { - if (m_database.lastError() == SQLResultFull) + if (m_database.lastError() == SQLITE_FULL) m_isMaximumSizeReached = true; } @@ -1516,10 +1456,10 @@ void ApplicationCacheStorage::checkForDeletedResources() "ON DeletedCacheResources.path = CacheResourceData.path " "WHERE (SELECT DeletedCacheResources.path == CacheResourceData.path) IS NULL"); - if (selectPaths.prepare() != SQLResultOk) + if (selectPaths.prepare() != SQLITE_OK) return; - if (selectPaths.step() != SQLResultRow) + if (selectPaths.step() != SQLITE_ROW) return; do { @@ -1527,7 +1467,7 @@ void ApplicationCacheStorage::checkForDeletedResources() if (path.isEmpty()) continue; - String flatFileDirectory = pathByAppendingComponent(m_cacheDirectory, flatFileSubdirectory); + String flatFileDirectory = pathByAppendingComponent(m_cacheDirectory, m_flatFileSubdirectoryName); String fullPath = pathByAppendingComponent(flatFileDirectory, path); // Don't exit the flatFileDirectory! This should only happen if the "path" entry contains a directory @@ -1536,7 +1476,7 @@ void ApplicationCacheStorage::checkForDeletedResources() continue; deleteFile(fullPath); - } while (selectPaths.step() == SQLResultRow); + } while (selectPaths.step() == SQLITE_ROW); executeSQLCommand("DELETE FROM DeletedCacheResources"); } @@ -1549,14 +1489,14 @@ long long ApplicationCacheStorage::flatFileAreaSize() SQLiteStatement selectPaths(m_database, "SELECT path FROM CacheResourceData WHERE path NOT NULL"); - if (selectPaths.prepare() != SQLResultOk) { + if (selectPaths.prepare() != SQLITE_OK) { LOG_ERROR("Could not load flat file cache resource data, error \"%s\"", m_database.lastErrorMsg()); return 0; } long long totalSize = 0; - String flatFileDirectory = pathByAppendingComponent(m_cacheDirectory, flatFileSubdirectory); - while (selectPaths.step() == SQLResultRow) { + String flatFileDirectory = pathByAppendingComponent(m_cacheDirectory, m_flatFileSubdirectoryName); + while (selectPaths.step() == SQLITE_ROW) { String path = selectPaths.getColumnText(0); String fullPath = pathByAppendingComponent(flatFileDirectory, path); long long pathSize = 0; @@ -1571,18 +1511,12 @@ long long ApplicationCacheStorage::flatFileAreaSize() void ApplicationCacheStorage::getOriginsWithCache(HashSet<RefPtr<SecurityOrigin>>& origins) { Vector<URL> urls; - if (!manifestURLs(&urls)) { - LOG_ERROR("Failed to retrieve ApplicationCache manifest URLs"); - return; - } + getManifestURLs(&urls); // Multiple manifest URLs might share the same SecurityOrigin, so we might be creating extra, wasted origins here. // The current schema doesn't allow for a more efficient way of building this list. - size_t count = urls.size(); - for (size_t i = 0; i < count; ++i) { - RefPtr<SecurityOrigin> origin = SecurityOrigin::create(urls[i]); - origins.add(origin); - } + for (auto& url : urls) + origins.add(SecurityOrigin::create(url)); } void ApplicationCacheStorage::deleteAllEntries() @@ -1591,18 +1525,57 @@ void ApplicationCacheStorage::deleteAllEntries() vacuumDatabaseFile(); } -ApplicationCacheStorage::ApplicationCacheStorage() - : m_maximumSize(ApplicationCacheStorage::noQuota()) +void ApplicationCacheStorage::deleteAllCaches() +{ + HashSet<RefPtr<SecurityOrigin>> origins; + + getOriginsWithCache(origins); + for (auto& origin : origins) + deleteCacheForOrigin(*origin); + + vacuumDatabaseFile(); +} + +void ApplicationCacheStorage::deleteCacheForOrigin(const SecurityOrigin& securityOrigin) +{ + Vector<URL> urls; + if (!getManifestURLs(&urls)) { + LOG_ERROR("Failed to retrieve ApplicationCache manifest URLs"); + return; + } + + URL originURL(URL(), securityOrigin.toString()); + + for (const auto& url : urls) { + if (!protocolHostAndPortAreEqual(url, originURL)) + continue; + + if (auto* group = findInMemoryCacheGroup(url)) + group->makeObsolete(); + else + deleteCacheGroup(url); + } +} + +int64_t ApplicationCacheStorage::diskUsageForOrigin(const SecurityOrigin& securityOrigin) +{ + int64_t usage = 0; + calculateUsageForOrigin(&securityOrigin, usage); + return usage; +} + +ApplicationCacheStorage::ApplicationCacheStorage(const String& cacheDirectory, const String& flatFileSubdirectoryName) + : m_cacheDirectory(cacheDirectory) + , m_flatFileSubdirectoryName(flatFileSubdirectoryName) + , m_maximumSize(ApplicationCacheStorage::noQuota()) , m_isMaximumSizeReached(false) , m_defaultOriginQuota(ApplicationCacheStorage::noQuota()) { } -ApplicationCacheStorage& cacheStorage() +Ref<ApplicationCacheStorage> ApplicationCacheStorage::create(const String& cacheDirectory, const String& flatFileSubdirectoryName) { - DEFINE_STATIC_LOCAL(ApplicationCacheStorage, storage, ()); - - return storage; + return adoptRef(*new ApplicationCacheStorage(cacheDirectory, flatFileSubdirectoryName)); } -} // namespace WebCore +} |