📄 applicationcachegroup.cpp
字号:
m_currentHandle->setClient(0); m_currentHandle->cancel(); m_currentHandle = 0; } m_cacheBeingUpdated = 0; m_pendingEntries.clear();} void ApplicationCacheGroup::disassociateDocumentLoader(DocumentLoader* loader){ HashSet<DocumentLoader*>::iterator it = m_associatedDocumentLoaders.find(loader); if (it != m_associatedDocumentLoaders.end()) m_associatedDocumentLoaders.remove(it); m_pendingMasterResourceLoaders.remove(loader); loader->setApplicationCache(0); // Will set candidate to 0, too. if (!m_associatedDocumentLoaders.isEmpty() || !m_pendingMasterResourceLoaders.isEmpty()) return; if (m_caches.isEmpty()) { // There is an initial cache attempt in progress. ASSERT(!m_newestCache); // Delete ourselves, causing the cache attempt to be stopped. delete this; return; } ASSERT(m_caches.contains(m_newestCache.get())); // 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();}void ApplicationCacheGroup::cacheDestroyed(ApplicationCache* cache){ if (!m_caches.contains(cache)) return; m_caches.remove(cache); if (m_caches.isEmpty()) { ASSERT(m_associatedDocumentLoaders.isEmpty()); ASSERT(m_pendingMasterResourceLoaders.isEmpty()); delete this; }}void ApplicationCacheGroup::setNewestCache(PassRefPtr<ApplicationCache> newestCache){ ASSERT(!m_caches.contains(newestCache.get())); m_newestCache = newestCache; m_caches.add(m_newestCache.get()); m_newestCache->setGroup(this);}void ApplicationCacheGroup::makeObsolete(){ if (isObsolete()) return; m_isObsolete = true; cacheStorage().cacheGroupMadeObsolete(this); ASSERT(!m_storageID);}void ApplicationCacheGroup::update(Frame* frame, ApplicationCacheUpdateOption updateOption){ if (m_updateStatus == Checking || m_updateStatus == Downloading) { if (updateOption == ApplicationCacheUpdateWithBrowsingContext) { postListenerTask(&DOMApplicationCache::callCheckingListener, frame->loader()->documentLoader()); if (m_updateStatus == Downloading) postListenerTask(&DOMApplicationCache::callDownloadingListener, frame->loader()->documentLoader()); } return; } // Don't change anything on disk if private browsing is enabled. if (!frame->settings() || frame->settings()->privateBrowsingEnabled()) { ASSERT(m_pendingMasterResourceLoaders.isEmpty()); ASSERT(m_pendingEntries.isEmpty()); ASSERT(!m_cacheBeingUpdated); postListenerTask(&DOMApplicationCache::callCheckingListener, frame->loader()->documentLoader()); postListenerTask(&DOMApplicationCache::callNoUpdateListener, frame->loader()->documentLoader()); return; } ASSERT(!m_frame); m_frame = frame; m_updateStatus = Checking; postListenerTask(&DOMApplicationCache::callCheckingListener, m_associatedDocumentLoaders); if (!m_newestCache) { ASSERT(updateOption == ApplicationCacheUpdateWithBrowsingContext); postListenerTask(&DOMApplicationCache::callCheckingListener, frame->loader()->documentLoader()); } ASSERT(!m_manifestHandle); ASSERT(!m_manifestResource); ASSERT(m_completionType == None); // FIXME: Handle defer loading m_manifestHandle = createResourceHandle(m_manifestURL, m_newestCache ? m_newestCache->manifestResource() : 0);}PassRefPtr<ResourceHandle> ApplicationCacheGroup::createResourceHandle(const KURL& url, ApplicationCacheResource* newestCachedResource){ ResourceRequest request(url); m_frame->loader()->applyUserAgent(request); request.setHTTPHeaderField("Cache-Control", "max-age=0"); if (newestCachedResource) { const String& lastModified = newestCachedResource->response().httpHeaderField("Last-Modified"); const String& eTag = newestCachedResource->response().httpHeaderField("ETag"); if (!lastModified.isEmpty() || !eTag.isEmpty()) { if (!lastModified.isEmpty()) request.setHTTPHeaderField("If-Modified-Since", lastModified); if (!eTag.isEmpty()) request.setHTTPHeaderField("If-None-Match", eTag); } } return ResourceHandle::create(request, this, m_frame, false, true, false);}void ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, const ResourceResponse& response){ if (handle == m_manifestHandle) { didReceiveManifestResponse(response); return; } ASSERT(handle == m_currentHandle); const KURL& url = handle->request().url(); ASSERT(!m_currentResource); ASSERT(m_pendingEntries.contains(url)); unsigned type = m_pendingEntries.get(url); // If this is an initial cache attempt, we should not get master resources delivered here. if (!m_newestCache) ASSERT(!(type & ApplicationCacheResource::Master)); if (m_newestCache && response.httpStatusCode() == 304) { // Not modified. ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(handle->request().url()); if (newestCachedResource) { m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data())); m_currentHandle->cancel(); m_currentHandle = 0; // Load the next resource, if any. startLoadingEntry(); return; } // The server could return 304 for an unconditional request - in this case, we handle the response as a normal error. } if (response.httpStatusCode() / 100 != 2 || response.url() != m_currentHandle->request().url()) { if ((type & ApplicationCacheResource::Explicit) || (type & ApplicationCacheResource::Fallback)) { // 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_pendingEntries.remove(handle->request().url()); // Load the next resource, if any. startLoadingEntry(); } else { // Copy the resource and its metadata from the newest application cache in cache group whose completeness flag is complete, and act // as if that was the fetched resource, ignoring the resource obtained from the network. ASSERT(m_newestCache); ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(handle->request().url()); ASSERT(newestCachedResource); m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data())); m_currentHandle->cancel(); m_currentHandle = 0; // Load the next resource, if any. startLoadingEntry(); } return; } m_currentResource = ApplicationCacheResource::create(url, response, type);}void ApplicationCacheGroup::didReceiveData(ResourceHandle* handle, const char* data, int length, int){ if (handle == m_manifestHandle) { didReceiveManifestData(data, length); return; } ASSERT(handle == m_currentHandle); ASSERT(m_currentResource); m_currentResource->data()->append(data, length);}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 resource, if any. startLoadingEntry();}void ApplicationCacheGroup::didFail(ResourceHandle* handle, const ResourceError&){ if (handle == m_manifestHandle) { cacheUpdateFailed(); return; } unsigned type = m_currentResource ? m_currentResource->type() : m_pendingEntries.get(handle->request().url()); const KURL& url = handle->request().url(); ASSERT(!m_currentResource || !m_pendingEntries.contains(url)); m_currentResource = 0; m_pendingEntries.remove(url); if ((type & ApplicationCacheResource::Explicit) || (type & ApplicationCacheResource::Fallback)) { // Note that cacheUpdateFailed() can cause the cache group to be deleted. cacheUpdateFailed(); } else { // Copy the resource and its metadata from the newest application cache in cache group whose completeness flag is complete, and act // as if that was the fetched resource, ignoring the resource obtained from the network. ASSERT(m_newestCache); ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(url); ASSERT(newestCachedResource); m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data())); // Load the next resource, if any. startLoadingEntry(); }}void ApplicationCacheGroup::didReceiveManifestResponse(const ResourceResponse& response){ ASSERT(!m_manifestResource); ASSERT(m_manifestHandle); if (response.httpStatusCode() == 404 || response.httpStatusCode() == 410) { manifestNotFound(); return; } if (response.httpStatusCode() == 304) return; if (response.httpStatusCode() / 100 != 2 || response.url() != m_manifestHandle->request().url() || !equalIgnoringCase(response.mimeType(), "text/cache-manifest")) { cacheUpdateFailed(); return; } m_manifestResource = ApplicationCacheResource::create(m_manifestHandle->request().url(), response, ApplicationCacheResource::Manifest);}void ApplicationCacheGroup::didReceiveManifestData(const char* data, int length){ if (m_manifestResource) m_manifestResource->data()->append(data, length);}void ApplicationCacheGroup::didFinishLoadingManifest(){ bool isUpgradeAttempt = m_newestCache; if (!isUpgradeAttempt && !m_manifestResource) { // The server returned 304 Not Modified even though we didn't send a conditional request. cacheUpdateFailed(); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -