diff options
Diffstat (limited to 'Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp')
-rw-r--r-- | Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp | 628 |
1 files changed, 278 insertions, 350 deletions
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(); } |