Ejemplo n.º 1
0
void ApplicationCacheGroup::didFinishLoading(ResourceHandle* handle)
{
    if (handle == m_manifestHandle) {
        didFinishLoadingManifest();
        return;
    }
 
    ASSERT(m_currentHandle == handle);
    ASSERT(m_pendingEntries.contains(handle->request().url()));
    
    m_pendingEntries.remove(handle->request().url());
    
    ASSERT(m_cacheBeingUpdated);

    m_cacheBeingUpdated->addResource(m_currentResource.release());
    m_currentHandle = 0;
    
    // Load the next file.
    if (!m_pendingEntries.isEmpty()) {
        startLoadingEntry();
        return;
    }
    
    checkIfLoadIsComplete();
}
Ejemplo n.º 2
0
void ApplicationCacheGroup::finishedLoadingMainResource(DocumentLoader* loader)
{
    const KURL& url = loader->originalURL();
    
    if (ApplicationCache* cache = loader->applicationCache()) {
        RefPtr<ApplicationCacheResource> resource = ApplicationCacheResource::create(url, loader->response(), ApplicationCacheResource::Implicit, loader->mainResourceData());
        cache->addResource(resource.release());
        
        if (!m_cacheBeingUpdated)
            return;
    }
    
    ASSERT(m_pendingEntries.contains(url));
 
    EntryMap::iterator it = m_pendingEntries.find(url);
    ASSERT(it->second & ApplicationCacheResource::Implicit);

    RefPtr<ApplicationCacheResource> resource = ApplicationCacheResource::create(url, loader->response(), it->second, loader->mainResourceData());

    ASSERT(m_cacheBeingUpdated);
    m_cacheBeingUpdated->addResource(resource.release());
    
    m_pendingEntries.remove(it);
    
    checkIfLoadIsComplete();
}
void ApplicationCacheGroup::didReachMaxAppCacheSize()
{
    ASSERT(m_frame);
    ASSERT(m_cacheBeingUpdated);
    m_frame->page()->chrome().client().reachedMaxAppCacheSize(cacheStorage().spaceNeeded(m_cacheBeingUpdated->estimatedSizeInStorage()));
    m_calledReachedMaxAppCacheSize = true;
    checkIfLoadIsComplete();
}
void ApplicationCacheGroup::finishedLoadingMainResource(DocumentLoader* loader)
{
    ASSERT(m_pendingMasterResourceLoaders.contains(loader));
    ASSERT(m_completionType == None || m_pendingEntries.isEmpty());
    URL url = loader->url();
    if (url.hasFragmentIdentifier())
        url.removeFragmentIdentifier();

    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 {
            RefPtr<ResourceBuffer> buffer = loader->mainResourceData();
            m_newestCache->addResource(ApplicationCacheResource::create(url, loader->response(), ApplicationCacheResource::Master, buffer ? buffer->sharedBuffer() : 0));
        }

        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);
        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 {
            RefPtr<ResourceBuffer> buffer = loader->mainResourceData();
            m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, loader->response(), ApplicationCacheResource::Master, buffer ? buffer->sharedBuffer() : 0));
        }
        // The "cached" event will be posted to all associated documents once update is complete.
        break;
    }

    ASSERT(m_downloadingPendingMasterResourceLoadersCount > 0);
    m_downloadingPendingMasterResourceLoadersCount--;
    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(ApplicationCacheHost::ERROR_EVENT, 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);
        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);

        break;
    }

    ASSERT(m_downloadingPendingMasterResourceLoadersCount > 0);
    m_downloadingPendingMasterResourceLoadersCount--;
    checkIfLoadIsComplete();
}
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];
        if (loader->isLoadingMainResource())
            continue;

        const ResourceError& error = loader->mainDocumentError();
        if (error.isNull())
            finishedLoadingMainResource(loader);
        else
            failedLoadingMainResource(loader);
    }
    if (!count)
        checkIfLoadIsComplete();
}
Ejemplo n.º 7
0
void ApplicationCacheGroup::startLoadingEntry()
{
    ASSERT(m_cacheBeingUpdated);

    if (m_pendingEntries.isEmpty()) {
        checkIfLoadIsComplete();
        return;
    }
    
    EntryMap::const_iterator it = m_pendingEntries.begin();

    // If this is an initial cache attempt, we do not want to fetch any implicit entries,
    // since those are fed to us by the normal loader machinery.
    if (!m_newestCache) {
        // Get the first URL in the entry table that is not implicit
        EntryMap::const_iterator end = m_pendingEntries.end();
    
        while (it->second & ApplicationCacheResource::Implicit) {
            ++it;

            if (it == end)
                return;
        }
    }
    
    callListenersOnAssociatedDocuments(&DOMApplicationCache::callProgressListener);

    // FIXME: If this is an upgrade attempt, the newest cache should be used as an HTTP cache.
    
    ASSERT(!m_currentHandle);
    
    ResourceRequest request(it->first);
    m_frame->loader()->applyUserAgent(request);

    m_currentHandle = ResourceHandle::create(request, this, m_frame, false, true, false);
}