⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 applicationcachegroup.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2008, 2009 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.  */#include "config.h"#include "ApplicationCacheGroup.h"#if ENABLE(OFFLINE_WEB_APPLICATIONS)#include "ApplicationCache.h"#include "ApplicationCacheResource.h"#include "ApplicationCacheStorage.h"#include "DocumentLoader.h"#include "DOMApplicationCache.h"#include "DOMWindow.h"#include "Frame.h"#include "FrameLoader.h"#include "MainResourceLoader.h"#include "ManifestParser.h"#include "Page.h"#include "Settings.h"#include <wtf/HashMap.h>namespace WebCore {ApplicationCacheGroup::ApplicationCacheGroup(const KURL& manifestURL, bool isCopy)    : m_manifestURL(manifestURL)    , m_updateStatus(Idle)    , m_frame(0)    , m_storageID(0)    , m_isObsolete(false)    , m_completionType(None)    , m_isCopy(isCopy){}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);}    ApplicationCache* ApplicationCacheGroup::cacheForMainRequest(const ResourceRequest& request, DocumentLoader*){    if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request))        return 0;    if (ApplicationCacheGroup* group = cacheStorage().cacheGroupForURL(request.url())) {        ASSERT(group->newestCache());        ASSERT(!group->isObsolete());                return group->newestCache();    }        return 0;}    ApplicationCache* ApplicationCacheGroup::fallbackCacheForMainRequest(const ResourceRequest& request, DocumentLoader*){    if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request))        return 0;    if (ApplicationCacheGroup* group = cacheStorage().fallbackCacheGroupForURL(request.url())) {        ASSERT(group->newestCache());        ASSERT(!group->isObsolete());        return group->newestCache();    }        return 0;}void ApplicationCacheGroup::selectCache(Frame* frame, const KURL& manifestURL){    ASSERT(frame && frame->page());        if (!frame->settings()->offlineWebApplicationCacheEnabled())        return;        DocumentLoader* documentLoader = frame->loader()->documentLoader();    ASSERT(!documentLoader->applicationCache());    if (manifestURL.isNull()) {        selectCacheWithoutManifestURL(frame);                return;    }        ApplicationCache* mainResourceCache = documentLoader->mainResourceApplicationCache();        if (mainResourceCache) {        if (manifestURL == mainResourceCache->group()->m_manifestURL) {            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.            ApplicationCacheResource* resource = mainResourceCache->resourceForURL(documentLoader->url());            bool inStorage = resource->storageID();            resource->addType(ApplicationCacheResource::Foreign);            if (inStorage)                cacheStorage().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->loader()->scheduleLocationChange(documentLoader->url(), frame->loader()->referrer(), true);        }                return;    }        // The resource was loaded from the network, check if it is a HTTP/HTTPS GET.        const ResourceRequest& request = frame->loader()->activeDocumentLoader()->request();    if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request))        return;    // Check that the resource URL has the same scheme/host/port as the manifest URL.    if (!protocolHostAndPortAreEqual(manifestURL, request.url()))        return;    // Don't change anything on disk if private browsing is enabled.    if (!frame->settings() || frame->settings()->privateBrowsingEnabled()) {        postListenerTask(&DOMApplicationCache::callCheckingListener, documentLoader);        postListenerTask(&DOMApplicationCache::callErrorListener, documentLoader);        return;    }    ApplicationCacheGroup* group = cacheStorage().findOrCreateCacheGroup(manifestURL);    documentLoader->setCandidateApplicationCacheGroup(group);    group->m_pendingMasterResourceLoaders.add(documentLoader);    ASSERT(!group->m_cacheBeingUpdated || group->m_updateStatus != Idle);    group->update(frame, ApplicationCacheUpdateWithBrowsingContext);}void ApplicationCacheGroup::selectCacheWithoutManifestURL(Frame* frame){    if (!frame->settings()->offlineWebApplicationCacheEnabled())        return;    DocumentLoader* documentLoader = frame->loader()->documentLoader();    ASSERT(!documentLoader->applicationCache());    ApplicationCache* mainResourceCache = documentLoader->mainResourceApplicationCache();    if (mainResourceCache) {        mainResourceCache->group()->associateDocumentLoaderWithCache(documentLoader, mainResourceCache);        mainResourceCache->group()->update(frame, ApplicationCacheUpdateWithBrowsingContext);    }}void ApplicationCacheGroup::finishedLoadingMainResource(DocumentLoader* loader){    ASSERT(m_pendingMasterResourceLoaders.contains(loader));    ASSERT(m_completionType == None || m_pendingEntries.isEmpty());    const KURL& url = loader->url();    switch (m_completionType) {    case None:        // The main resource finished loading before the manifest was ready. It will be handled via dispatchMainResources() later.        return;    case NoUpdate:        ASSERT(!m_cacheBeingUpdated);        associateDocumentLoaderWithCache(loader, m_newestCache.get());        if (ApplicationCacheResource* resource = m_newestCache->resourceForURL(url)) {            if (!(resource->type() & ApplicationCacheResource::Master)) {                resource->addType(ApplicationCacheResource::Master);                ASSERT(!resource->storageID());            }        } 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->setApplicationCache(0); // Will unset candidate, too.        m_associatedDocumentLoaders.remove(loader);        postListenerTask(&DOMApplicationCache::callErrorListener, loader);        break;    case Completed:        ASSERT(m_associatedDocumentLoaders.contains(loader));        if (ApplicationCacheResource* resource = m_cacheBeingUpdated->resourceForURL(url)) {            if (!(resource->type() & ApplicationCacheResource::Master)) {                resource->addType(ApplicationCacheResource::Master);                ASSERT(!resource->storageID());            }        } 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;    }    m_pendingMasterResourceLoaders.remove(loader);    checkIfLoadIsComplete();}void ApplicationCacheGroup::failedLoadingMainResource(DocumentLoader* loader){    ASSERT(m_pendingMasterResourceLoaders.contains(loader));    ASSERT(m_completionType == None || m_pendingEntries.isEmpty());    switch (m_completionType) {    case None:        // The main resource finished loading before the manifest was ready. It will be handled via dispatchMainResources() later.        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(&DOMApplicationCache::callErrorListener, loader);        break;    case Failure:        // Cache update failed, too.        ASSERT(!m_cacheBeingUpdated); // Already cleared out by stopLoading().        ASSERT(!loader->applicationCache() || loader->applicationCache() == m_cacheBeingUpdated);        loader->setApplicationCache(0); // Will unset candidate, too.        m_associatedDocumentLoaders.remove(loader);        postListenerTask(&DOMApplicationCache::callErrorListener, 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->applicationCache() == m_cacheBeingUpdated);        ASSERT(!loader->candidateApplicationCacheGroup());        m_associatedDocumentLoaders.remove(loader);        loader->setApplicationCache(0);        postListenerTask(&DOMApplicationCache::callErrorListener, loader);        break;    }    m_pendingMasterResourceLoaders.remove(loader);    checkIfLoadIsComplete();}void ApplicationCacheGroup::stopLoading(){    if (m_manifestHandle) {        ASSERT(!m_currentHandle);        m_manifestHandle->setClient(0);        m_manifestHandle->cancel();        m_manifestHandle = 0;    }        if (m_currentHandle) {        ASSERT(!m_manifestHandle);        ASSERT(m_cacheBeingUpdated);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -