summaryrefslogtreecommitdiff
path: root/Source/WebCore/loader/appcache
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/loader/appcache
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/loader/appcache')
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCache.cpp122
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCache.h64
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCacheAllInOne.cpp32
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp628
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCacheGroup.h100
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCacheHost.cpp315
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCacheHost.h291
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCacheResource.cpp12
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCacheResource.h15
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp517
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCacheStorage.h88
-rw-r--r--Source/WebCore/loader/appcache/DOMApplicationCache.cpp104
-rw-r--r--Source/WebCore/loader/appcache/DOMApplicationCache.h61
-rw-r--r--Source/WebCore/loader/appcache/DOMApplicationCache.idl35
-rw-r--r--Source/WebCore/loader/appcache/ManifestParser.cpp34
-rw-r--r--Source/WebCore/loader/appcache/ManifestParser.h24
16 files changed, 1132 insertions, 1310 deletions
diff --git a/Source/WebCore/loader/appcache/ApplicationCache.cpp b/Source/WebCore/loader/appcache/ApplicationCache.cpp
index 983becc21..a95ed2cac 100644
--- a/Source/WebCore/loader/appcache/ApplicationCache.cpp
+++ b/Source/WebCore/loader/appcache/ApplicationCache.cpp
@@ -30,7 +30,6 @@
#include "ApplicationCacheResource.h"
#include "ApplicationCacheStorage.h"
#include "ResourceRequest.h"
-#include "SecurityOrigin.h"
#include <algorithm>
#include <stdio.h>
#include <wtf/text/CString.h>
@@ -43,17 +42,13 @@ static inline bool fallbackURLLongerThan(const std::pair<URL, URL>& lhs, const s
}
ApplicationCache::ApplicationCache()
- : m_group(0)
- , m_manifest(0)
- , m_estimatedSizeInStorage(0)
- , m_storageID(0)
{
}
ApplicationCache::~ApplicationCache()
{
- if (m_group && !m_group->isCopy())
- m_group->cacheDestroyed(this);
+ if (m_group)
+ m_group->cacheDestroyed(*this);
}
void ApplicationCache::setGroup(ApplicationCacheGroup* group)
@@ -62,59 +57,41 @@ void ApplicationCache::setGroup(ApplicationCacheGroup* group)
m_group = group;
}
-bool ApplicationCache::isComplete() const
+bool ApplicationCache::isComplete()
{
- return !m_group->cacheIsBeingUpdated(this);
+ return m_group && m_group->cacheIsComplete(*this);
}
-void ApplicationCache::setManifestResource(PassRefPtr<ApplicationCacheResource> manifest)
+void ApplicationCache::setManifestResource(Ref<ApplicationCacheResource>&& manifest)
{
- ASSERT(manifest);
ASSERT(!m_manifest);
ASSERT(manifest->type() & ApplicationCacheResource::Manifest);
-
- m_manifest = manifest.get();
-
- addResource(manifest);
+
+ m_manifest = manifest.ptr();
+
+ addResource(WTFMove(manifest));
}
-void ApplicationCache::addResource(PassRefPtr<ApplicationCacheResource> resource)
+void ApplicationCache::addResource(Ref<ApplicationCacheResource>&& resource)
{
- ASSERT(resource);
-
- const String& url = resource->url();
-
+ auto& url = resource->url();
+
+ ASSERT(!URL(ParsedURLString, url).hasFragmentIdentifier());
ASSERT(!m_resources.contains(url));
-
+
if (m_storageID) {
ASSERT(!resource->storageID());
ASSERT(resource->type() & ApplicationCacheResource::Master);
-
+
// Add the resource to the storage.
- cacheStorage().store(resource.get(), this);
+ m_group->storage().store(resource.ptr(), this);
}
m_estimatedSizeInStorage += resource->estimatedSizeInStorage();
- m_resources.set(url, resource);
+ m_resources.set(url, WTFMove(resource));
}
-unsigned ApplicationCache::removeResource(const String& url)
-{
- HashMap<String, RefPtr<ApplicationCacheResource>>::iterator it = m_resources.find(url);
- if (it == m_resources.end())
- return 0;
-
- // The resource exists, get its type so we can return it.
- unsigned type = it->value->type();
-
- m_estimatedSizeInStorage -= it->value->estimatedSizeInStorage();
-
- m_resources.remove(it);
-
- return type;
-}
-
ApplicationCacheResource* ApplicationCache::resourceForURL(const String& url)
{
ASSERT(!URL(ParsedURLString, url).hasFragmentIdentifier());
@@ -123,25 +100,17 @@ ApplicationCacheResource* ApplicationCache::resourceForURL(const String& url)
bool ApplicationCache::requestIsHTTPOrHTTPSGet(const ResourceRequest& request)
{
- if (!request.url().protocolIsInHTTPFamily())
- return false;
-
- if (!equalIgnoringCase(request.httpMethod(), "GET"))
- return false;
-
- return true;
-}
+ return request.url().protocolIsInHTTPFamily() && equalLettersIgnoringASCIICase(request.httpMethod(), "get");
+}
ApplicationCacheResource* ApplicationCache::resourceForRequest(const ResourceRequest& request)
{
// We only care about HTTP/HTTPS GET requests.
if (!requestIsHTTPOrHTTPSGet(request))
- return 0;
+ return nullptr;
URL url(request.url());
- if (url.hasFragmentIdentifier())
- url.removeFragmentIdentifier();
-
+ url.removeFragmentIdentifier();
return resourceForURL(url);
}
@@ -153,9 +122,8 @@ void ApplicationCache::setOnlineWhitelist(const Vector<URL>& onlineWhitelist)
bool ApplicationCache::isURLInOnlineWhitelist(const URL& url)
{
- size_t whitelistSize = m_onlineWhitelist.size();
- for (size_t i = 0; i < whitelistSize; ++i) {
- if (protocolHostAndPortAreEqual(url, m_onlineWhitelist[i]) && url.string().startsWith(m_onlineWhitelist[i].string()))
+ for (auto& whitelistURL : m_onlineWhitelist) {
+ if (protocolHostAndPortAreEqual(url, whitelistURL) && url.string().startsWith(whitelistURL.string()))
return true;
}
return false;
@@ -171,11 +139,10 @@ void ApplicationCache::setFallbackURLs(const FallbackURLVector& fallbackURLs)
bool ApplicationCache::urlMatchesFallbackNamespace(const URL& url, URL* fallbackURL)
{
- size_t fallbackCount = m_fallbackURLs.size();
- for (size_t i = 0; i < fallbackCount; ++i) {
- if (protocolHostAndPortAreEqual(url, m_fallbackURLs[i].first) && url.string().startsWith(m_fallbackURLs[i].first.string())) {
+ for (auto& fallback : m_fallbackURLs) {
+ if (protocolHostAndPortAreEqual(url, fallback.first) && url.string().startsWith(fallback.first.string())) {
if (fallbackURL)
- *fallbackURL = m_fallbackURLs[i].second;
+ *fallbackURL = fallback.second;
return true;
}
}
@@ -190,43 +157,12 @@ void ApplicationCache::clearStorageID()
resource->clearStorageID();
}
-void ApplicationCache::deleteCacheForOrigin(SecurityOrigin* origin)
-{
- Vector<URL> urls;
- if (!cacheStorage().manifestURLs(&urls)) {
- LOG_ERROR("Failed to retrieve ApplicationCache manifest URLs");
- return;
- }
-
- URL originURL(URL(), origin->toString());
-
- size_t count = urls.size();
- for (size_t i = 0; i < count; ++i) {
- if (protocolHostAndPortAreEqual(urls[i], originURL)) {
- ApplicationCacheGroup* group = cacheStorage().findInMemoryCacheGroup(urls[i]);
- if (group)
- group->makeObsolete();
- else
- cacheStorage().deleteCacheGroup(urls[i]);
- }
- }
-}
-
-int64_t ApplicationCache::diskUsageForOrigin(SecurityOrigin* origin)
-{
- int64_t usage = 0;
- cacheStorage().calculateUsageForOrigin(origin, usage);
- return usage;
-}
-
#ifndef NDEBUG
void ApplicationCache::dump()
{
- HashMap<String, RefPtr<ApplicationCacheResource>>::const_iterator end = m_resources.end();
-
- for (HashMap<String, RefPtr<ApplicationCacheResource>>::const_iterator it = m_resources.begin(); it != end; ++it) {
- printf("%s ", it->key.ascii().data());
- ApplicationCacheResource::dumpType(it->value->type());
+ for (const auto& urlAndResource : m_resources) {
+ printf("%s ", urlAndResource.key.utf8().data());
+ ApplicationCacheResource::dumpType(urlAndResource.value->type());
}
}
#endif
diff --git a/Source/WebCore/loader/appcache/ApplicationCache.h b/Source/WebCore/loader/appcache/ApplicationCache.h
index 680635def..5df5f6017 100644
--- a/Source/WebCore/loader/appcache/ApplicationCache.h
+++ b/Source/WebCore/loader/appcache/ApplicationCache.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008-2017 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,45 +23,35 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ApplicationCache_h
-#define ApplicationCache_h
+#pragma once
#include <wtf/HashMap.h>
-#include <wtf/HashSet.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
#include <wtf/text/StringHash.h>
-#include <wtf/text/WTFString.h>
namespace WebCore {
class ApplicationCacheGroup;
class ApplicationCacheResource;
-class DocumentLoader;
-class URL;
class ResourceRequest;
-class SecurityOrigin;
+class URL;
-typedef Vector<std::pair<URL, URL>> FallbackURLVector;
+using FallbackURLVector = Vector<std::pair<URL, URL>>;
class ApplicationCache : public RefCounted<ApplicationCache> {
public:
- static PassRefPtr<ApplicationCache> create() { return adoptRef(new ApplicationCache); }
-
- static void deleteCacheForOrigin(SecurityOrigin*);
-
+ static Ref<ApplicationCache> create() { return adoptRef(*new ApplicationCache); }
+
~ApplicationCache();
- void addResource(PassRefPtr<ApplicationCacheResource> resource);
- unsigned removeResource(const String& url);
-
- void setManifestResource(PassRefPtr<ApplicationCacheResource> manifest);
+ void addResource(Ref<ApplicationCacheResource>&&);
+
+ void setManifestResource(Ref<ApplicationCacheResource>&&);
ApplicationCacheResource* manifestResource() const { return m_manifest; }
-
+
void setGroup(ApplicationCacheGroup*);
ApplicationCacheGroup* group() const { return m_group; }
- bool isComplete() const;
+ bool isComplete();
ApplicationCacheResource* resourceForRequest(const ResourceRequest&);
ApplicationCacheResource* resourceForURL(const String& url);
@@ -74,45 +64,39 @@ public:
void setFallbackURLs(const FallbackURLVector&);
const FallbackURLVector& fallbackURLs() const { return m_fallbackURLs; }
- bool urlMatchesFallbackNamespace(const URL&, URL* fallbackURL = 0);
-
+ bool urlMatchesFallbackNamespace(const URL&, URL* fallbackURL = nullptr);
+
#ifndef NDEBUG
void dump();
#endif
- typedef HashMap<String, RefPtr<ApplicationCacheResource>> ResourceMap;
- ResourceMap::const_iterator begin() const { return m_resources.begin(); }
- ResourceMap::const_iterator end() const { return m_resources.end(); }
-
+ using ResourceMap = HashMap<String, RefPtr<ApplicationCacheResource>>;
+ const ResourceMap& resources() const { return m_resources; }
+
void setStorageID(unsigned storageID) { m_storageID = storageID; }
unsigned storageID() const { return m_storageID; }
void clearStorageID();
-
+
static bool requestIsHTTPOrHTTPSGet(const ResourceRequest&);
- static int64_t diskUsageForOrigin(SecurityOrigin*);
-
int64_t estimatedSizeInStorage() const { return m_estimatedSizeInStorage; }
private:
ApplicationCache();
-
- ApplicationCacheGroup* m_group;
+
+ ApplicationCacheGroup* m_group { nullptr };
ResourceMap m_resources;
- ApplicationCacheResource* m_manifest;
+ ApplicationCacheResource* m_manifest { nullptr };
- bool m_allowAllNetworkRequests;
+ bool m_allowAllNetworkRequests { false };
Vector<URL> m_onlineWhitelist;
FallbackURLVector m_fallbackURLs;
// The total size of the resources belonging to this Application Cache instance.
- // This is an estimation of the size this Application Cache occupies in the
- // database file.
- int64_t m_estimatedSizeInStorage;
+ // This is an estimation of the size this Application Cache occupies in the database file.
+ int64_t m_estimatedSizeInStorage { 0 };
- unsigned m_storageID;
+ unsigned m_storageID { 0 };
};
} // namespace WebCore
-
-#endif // ApplicationCache_h
diff --git a/Source/WebCore/loader/appcache/ApplicationCacheAllInOne.cpp b/Source/WebCore/loader/appcache/ApplicationCacheAllInOne.cpp
new file mode 100644
index 000000000..73eaf7214
--- /dev/null
+++ b/Source/WebCore/loader/appcache/ApplicationCacheAllInOne.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This all-in-one cpp file cuts down on template bloat to allow us to build our Windows release build.
+
+#include "ApplicationCache.cpp"
+#include "ApplicationCacheGroup.cpp"
+#include "ApplicationCacheHost.cpp"
+#include "ApplicationCacheResource.cpp"
+#include "ApplicationCacheStorage.cpp"
diff --git a/Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp b/Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp
index 8e67597a6..9f9ab000c 100644
--- a/Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp
+++ b/Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2010 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008-2017 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -20,7 +20,7 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -32,161 +32,151 @@
#include "ApplicationCacheStorage.h"
#include "Chrome.h"
#include "ChromeClient.h"
-#include "Console.h"
#include "DOMApplicationCache.h"
-#include "DOMWindow.h"
#include "DocumentLoader.h"
+#include "EventNames.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
+#include "HTTPHeaderNames.h"
#include "InspectorInstrumentation.h"
#include "ManifestParser.h"
#include "Page.h"
-#include "ResourceBuffer.h"
+#include "ProgressTracker.h"
#include "ResourceHandle.h"
-#include "ScriptProfile.h"
#include "SecurityOrigin.h"
#include "Settings.h"
#include <wtf/HashMap.h>
#include <wtf/MainThread.h>
-#if ENABLE(INSPECTOR)
-#include "ProgressTracker.h"
-#endif
-
namespace WebCore {
-ApplicationCacheGroup::ApplicationCacheGroup(const URL& manifestURL, bool isCopy)
- : m_manifestURL(manifestURL)
+ApplicationCacheGroup::ApplicationCacheGroup(Ref<ApplicationCacheStorage>&& storage, const URL& manifestURL)
+ : m_storage(WTFMove(storage))
+ , m_manifestURL(manifestURL)
, m_origin(SecurityOrigin::create(manifestURL))
- , m_updateStatus(Idle)
- , m_downloadingPendingMasterResourceLoadersCount(0)
- , m_progressTotal(0)
- , m_progressDone(0)
- , m_frame(0)
- , m_storageID(0)
- , m_isObsolete(false)
- , m_completionType(None)
- , m_isCopy(isCopy)
- , m_calledReachedMaxAppCacheSize(false)
, m_availableSpaceInQuota(ApplicationCacheStorage::unknownQuota())
- , m_originQuotaExceededPreviously(false)
{
}
ApplicationCacheGroup::~ApplicationCacheGroup()
{
- if (m_isCopy) {
- ASSERT(m_newestCache);
- ASSERT(m_caches.size() == 1);
- ASSERT(m_caches.contains(m_newestCache.get()));
- ASSERT(!m_cacheBeingUpdated);
- ASSERT(m_associatedDocumentLoaders.isEmpty());
- ASSERT(m_pendingMasterResourceLoaders.isEmpty());
- ASSERT(m_newestCache->group() == this);
-
- return;
- }
-
ASSERT(!m_newestCache);
ASSERT(m_caches.isEmpty());
-
+
stopLoading();
-
- cacheStorage().cacheGroupDestroyed(this);
+
+ m_storage->cacheGroupDestroyed(*this);
}
-ApplicationCache* ApplicationCacheGroup::cacheForMainRequest(const ResourceRequest& request, DocumentLoader*)
+ApplicationCache* ApplicationCacheGroup::cacheForMainRequest(const ResourceRequest& request, DocumentLoader* documentLoader)
{
if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request))
- return 0;
+ return nullptr;
URL url(request.url());
- if (url.hasFragmentIdentifier())
- url.removeFragmentIdentifier();
+ url.removeFragmentIdentifier();
- if (ApplicationCacheGroup* group = cacheStorage().cacheGroupForURL(url)) {
- ASSERT(group->newestCache());
- ASSERT(!group->isObsolete());
-
- return group->newestCache();
- }
-
- return 0;
+ auto* page = documentLoader->frame() ? documentLoader->frame()->page() : nullptr;
+ if (!page || page->usesEphemeralSession())
+ return nullptr;
+
+ auto* group = page->applicationCacheStorage().cacheGroupForURL(url);
+ if (!group)
+ return nullptr;
+
+ ASSERT(group->newestCache());
+ ASSERT(!group->isObsolete());
+
+ return group->newestCache();
}
-ApplicationCache* ApplicationCacheGroup::fallbackCacheForMainRequest(const ResourceRequest& request, DocumentLoader*)
+ApplicationCache* ApplicationCacheGroup::fallbackCacheForMainRequest(const ResourceRequest& request, DocumentLoader* documentLoader)
{
if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request))
- return 0;
+ return nullptr;
+
+ auto* frame = documentLoader->frame();
+ if (!frame)
+ return nullptr;
+
+ auto* page = frame->page();
+ if (!page)
+ return nullptr;
URL url(request.url());
- if (url.hasFragmentIdentifier())
- url.removeFragmentIdentifier();
+ url.removeFragmentIdentifier();
- if (ApplicationCacheGroup* group = cacheStorage().fallbackCacheGroupForURL(url)) {
- ASSERT(group->newestCache());
- ASSERT(!group->isObsolete());
+ auto* group = page->applicationCacheStorage().fallbackCacheGroupForURL(url);
+ if (!group)
+ return nullptr;
- return group->newestCache();
- }
-
- return 0;
+ ASSERT(group->newestCache());
+ ASSERT(!group->isObsolete());
+
+ return group->newestCache();
}
-void ApplicationCacheGroup::selectCache(Frame* frame, const URL& passedManifestURL)
+void ApplicationCacheGroup::selectCache(Frame& frame, const URL& passedManifestURL)
{
- ASSERT(frame && frame->page());
-
- if (!frame->settings().offlineWebApplicationCacheEnabled())
- return;
+ ASSERT(frame.document());
+ ASSERT(frame.page());
+ ASSERT(frame.loader().documentLoader());
- if (!frame->document()->securityOrigin()->canAccessApplicationCache(frame->tree().top().document()->securityOrigin()))
+ if (!frame.settings().offlineWebApplicationCacheEnabled())
return;
-
- DocumentLoader* documentLoader = frame->loader().documentLoader();
- ASSERT(!documentLoader->applicationCacheHost()->applicationCache());
+
+ auto& documentLoader = *frame.loader().documentLoader();
+ ASSERT(!documentLoader.applicationCacheHost().applicationCache());
if (passedManifestURL.isNull()) {
- selectCacheWithoutManifestURL(frame);
+ selectCacheWithoutManifestURL(frame);
+ return;
+ }
+
+ // Don't access anything on disk if private browsing is enabled.
+ if (frame.page()->usesEphemeralSession() || !frame.document()->securityOrigin().canAccessApplicationCache(frame.tree().top().document()->securityOrigin())) {
+ postListenerTask(eventNames().checkingEvent, documentLoader);
+ postListenerTask(eventNames().errorEvent, documentLoader);
return;
}
URL manifestURL(passedManifestURL);
- if (manifestURL.hasFragmentIdentifier())
- manifestURL.removeFragmentIdentifier();
+ manifestURL.removeFragmentIdentifier();
- ApplicationCache* mainResourceCache = documentLoader->applicationCacheHost()->mainResourceApplicationCache();
+ auto* mainResourceCache = documentLoader.applicationCacheHost().mainResourceApplicationCache();
if (mainResourceCache) {
+ ASSERT(mainResourceCache->group());
if (manifestURL == mainResourceCache->group()->m_manifestURL) {
// The cache may have gotten obsoleted after we've loaded from it, but before we parsed the document and saw cache manifest.
if (mainResourceCache->group()->isObsolete())
return;
- mainResourceCache->group()->associateDocumentLoaderWithCache(documentLoader, mainResourceCache);
+ mainResourceCache->group()->associateDocumentLoaderWithCache(&documentLoader, mainResourceCache);
mainResourceCache->group()->update(frame, ApplicationCacheUpdateWithBrowsingContext);
} else {
// The main resource was loaded from cache, so the cache must have an entry for it. Mark it as foreign.
- URL resourceURL(documentLoader->responseURL());
- if (resourceURL.hasFragmentIdentifier())
- resourceURL.removeFragmentIdentifier();
- ApplicationCacheResource* resource = mainResourceCache->resourceForURL(resourceURL);
- bool inStorage = resource->storageID();
- resource->addType(ApplicationCacheResource::Foreign);
+ URL resourceURL { documentLoader.responseURL() };
+ resourceURL.removeFragmentIdentifier();
+
+ ASSERT(mainResourceCache->resourceForURL(resourceURL));
+ auto& resource = *mainResourceCache->resourceForURL(resourceURL);
+
+ bool inStorage = resource.storageID();
+ resource.addType(ApplicationCacheResource::Foreign);
if (inStorage)
- cacheStorage().storeUpdatedType(resource, mainResourceCache);
+ frame.page()->applicationCacheStorage().storeUpdatedType(&resource, mainResourceCache);
// Restart the current navigation from the top of the navigation algorithm, undoing any changes that were made
// as part of the initial load.
// The navigation will not result in the same resource being loaded, because "foreign" entries are never picked during navigation.
- frame->navigationScheduler().scheduleLocationChange(frame->document()->securityOrigin(), documentLoader->url(), frame->loader().referrer());
+ frame.navigationScheduler().scheduleLocationChange(*frame.document(), frame.document()->securityOrigin(), documentLoader.url(), frame.loader().referrer());
}
-
return;
}
-
+
// The resource was loaded from the network, check if it is a HTTP/HTTPS GET.
- const ResourceRequest& request = frame->loader().activeDocumentLoader()->request();
+ auto& request = frame.loader().activeDocumentLoader()->request();
if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request))
return;
@@ -195,49 +185,48 @@ void ApplicationCacheGroup::selectCache(Frame* frame, const URL& passedManifestU
if (!protocolHostAndPortAreEqual(manifestURL, request.url()))
return;
- // Don't change anything on disk if private browsing is enabled.
- if (frame->settings().privateBrowsingEnabled()) {
- postListenerTask(ApplicationCacheHost::CHECKING_EVENT, documentLoader);
- postListenerTask(ApplicationCacheHost::ERROR_EVENT, documentLoader);
- return;
- }
-
- ApplicationCacheGroup* group = cacheStorage().findOrCreateCacheGroup(manifestURL);
+ auto& group = *frame.page()->applicationCacheStorage().findOrCreateCacheGroup(manifestURL);
- documentLoader->applicationCacheHost()->setCandidateApplicationCacheGroup(group);
- group->m_pendingMasterResourceLoaders.add(documentLoader);
- group->m_downloadingPendingMasterResourceLoadersCount++;
+ documentLoader.applicationCacheHost().setCandidateApplicationCacheGroup(&group);
+ group.m_pendingMasterResourceLoaders.add(&documentLoader);
+ group.m_downloadingPendingMasterResourceLoadersCount++;
- ASSERT(!group->m_cacheBeingUpdated || group->m_updateStatus != Idle);
- group->update(frame, ApplicationCacheUpdateWithBrowsingContext);
+ ASSERT(!group.m_cacheBeingUpdated || group.m_updateStatus != Idle);
+ group.update(frame, ApplicationCacheUpdateWithBrowsingContext);
}
-void ApplicationCacheGroup::selectCacheWithoutManifestURL(Frame* frame)
+void ApplicationCacheGroup::selectCacheWithoutManifestURL(Frame& frame)
{
- if (!frame->settings().offlineWebApplicationCacheEnabled())
- return;
-
- if (!frame->document()->securityOrigin()->canAccessApplicationCache(frame->tree().top().document()->securityOrigin()))
+ if (!frame.settings().offlineWebApplicationCacheEnabled())
return;
- DocumentLoader* documentLoader = frame->loader().documentLoader();
- ASSERT(!documentLoader->applicationCacheHost()->applicationCache());
+ ASSERT(frame.document());
+ ASSERT(frame.page());
+ ASSERT(frame.loader().documentLoader());
+ auto& documentLoader = *frame.loader().documentLoader();
+ ASSERT(!documentLoader.applicationCacheHost().applicationCache());
- ApplicationCache* mainResourceCache = documentLoader->applicationCacheHost()->mainResourceApplicationCache();
+ // Don't access anything on disk if private browsing is enabled.
+ if (frame.page()->usesEphemeralSession() || !frame.document()->securityOrigin().canAccessApplicationCache(frame.tree().top().document()->securityOrigin())) {
+ postListenerTask(eventNames().checkingEvent, documentLoader);
+ postListenerTask(eventNames().errorEvent, documentLoader);
+ return;
+ }
- if (mainResourceCache) {
- mainResourceCache->group()->associateDocumentLoaderWithCache(documentLoader, mainResourceCache);
- mainResourceCache->group()->update(frame, ApplicationCacheUpdateWithBrowsingContext);
+ if (auto* mainResourceCache = documentLoader.applicationCacheHost().mainResourceApplicationCache()) {
+ ASSERT(mainResourceCache->group());
+ auto& group = *mainResourceCache->group();
+ group.associateDocumentLoaderWithCache(&documentLoader, mainResourceCache);
+ group.update(frame, ApplicationCacheUpdateWithBrowsingContext);
}
}
-void ApplicationCacheGroup::finishedLoadingMainResource(DocumentLoader* loader)
+void ApplicationCacheGroup::finishedLoadingMainResource(DocumentLoader& loader)
{
- ASSERT(m_pendingMasterResourceLoaders.contains(loader));
+ ASSERT(m_pendingMasterResourceLoaders.contains(&loader));
ASSERT(m_completionType == None || m_pendingEntries.isEmpty());
- URL url = loader->url();
- if (url.hasFragmentIdentifier())
- url.removeFragmentIdentifier();
+ URL url = loader.url();
+ url.removeFragmentIdentifier();
switch (m_completionType) {
case None:
@@ -245,39 +234,32 @@ void ApplicationCacheGroup::finishedLoadingMainResource(DocumentLoader* loader)
return;
case NoUpdate:
ASSERT(!m_cacheBeingUpdated);
- associateDocumentLoaderWithCache(loader, m_newestCache.get());
-
- if (ApplicationCacheResource* resource = m_newestCache->resourceForURL(url)) {
+ associateDocumentLoaderWithCache(&loader, m_newestCache.get());
+ if (auto* resource = m_newestCache->resourceForURL(url)) {
if (!(resource->type() & ApplicationCacheResource::Master)) {
resource->addType(ApplicationCacheResource::Master);
ASSERT(!resource->storageID());
}
- } else {
- RefPtr<ResourceBuffer> buffer = loader->mainResourceData();
- m_newestCache->addResource(ApplicationCacheResource::create(url, loader->response(), ApplicationCacheResource::Master, buffer ? buffer->sharedBuffer() : 0));
- }
-
+ } else
+ m_newestCache->addResource(ApplicationCacheResource::create(url, loader.response(), ApplicationCacheResource::Master, loader.mainResourceData()));
break;
case Failure:
// Cache update has been a failure, so there is no reason to keep the document associated with the incomplete cache
// (its main resource was not cached yet, so it is likely that the application changed significantly server-side).
ASSERT(!m_cacheBeingUpdated); // Already cleared out by stopLoading().
- loader->applicationCacheHost()->setApplicationCache(0); // Will unset candidate, too.
- m_associatedDocumentLoaders.remove(loader);
- postListenerTask(ApplicationCacheHost::ERROR_EVENT, loader);
+ loader.applicationCacheHost().setApplicationCache(nullptr); // Will unset candidate, too.
+ m_associatedDocumentLoaders.remove(&loader);
+ postListenerTask(eventNames().errorEvent, loader);
break;
case Completed:
- ASSERT(m_associatedDocumentLoaders.contains(loader));
-
- if (ApplicationCacheResource* resource = m_cacheBeingUpdated->resourceForURL(url)) {
+ ASSERT(m_associatedDocumentLoaders.contains(&loader));
+ if (auto* resource = m_cacheBeingUpdated->resourceForURL(url)) {
if (!(resource->type() & ApplicationCacheResource::Master)) {
resource->addType(ApplicationCacheResource::Master);
ASSERT(!resource->storageID());
}
- } else {
- RefPtr<ResourceBuffer> buffer = loader->mainResourceData();
- m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, loader->response(), ApplicationCacheResource::Master, buffer ? buffer->sharedBuffer() : 0));
- }
+ } else
+ m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, loader.response(), ApplicationCacheResource::Master, loader.mainResourceData()));
// The "cached" event will be posted to all associated documents once update is complete.
break;
}
@@ -287,9 +269,9 @@ void ApplicationCacheGroup::finishedLoadingMainResource(DocumentLoader* loader)
checkIfLoadIsComplete();
}
-void ApplicationCacheGroup::failedLoadingMainResource(DocumentLoader* loader)
+void ApplicationCacheGroup::failedLoadingMainResource(DocumentLoader& loader)
{
- ASSERT(m_pendingMasterResourceLoaders.contains(loader));
+ ASSERT(m_pendingMasterResourceLoaders.contains(&loader));
ASSERT(m_completionType == None || m_pendingEntries.isEmpty());
switch (m_completionType) {
@@ -298,32 +280,27 @@ void ApplicationCacheGroup::failedLoadingMainResource(DocumentLoader* loader)
return;
case NoUpdate:
ASSERT(!m_cacheBeingUpdated);
-
// The manifest didn't change, and we have a relevant cache - but the main resource download failed mid-way, so it cannot be stored to the cache,
// and the loader does not get associated to it. If there are other main resources being downloaded for this cache group, they may still succeed.
- postListenerTask(ApplicationCacheHost::ERROR_EVENT, loader);
-
+ postListenerTask(eventNames().errorEvent, loader);
break;
case Failure:
// Cache update failed, too.
ASSERT(!m_cacheBeingUpdated); // Already cleared out by stopLoading().
- ASSERT(!loader->applicationCacheHost()->applicationCache() || loader->applicationCacheHost()->applicationCache() == m_cacheBeingUpdated);
-
- loader->applicationCacheHost()->setApplicationCache(0); // Will unset candidate, too.
- m_associatedDocumentLoaders.remove(loader);
- postListenerTask(ApplicationCacheHost::ERROR_EVENT, loader);
+ ASSERT(!loader.applicationCacheHost().applicationCache() || loader.applicationCacheHost().applicationCache()->group() == this);
+ loader.applicationCacheHost().setApplicationCache(nullptr); // Will unset candidate, too.
+ m_associatedDocumentLoaders.remove(&loader);
+ postListenerTask(eventNames().errorEvent, loader);
break;
case Completed:
// The cache manifest didn't list this main resource, and all cache entries were already updated successfully - but the main resource failed to load,
// so it cannot be stored to the cache. If there are other main resources being downloaded for this cache group, they may still succeed.
- ASSERT(m_associatedDocumentLoaders.contains(loader));
- ASSERT(loader->applicationCacheHost()->applicationCache() == m_cacheBeingUpdated);
- ASSERT(!loader->applicationCacheHost()->candidateApplicationCacheGroup());
- m_associatedDocumentLoaders.remove(loader);
- loader->applicationCacheHost()->setApplicationCache(0);
-
- postListenerTask(ApplicationCacheHost::ERROR_EVENT, loader);
-
+ ASSERT(m_associatedDocumentLoaders.contains(&loader));
+ ASSERT(loader.applicationCacheHost().applicationCache() == m_cacheBeingUpdated);
+ ASSERT(!loader.applicationCacheHost().candidateApplicationCacheGroup());
+ m_associatedDocumentLoaders.remove(&loader);
+ loader.applicationCacheHost().setApplicationCache(nullptr);
+ postListenerTask(eventNames().errorEvent, loader);
break;
}
@@ -338,10 +315,10 @@ void ApplicationCacheGroup::stopLoading()
ASSERT(!m_currentHandle);
ASSERT(m_manifestHandle->client() == this);
- m_manifestHandle->setClient(0);
+ m_manifestHandle->clearClient();
m_manifestHandle->cancel();
- m_manifestHandle = 0;
+ m_manifestHandle = nullptr;
}
if (m_currentHandle) {
@@ -349,23 +326,24 @@ void ApplicationCacheGroup::stopLoading()
ASSERT(m_cacheBeingUpdated);
ASSERT(m_currentHandle->client() == this);
- m_currentHandle->setClient(0);
+ m_currentHandle->clearClient();
m_currentHandle->cancel();
- m_currentHandle = 0;
+ m_currentHandle = nullptr;
}
// FIXME: Resetting just a tiny part of the state in this function is confusing. Callers have to take care of a lot more.
- m_cacheBeingUpdated = 0;
+ m_cacheBeingUpdated = nullptr;
m_pendingEntries.clear();
}
-void ApplicationCacheGroup::disassociateDocumentLoader(DocumentLoader* loader)
+void ApplicationCacheGroup::disassociateDocumentLoader(DocumentLoader& loader)
{
- m_associatedDocumentLoaders.remove(loader);
- m_pendingMasterResourceLoaders.remove(loader);
+ m_associatedDocumentLoaders.remove(&loader);
+ m_pendingMasterResourceLoaders.remove(&loader);
- loader->applicationCacheHost()->setApplicationCache(0); // Will set candidate to 0, too.
+ if (auto* host = loader.applicationCacheHostUnlessBeingDestroyed())
+ host->setApplicationCache(nullptr); // Will set candidate group to null, too.
if (!m_associatedDocumentLoaders.isEmpty() || !m_pendingMasterResourceLoaders.isEmpty())
return;
@@ -382,29 +360,29 @@ void ApplicationCacheGroup::disassociateDocumentLoader(DocumentLoader* loader)
// Release our reference to the newest cache. This could cause us to be deleted.
// Any ongoing updates will be stopped from destructor.
- m_newestCache.release();
+ m_newestCache = nullptr;
}
-void ApplicationCacheGroup::cacheDestroyed(ApplicationCache* cache)
+void ApplicationCacheGroup::cacheDestroyed(ApplicationCache& cache)
{
- if (m_caches.remove(cache) && m_caches.isEmpty()) {
+ if (m_caches.remove(&cache) && m_caches.isEmpty()) {
ASSERT(m_associatedDocumentLoaders.isEmpty());
ASSERT(m_pendingMasterResourceLoaders.isEmpty());
delete this;
}
}
-void ApplicationCacheGroup::stopLoadingInFrame(Frame* frame)
+void ApplicationCacheGroup::stopLoadingInFrame(Frame& frame)
{
- if (frame != m_frame)
+ if (&frame != m_frame)
return;
cacheUpdateFailed();
}
-void ApplicationCacheGroup::setNewestCache(PassRefPtr<ApplicationCache> newestCache)
+void ApplicationCacheGroup::setNewestCache(Ref<ApplicationCache>&& newestCache)
{
- m_newestCache = newestCache;
+ m_newestCache = WTFMove(newestCache);
m_caches.add(m_newestCache.get());
m_newestCache->setGroup(this);
@@ -416,40 +394,43 @@ void ApplicationCacheGroup::makeObsolete()
return;
m_isObsolete = true;
- cacheStorage().cacheGroupMadeObsolete(this);
+ m_storage->cacheGroupMadeObsolete(*this);
ASSERT(!m_storageID);
}
-void ApplicationCacheGroup::update(Frame* frame, ApplicationCacheUpdateOption updateOption)
+void ApplicationCacheGroup::update(Frame& frame, ApplicationCacheUpdateOption updateOption)
{
+ ASSERT(frame.loader().documentLoader());
+ auto& documentLoader = *frame.loader().documentLoader();
+
if (m_updateStatus == Checking || m_updateStatus == Downloading) {
if (updateOption == ApplicationCacheUpdateWithBrowsingContext) {
- postListenerTask(ApplicationCacheHost::CHECKING_EVENT, frame->loader().documentLoader());
+ postListenerTask(eventNames().checkingEvent, documentLoader);
if (m_updateStatus == Downloading)
- postListenerTask(ApplicationCacheHost::DOWNLOADING_EVENT, frame->loader().documentLoader());
+ postListenerTask(eventNames().downloadingEvent, documentLoader);
}
return;
}
- // Don't change anything on disk if private browsing is enabled.
- if (frame->settings().privateBrowsingEnabled()) {
+ // Don't access anything on disk if private browsing is enabled.
+ if (frame.page()->usesEphemeralSession() || !frame.document()->securityOrigin().canAccessApplicationCache(frame.tree().top().document()->securityOrigin())) {
ASSERT(m_pendingMasterResourceLoaders.isEmpty());
ASSERT(m_pendingEntries.isEmpty());
ASSERT(!m_cacheBeingUpdated);
- postListenerTask(ApplicationCacheHost::CHECKING_EVENT, frame->loader().documentLoader());
- postListenerTask(ApplicationCacheHost::NOUPDATE_EVENT, frame->loader().documentLoader());
+ postListenerTask(eventNames().checkingEvent, documentLoader);
+ postListenerTask(eventNames().errorEvent, documentLoader);
return;
}
ASSERT(!m_frame);
- m_frame = frame;
+ m_frame = &frame;
setUpdateStatus(Checking);
- postListenerTask(ApplicationCacheHost::CHECKING_EVENT, m_associatedDocumentLoaders);
+ postListenerTask(eventNames().checkingEvent, m_associatedDocumentLoaders);
if (!m_newestCache) {
ASSERT(updateOption == ApplicationCacheUpdateWithBrowsingContext);
- postListenerTask(ApplicationCacheHost::CHECKING_EVENT, frame->loader().documentLoader());
+ postListenerTask(eventNames().checkingEvent, documentLoader);
}
ASSERT(!m_manifestHandle);
@@ -462,7 +443,7 @@ void ApplicationCacheGroup::update(Frame* frame, ApplicationCacheUpdateOption up
m_manifestHandle = createResourceHandle(m_manifestURL, m_newestCache ? m_newestCache->manifestResource() : 0);
}
-void ApplicationCacheGroup::abort(Frame* frame)
+void ApplicationCacheGroup::abort(Frame& frame)
{
if (m_updateStatus == Idle)
return;
@@ -471,56 +452,51 @@ void ApplicationCacheGroup::abort(Frame* frame)
if (m_completionType != None)
return;
- frame->document()->addConsoleMessage(NetworkMessageSource, DebugMessageLevel, "Application Cache download process was aborted.");
+ frame.document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Debug, ASCIILiteral("Application Cache download process was aborted."));
cacheUpdateFailed();
}
-PassRefPtr<ResourceHandle> ApplicationCacheGroup::createResourceHandle(const URL& url, ApplicationCacheResource* newestCachedResource)
+RefPtr<ResourceHandle> ApplicationCacheGroup::createResourceHandle(const URL& url, ApplicationCacheResource* newestCachedResource)
{
ResourceRequest request(url);
m_frame->loader().applyUserAgent(request);
- request.setHTTPHeaderField("Cache-Control", "max-age=0");
+ request.setHTTPHeaderField(HTTPHeaderName::CacheControl, "max-age=0");
if (newestCachedResource) {
- const String& lastModified = newestCachedResource->response().httpHeaderField("Last-Modified");
- const String& eTag = newestCachedResource->response().httpHeaderField("ETag");
+ const String& lastModified = newestCachedResource->response().httpHeaderField(HTTPHeaderName::LastModified);
+ const String& eTag = newestCachedResource->response().httpHeaderField(HTTPHeaderName::ETag);
if (!lastModified.isEmpty() || !eTag.isEmpty()) {
if (!lastModified.isEmpty())
- request.setHTTPHeaderField("If-Modified-Since", lastModified);
+ request.setHTTPHeaderField(HTTPHeaderName::IfModifiedSince, lastModified);
if (!eTag.isEmpty())
- request.setHTTPHeaderField("If-None-Match", eTag);
+ request.setHTTPHeaderField(HTTPHeaderName::IfNoneMatch, eTag);
}
}
RefPtr<ResourceHandle> handle = ResourceHandle::create(m_frame->loader().networkingContext(), request, this, false, true);
-#if ENABLE(INSPECTOR)
+
// Because willSendRequest only gets called during redirects, we initialize
// the identifier and the first willSendRequest here.
m_currentResourceIdentifier = m_frame->page()->progress().createUniqueIdentifier();
ResourceResponse redirectResponse = ResourceResponse();
InspectorInstrumentation::willSendRequest(m_frame, m_currentResourceIdentifier, m_frame->loader().documentLoader(), request, redirectResponse);
-#endif
return handle;
}
-void ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, const ResourceResponse& response)
+void ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, ResourceResponse&& response)
{
-#if ENABLE(INSPECTOR)
- DocumentLoader* loader = (handle == m_manifestHandle) ? 0 : m_frame->loader().documentLoader();
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceResponse(m_frame, m_currentResourceIdentifier, response);
- InspectorInstrumentation::didReceiveResourceResponse(cookie, m_currentResourceIdentifier, loader, response, 0);
-#endif
+ ASSERT(m_frame);
+ InspectorInstrumentation::didReceiveResourceResponse(*m_frame, m_currentResourceIdentifier, m_frame->loader().documentLoader(), response, nullptr);
if (handle == m_manifestHandle) {
didReceiveManifestResponse(response);
return;
}
-
+
ASSERT(handle == m_currentHandle);
URL url(handle->firstRequest().url());
- if (url.hasFragmentIdentifier())
- url.removeFragmentIdentifier();
+ url.removeFragmentIdentifier();
ASSERT(!m_currentResource);
ASSERT(m_pendingEntries.contains(url));
@@ -534,10 +510,10 @@ void ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, const Res
if (m_newestCache && response.httpStatusCode() == 304) { // Not modified.
ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(url);
if (newestCachedResource) {
- m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data(), newestCachedResource->path()));
+ m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, &newestCachedResource->data(), newestCachedResource->path()));
m_pendingEntries.remove(m_currentHandle->firstRequest().url());
m_currentHandle->cancel();
- m_currentHandle = 0;
+ m_currentHandle = nullptr;
// Load the next resource, if any.
startLoadingEntry();
return;
@@ -547,14 +523,14 @@ void ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, const Res
if (response.httpStatusCode() / 100 != 2 || response.url() != m_currentHandle->firstRequest().url()) {
if ((type & ApplicationCacheResource::Explicit) || (type & ApplicationCacheResource::Fallback)) {
- m_frame->document()->addConsoleMessage(AppCacheMessageSource, ErrorMessageLevel, "Application Cache update failed, because " + m_currentHandle->firstRequest().url().stringCenterEllipsizedToLength() +
+ m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, "Application Cache update failed, because " + m_currentHandle->firstRequest().url().stringCenterEllipsizedToLength() +
((response.httpStatusCode() / 100 != 2) ? " could not be fetched." : " was redirected."));
// Note that cacheUpdateFailed() can cause the cache group to be deleted.
cacheUpdateFailed();
} else if (response.httpStatusCode() == 404 || response.httpStatusCode() == 410) {
// Skip this resource. It is dropped from the cache.
m_currentHandle->cancel();
- m_currentHandle = 0;
+ m_currentHandle = nullptr;
m_pendingEntries.remove(url);
// Load the next resource, if any.
startLoadingEntry();
@@ -564,10 +540,10 @@ void ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, const Res
ASSERT(m_newestCache);
ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(handle->firstRequest().url());
ASSERT(newestCachedResource);
- m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data(), newestCachedResource->path()));
+ m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, &newestCachedResource->data(), newestCachedResource->path()));
m_pendingEntries.remove(m_currentHandle->firstRequest().url());
m_currentHandle->cancel();
- m_currentHandle = 0;
+ m_currentHandle = nullptr;
// Load the next resource, if any.
startLoadingEntry();
}
@@ -581,9 +557,7 @@ void ApplicationCacheGroup::didReceiveData(ResourceHandle* handle, const char* d
{
UNUSED_PARAM(encodedDataLength);
-#if ENABLE(INSPECTOR)
InspectorInstrumentation::didReceiveData(m_frame, m_currentResourceIdentifier, 0, length, 0);
-#endif
if (handle == m_manifestHandle) {
didReceiveManifestData(data, length);
@@ -593,16 +567,12 @@ void ApplicationCacheGroup::didReceiveData(ResourceHandle* handle, const char* d
ASSERT(handle == m_currentHandle);
ASSERT(m_currentResource);
- m_currentResource->data()->append(data, length);
+ m_currentResource->data().append(data, length);
}
void ApplicationCacheGroup::didFinishLoading(ResourceHandle* handle, double finishTime)
{
-#if ENABLE(INSPECTOR)
InspectorInstrumentation::didFinishLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, finishTime);
-#else
- UNUSED_PARAM(finishTime);
-#endif
if (handle == m_manifestHandle) {
didFinishLoadingManifest();
@@ -616,8 +586,8 @@ void ApplicationCacheGroup::didFinishLoading(ResourceHandle* handle, double fini
ASSERT(m_cacheBeingUpdated);
- m_cacheBeingUpdated->addResource(m_currentResource.release());
- m_currentHandle = 0;
+ m_cacheBeingUpdated->addResource(m_currentResource.releaseNonNull());
+ m_currentHandle = nullptr;
// While downloading check to see if we have exceeded the available quota.
// We can stop immediately if we have already previously failed
@@ -625,8 +595,8 @@ void ApplicationCacheGroup::didFinishLoading(ResourceHandle* handle, double fini
// of the quota being reached and decided not to increase it then.
// FIXME: Should we break earlier and prevent redownloading on later page loads?
if (m_originQuotaExceededPreviously && m_availableSpaceInQuota < m_cacheBeingUpdated->estimatedSizeInStorage()) {
- m_currentResource = 0;
- m_frame->document()->addConsoleMessage(AppCacheMessageSource, ErrorMessageLevel, "Application Cache update failed, because size quota was exceeded.");
+ m_currentResource = nullptr;
+ m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, ASCIILiteral("Application Cache update failed, because size quota was exceeded."));
cacheUpdateFailed();
return;
}
@@ -637,11 +607,7 @@ void ApplicationCacheGroup::didFinishLoading(ResourceHandle* handle, double fini
void ApplicationCacheGroup::didFail(ResourceHandle* handle, const ResourceError& error)
{
-#if ENABLE(INSPECTOR)
InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, error);
-#else
- UNUSED_PARAM(error);
-#endif
if (handle == m_manifestHandle) {
// A network error is logged elsewhere, no need to log again. Also, it's normal for manifest fetching to fail when working offline.
@@ -653,15 +619,14 @@ void ApplicationCacheGroup::didFail(ResourceHandle* handle, const ResourceError&
unsigned type = m_currentResource ? m_currentResource->type() : m_pendingEntries.get(handle->firstRequest().url());
URL url(handle->firstRequest().url());
- if (url.hasFragmentIdentifier())
- url.removeFragmentIdentifier();
+ url.removeFragmentIdentifier();
ASSERT(!m_currentResource || !m_pendingEntries.contains(url));
- m_currentResource = 0;
+ m_currentResource = nullptr;
m_pendingEntries.remove(url);
if ((type & ApplicationCacheResource::Explicit) || (type & ApplicationCacheResource::Fallback)) {
- m_frame->document()->addConsoleMessage(AppCacheMessageSource, ErrorMessageLevel, "Application Cache update failed, because " + url.stringCenterEllipsizedToLength() + " could not be fetched.");
+ m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, "Application Cache update failed, because " + url.stringCenterEllipsizedToLength() + " could not be fetched.");
// Note that cacheUpdateFailed() can cause the cache group to be deleted.
cacheUpdateFailed();
} else {
@@ -670,7 +635,7 @@ void ApplicationCacheGroup::didFail(ResourceHandle* handle, const ResourceError&
ASSERT(m_newestCache);
ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(url);
ASSERT(newestCachedResource);
- m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data(), newestCachedResource->path()));
+ m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, &newestCachedResource->data(), newestCachedResource->path()));
// Load the next resource, if any.
startLoadingEntry();
}
@@ -682,6 +647,8 @@ void ApplicationCacheGroup::didReceiveManifestResponse(const ResourceResponse& r
ASSERT(m_manifestHandle);
if (response.httpStatusCode() == 404 || response.httpStatusCode() == 410) {
+ InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, m_frame->loader().cancelledError(m_manifestHandle->firstRequest()));
+ m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, makeString("Application Cache manifest could not be fetched, because the manifest had a ", String::number(response.httpStatusCode()), " response."));
manifestNotFound();
return;
}
@@ -690,13 +657,15 @@ void ApplicationCacheGroup::didReceiveManifestResponse(const ResourceResponse& r
return;
if (response.httpStatusCode() / 100 != 2) {
- m_frame->document()->addConsoleMessage(OtherMessageSource, ErrorMessageLevel, "Application Cache manifest could not be fetched.");
+ InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, m_frame->loader().cancelledError(m_manifestHandle->firstRequest()));
+ m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, makeString("Application Cache manifest could not be fetched, because the manifest had a ", String::number(response.httpStatusCode()), " response."));
cacheUpdateFailed();
return;
}
if (response.url() != m_manifestHandle->firstRequest().url()) {
- m_frame->document()->addConsoleMessage(OtherMessageSource, ErrorMessageLevel, "Application Cache manifest could not be fetched, because a redirection was attempted.");
+ InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, m_frame->loader().cancelledError(m_manifestHandle->firstRequest()));
+ m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, ASCIILiteral("Application Cache manifest could not be fetched, because a redirection was attempted."));
cacheUpdateFailed();
return;
}
@@ -707,7 +676,7 @@ void ApplicationCacheGroup::didReceiveManifestResponse(const ResourceResponse& r
void ApplicationCacheGroup::didReceiveManifestData(const char* data, int length)
{
if (m_manifestResource)
- m_manifestResource->data()->append(data, length);
+ m_manifestResource->data().append(data, length);
}
void ApplicationCacheGroup::didFinishLoadingManifest()
@@ -716,12 +685,12 @@ void ApplicationCacheGroup::didFinishLoadingManifest()
if (!isUpgradeAttempt && !m_manifestResource) {
// The server returned 304 Not Modified even though we didn't send a conditional request.
- m_frame->document()->addConsoleMessage(OtherMessageSource, ErrorMessageLevel, "Application Cache manifest could not be fetched because of an unexpected 304 Not Modified server response.");
+ m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, ASCIILiteral("Application Cache manifest could not be fetched because of an unexpected 304 Not Modified server response."));
cacheUpdateFailed();
return;
}
- m_manifestHandle = 0;
+ m_manifestHandle = nullptr;
// Check if the manifest was not modified.
if (isUpgradeAttempt) {
@@ -729,10 +698,10 @@ void ApplicationCacheGroup::didFinishLoadingManifest()
ASSERT(newestManifest);
if (!m_manifestResource || // The resource will be null if HTTP response was 304 Not Modified.
- (newestManifest->data()->size() == m_manifestResource->data()->size() && !memcmp(newestManifest->data()->data(), m_manifestResource->data()->data(), newestManifest->data()->size()))) {
+ (newestManifest->data().size() == m_manifestResource->data().size() && !memcmp(newestManifest->data().data(), m_manifestResource->data().data(), newestManifest->data().size()))) {
m_completionType = NoUpdate;
- m_manifestResource = 0;
+ m_manifestResource = nullptr;
deliverDelayedMainResources();
return;
@@ -740,9 +709,9 @@ void ApplicationCacheGroup::didFinishLoadingManifest()
}
Manifest manifest;
- if (!parseManifest(m_manifestURL, m_manifestResource->data()->data(), m_manifestResource->data()->size(), manifest)) {
+ if (!parseManifest(m_manifestURL, m_manifestResource->data().data(), m_manifestResource->data().size(), manifest)) {
// At the time of this writing, lack of "CACHE MANIFEST" signature is the only reason for parseManifest to fail.
- m_frame->document()->addConsoleMessage(OtherMessageSource, ErrorMessageLevel, "Application Cache manifest could not be parsed. Does it start with CACHE MANIFEST?");
+ m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, ASCIILiteral("Application Cache manifest could not be parsed. Does it start with CACHE MANIFEST?"));
cacheUpdateFailed();
return;
}
@@ -751,19 +720,18 @@ void ApplicationCacheGroup::didFinishLoadingManifest()
m_cacheBeingUpdated = ApplicationCache::create();
m_cacheBeingUpdated->setGroup(this);
- HashSet<DocumentLoader*>::const_iterator masterEnd = m_pendingMasterResourceLoaders.end();
- for (HashSet<DocumentLoader*>::const_iterator iter = m_pendingMasterResourceLoaders.begin(); iter != masterEnd; ++iter)
- associateDocumentLoaderWithCache(*iter, m_cacheBeingUpdated.get());
+ for (auto& loader : m_pendingMasterResourceLoaders)
+ associateDocumentLoaderWithCache(loader, m_cacheBeingUpdated.get());
// We have the manifest, now download the resources.
setUpdateStatus(Downloading);
- postListenerTask(ApplicationCacheHost::DOWNLOADING_EVENT, m_associatedDocumentLoaders);
+ postListenerTask(eventNames().downloadingEvent, m_associatedDocumentLoaders);
ASSERT(m_pendingEntries.isEmpty());
if (isUpgradeAttempt) {
- for (const auto& urlAndResource : *m_newestCache) {
+ for (const auto& urlAndResource : m_newestCache->resources()) {
unsigned type = urlAndResource.value->type();
if (type & ApplicationCacheResource::Master)
addEntry(urlAndResource.key, type);
@@ -773,9 +741,8 @@ void ApplicationCacheGroup::didFinishLoadingManifest()
for (const auto& explicitURL : manifest.explicitURLs)
addEntry(explicitURL, ApplicationCacheResource::Explicit);
- size_t fallbackCount = manifest.fallbackURLs.size();
- for (size_t i = 0; i < fallbackCount; ++i)
- addEntry(manifest.fallbackURLs[i].second, ApplicationCacheResource::Fallback);
+ for (auto& fallbackURL : manifest.fallbackURLs)
+ addEntry(fallbackURL.second, ApplicationCacheResource::Fallback);
m_cacheBeingUpdated->setOnlineWhitelist(manifest.onlineWhitelistedURLs);
m_cacheBeingUpdated->setFallbackURLs(manifest.fallbackURLs);
@@ -793,7 +760,7 @@ void ApplicationCacheGroup::didReachMaxAppCacheSize()
{
ASSERT(m_frame);
ASSERT(m_cacheBeingUpdated);
- m_frame->page()->chrome().client().reachedMaxAppCacheSize(cacheStorage().spaceNeeded(m_cacheBeingUpdated->estimatedSizeInStorage()));
+ m_frame->page()->chrome().client().reachedMaxAppCacheSize(m_frame->page()->applicationCacheStorage().spaceNeeded(m_cacheBeingUpdated->estimatedSizeInStorage()));
m_calledReachedMaxAppCacheSize = true;
checkIfLoadIsComplete();
}
@@ -808,7 +775,7 @@ void ApplicationCacheGroup::didReachOriginQuota(int64_t totalSpaceNeeded)
void ApplicationCacheGroup::cacheUpdateFailed()
{
stopLoading();
- m_manifestResource = 0;
+ m_manifestResource = nullptr;
// Wait for master resource loads to finish.
m_completionType = Failure;
@@ -817,7 +784,7 @@ void ApplicationCacheGroup::cacheUpdateFailed()
void ApplicationCacheGroup::recalculateAvailableSpaceInQuota()
{
- if (!cacheStorage().calculateRemainingSizeForOriginExcludingCache(m_origin.get(), m_newestCache.get(), m_availableSpaceInQuota)) {
+ if (!m_frame->page()->applicationCacheStorage().calculateRemainingSizeForOriginExcludingCache(m_origin, m_newestCache.get(), m_availableSpaceInQuota)) {
// Failed to determine what is left in the quota. Fallback to allowing anything.
m_availableSpaceInQuota = ApplicationCacheStorage::noQuota();
}
@@ -827,27 +794,27 @@ void ApplicationCacheGroup::manifestNotFound()
{
makeObsolete();
- postListenerTask(ApplicationCacheHost::OBSOLETE_EVENT, m_associatedDocumentLoaders);
- postListenerTask(ApplicationCacheHost::ERROR_EVENT, m_pendingMasterResourceLoaders);
+ postListenerTask(eventNames().obsoleteEvent, m_associatedDocumentLoaders);
+ postListenerTask(eventNames().errorEvent, m_pendingMasterResourceLoaders);
stopLoading();
ASSERT(m_pendingEntries.isEmpty());
- m_manifestResource = 0;
+ m_manifestResource = nullptr;
while (!m_pendingMasterResourceLoaders.isEmpty()) {
HashSet<DocumentLoader*>::iterator it = m_pendingMasterResourceLoaders.begin();
- ASSERT((*it)->applicationCacheHost()->candidateApplicationCacheGroup() == this);
- ASSERT(!(*it)->applicationCacheHost()->applicationCache());
- (*it)->applicationCacheHost()->setCandidateApplicationCacheGroup(0);
+ ASSERT((*it)->applicationCacheHost().candidateApplicationCacheGroup() == this);
+ ASSERT(!(*it)->applicationCacheHost().applicationCache());
+ (*it)->applicationCacheHost().setCandidateApplicationCacheGroup(nullptr);
m_pendingMasterResourceLoaders.remove(it);
}
m_downloadingPendingMasterResourceLoadersCount = 0;
setUpdateStatus(Idle);
- m_frame = 0;
-
+ m_frame = nullptr;
+
if (m_caches.isEmpty()) {
ASSERT(m_associatedDocumentLoaders.isEmpty());
ASSERT(!m_cacheBeingUpdated);
@@ -874,13 +841,13 @@ void ApplicationCacheGroup::checkIfLoadIsComplete()
// The storage could have been manually emptied by the user.
if (!m_storageID)
- cacheStorage().storeNewestCache(this);
+ m_storage->storeNewestCache(*this);
- postListenerTask(ApplicationCacheHost::NOUPDATE_EVENT, m_associatedDocumentLoaders);
+ postListenerTask(eventNames().noupdateEvent, m_associatedDocumentLoaders);
break;
case Failure:
ASSERT(!m_cacheBeingUpdated);
- postListenerTask(ApplicationCacheHost::ERROR_EVENT, m_associatedDocumentLoaders);
+ postListenerTask(eventNames().errorEvent, m_associatedDocumentLoaders);
if (m_caches.isEmpty()) {
ASSERT(m_associatedDocumentLoaders.isEmpty());
delete this;
@@ -892,14 +859,14 @@ void ApplicationCacheGroup::checkIfLoadIsComplete()
ASSERT(m_cacheBeingUpdated);
if (m_manifestResource)
- m_cacheBeingUpdated->setManifestResource(m_manifestResource.release());
+ m_cacheBeingUpdated->setManifestResource(m_manifestResource.releaseNonNull());
else {
// We can get here as a result of retrying the Complete step, following
// a failure of the cache storage to save the newest cache due to hitting
// the maximum size. In such a case, m_manifestResource may be 0, as
// the manifest was already set on the newest cache object.
ASSERT(m_cacheBeingUpdated->manifestResource());
- ASSERT(cacheStorage().isMaximumSizeReached());
+ ASSERT(m_storage->isMaximumSizeReached());
ASSERT(m_calledReachedMaxAppCacheSize);
}
@@ -908,22 +875,22 @@ void ApplicationCacheGroup::checkIfLoadIsComplete()
// If we exceeded the origin quota while downloading we can request a quota
// increase now, before we attempt to store the cache.
int64_t totalSpaceNeeded;
- if (!cacheStorage().checkOriginQuota(this, oldNewestCache.get(), m_cacheBeingUpdated.get(), totalSpaceNeeded))
+ if (!m_storage->checkOriginQuota(this, oldNewestCache.get(), m_cacheBeingUpdated.get(), totalSpaceNeeded))
didReachOriginQuota(totalSpaceNeeded);
ApplicationCacheStorage::FailureReason failureReason;
- setNewestCache(m_cacheBeingUpdated.release());
- if (cacheStorage().storeNewestCache(this, oldNewestCache.get(), failureReason)) {
+ setNewestCache(m_cacheBeingUpdated.releaseNonNull());
+ if (m_storage->storeNewestCache(*this, oldNewestCache.get(), failureReason)) {
// New cache stored, now remove the old cache.
if (oldNewestCache)
- cacheStorage().remove(oldNewestCache.get());
+ m_storage->remove(oldNewestCache.get());
// Fire the final progress event.
ASSERT(m_progressDone == m_progressTotal);
- postListenerTask(ApplicationCacheHost::PROGRESS_EVENT, m_progressTotal, m_progressDone, m_associatedDocumentLoaders);
+ postListenerTask(eventNames().progressEvent, m_progressTotal, m_progressDone, m_associatedDocumentLoaders);
// Fire the success event.
- postListenerTask(isUpgradeAttempt ? ApplicationCacheHost::UPDATEREADY_EVENT : ApplicationCacheHost::CACHED_EVENT, m_associatedDocumentLoaders);
+ postListenerTask(isUpgradeAttempt ? eventNames().updatereadyEvent : eventNames().cachedEvent, m_associatedDocumentLoaders);
// It is clear that the origin quota was not reached, so clear the flag if it was set.
m_originQuotaExceededPreviously = false;
} else {
@@ -931,7 +898,7 @@ void ApplicationCacheGroup::checkIfLoadIsComplete()
// We ran out of space for this origin. Fall down to the normal error handling
// after recording this state.
m_originQuotaExceededPreviously = true;
- m_frame->document()->addConsoleMessage(OtherMessageSource, ErrorMessageLevel, "Application Cache update failed, because size quota was exceeded.");
+ m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, ASCIILiteral("Application Cache update failed, because size quota was exceeded."));
}
if (failureReason == ApplicationCacheStorage::TotalQuotaReached && !m_calledReachedMaxAppCacheSize) {
@@ -943,11 +910,9 @@ void ApplicationCacheGroup::checkIfLoadIsComplete()
// save the new cache.
// Save a reference to the new cache.
- m_cacheBeingUpdated = m_newestCache.release();
- if (oldNewestCache) {
- // Reinstate the oldNewestCache.
- setNewestCache(oldNewestCache.release());
- }
+ m_cacheBeingUpdated = WTFMove(m_newestCache);
+ if (oldNewestCache)
+ setNewestCache(oldNewestCache.releaseNonNull());
scheduleReachedMaxAppCacheSizeCallback();
return;
}
@@ -955,7 +920,7 @@ void ApplicationCacheGroup::checkIfLoadIsComplete()
// Run the "cache failure steps"
// Fire the error events to all pending master entries, as well any other cache hosts
// currently associated with a cache in this group.
- postListenerTask(ApplicationCacheHost::ERROR_EVENT, m_associatedDocumentLoaders);
+ postListenerTask(eventNames().errorEvent, m_associatedDocumentLoaders);
// Disassociate the pending master entries from the failed new cache. Note that
// all other loaders in the m_associatedDocumentLoaders are still associated with
// some other cache in this group. They are not associated with the failed new cache.
@@ -963,14 +928,13 @@ void ApplicationCacheGroup::checkIfLoadIsComplete()
// Need to copy loaders, because the cache group may be destroyed at the end of iteration.
Vector<DocumentLoader*> loaders;
copyToVector(m_pendingMasterResourceLoaders, loaders);
- size_t count = loaders.size();
- for (size_t i = 0; i != count; ++i)
- disassociateDocumentLoader(loaders[i]); // This can delete this group.
+ for (auto& loader : loaders)
+ disassociateDocumentLoader(*loader); // This can delete this group.
// Reinstate the oldNewestCache, if there was one.
if (oldNewestCache) {
// This will discard the failed new cache.
- setNewestCache(oldNewestCache.release());
+ setNewestCache(oldNewestCache.releaseNonNull());
} else {
// We must have been deleted by the last call to disassociateDocumentLoader().
return;
@@ -984,7 +948,7 @@ void ApplicationCacheGroup::checkIfLoadIsComplete()
m_pendingMasterResourceLoaders.clear();
m_completionType = None;
setUpdateStatus(Idle);
- m_frame = 0;
+ m_frame = nullptr;
m_availableSpaceInQuota = ApplicationCacheStorage::unknownQuota();
m_calledReachedMaxAppCacheSize = false;
}
@@ -999,14 +963,13 @@ void ApplicationCacheGroup::startLoadingEntry()
return;
}
- EntryMap::const_iterator it = m_pendingEntries.begin();
+ auto firstPendingEntryURL = m_pendingEntries.begin()->key;
- postListenerTask(ApplicationCacheHost::PROGRESS_EVENT, m_progressTotal, m_progressDone, m_associatedDocumentLoaders);
+ postListenerTask(eventNames().progressEvent, m_progressTotal, m_progressDone, m_associatedDocumentLoaders);
m_progressDone++;
ASSERT(!m_currentHandle);
-
- m_currentHandle = createResourceHandle(URL(ParsedURLString, it->key), m_newestCache ? m_newestCache->resourceForURL(it->key) : 0);
+ m_currentHandle = createResourceHandle(URL(ParsedURLString, firstPendingEntryURL), m_newestCache ? m_newestCache->resourceForURL(firstPendingEntryURL) : 0);
}
void ApplicationCacheGroup::deliverDelayedMainResources()
@@ -1014,19 +977,15 @@ void ApplicationCacheGroup::deliverDelayedMainResources()
// Need to copy loaders, because the cache group may be destroyed at the end of iteration.
Vector<DocumentLoader*> loaders;
copyToVector(m_pendingMasterResourceLoaders, loaders);
- size_t count = loaders.size();
- for (size_t i = 0; i != count; ++i) {
- DocumentLoader* loader = loaders[i];
+ for (auto* loader : loaders) {
if (loader->isLoadingMainResource())
continue;
-
- const ResourceError& error = loader->mainDocumentError();
- if (error.isNull())
- finishedLoadingMainResource(loader);
+ if (loader->mainDocumentError().isNull())
+ finishedLoadingMainResource(*loader);
else
- failedLoadingMainResource(loader);
+ failedLoadingMainResource(*loader);
}
- if (!count)
+ if (loaders.isEmpty())
checkIfLoadIsComplete();
}
@@ -1034,13 +993,12 @@ void ApplicationCacheGroup::addEntry(const String& url, unsigned type)
{
ASSERT(m_cacheBeingUpdated);
ASSERT(!URL(ParsedURLString, url).hasFragmentIdentifier());
-
+
// Don't add the URL if we already have an master resource in the cache
// (i.e., the main resource finished loading before the manifest).
- if (ApplicationCacheResource* resource = m_cacheBeingUpdated->resourceForURL(url)) {
+ if (auto* resource = m_cacheBeingUpdated->resourceForURL(url)) {
ASSERT(resource->type() & ApplicationCacheResource::Master);
ASSERT(!m_frame->loader().documentLoader()->isLoadingMainResource());
-
resource->addType(type);
return;
}
@@ -1051,11 +1009,8 @@ void ApplicationCacheGroup::addEntry(const String& url, unsigned type)
m_manifestResource->addType(type);
return;
}
-
- EntryMap::AddResult result = m_pendingEntries.add(url, type);
-
- if (!result.isNewEntry)
- result.iterator->value |= type;
+
+ m_pendingEntries.add(url, type).iterator->value |= type;
}
void ApplicationCacheGroup::associateDocumentLoaderWithCache(DocumentLoader* loader, ApplicationCache* cache)
@@ -1066,90 +1021,64 @@ void ApplicationCacheGroup::associateDocumentLoaderWithCache(DocumentLoader* loa
ASSERT(!m_isObsolete);
- loader->applicationCacheHost()->setApplicationCache(cache);
+ loader->applicationCacheHost().setApplicationCache(cache);
ASSERT(!m_associatedDocumentLoaders.contains(loader));
m_associatedDocumentLoaders.add(loader);
}
-class ChromeClientCallbackTimer: public TimerBase {
+class ChromeClientCallbackTimer final : public TimerBase {
public:
- ChromeClientCallbackTimer(ApplicationCacheGroup* cacheGroup)
- : m_cacheGroup(cacheGroup)
+ ChromeClientCallbackTimer(ApplicationCacheGroup& group)
+ : m_group(group)
{
}
private:
- virtual void fired() override
+ void fired() final
{
- m_cacheGroup->didReachMaxAppCacheSize();
+ m_group.didReachMaxAppCacheSize();
delete this;
}
- // Note that there is no need to use a RefPtr here. The ApplicationCacheGroup instance is guaranteed
- // to be alive when the timer fires since invoking the ChromeClient callback is part of its normal
+
+ // Note that there is no need to use a Ref here. The ApplicationCacheGroup instance is guaranteed
+ // to be alive when the timer fires since invoking the callback is part of its normal
// update machinery and nothing can yet cause it to get deleted.
- ApplicationCacheGroup* m_cacheGroup;
+ ApplicationCacheGroup& m_group;
};
void ApplicationCacheGroup::scheduleReachedMaxAppCacheSizeCallback()
{
ASSERT(isMainThread());
- ChromeClientCallbackTimer* timer = new ChromeClientCallbackTimer(this);
+ auto* timer = new ChromeClientCallbackTimer(*this);
timer->startOneShot(0);
// The timer will delete itself once it fires.
}
-class CallCacheListenerTask : public ScriptExecutionContext::Task {
-public:
- static PassOwnPtr<CallCacheListenerTask> create(PassRefPtr<DocumentLoader> loader, ApplicationCacheHost::EventID eventID, int progressTotal, int progressDone)
- {
- return adoptPtr(new CallCacheListenerTask(loader, eventID, progressTotal, progressDone));
- }
-
- virtual void performTask(ScriptExecutionContext* context) override
- {
-
- ASSERT_UNUSED(context, context->isDocument());
- Frame* frame = m_documentLoader->frame();
- if (!frame)
- return;
-
- ASSERT(frame->loader().documentLoader() == m_documentLoader.get());
-
- m_documentLoader->applicationCacheHost()->notifyDOMApplicationCache(m_eventID, m_progressTotal, m_progressDone);
- }
-
-private:
- CallCacheListenerTask(PassRefPtr<DocumentLoader> loader, ApplicationCacheHost::EventID eventID, int progressTotal, int progressDone)
- : m_documentLoader(loader)
- , m_eventID(eventID)
- , m_progressTotal(progressTotal)
- , m_progressDone(progressDone)
- {
- }
-
- RefPtr<DocumentLoader> m_documentLoader;
- ApplicationCacheHost::EventID m_eventID;
- int m_progressTotal;
- int m_progressDone;
-};
-
-void ApplicationCacheGroup::postListenerTask(ApplicationCacheHost::EventID eventID, int progressTotal, int progressDone, const HashSet<DocumentLoader*>& loaderSet)
+void ApplicationCacheGroup::postListenerTask(const AtomicString& eventType, int progressTotal, int progressDone, const HashSet<DocumentLoader*>& loaderSet)
{
- HashSet<DocumentLoader*>::const_iterator loaderSetEnd = loaderSet.end();
- for (HashSet<DocumentLoader*>::const_iterator iter = loaderSet.begin(); iter != loaderSetEnd; ++iter)
- postListenerTask(eventID, progressTotal, progressDone, *iter);
+ for (auto& loader : loaderSet)
+ postListenerTask(eventType, progressTotal, progressDone, *loader);
}
-void ApplicationCacheGroup::postListenerTask(ApplicationCacheHost::EventID eventID, int progressTotal, int progressDone, DocumentLoader* loader)
+void ApplicationCacheGroup::postListenerTask(const AtomicString& eventType, int progressTotal, int progressDone, DocumentLoader& loader)
{
- Frame* frame = loader->frame();
+ auto* frame = loader.frame();
if (!frame)
return;
- ASSERT(frame->loader().documentLoader() == loader);
+ ASSERT(frame->loader().documentLoader() == &loader);
+
+ RefPtr<DocumentLoader> protectedLoader(&loader);
+ frame->document()->postTask([protectedLoader, &eventType, progressTotal, progressDone] (ScriptExecutionContext& context) {
+ ASSERT_UNUSED(context, context.isDocument());
+ auto* frame = protectedLoader->frame();
+ if (!frame)
+ return;
- frame->document()->postTask(CallCacheListenerTask::create(loader, eventID, progressTotal, progressDone));
+ ASSERT(frame->loader().documentLoader() == protectedLoader);
+ protectedLoader->applicationCacheHost().notifyDOMApplicationCache(eventType, progressTotal, progressDone);
+ });
}
void ApplicationCacheGroup::setUpdateStatus(UpdateStatus status)
@@ -1160,8 +1089,7 @@ void ApplicationCacheGroup::setUpdateStatus(UpdateStatus status)
void ApplicationCacheGroup::clearStorageID()
{
m_storageID = 0;
-
- for (const auto& cache : m_caches)
+ for (auto& cache : m_caches)
cache->clearStorageID();
}
diff --git a/Source/WebCore/loader/appcache/ApplicationCacheGroup.h b/Source/WebCore/loader/appcache/ApplicationCacheGroup.h
index e1fb198ed..ceb83dfc6 100644
--- a/Source/WebCore/loader/appcache/ApplicationCacheGroup.h
+++ b/Source/WebCore/loader/appcache/ApplicationCacheGroup.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2010 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008-2017 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,13 +23,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ApplicationCacheGroup_h
-#define ApplicationCacheGroup_h
+#pragma once
#include "DOMApplicationCache.h"
#include "URL.h"
#include "ResourceHandleClient.h"
-#include "SharedBuffer.h"
#include <wtf/Noncopyable.h>
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
@@ -39,6 +37,7 @@ namespace WebCore {
class ApplicationCache;
class ApplicationCacheResource;
+class ApplicationCacheStorage;
class Document;
class DocumentLoader;
class Frame;
@@ -50,10 +49,11 @@ enum ApplicationCacheUpdateOption {
ApplicationCacheUpdateWithoutBrowsingContext
};
-class ApplicationCacheGroup : ResourceHandleClient {
- WTF_MAKE_NONCOPYABLE(ApplicationCacheGroup); WTF_MAKE_FAST_ALLOCATED;
+class ApplicationCacheGroup final : private ResourceHandleClient {
+ WTF_MAKE_NONCOPYABLE(ApplicationCacheGroup);
+ WTF_MAKE_FAST_ALLOCATED;
public:
- ApplicationCacheGroup(const URL& manifestURL, bool isCopy = false);
+ explicit ApplicationCacheGroup(Ref<ApplicationCacheStorage>&&, const URL& manifestURL);
virtual ~ApplicationCacheGroup();
enum UpdateStatus { Idle, Checking, Downloading };
@@ -61,11 +61,12 @@ public:
static ApplicationCache* cacheForMainRequest(const ResourceRequest&, DocumentLoader*);
static ApplicationCache* fallbackCacheForMainRequest(const ResourceRequest&, DocumentLoader*);
- static void selectCache(Frame*, const URL& manifestURL);
- static void selectCacheWithoutManifestURL(Frame*);
-
+ static void selectCache(Frame&, const URL& manifestURL);
+ static void selectCacheWithoutManifestURL(Frame&);
+
+ ApplicationCacheStorage& storage() { return m_storage; }
const URL& manifestURL() const { return m_manifestURL; }
- const SecurityOrigin* origin() const { return m_origin.get(); }
+ const SecurityOrigin& origin() const { return m_origin.get(); }
UpdateStatus updateStatus() const { return m_updateStatus; }
void setUpdateStatus(UpdateStatus status);
@@ -73,46 +74,44 @@ public:
unsigned storageID() const { return m_storageID; }
void clearStorageID();
- void update(Frame*, ApplicationCacheUpdateOption); // FIXME: Frame should not be needed when updating without browsing context.
- void cacheDestroyed(ApplicationCache*);
+ void update(Frame&, ApplicationCacheUpdateOption); // FIXME: Frame should not be needed when updating without browsing context.
+ void cacheDestroyed(ApplicationCache&);
- void abort(Frame*);
+ void abort(Frame&);
- bool cacheIsBeingUpdated(const ApplicationCache* cache) const { return cache == m_cacheBeingUpdated; }
+ bool cacheIsComplete(ApplicationCache& cache) { return m_caches.contains(&cache); }
- void stopLoadingInFrame(Frame*);
+ void stopLoadingInFrame(Frame&);
ApplicationCache* newestCache() const { return m_newestCache.get(); }
- void setNewestCache(PassRefPtr<ApplicationCache>);
+ void setNewestCache(Ref<ApplicationCache>&&);
void makeObsolete();
bool isObsolete() const { return m_isObsolete; }
- void finishedLoadingMainResource(DocumentLoader*);
- void failedLoadingMainResource(DocumentLoader*);
-
- void disassociateDocumentLoader(DocumentLoader*);
+ void finishedLoadingMainResource(DocumentLoader&);
+ void failedLoadingMainResource(DocumentLoader&);
- bool isCopy() const { return m_isCopy; }
+ void disassociateDocumentLoader(DocumentLoader&);
private:
- static void postListenerTask(ApplicationCacheHost::EventID id, const HashSet<DocumentLoader*>& set) { postListenerTask(id, 0, 0, set); }
- static void postListenerTask(ApplicationCacheHost::EventID id, DocumentLoader* loader) { postListenerTask(id, 0, 0, loader); }
- static void postListenerTask(ApplicationCacheHost::EventID, int progressTotal, int progressDone, const HashSet<DocumentLoader*>&);
- static void postListenerTask(ApplicationCacheHost::EventID, int progressTotal, int progressDone, DocumentLoader*);
+ static void postListenerTask(const AtomicString& eventType, const HashSet<DocumentLoader*>& set) { postListenerTask(eventType, 0, 0, set); }
+ static void postListenerTask(const AtomicString& eventType, DocumentLoader& loader) { postListenerTask(eventType, 0, 0, loader); }
+ static void postListenerTask(const AtomicString& eventType, int progressTotal, int progressDone, const HashSet<DocumentLoader*>&);
+ static void postListenerTask(const AtomicString& eventType, int progressTotal, int progressDone, DocumentLoader&);
void scheduleReachedMaxAppCacheSizeCallback();
- PassRefPtr<ResourceHandle> createResourceHandle(const URL&, ApplicationCacheResource* newestCachedResource);
+ RefPtr<ResourceHandle> createResourceHandle(const URL&, ApplicationCacheResource* newestCachedResource);
// For normal resource loading, WebKit client is asked about each resource individually. Since application cache does not belong to any particular document,
// the existing client callback cannot be used, so assume that any client that enables application cache also wants it to use credential storage.
- virtual bool shouldUseCredentialStorage(ResourceHandle*) override { return true; }
+ bool shouldUseCredentialStorage(ResourceHandle*) override { return true; }
- virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&) override;
- virtual void didReceiveData(ResourceHandle*, const char*, unsigned length, int encodedDataLength) override;
- virtual void didFinishLoading(ResourceHandle*, double finishTime) override;
- virtual void didFail(ResourceHandle*, const ResourceError&) override;
+ void didReceiveResponse(ResourceHandle*, ResourceResponse&&) override;
+ void didReceiveData(ResourceHandle*, const char*, unsigned length, int encodedDataLength) override;
+ void didFinishLoading(ResourceHandle*, double finishTime) override;
+ void didFail(ResourceHandle*, const ResourceError&) override;
void didReceiveManifestResponse(const ResourceResponse&);
void didReceiveManifestData(const char*, int);
@@ -132,10 +131,12 @@ private:
void associateDocumentLoaderWithCache(DocumentLoader*, ApplicationCache*);
void stopLoading();
-
+
+ Ref<ApplicationCacheStorage> m_storage;
+
URL m_manifestURL;
- RefPtr<SecurityOrigin> m_origin;
- UpdateStatus m_updateStatus;
+ Ref<SecurityOrigin> m_origin;
+ UpdateStatus m_updateStatus { Idle };
// This is the newest complete cache in the group.
RefPtr<ApplicationCache> m_newestCache;
@@ -150,26 +151,25 @@ private:
// List of pending master entries, used during the update process to ensure that new master entries are cached.
HashSet<DocumentLoader*> m_pendingMasterResourceLoaders;
// How many of the above pending master entries have not yet finished downloading.
- int m_downloadingPendingMasterResourceLoadersCount;
+ int m_downloadingPendingMasterResourceLoadersCount { 0 };
// These are all the document loaders that are associated with a cache in this group.
HashSet<DocumentLoader*> m_associatedDocumentLoaders;
// The URLs and types of pending cache entries.
- typedef HashMap<String, unsigned> EntryMap;
- EntryMap m_pendingEntries;
+ HashMap<String, unsigned> m_pendingEntries;
// The total number of items to be processed to update the cache group and the number that have been done.
- int m_progressTotal;
- int m_progressDone;
+ int m_progressTotal { 0 };
+ int m_progressDone { 0 };
// Frame used for fetching resources when updating.
// FIXME: An update started by a particular frame should not stop if it is destroyed, but there are other frames associated with the same cache group.
- Frame* m_frame;
+ Frame* m_frame { nullptr };
// An obsolete cache group is never stored, but the opposite is not true - storing may fail for multiple reasons, such as exceeding disk quota.
- unsigned m_storageID;
- bool m_isObsolete;
+ unsigned m_storageID { 0 };
+ bool m_isObsolete { false };
// During update, this is used to handle asynchronously arriving results.
enum CompletionType {
@@ -178,32 +178,24 @@ private:
Failure,
Completed
};
- CompletionType m_completionType;
-
- // Whether this cache group is a copy that's only used for transferring the cache to another file.
- bool m_isCopy;
+ CompletionType m_completionType { None };
// This flag is set immediately after the ChromeClient::reachedMaxAppCacheSize() callback is invoked as a result of the storage layer failing to save a cache
// due to reaching the maximum size of the application cache database file. This flag is used by ApplicationCacheGroup::checkIfLoadIsComplete() to decide
// the course of action in case of this failure (i.e. call the ChromeClient callback or run the failure steps).
- bool m_calledReachedMaxAppCacheSize;
+ bool m_calledReachedMaxAppCacheSize { false };
RefPtr<ResourceHandle> m_currentHandle;
RefPtr<ApplicationCacheResource> m_currentResource;
-
-#if ENABLE(INSPECTOR)
unsigned long m_currentResourceIdentifier;
-#endif
RefPtr<ApplicationCacheResource> m_manifestResource;
RefPtr<ResourceHandle> m_manifestHandle;
int64_t m_availableSpaceInQuota;
- bool m_originQuotaExceededPreviously;
+ bool m_originQuotaExceededPreviously { false };
friend class ChromeClientCallbackTimer;
};
} // namespace WebCore
-
-#endif // ApplicationCacheGroup_h
diff --git a/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp b/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp
index 9cc3f8d85..9114699c8 100644
--- a/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp
+++ b/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008-2016 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,33 +29,33 @@
#include "ApplicationCache.h"
#include "ApplicationCacheGroup.h"
#include "ApplicationCacheResource.h"
+#include "ContentSecurityPolicy.h"
#include "DocumentLoader.h"
#include "DOMApplicationCache.h"
+#include "EventNames.h"
+#include "FileSystem.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
#include "InspectorInstrumentation.h"
+#include "MainFrame.h"
+#include "Page.h"
#include "ProgressEvent.h"
#include "ResourceHandle.h"
-#include "ResourceLoader.h"
#include "ResourceRequest.h"
#include "Settings.h"
+#include "SubresourceLoader.h"
namespace WebCore {
-ApplicationCacheHost::ApplicationCacheHost(DocumentLoader* documentLoader)
- : m_domApplicationCache(0)
- , m_documentLoader(documentLoader)
- , m_defersEvents(true)
- , m_candidateApplicationCacheGroup(0)
+ApplicationCacheHost::ApplicationCacheHost(DocumentLoader& documentLoader)
+ : m_documentLoader(documentLoader)
{
- ASSERT(m_documentLoader);
}
ApplicationCacheHost::~ApplicationCacheHost()
{
ASSERT(!m_applicationCache || !m_candidateApplicationCacheGroup || m_applicationCache->group() == m_candidateApplicationCacheGroup);
-
if (m_applicationCache)
m_applicationCache->group()->disassociateDocumentLoader(m_documentLoader);
else if (m_candidateApplicationCacheGroup)
@@ -64,31 +64,41 @@ ApplicationCacheHost::~ApplicationCacheHost()
void ApplicationCacheHost::selectCacheWithoutManifest()
{
- ApplicationCacheGroup::selectCacheWithoutManifestURL(m_documentLoader->frame());
+ ASSERT(m_documentLoader.frame());
+ ApplicationCacheGroup::selectCacheWithoutManifestURL(*m_documentLoader.frame());
}
void ApplicationCacheHost::selectCacheWithManifest(const URL& manifestURL)
{
- ApplicationCacheGroup::selectCache(m_documentLoader->frame(), manifestURL);
+ ASSERT(m_documentLoader.frame());
+ ApplicationCacheGroup::selectCache(*m_documentLoader.frame(), manifestURL);
}
void ApplicationCacheHost::maybeLoadMainResource(ResourceRequest& request, SubstituteData& substituteData)
{
// Check if this request should be loaded from the application cache
- if (!substituteData.isValid() && isApplicationCacheEnabled()) {
+ if (!substituteData.isValid() && isApplicationCacheEnabled() && !isApplicationCacheBlockedForRequest(request)) {
ASSERT(!m_mainResourceApplicationCache);
- m_mainResourceApplicationCache = ApplicationCacheGroup::cacheForMainRequest(request, m_documentLoader);
+ m_mainResourceApplicationCache = ApplicationCacheGroup::cacheForMainRequest(request, &m_documentLoader);
if (m_mainResourceApplicationCache) {
// Get the resource from the application cache. By definition, cacheForMainRequest() returns a cache that contains the resource.
ApplicationCacheResource* resource = m_mainResourceApplicationCache->resourceForRequest(request);
- substituteData = SubstituteData(resource->data(),
- resource->response().mimeType(),
- resource->response().textEncodingName(),
- URL(),
+
+ // ApplicationCache resources have fragment identifiers stripped off of their URLs,
+ // but we'll need to restore that for the SubstituteData.
+ ResourceResponse responseToUse = resource->response();
+ if (request.url().hasFragmentIdentifier()) {
+ URL url = responseToUse.url();
+ url.setFragmentIdentifier(request.url().fragmentIdentifier());
+ responseToUse.setURL(url);
+ }
+
+ substituteData = SubstituteData(&resource->data(),
URL(),
- SubstituteData::ShouldRevealToSessionHistory);
+ responseToUse,
+ SubstituteData::SessionHistoryVisibility::Visible);
}
}
}
@@ -103,10 +113,10 @@ bool ApplicationCacheHost::maybeLoadFallbackForMainResponse(const ResourceReques
{
if (r.httpStatusCode() / 100 == 4 || r.httpStatusCode() / 100 == 5) {
ASSERT(!m_mainResourceApplicationCache);
- if (isApplicationCacheEnabled()) {
- m_mainResourceApplicationCache = ApplicationCacheGroup::fallbackCacheForMainRequest(request, documentLoader());
+ if (isApplicationCacheEnabled() && !isApplicationCacheBlockedForRequest(request)) {
+ m_mainResourceApplicationCache = ApplicationCacheGroup::fallbackCacheForMainRequest(request, &m_documentLoader);
- if (scheduleLoadFallbackResourceFromApplicationCache(documentLoader()->mainResourceLoader(), m_mainResourceApplicationCache.get()))
+ if (scheduleLoadFallbackResourceFromApplicationCache(m_documentLoader.mainResourceLoader(), m_mainResourceApplicationCache.get()))
return true;
}
}
@@ -117,10 +127,10 @@ bool ApplicationCacheHost::maybeLoadFallbackForMainError(const ResourceRequest&
{
if (!error.isCancellation()) {
ASSERT(!m_mainResourceApplicationCache);
- if (isApplicationCacheEnabled()) {
- m_mainResourceApplicationCache = ApplicationCacheGroup::fallbackCacheForMainRequest(request, m_documentLoader);
+ if (isApplicationCacheEnabled() && !isApplicationCacheBlockedForRequest(request)) {
+ m_mainResourceApplicationCache = ApplicationCacheGroup::fallbackCacheForMainRequest(request, &m_documentLoader);
- if (scheduleLoadFallbackResourceFromApplicationCache(documentLoader()->mainResourceLoader(), m_mainResourceApplicationCache.get()))
+ if (scheduleLoadFallbackResourceFromApplicationCache(m_documentLoader.mainResourceLoader(), m_mainResourceApplicationCache.get()))
return true;
}
}
@@ -129,12 +139,11 @@ bool ApplicationCacheHost::maybeLoadFallbackForMainError(const ResourceRequest&
void ApplicationCacheHost::mainResourceDataReceived(const char*, int, long long, bool)
{
- // This method is here to facilitate alternate implemetations of this interface by the host browser.
}
void ApplicationCacheHost::failedLoadingMainResource()
{
- ApplicationCacheGroup* group = m_candidateApplicationCacheGroup;
+ auto* group = m_candidateApplicationCacheGroup;
if (!group && m_applicationCache) {
if (mainResourceApplicationCache()) {
// Even when the main resource is being loaded from an application cache, loading can fail if aborted.
@@ -149,7 +158,7 @@ void ApplicationCacheHost::failedLoadingMainResource()
void ApplicationCacheHost::finishedLoadingMainResource()
{
- ApplicationCacheGroup* group = candidateApplicationCacheGroup();
+ auto* group = candidateApplicationCacheGroup();
if (!group && applicationCache() && !mainResourceApplicationCache())
group = applicationCache()->group();
@@ -157,9 +166,9 @@ void ApplicationCacheHost::finishedLoadingMainResource()
group->finishedLoadingMainResource(m_documentLoader);
}
-bool ApplicationCacheHost::maybeLoadResource(ResourceLoader* loader, ResourceRequest& request, const URL& originalURL)
+bool ApplicationCacheHost::maybeLoadResource(ResourceLoader& loader, const ResourceRequest& request, const URL& originalURL)
{
- if (!isApplicationCacheEnabled())
+ if (!isApplicationCacheEnabled() && !isApplicationCacheBlockedForRequest(request))
return false;
if (request.url() != originalURL)
@@ -168,33 +177,33 @@ bool ApplicationCacheHost::maybeLoadResource(ResourceLoader* loader, ResourceReq
ApplicationCacheResource* resource;
if (!shouldLoadResourceFromApplicationCache(request, resource))
return false;
-
- m_documentLoader->m_pendingSubstituteResources.set(loader, resource);
- m_documentLoader->deliverSubstituteResourcesAfterDelay();
-
+
+ m_documentLoader.scheduleSubstituteResourceLoad(loader, *resource);
return true;
}
bool ApplicationCacheHost::maybeLoadFallbackForRedirect(ResourceLoader* resourceLoader, ResourceRequest& request, const ResourceResponse& redirectResponse)
{
- if (!redirectResponse.isNull() && !protocolHostAndPortAreEqual(request.url(), redirectResponse.url()))
+ if (!redirectResponse.isNull() && !protocolHostAndPortAreEqual(request.url(), redirectResponse.url())) {
if (scheduleLoadFallbackResourceFromApplicationCache(resourceLoader))
return true;
+ }
return false;
}
bool ApplicationCacheHost::maybeLoadFallbackForResponse(ResourceLoader* resourceLoader, const ResourceResponse& response)
{
- if (response.httpStatusCode() / 100 == 4 || response.httpStatusCode() / 100 == 5)
+ if (response.httpStatusCode() / 100 == 4 || response.httpStatusCode() / 100 == 5) {
if (scheduleLoadFallbackResourceFromApplicationCache(resourceLoader))
return true;
+ }
return false;
}
bool ApplicationCacheHost::maybeLoadFallbackForError(ResourceLoader* resourceLoader, const ResourceError& error)
{
if (!error.isCancellation()) {
- if (resourceLoader == m_documentLoader->mainResourceLoader())
+ if (resourceLoader == m_documentLoader.mainResourceLoader())
return maybeLoadFallbackForMainError(resourceLoader->request(), error);
if (scheduleLoadFallbackResourceFromApplicationCache(resourceLoader))
return true;
@@ -202,22 +211,51 @@ bool ApplicationCacheHost::maybeLoadFallbackForError(ResourceLoader* resourceLoa
return false;
}
-bool ApplicationCacheHost::maybeLoadSynchronously(ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data)
+URL ApplicationCacheHost::createFileURL(const String& path)
+{
+ // FIXME: Can we just use fileURLWithFileSystemPath instead?
+
+ // fileURLWithFileSystemPath function is not suitable because URL::setPath uses encodeWithURLEscapeSequences, which it notes
+ // does not correctly escape '#' and '?'. This function works for our purposes because
+ // app cache media files are always created with encodeForFileName(createCanonicalUUIDString()).
+
+#if USE(CF) && PLATFORM(WIN)
+ URL url(adoptCF(CFURLCreateWithFileSystemPath(0, path.createCFString().get(), kCFURLWindowsPathStyle, false)).get());
+#else
+ URL url;
+ url.setProtocol(ASCIILiteral("file"));
+ url.setPath(path);
+#endif
+ return url;
+}
+
+static inline RefPtr<SharedBuffer> bufferFromResource(ApplicationCacheResource& resource)
+{
+ // FIXME: Clients probably do not need a copy of the SharedBuffer.
+ // Remove the call to copy() once we ensure SharedBuffer will not be modified.
+ if (resource.path().isEmpty())
+ return resource.data().copy();
+ return SharedBuffer::createWithContentsOfFile(resource.path());
+}
+
+bool ApplicationCacheHost::maybeLoadSynchronously(ResourceRequest& request, ResourceError& error, ResourceResponse& response, RefPtr<SharedBuffer>& data)
{
ApplicationCacheResource* resource;
- if (shouldLoadResourceFromApplicationCache(request, resource)) {
- if (resource) {
- response = resource->response();
- data.append(resource->data()->data(), resource->data()->size());
- } else {
- error = documentLoader()->frameLoader()->client().cannotShowURLError(request);
- }
+ if (!shouldLoadResourceFromApplicationCache(request, resource))
+ return false;
+
+ auto responseData = resource ? bufferFromResource(*resource) : nullptr;
+ if (!responseData) {
+ error = m_documentLoader.frameLoader()->client().cannotShowURLError(request);
return true;
}
- return false;
+
+ response = resource->response();
+ data = WTFMove(responseData);
+ return true;
}
-void ApplicationCacheHost::maybeLoadFallbackSynchronously(const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data)
+void ApplicationCacheHost::maybeLoadFallbackSynchronously(const ResourceRequest& request, ResourceError& error, ResourceResponse& response, RefPtr<SharedBuffer>& data)
{
// If normal loading results in a redirect to a resource with another origin (indicative of a captive portal), or a 4xx or 5xx status code or equivalent,
// or if there were network errors (but not if the user canceled the download), then instead get, from the cache, the resource of the fallback entry
@@ -228,8 +266,9 @@ void ApplicationCacheHost::maybeLoadFallbackSynchronously(const ResourceRequest&
ApplicationCacheResource* resource;
if (getApplicationCacheFallbackResource(request, resource)) {
response = resource->response();
- data.clear();
- data.append(resource->data()->data(), resource->data()->size());
+ // FIXME: Clients proably do not need a copy of the SharedBuffer.
+ // Remove the call to copy() once we ensure SharedBuffer will not be modified.
+ data = resource->data().copy();
}
}
}
@@ -245,20 +284,21 @@ void ApplicationCacheHost::setDOMApplicationCache(DOMApplicationCache* domApplic
m_domApplicationCache = domApplicationCache;
}
-void ApplicationCacheHost::notifyDOMApplicationCache(EventID id, int total, int done)
+void ApplicationCacheHost::notifyDOMApplicationCache(const AtomicString& eventType, int total, int done)
{
- if (id != PROGRESS_EVENT)
- InspectorInstrumentation::updateApplicationCacheStatus(m_documentLoader->frame());
+ if (eventType != eventNames().progressEvent)
+ InspectorInstrumentation::updateApplicationCacheStatus(m_documentLoader.frame());
if (m_defersEvents) {
// Event dispatching is deferred until document.onload has fired.
- m_deferredEvents.append(DeferredEvent(id, total, done));
+ m_deferredEvents.append({ eventType, total, done });
return;
}
- dispatchDOMEvent(id, total, done);
+
+ dispatchDOMEvent(eventType, total, done);
}
-void ApplicationCacheHost::stopLoadingInFrame(Frame* frame)
+void ApplicationCacheHost::stopLoadingInFrame(Frame& frame)
{
ASSERT(!m_applicationCache || !m_candidateApplicationCacheGroup || m_applicationCache->group() == m_candidateApplicationCacheGroup);
@@ -270,56 +310,69 @@ void ApplicationCacheHost::stopLoadingInFrame(Frame* frame)
void ApplicationCacheHost::stopDeferringEvents()
{
- RefPtr<DocumentLoader> protect(documentLoader());
- for (unsigned i = 0; i < m_deferredEvents.size(); ++i) {
- const DeferredEvent& deferred = m_deferredEvents[i];
- dispatchDOMEvent(deferred.eventID, deferred.progressTotal, deferred.progressDone);
+ Ref<DocumentLoader> protect(m_documentLoader);
+
+ // Note, do not cache the size in a local variable.
+ // This code needs to properly handle the case where more events are added to
+ // m_deferredEvents while iterating it. This is why we don't use a modern for loop.
+ for (size_t i = 0; i < m_deferredEvents.size(); ++i) {
+ auto& event = m_deferredEvents[i];
+ dispatchDOMEvent(event.eventType, event.progressTotal, event.progressDone);
}
+
m_deferredEvents.clear();
m_defersEvents = false;
}
-#if ENABLE(INSPECTOR)
-void ApplicationCacheHost::fillResourceList(ResourceInfoList* resources)
+Vector<ApplicationCacheHost::ResourceInfo> ApplicationCacheHost::resourceList()
{
- ApplicationCache* cache = applicationCache();
+ Vector<ResourceInfo> result;
+
+ auto* cache = applicationCache();
if (!cache || !cache->isComplete())
- return;
-
- for (const auto& urlAndResource : *cache) {
- RefPtr<ApplicationCacheResource> resource = urlAndResource.value;
- unsigned type = resource->type();
- bool isMaster = type & ApplicationCacheResource::Master;
+ return result;
+
+ result.reserveInitialCapacity(cache->resources().size());
+
+ for (auto& urlAndResource : cache->resources()) {
+ ASSERT(urlAndResource.value);
+ auto& resource = *urlAndResource.value;
+
+ unsigned type = resource.type();
+ bool isMaster = type & ApplicationCacheResource::Master;
bool isManifest = type & ApplicationCacheResource::Manifest;
bool isExplicit = type & ApplicationCacheResource::Explicit;
- bool isForeign = type & ApplicationCacheResource::Foreign;
+ bool isForeign = type & ApplicationCacheResource::Foreign;
bool isFallback = type & ApplicationCacheResource::Fallback;
- resources->append(ResourceInfo(resource->url(), isMaster, isManifest, isFallback, isForeign, isExplicit, resource->estimatedSizeInStorage()));
+
+ result.uncheckedAppend({ resource.url(), isMaster, isManifest, isFallback, isForeign, isExplicit, resource.estimatedSizeInStorage() });
}
+
+ return result;
}
-
+
ApplicationCacheHost::CacheInfo ApplicationCacheHost::applicationCacheInfo()
{
- ApplicationCache* cache = applicationCache();
+ auto* cache = applicationCache();
if (!cache || !cache->isComplete())
- return CacheInfo(URL(), 0, 0, 0);
-
+ return { { }, 0, 0, 0 };
+
// FIXME: Add "Creation Time" and "Update Time" to Application Caches.
- return CacheInfo(cache->manifestResource()->url(), 0, 0, cache->estimatedSizeInStorage());
+ return { cache->manifestResource()->url(), 0, 0, cache->estimatedSizeInStorage() };
}
-#endif
-void ApplicationCacheHost::dispatchDOMEvent(EventID id, int total, int done)
+static Ref<Event> createApplicationCacheEvent(const AtomicString& eventType, int total, int done)
{
- if (m_domApplicationCache) {
- const AtomicString& eventType = DOMApplicationCache::toEventType(id);
- RefPtr<Event> event;
- if (id == PROGRESS_EVENT)
- event = ProgressEvent::create(eventType, true, done, total);
- else
- event = Event::create(eventType, false, false);
- m_domApplicationCache->dispatchEvent(event, ASSERT_NO_EXCEPTION);
- }
+ if (eventType == eventNames().progressEvent)
+ return ProgressEvent::create(eventType, true, done, total);
+ return Event::create(eventType, false, false);
+}
+
+void ApplicationCacheHost::dispatchDOMEvent(const AtomicString& eventType, int total, int done)
+{
+ if (!m_domApplicationCache)
+ return;
+ m_domApplicationCache->dispatchEvent(createApplicationCacheEvent(eventType, total, done));
}
void ApplicationCacheHost::setCandidateApplicationCacheGroup(ApplicationCacheGroup* group)
@@ -328,25 +381,30 @@ void ApplicationCacheHost::setCandidateApplicationCacheGroup(ApplicationCacheGro
m_candidateApplicationCacheGroup = group;
}
-void ApplicationCacheHost::setApplicationCache(PassRefPtr<ApplicationCache> applicationCache)
+void ApplicationCacheHost::setApplicationCache(RefPtr<ApplicationCache>&& applicationCache)
{
if (m_candidateApplicationCacheGroup) {
ASSERT(!m_applicationCache);
- m_candidateApplicationCacheGroup = 0;
+ m_candidateApplicationCacheGroup = nullptr;
}
-
- m_applicationCache = applicationCache;
+ m_applicationCache = WTFMove(applicationCache);
}
-bool ApplicationCacheHost::shouldLoadResourceFromApplicationCache(const ResourceRequest& request, ApplicationCacheResource*& resource)
+bool ApplicationCacheHost::shouldLoadResourceFromApplicationCache(const ResourceRequest& originalRequest, ApplicationCacheResource*& resource)
{
- ApplicationCache* cache = applicationCache();
+ auto* cache = applicationCache();
if (!cache || !cache->isComplete())
return false;
+ ResourceRequest request(originalRequest);
+ if (auto* loaderFrame = m_documentLoader.frame()) {
+ if (auto* document = loaderFrame->document())
+ document->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(request, ContentSecurityPolicy::InsecureRequestType::Load);
+ }
+
// If the resource is not to be fetched using the HTTP GET mechanism or equivalent, or if its URL has a different
// <scheme> component than the application cache's manifest, then fetch the resource normally.
- if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request) || !equalIgnoringCase(request.url().protocol(), cache->manifestResource()->url().protocol()))
+ if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request) || !equalIgnoringASCIICase(request.url().protocol(), cache->manifestResource()->url().protocol()))
return false;
// If the resource's URL is an master entry, the manifest, an explicit entry, or a fallback entry
@@ -385,45 +443,40 @@ bool ApplicationCacheHost::getApplicationCacheFallbackResource(const ResourceReq
resource = cache->resourceForURL(fallbackURL);
ASSERT(resource);
-
return true;
}
bool ApplicationCacheHost::scheduleLoadFallbackResourceFromApplicationCache(ResourceLoader* loader, ApplicationCache* cache)
{
- if (!isApplicationCacheEnabled())
+ if (!isApplicationCacheEnabled() && !isApplicationCacheBlockedForRequest(loader->request()))
return false;
ApplicationCacheResource* resource;
if (!getApplicationCacheFallbackResource(loader->request(), resource, cache))
return false;
- m_documentLoader->m_pendingSubstituteResources.set(loader, resource);
- m_documentLoader->deliverSubstituteResourcesAfterDelay();
-
- loader->handle()->cancel();
-
+ loader->willSwitchToSubstituteResource();
+ m_documentLoader.scheduleSubstituteResourceLoad(*loader, *resource);
return true;
}
ApplicationCacheHost::Status ApplicationCacheHost::status() const
{
- ApplicationCache* cache = applicationCache();
+ auto* cache = applicationCache();
if (!cache)
return UNCACHED;
switch (cache->group()->updateStatus()) {
- case ApplicationCacheGroup::Checking:
- return CHECKING;
- case ApplicationCacheGroup::Downloading:
- return DOWNLOADING;
- case ApplicationCacheGroup::Idle: {
- if (cache->group()->isObsolete())
- return OBSOLETE;
- if (cache != cache->group()->newestCache())
- return UPDATEREADY;
- return IDLE;
- }
+ case ApplicationCacheGroup::Checking:
+ return CHECKING;
+ case ApplicationCacheGroup::Downloading:
+ return DOWNLOADING;
+ case ApplicationCacheGroup::Idle:
+ if (cache->group()->isObsolete())
+ return OBSOLETE;
+ if (cache != cache->group()->newestCache())
+ return UPDATEREADY;
+ return IDLE;
}
ASSERT_NOT_REACHED();
@@ -432,16 +485,19 @@ ApplicationCacheHost::Status ApplicationCacheHost::status() const
bool ApplicationCacheHost::update()
{
- ApplicationCache* cache = applicationCache();
+ auto* cache = applicationCache();
if (!cache)
return false;
- cache->group()->update(m_documentLoader->frame(), ApplicationCacheUpdateWithoutBrowsingContext);
+ auto* frame = m_documentLoader.frame();
+ if (!frame)
+ return false;
+ cache->group()->update(*frame, ApplicationCacheUpdateWithoutBrowsingContext);
return true;
}
bool ApplicationCacheHost::swapCache()
{
- ApplicationCache* cache = applicationCache();
+ auto* cache = applicationCache();
if (!cache)
return false;
@@ -452,31 +508,40 @@ bool ApplicationCacheHost::swapCache()
}
// If there is no newer cache, raise an INVALID_STATE_ERR exception.
- ApplicationCache* newestCache = cache->group()->newestCache();
+ auto* newestCache = cache->group()->newestCache();
if (cache == newestCache)
return false;
ASSERT(cache->group() == newestCache->group());
setApplicationCache(newestCache);
- InspectorInstrumentation::updateApplicationCacheStatus(m_documentLoader->frame());
+ InspectorInstrumentation::updateApplicationCacheStatus(m_documentLoader.frame());
return true;
}
void ApplicationCacheHost::abort()
{
- ApplicationCacheGroup* cacheGroup = candidateApplicationCacheGroup();
- if (cacheGroup)
- cacheGroup->abort(m_documentLoader->frame());
- else {
- ApplicationCache* cache = applicationCache();
- if (cache)
- cache->group()->abort(m_documentLoader->frame());
- }
+ auto* frame = m_documentLoader.frame();
+ if (!frame)
+ return;
+ if (auto* cacheGroup = candidateApplicationCacheGroup())
+ cacheGroup->abort(*frame);
+ else if (auto* cache = applicationCache())
+ cache->group()->abort(*frame);
}
bool ApplicationCacheHost::isApplicationCacheEnabled()
{
- return m_documentLoader->frame() && m_documentLoader->frame()->settings().offlineWebApplicationCacheEnabled();
+ return m_documentLoader.frame() && m_documentLoader.frame()->settings().offlineWebApplicationCacheEnabled() && !m_documentLoader.frame()->page()->usesEphemeralSession();
+}
+
+bool ApplicationCacheHost::isApplicationCacheBlockedForRequest(const ResourceRequest& request)
+{
+ auto* frame = m_documentLoader.frame();
+ if (!frame)
+ return false;
+ if (frame->isMainFrame())
+ return false;
+ return !SecurityOrigin::create(request.url())->canAccessApplicationCache(frame->document()->topOrigin());
}
} // namespace WebCore
diff --git a/Source/WebCore/loader/appcache/ApplicationCacheHost.h b/Source/WebCore/loader/appcache/ApplicationCacheHost.h
index f6e0d0b94..2bfdc62f9 100644
--- a/Source/WebCore/loader/appcache/ApplicationCacheHost.h
+++ b/Source/WebCore/loader/appcache/ApplicationCacheHost.h
@@ -1,6 +1,7 @@
/*
- * Copyright (c) 2009, Google Inc. All rights reserved.
- *
+ * Copyright (c) 2009, Google Inc. All rights reserved.
+ * Copyright (c) 2017 Apple Inc. All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
@@ -28,172 +29,138 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ApplicationCacheHost_h
-#define ApplicationCacheHost_h
+#pragma once
#include "URL.h"
#include <wtf/Deque.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
namespace WebCore {
- class DOMApplicationCache;
- class DocumentLoader;
- class Frame;
- class ResourceLoader;
- class ResourceError;
- class ResourceRequest;
- class ResourceResponse;
- class SubstituteData;
- class ApplicationCache;
- class ApplicationCacheGroup;
- class ApplicationCacheResource;
- class ApplicationCacheStorage;
-
- class ApplicationCacheHost {
- WTF_MAKE_NONCOPYABLE(ApplicationCacheHost); WTF_MAKE_FAST_ALLOCATED;
- public:
- // The Status numeric values are specified in the HTML5 spec.
- enum Status {
- UNCACHED = 0,
- IDLE = 1,
- CHECKING = 2,
- DOWNLOADING = 3,
- UPDATEREADY = 4,
- OBSOLETE = 5
- };
-
- enum EventID {
- CHECKING_EVENT = 0,
- ERROR_EVENT,
- NOUPDATE_EVENT,
- DOWNLOADING_EVENT,
- PROGRESS_EVENT,
- UPDATEREADY_EVENT,
- CACHED_EVENT,
- OBSOLETE_EVENT // Must remain the last value, this is used to size arrays.
- };
-
-#if ENABLE(INSPECTOR)
- struct CacheInfo {
- CacheInfo(const URL& manifest, double creationTime, double updateTime, long long size)
- : m_manifest(manifest)
- , m_creationTime(creationTime)
- , m_updateTime(updateTime)
- , m_size(size) { }
- URL m_manifest;
- double m_creationTime;
- double m_updateTime;
- long long m_size;
- };
-
- struct ResourceInfo {
- ResourceInfo(const URL& resource, bool isMaster, bool isManifest, bool isFallback, bool isForeign, bool isExplicit, long long size)
- : m_resource(resource)
- , m_isMaster(isMaster)
- , m_isManifest(isManifest)
- , m_isFallback(isFallback)
- , m_isForeign(isForeign)
- , m_isExplicit(isExplicit)
- , m_size(size) { }
- URL m_resource;
- bool m_isMaster;
- bool m_isManifest;
- bool m_isFallback;
- bool m_isForeign;
- bool m_isExplicit;
- long long m_size;
- };
-
- typedef Vector<ResourceInfo> ResourceInfoList;
-#endif
-
- ApplicationCacheHost(DocumentLoader*);
- ~ApplicationCacheHost();
-
- void selectCacheWithoutManifest();
- void selectCacheWithManifest(const URL& manifestURL);
-
- void maybeLoadMainResource(ResourceRequest&, SubstituteData&);
- void maybeLoadMainResourceForRedirect(ResourceRequest&, SubstituteData&);
- bool maybeLoadFallbackForMainResponse(const ResourceRequest&, const ResourceResponse&);
- void mainResourceDataReceived(const char* data, int length, long long encodedDataLength, bool allAtOnce);
- void finishedLoadingMainResource();
- void failedLoadingMainResource();
-
- bool maybeLoadResource(ResourceLoader*, ResourceRequest&, const URL& originalURL);
- bool maybeLoadFallbackForRedirect(ResourceLoader*, ResourceRequest&, const ResourceResponse&);
- bool maybeLoadFallbackForResponse(ResourceLoader*, const ResourceResponse&);
- bool maybeLoadFallbackForError(ResourceLoader*, const ResourceError&);
-
- bool maybeLoadSynchronously(ResourceRequest&, ResourceError&, ResourceResponse&, Vector<char>& data);
- void maybeLoadFallbackSynchronously(const ResourceRequest&, ResourceError&, ResourceResponse&, Vector<char>& data);
-
- bool canCacheInPageCache();
-
- Status status() const;
- bool update();
- bool swapCache();
- void abort();
-
- void setDOMApplicationCache(DOMApplicationCache*);
- void notifyDOMApplicationCache(EventID, int progressTotal, int progressDone);
-
- void stopLoadingInFrame(Frame*);
-
- void stopDeferringEvents(); // Also raises the events that have been queued up.
-
-#if ENABLE(INSPECTOR)
- void fillResourceList(ResourceInfoList*);
- CacheInfo applicationCacheInfo();
-#endif
-
- bool shouldLoadResourceFromApplicationCache(const ResourceRequest&, ApplicationCacheResource*&);
- bool getApplicationCacheFallbackResource(const ResourceRequest&, ApplicationCacheResource*&, ApplicationCache* = 0);
-
- private:
- bool isApplicationCacheEnabled();
- DocumentLoader* documentLoader() const { return m_documentLoader; }
-
- struct DeferredEvent {
- EventID eventID;
- int progressTotal;
- int progressDone;
- DeferredEvent(EventID id, int total, int done) : eventID(id), progressTotal(total), progressDone(done) { }
- };
-
- DOMApplicationCache* m_domApplicationCache;
- DocumentLoader* m_documentLoader;
- bool m_defersEvents; // Events are deferred until after document onload.
- Vector<DeferredEvent> m_deferredEvents;
-
- void dispatchDOMEvent(EventID, int progressTotal, int progressDone);
-
- friend class ApplicationCacheGroup;
- friend class ApplicationCacheStorage;
-
- bool scheduleLoadFallbackResourceFromApplicationCache(ResourceLoader*, ApplicationCache* = 0);
- void setCandidateApplicationCacheGroup(ApplicationCacheGroup* group);
- ApplicationCacheGroup* candidateApplicationCacheGroup() const { return m_candidateApplicationCacheGroup; }
- void setApplicationCache(PassRefPtr<ApplicationCache> applicationCache);
- ApplicationCache* applicationCache() const { return m_applicationCache.get(); }
- ApplicationCache* mainResourceApplicationCache() const { return m_mainResourceApplicationCache.get(); }
- bool maybeLoadFallbackForMainError(const ResourceRequest&, const ResourceError&);
-
-
- // The application cache that the document loader is associated with (if any).
- RefPtr<ApplicationCache> m_applicationCache;
-
- // Before an application cache has finished loading, this will be the candidate application
- // group that the document loader is associated with.
- ApplicationCacheGroup* m_candidateApplicationCacheGroup;
-
- // This is the application cache the main resource was loaded from (if any).
- RefPtr<ApplicationCache> m_mainResourceApplicationCache;
+
+class ApplicationCache;
+class ApplicationCacheGroup;
+class ApplicationCacheResource;
+class ApplicationCacheStorage;
+class DOMApplicationCache;
+class DocumentLoader;
+class Frame;
+class ResourceError;
+class ResourceLoader;
+class ResourceRequest;
+class ResourceResponse;
+class SharedBuffer;
+class SubstituteData;
+
+class ApplicationCacheHost {
+ WTF_MAKE_NONCOPYABLE(ApplicationCacheHost); WTF_MAKE_FAST_ALLOCATED;
+public:
+ // The Status numeric values are specified in the HTML5 spec.
+ enum Status {
+ UNCACHED = 0,
+ IDLE = 1,
+ CHECKING = 2,
+ DOWNLOADING = 3,
+ UPDATEREADY = 4,
+ OBSOLETE = 5
};
-} // namespace WebCore
+ struct CacheInfo {
+ URL manifest;
+ double creationTime;
+ double updateTime;
+ long long size;
+ };
+
+ struct ResourceInfo {
+ URL resource;
+ bool isMaster;
+ bool isManifest;
+ bool isFallback;
+ bool isForeign;
+ bool isExplicit;
+ long long size;
+ };
+
+ explicit ApplicationCacheHost(DocumentLoader&);
+ ~ApplicationCacheHost();
+
+ static URL createFileURL(const String&);
+
+ void selectCacheWithoutManifest();
+ void selectCacheWithManifest(const URL& manifestURL);
+
+ void maybeLoadMainResource(ResourceRequest&, SubstituteData&);
+ void maybeLoadMainResourceForRedirect(ResourceRequest&, SubstituteData&);
+ bool maybeLoadFallbackForMainResponse(const ResourceRequest&, const ResourceResponse&);
+ void mainResourceDataReceived(const char* data, int length, long long encodedDataLength, bool allAtOnce);
+ void finishedLoadingMainResource();
+ void failedLoadingMainResource();
+
+ WEBCORE_EXPORT bool maybeLoadResource(ResourceLoader&, const ResourceRequest&, const URL& originalURL);
+ WEBCORE_EXPORT bool maybeLoadFallbackForRedirect(ResourceLoader*, ResourceRequest&, const ResourceResponse&);
+ WEBCORE_EXPORT bool maybeLoadFallbackForResponse(ResourceLoader*, const ResourceResponse&);
+ WEBCORE_EXPORT bool maybeLoadFallbackForError(ResourceLoader*, const ResourceError&);
+
+ bool maybeLoadSynchronously(ResourceRequest&, ResourceError&, ResourceResponse&, RefPtr<SharedBuffer>&);
+ void maybeLoadFallbackSynchronously(const ResourceRequest&, ResourceError&, ResourceResponse&, RefPtr<SharedBuffer>&);
+
+ bool canCacheInPageCache();
+
+ Status status() const;
+ bool update();
+ bool swapCache();
+ void abort();
+
+ void setDOMApplicationCache(DOMApplicationCache*);
+ void notifyDOMApplicationCache(const AtomicString& eventType, int progressTotal, int progressDone);
+
+ void stopLoadingInFrame(Frame&);
-#endif // ApplicationCacheHost_h
+ void stopDeferringEvents(); // Also raises the events that have been queued up.
+
+ Vector<ResourceInfo> resourceList();
+ CacheInfo applicationCacheInfo();
+
+ bool shouldLoadResourceFromApplicationCache(const ResourceRequest&, ApplicationCacheResource*&);
+ bool getApplicationCacheFallbackResource(const ResourceRequest&, ApplicationCacheResource*&, ApplicationCache* = nullptr);
+
+private:
+ friend class ApplicationCacheGroup;
+
+ struct DeferredEvent {
+ AtomicString eventType;
+ int progressTotal;
+ int progressDone;
+ };
+
+ bool isApplicationCacheEnabled();
+ bool isApplicationCacheBlockedForRequest(const ResourceRequest&);
+
+ void dispatchDOMEvent(const AtomicString& eventType, int progressTotal, int progressDone);
+
+ bool scheduleLoadFallbackResourceFromApplicationCache(ResourceLoader*, ApplicationCache* = nullptr);
+ void setCandidateApplicationCacheGroup(ApplicationCacheGroup*);
+ ApplicationCacheGroup* candidateApplicationCacheGroup() const { return m_candidateApplicationCacheGroup; }
+ void setApplicationCache(RefPtr<ApplicationCache>&&);
+ ApplicationCache* applicationCache() const { return m_applicationCache.get(); }
+ ApplicationCache* mainResourceApplicationCache() const { return m_mainResourceApplicationCache.get(); }
+ bool maybeLoadFallbackForMainError(const ResourceRequest&, const ResourceError&);
+
+ DOMApplicationCache* m_domApplicationCache { nullptr };
+ DocumentLoader& m_documentLoader;
+
+ bool m_defersEvents { true }; // Events are deferred until after document onload.
+ Vector<DeferredEvent> m_deferredEvents;
+
+ // The application cache that the document loader is associated with (if any).
+ RefPtr<ApplicationCache> m_applicationCache;
+
+ // Before an application cache has finished loading, this will be the candidate application
+ // group that the document loader is associated with.
+ ApplicationCacheGroup* m_candidateApplicationCacheGroup { nullptr };
+
+ // This is the application cache the main resource was loaded from (if any).
+ RefPtr<ApplicationCache> m_mainResourceApplicationCache;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/loader/appcache/ApplicationCacheResource.cpp b/Source/WebCore/loader/appcache/ApplicationCacheResource.cpp
index 2d9a8f1e6..f854a7212 100644
--- a/Source/WebCore/loader/appcache/ApplicationCacheResource.cpp
+++ b/Source/WebCore/loader/appcache/ApplicationCacheResource.cpp
@@ -29,8 +29,8 @@
namespace WebCore {
-ApplicationCacheResource::ApplicationCacheResource(const URL& url, const ResourceResponse& response, unsigned type, PassRefPtr<SharedBuffer> data, const String& path)
- : SubstituteResource(url, response, data)
+ApplicationCacheResource::ApplicationCacheResource(const URL& url, const ResourceResponse& response, unsigned type, Ref<SharedBuffer>&& data, const String& path)
+ : SubstituteResource(url, response, WTFMove(data))
, m_type(type)
, m_storageID(0)
, m_estimatedSizeInStorage(0)
@@ -38,6 +38,11 @@ ApplicationCacheResource::ApplicationCacheResource(const URL& url, const Resourc
{
}
+void ApplicationCacheResource::deliver(ResourceLoader& loader)
+{
+ loader.deliverResponseAndData(response(), m_path.isEmpty() ? data().copy() : SharedBuffer::createWithContentsOfFile(m_path));
+}
+
void ApplicationCacheResource::addType(unsigned type)
{
// Caller should take care of storing the new type in database.
@@ -49,8 +54,7 @@ int64_t ApplicationCacheResource::estimatedSizeInStorage()
if (m_estimatedSizeInStorage)
return m_estimatedSizeInStorage;
- if (data())
- m_estimatedSizeInStorage = data()->size();
+ m_estimatedSizeInStorage = data().size();
for (const auto& headerField : response().httpHeaderFields())
m_estimatedSizeInStorage += (headerField.key.length() + headerField.value.length() + 2) * sizeof(UChar);
diff --git a/Source/WebCore/loader/appcache/ApplicationCacheResource.h b/Source/WebCore/loader/appcache/ApplicationCacheResource.h
index d8d3f1aa0..a39613fa3 100644
--- a/Source/WebCore/loader/appcache/ApplicationCacheResource.h
+++ b/Source/WebCore/loader/appcache/ApplicationCacheResource.h
@@ -23,8 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ApplicationCacheResource_h
-#define ApplicationCacheResource_h
+#pragma once
#include "SubstituteResource.h"
@@ -40,10 +39,12 @@ public:
Fallback = 1 << 4
};
- static PassRefPtr<ApplicationCacheResource> create(const URL& url, const ResourceResponse& response, unsigned type, PassRefPtr<SharedBuffer> buffer = SharedBuffer::create(), const String& path = String())
+ static Ref<ApplicationCacheResource> create(const URL& url, const ResourceResponse& response, unsigned type, RefPtr<SharedBuffer> buffer = SharedBuffer::create(), const String& path = String())
{
ASSERT(!url.hasFragmentIdentifier());
- return adoptRef(new ApplicationCacheResource(url, response, type, buffer, path));
+ if (!buffer)
+ buffer = SharedBuffer::create();
+ return adoptRef(*new ApplicationCacheResource(url, response, type, buffer.releaseNonNull(), path));
}
unsigned type() const { return m_type; }
@@ -62,7 +63,9 @@ public:
#endif
private:
- ApplicationCacheResource(const URL&, const ResourceResponse&, unsigned type, PassRefPtr<SharedBuffer>, const String& path);
+ ApplicationCacheResource(const URL&, const ResourceResponse&, unsigned type, Ref<SharedBuffer>&&, const String& path);
+
+ void deliver(ResourceLoader&) override;
unsigned m_type;
unsigned m_storageID;
@@ -71,5 +74,3 @@ private:
};
} // namespace WebCore
-
-#endif // ApplicationCacheResource_h
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
+}
diff --git a/Source/WebCore/loader/appcache/ApplicationCacheStorage.h b/Source/WebCore/loader/appcache/ApplicationCacheStorage.h
index 76eaa3ecf..9d17a1bcd 100644
--- a/Source/WebCore/loader/appcache/ApplicationCacheStorage.h
+++ b/Source/WebCore/loader/appcache/ApplicationCacheStorage.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2010, 2011 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008-2017 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,8 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ApplicationCacheStorage_h
-#define ApplicationCacheStorage_h
+#pragma once
#include "SecurityOriginHash.h"
#include "SQLiteDatabase.h"
@@ -42,10 +41,9 @@ class ApplicationCacheResource;
class URL;
class SecurityOrigin;
class SharedBuffer;
-template <class T> class StorageIDJournal;
+template<typename> class StorageIDJournal;
-class ApplicationCacheStorage {
- WTF_MAKE_NONCOPYABLE(ApplicationCacheStorage); WTF_MAKE_FAST_ALLOCATED;
+class ApplicationCacheStorage : public RefCounted<ApplicationCacheStorage> {
public:
enum FailureReason {
OriginQuotaReached,
@@ -53,20 +51,21 @@ public:
DiskOrOperationFailure
};
- void setCacheDirectory(const String&);
+ WEBCORE_EXPORT static Ref<ApplicationCacheStorage> create(const String& cacheDirectory, const String& flatFileSubdirectoryName);
+
const String& cacheDirectory() const;
- void setMaximumSize(int64_t size);
- int64_t maximumSize() const;
+ WEBCORE_EXPORT void setMaximumSize(int64_t size);
+ WEBCORE_EXPORT int64_t maximumSize() const;
bool isMaximumSizeReached() const;
int64_t spaceNeeded(int64_t cacheToSave);
int64_t defaultOriginQuota() const { return m_defaultOriginQuota; }
- void setDefaultOriginQuota(int64_t quota);
- bool calculateUsageForOrigin(const SecurityOrigin*, int64_t& usage);
- bool calculateQuotaForOrigin(const SecurityOrigin*, int64_t& quota);
- bool calculateRemainingSizeForOriginExcludingCache(const SecurityOrigin*, ApplicationCache*, int64_t& remainingSize);
- bool storeUpdatedQuotaForOrigin(const SecurityOrigin*, int64_t quota);
+ WEBCORE_EXPORT void setDefaultOriginQuota(int64_t quota);
+ WEBCORE_EXPORT bool calculateUsageForOrigin(const SecurityOrigin*, int64_t& usage);
+ WEBCORE_EXPORT bool calculateQuotaForOrigin(const SecurityOrigin&, int64_t& quota);
+ bool calculateRemainingSizeForOriginExcludingCache(const SecurityOrigin&, ApplicationCache*, int64_t& remainingSize);
+ WEBCORE_EXPORT bool storeUpdatedQuotaForOrigin(const SecurityOrigin*, int64_t quota);
bool checkOriginQuota(ApplicationCacheGroup*, ApplicationCache* oldCache, ApplicationCache* newCache, int64_t& totalSpaceNeeded);
ApplicationCacheGroup* cacheGroupForURL(const URL&); // Cache to load a main resource from.
@@ -74,38 +73,47 @@ public:
ApplicationCacheGroup* findOrCreateCacheGroup(const URL& manifestURL);
ApplicationCacheGroup* findInMemoryCacheGroup(const URL& manifestURL) const;
- void cacheGroupDestroyed(ApplicationCacheGroup*);
- void cacheGroupMadeObsolete(ApplicationCacheGroup*);
-
- bool storeNewestCache(ApplicationCacheGroup*, ApplicationCache* oldCache, FailureReason& failureReason);
- bool storeNewestCache(ApplicationCacheGroup*); // Updates the cache group, but doesn't remove old cache.
+ void cacheGroupDestroyed(ApplicationCacheGroup&);
+ void cacheGroupMadeObsolete(ApplicationCacheGroup&);
+
+ bool storeNewestCache(ApplicationCacheGroup&, ApplicationCache* oldCache, FailureReason&);
+ bool storeNewestCache(ApplicationCacheGroup&); // Updates the cache group, but doesn't remove old cache.
bool store(ApplicationCacheResource*, ApplicationCache*);
bool storeUpdatedType(ApplicationCacheResource*, ApplicationCache*);
// Removes the group if the cache to be removed is the newest one (so, storeNewestCache() needs to be called beforehand when updating).
void remove(ApplicationCache*);
-
- void empty();
-
- static bool storeCopyOfCache(const String& cacheDirectory, ApplicationCacheHost*);
- bool manifestURLs(Vector<URL>* urls);
+ WEBCORE_EXPORT void empty();
+
+ bool getManifestURLs(Vector<URL>* urls);
bool cacheGroupSize(const String& manifestURL, int64_t* size);
bool deleteCacheGroup(const String& manifestURL);
- void vacuumDatabaseFile();
+ WEBCORE_EXPORT void vacuumDatabaseFile();
+
+ WEBCORE_EXPORT void getOriginsWithCache(HashSet<RefPtr<SecurityOrigin>, SecurityOriginHash>&);
+ WEBCORE_EXPORT void deleteAllEntries();
+
+ // FIXME: This should be consolidated with deleteAllEntries().
+ WEBCORE_EXPORT void deleteAllCaches();
+
+ // FIXME: This should be consolidated with deleteCacheGroup().
+ WEBCORE_EXPORT void deleteCacheForOrigin(const SecurityOrigin&);
- void getOriginsWithCache(HashSet<RefPtr<SecurityOrigin>, SecurityOriginHash>&);
- void deleteAllEntries();
+ // FIXME: This should be consolidated with calculateUsageForOrigin().
+ WEBCORE_EXPORT int64_t diskUsageForOrigin(const SecurityOrigin&);
static int64_t unknownQuota() { return -1; }
static int64_t noQuota() { return std::numeric_limits<int64_t>::max(); }
+
private:
- ApplicationCacheStorage();
- PassRefPtr<ApplicationCache> loadCache(unsigned storageID);
+ ApplicationCacheStorage(const String& cacheDirectory, const String& flatFileSubdirectoryName);
+
+ RefPtr<ApplicationCache> loadCache(unsigned storageID);
ApplicationCacheGroup* loadCacheGroup(const URL& manifestURL);
- typedef StorageIDJournal<ApplicationCacheResource> ResourceStorageIDJournal;
- typedef StorageIDJournal<ApplicationCacheGroup> GroupStorageIDJournal;
+ using ResourceStorageIDJournal = StorageIDJournal<ApplicationCacheResource>;
+ using GroupStorageIDJournal = StorageIDJournal<ApplicationCacheGroup>;
bool store(ApplicationCacheGroup*, GroupStorageIDJournal*);
bool store(ApplicationCache*, ResourceStorageIDJournal*);
@@ -115,7 +123,7 @@ private:
bool ensureOriginRecord(const SecurityOrigin*);
bool shouldStoreResourceAsFlatFile(ApplicationCacheResource*);
void deleteTables();
- bool writeDataToUniqueFileInDirectory(SharedBuffer*, const String& directory, String& outFilename, const String& fileExtension);
+ bool writeDataToUniqueFileInDirectory(SharedBuffer&, const String& directory, String& outFilename, const String& fileExtension);
void loadManifestHostHashes();
@@ -129,8 +137,9 @@ private:
void checkForMaxSizeReached();
void checkForDeletedResources();
long long flatFileAreaSize();
-
- String m_cacheDirectory;
+
+ const String m_cacheDirectory;
+ const String m_flatFileSubdirectoryName;
String m_cacheFile;
int64_t m_maximumSize;
@@ -144,14 +153,9 @@ private:
// we keep a hash set of the hosts of the manifest URLs of all non-obsolete cache groups.
HashCountedSet<unsigned, AlreadyHashed> m_cacheHostSet;
- typedef HashMap<String, ApplicationCacheGroup*> CacheGroupMap;
- CacheGroupMap m_cachesInMemory; // Excludes obsolete cache groups.
+ HashMap<String, ApplicationCacheGroup*> m_cachesInMemory; // Excludes obsolete cache groups.
- friend ApplicationCacheStorage& cacheStorage();
+ friend class WTF::NeverDestroyed<ApplicationCacheStorage>;
};
-
-ApplicationCacheStorage& cacheStorage();
-
-} // namespace WebCore
-#endif // ApplicationCacheStorage_h
+} // namespace WebCore
diff --git a/Source/WebCore/loader/appcache/DOMApplicationCache.cpp b/Source/WebCore/loader/appcache/DOMApplicationCache.cpp
index 56437a80d..ed8fad8f6 100644
--- a/Source/WebCore/loader/appcache/DOMApplicationCache.cpp
+++ b/Source/WebCore/loader/appcache/DOMApplicationCache.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008-2017 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,110 +29,84 @@
#include "ApplicationCacheHost.h"
#include "Document.h"
#include "DocumentLoader.h"
-#include "Event.h"
-#include "EventException.h"
-#include "EventListener.h"
-#include "EventNames.h"
#include "ExceptionCode.h"
#include "Frame.h"
-#include "FrameLoader.h"
namespace WebCore {
-DOMApplicationCache::DOMApplicationCache(Frame* frame)
- : DOMWindowProperty(frame)
+DOMApplicationCache::DOMApplicationCache(Frame& frame)
+ : DOMWindowProperty(&frame)
{
- ApplicationCacheHost* cacheHost = applicationCacheHost();
- if (cacheHost)
- cacheHost->setDOMApplicationCache(this);
+ if (auto* host = applicationCacheHost())
+ host->setDOMApplicationCache(this);
}
-void DOMApplicationCache::disconnectFrameForPageCache()
+void DOMApplicationCache::disconnectFrameForDocumentSuspension()
{
- if (ApplicationCacheHost* cacheHost = applicationCacheHost())
- cacheHost->setDOMApplicationCache(0);
- DOMWindowProperty::disconnectFrameForPageCache();
+ if (auto* host = applicationCacheHost())
+ host->setDOMApplicationCache(nullptr);
+ DOMWindowProperty::disconnectFrameForDocumentSuspension();
}
-void DOMApplicationCache::reconnectFrameFromPageCache(Frame* frame)
+void DOMApplicationCache::reconnectFrameFromDocumentSuspension(Frame* frame)
{
- DOMWindowProperty::reconnectFrameFromPageCache(frame);
- if (ApplicationCacheHost* cacheHost = applicationCacheHost())
- cacheHost->setDOMApplicationCache(this);
+ DOMWindowProperty::reconnectFrameFromDocumentSuspension(frame);
+ if (auto* host = applicationCacheHost())
+ host->setDOMApplicationCache(this);
}
void DOMApplicationCache::willDestroyGlobalObjectInFrame()
{
- if (ApplicationCacheHost* cacheHost = applicationCacheHost())
- cacheHost->setDOMApplicationCache(0);
+ if (auto* host = applicationCacheHost())
+ host->setDOMApplicationCache(nullptr);
DOMWindowProperty::willDestroyGlobalObjectInFrame();
}
ApplicationCacheHost* DOMApplicationCache::applicationCacheHost() const
{
- if (!m_frame || !m_frame->loader().documentLoader())
- return 0;
- return m_frame->loader().documentLoader()->applicationCacheHost();
+ if (!m_frame)
+ return nullptr;
+ auto* documentLoader = m_frame->loader().documentLoader();
+ if (!documentLoader)
+ return nullptr;
+ return &documentLoader->applicationCacheHost();
}
unsigned short DOMApplicationCache::status() const
{
- ApplicationCacheHost* cacheHost = applicationCacheHost();
- if (!cacheHost)
+ auto* host = applicationCacheHost();
+ if (!host)
return ApplicationCacheHost::UNCACHED;
- return cacheHost->status();
+ return host->status();
}
-void DOMApplicationCache::update(ExceptionCode& ec)
+ExceptionOr<void> DOMApplicationCache::update()
{
- ApplicationCacheHost* cacheHost = applicationCacheHost();
- if (!cacheHost || !cacheHost->update())
- ec = INVALID_STATE_ERR;
+ auto* host = applicationCacheHost();
+ if (!host || !host->update())
+ return Exception { INVALID_STATE_ERR };
+ return { };
}
-void DOMApplicationCache::swapCache(ExceptionCode& ec)
+ExceptionOr<void> DOMApplicationCache::swapCache()
{
- ApplicationCacheHost* cacheHost = applicationCacheHost();
- if (!cacheHost || !cacheHost->swapCache())
- ec = INVALID_STATE_ERR;
+ auto* host = applicationCacheHost();
+ if (!host || !host->swapCache())
+ return Exception { INVALID_STATE_ERR };
+ return { };
}
void DOMApplicationCache::abort()
{
- ApplicationCacheHost* cacheHost = applicationCacheHost();
- if (cacheHost)
- cacheHost->abort();
+ if (auto* host = applicationCacheHost())
+ host->abort();
}
ScriptExecutionContext* DOMApplicationCache::scriptExecutionContext() const
{
- if (m_frame)
- return m_frame->document();
- return 0;
-}
-
-const AtomicString& DOMApplicationCache::toEventType(ApplicationCacheHost::EventID id)
-{
- switch (id) {
- case ApplicationCacheHost::CHECKING_EVENT:
- return eventNames().checkingEvent;
- case ApplicationCacheHost::ERROR_EVENT:
- return eventNames().errorEvent;
- case ApplicationCacheHost::NOUPDATE_EVENT:
- return eventNames().noupdateEvent;
- case ApplicationCacheHost::DOWNLOADING_EVENT:
- return eventNames().downloadingEvent;
- case ApplicationCacheHost::PROGRESS_EVENT:
- return eventNames().progressEvent;
- case ApplicationCacheHost::UPDATEREADY_EVENT:
- return eventNames().updatereadyEvent;
- case ApplicationCacheHost::CACHED_EVENT:
- return eventNames().cachedEvent;
- case ApplicationCacheHost::OBSOLETE_EVENT:
- return eventNames().obsoleteEvent;
- }
- ASSERT_NOT_REACHED();
- return eventNames().errorEvent;
+ if (!m_frame)
+ return nullptr;
+ return m_frame->document();
}
} // namespace WebCore
diff --git a/Source/WebCore/loader/appcache/DOMApplicationCache.h b/Source/WebCore/loader/appcache/DOMApplicationCache.h
index 910cb7502..cf6d2a9d9 100644
--- a/Source/WebCore/loader/appcache/DOMApplicationCache.h
+++ b/Source/WebCore/loader/appcache/DOMApplicationCache.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008-2017 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,68 +23,43 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DOMApplicationCache_h
-#define DOMApplicationCache_h
+#pragma once
-#include "ApplicationCacheHost.h"
#include "DOMWindowProperty.h"
-#include "EventNames.h"
#include "EventTarget.h"
-#include "ScriptWrappable.h"
-#include <wtf/Forward.h>
-#include <wtf/HashMap.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
-#include <wtf/text/AtomicStringHash.h>
namespace WebCore {
+class ApplicationCacheHost;
class Frame;
-class URL;
-class DOMApplicationCache final : public ScriptWrappable, public RefCounted<DOMApplicationCache>, public EventTargetWithInlineData, public DOMWindowProperty {
+class DOMApplicationCache final : public RefCounted<DOMApplicationCache>, public EventTargetWithInlineData, public DOMWindowProperty {
public:
- static PassRefPtr<DOMApplicationCache> create(Frame* frame) { return adoptRef(new DOMApplicationCache(frame)); }
+ static Ref<DOMApplicationCache> create(Frame& frame) { return adoptRef(*new DOMApplicationCache(frame)); }
virtual ~DOMApplicationCache() { ASSERT(!m_frame); }
- virtual void disconnectFrameForPageCache() override;
- virtual void reconnectFrameFromPageCache(Frame*) override;
- virtual void willDestroyGlobalObjectInFrame() override;
-
unsigned short status() const;
- void update(ExceptionCode&);
- void swapCache(ExceptionCode&);
+ ExceptionOr<void> update();
+ ExceptionOr<void> swapCache();
void abort();
- using RefCounted<DOMApplicationCache>::ref;
- using RefCounted<DOMApplicationCache>::deref;
-
- // Explicitly named attribute event listener helpers
-
- DEFINE_ATTRIBUTE_EVENT_LISTENER(checking);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(noupdate);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(downloading);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(updateready);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(cached);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(obsolete);
+ using RefCounted::ref;
+ using RefCounted::deref;
- virtual EventTargetInterface eventTargetInterface() const override { return DOMApplicationCacheEventTargetInterfaceType; }
- virtual ScriptExecutionContext* scriptExecutionContext() const override;
+private:
+ explicit DOMApplicationCache(Frame&);
- static const AtomicString& toEventType(ApplicationCacheHost::EventID id);
+ void refEventTarget() final { ref(); }
+ void derefEventTarget() final { deref(); }
-private:
- explicit DOMApplicationCache(Frame*);
+ EventTargetInterface eventTargetInterface() const final { return DOMApplicationCacheEventTargetInterfaceType; }
+ ScriptExecutionContext* scriptExecutionContext() const final;
- virtual void refEventTarget() override { ref(); }
- virtual void derefEventTarget() override { deref(); }
+ void disconnectFrameForDocumentSuspension() final;
+ void reconnectFrameFromDocumentSuspension(Frame*) final;
+ void willDestroyGlobalObjectInFrame() final;
ApplicationCacheHost* applicationCacheHost() const;
};
} // namespace WebCore
-
-#endif // DOMApplicationCache_h
diff --git a/Source/WebCore/loader/appcache/DOMApplicationCache.idl b/Source/WebCore/loader/appcache/DOMApplicationCache.idl
index 9622c128b..1799f2e38 100644
--- a/Source/WebCore/loader/appcache/DOMApplicationCache.idl
+++ b/Source/WebCore/loader/appcache/DOMApplicationCache.idl
@@ -24,11 +24,10 @@
*/
[
- NoInterfaceObject,
- EventTarget,
DoNotCheckConstants,
GenerateIsReachable=ImplFrame,
-] interface DOMApplicationCache {
+ InterfaceName=ApplicationCache,
+] interface DOMApplicationCache : EventTarget {
// update status
const unsigned short UNCACHED = 0;
const unsigned short IDLE = 1;
@@ -38,27 +37,17 @@
const unsigned short OBSOLETE = 5;
readonly attribute unsigned short status;
- [RaisesException] void update();
- [RaisesException] void swapCache();
+ [MayThrowException] void update();
+ [MayThrowException] void swapCache();
void abort();
- // events
- attribute EventListener onchecking;
- attribute EventListener onerror;
- attribute EventListener onnoupdate;
- attribute EventListener ondownloading;
- attribute EventListener onprogress;
- attribute EventListener onupdateready;
- attribute EventListener oncached;
- attribute EventListener onobsolete;
-
- // EventTarget interface
- void addEventListener(DOMString type,
- EventListener listener,
- optional boolean useCapture);
- void removeEventListener(DOMString type,
- EventListener listener,
- optional boolean useCapture);
- [RaisesException] boolean dispatchEvent(Event evt);
+ attribute EventHandler onchecking;
+ attribute EventHandler onerror;
+ attribute EventHandler onnoupdate;
+ attribute EventHandler ondownloading;
+ attribute EventHandler onprogress;
+ attribute EventHandler onupdateready;
+ attribute EventHandler oncached;
+ attribute EventHandler onobsolete;
};
diff --git a/Source/WebCore/loader/appcache/ManifestParser.cpp b/Source/WebCore/loader/appcache/ManifestParser.cpp
index a47aa150e..5c151359d 100644
--- a/Source/WebCore/loader/appcache/ManifestParser.cpp
+++ b/Source/WebCore/loader/appcache/ManifestParser.cpp
@@ -28,6 +28,7 @@
#include "TextResourceDecoder.h"
#include "URL.h"
+#include <wtf/text/StringView.h>
#include <wtf/unicode/CharacterNames.h>
namespace WebCore {
@@ -43,9 +44,7 @@ bool parseManifest(const URL& manifestURL, const char* data, int length, Manifes
Mode mode = Explicit;
- RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("text/cache-manifest", "UTF-8");
- String s = decoder->decode(data, length);
- s.append(decoder->flush());
+ String s = TextResourceDecoder::create("text/cache-manifest", "UTF-8")->decodeAndFlush(data, length);
// Look for the magic signature: "^\xFEFF?CACHE MANIFEST[ \t]?" (the BOM is removed by TextResourceDecoder).
// Example: "CACHE MANIFEST #comment" is a valid signature.
@@ -53,8 +52,10 @@ bool parseManifest(const URL& manifestURL, const char* data, int length, Manifes
if (!s.startsWith("CACHE MANIFEST"))
return false;
- const UChar* end = s.deprecatedCharacters() + s.length();
- const UChar* p = s.deprecatedCharacters() + 14; // "CACHE MANIFEST" is 14 characters.
+ StringView manifestAfterSignature = StringView(s).substring(14); // "CACHE MANIFEST" is 14 characters.
+ auto upconvertedCharacters = manifestAfterSignature.upconvertedCharacters();
+ const UChar* p = upconvertedCharacters;
+ const UChar* end = p + manifestAfterSignature.length();
if (p < end && *p != ' ' && *p != '\t' && *p != '\n' && *p != '\r')
return false;
@@ -99,28 +100,28 @@ bool parseManifest(const URL& manifestURL, const char* data, int length, Manifes
else if (mode == Unknown)
continue;
else if (mode == Explicit || mode == OnlineWhitelist) {
- const UChar* p = line.deprecatedCharacters();
+ auto upconvertedLineCharacters = StringView(line).upconvertedCharacters();
+ const UChar* p = upconvertedLineCharacters;
const UChar* lineEnd = p + line.length();
// Look for whitespace separating the URL from subsequent ignored tokens.
while (p < lineEnd && *p != '\t' && *p != ' ')
p++;
- if (mode == OnlineWhitelist && p - line.deprecatedCharacters() == 1 && *line.deprecatedCharacters() == '*') {
+ if (mode == OnlineWhitelist && p - upconvertedLineCharacters == 1 && line[0] == '*') {
// Wildcard was found.
manifest.allowAllNetworkRequests = true;
continue;
}
- URL url(manifestURL, String(line.deprecatedCharacters(), p - line.deprecatedCharacters()));
+ URL url(manifestURL, line.substring(0, p - upconvertedLineCharacters));
if (!url.isValid())
continue;
- if (url.hasFragmentIdentifier())
- url.removeFragmentIdentifier();
+ url.removeFragmentIdentifier();
- if (!equalIgnoringCase(url.protocol(), manifestURL.protocol()))
+ if (!equalIgnoringASCIICase(url.protocol(), manifestURL.protocol()))
continue;
if (mode == Explicit && manifestURL.protocolIs("https") && !protocolHostAndPortAreEqual(manifestURL, url))
@@ -132,7 +133,8 @@ bool parseManifest(const URL& manifestURL, const char* data, int length, Manifes
manifest.onlineWhitelistedURLs.append(url);
} else if (mode == Fallback) {
- const UChar* p = line.deprecatedCharacters();
+ auto upconvertedLineCharacters = StringView(line).upconvertedCharacters();
+ const UChar* p = upconvertedLineCharacters;
const UChar* lineEnd = p + line.length();
// Look for whitespace separating the two URLs
@@ -144,11 +146,10 @@ bool parseManifest(const URL& manifestURL, const char* data, int length, Manifes
continue;
}
- URL namespaceURL(manifestURL, String(line.deprecatedCharacters(), p - line.deprecatedCharacters()));
+ URL namespaceURL(manifestURL, line.substring(0, p - upconvertedLineCharacters));
if (!namespaceURL.isValid())
continue;
- if (namespaceURL.hasFragmentIdentifier())
- namespaceURL.removeFragmentIdentifier();
+ namespaceURL.removeFragmentIdentifier();
if (!protocolHostAndPortAreEqual(manifestURL, namespaceURL))
continue;
@@ -165,8 +166,7 @@ bool parseManifest(const URL& manifestURL, const char* data, int length, Manifes
URL fallbackURL(manifestURL, String(fallbackStart, p - fallbackStart));
if (!fallbackURL.isValid())
continue;
- if (fallbackURL.hasFragmentIdentifier())
- fallbackURL.removeFragmentIdentifier();
+ fallbackURL.removeFragmentIdentifier();
if (!protocolHostAndPortAreEqual(manifestURL, fallbackURL))
continue;
diff --git a/Source/WebCore/loader/appcache/ManifestParser.h b/Source/WebCore/loader/appcache/ManifestParser.h
index 28315dde6..b28249ebe 100644
--- a/Source/WebCore/loader/appcache/ManifestParser.h
+++ b/Source/WebCore/loader/appcache/ManifestParser.h
@@ -23,24 +23,22 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ManifestParser_h
-#define ManifestParser_h
+#pragma once
#include "ApplicationCache.h"
+#include <wtf/HashSet.h>
namespace WebCore {
- class URL;
+class URL;
- struct Manifest {
- Vector<URL> onlineWhitelistedURLs;
- HashSet<String> explicitURLs;
- FallbackURLVector fallbackURLs;
- bool allowAllNetworkRequests; // Wildcard found in NETWORK section.
- };
+struct Manifest {
+ Vector<URL> onlineWhitelistedURLs;
+ HashSet<String> explicitURLs;
+ FallbackURLVector fallbackURLs;
+ bool allowAllNetworkRequests; // Wildcard found in NETWORK section.
+};
- bool parseManifest(const URL& manifestURL, const char* data, int length, Manifest&);
+bool parseManifest(const URL& manifestURL, const char* data, int length, Manifest&);
-}
-
-#endif // ManifestParser_h
+} // namespace WebCore