bool DocumentLoader::isLoading() const { if (document() && document()->hasActiveParser()) return true; return isLoadingMainResource() || !m_resourceLoaders.isEmpty(); }
// Cancels the data source's pending loads. Conceptually, a data source only loads // one document at a time, but one document may have many related resources. // stopLoading will stop all loads initiated by the data source, // but not loads initiated by child frames' data sources -- that's the WebFrame's job. void DocumentLoader::stopLoading() { RefPtr<Frame> protectFrame(m_frame); RefPtr<DocumentLoader> protectLoader(this); // In some rare cases, calling FrameLoader::stopLoading could cause isLoading() to return false. // (This can happen when there's a single XMLHttpRequest currently loading and stopLoading causes it // to stop loading. Because of this, we need to save it so we don't return early. bool loading = isLoading(); if (m_committed) { // Attempt to stop the frame if the document loader is loading, or if it is done loading but // still parsing. Failure to do so can cause a world leak. Document* doc = m_frame->document(); if (loading || doc->parsing()) m_frame->loader()->stopLoading(UnloadEventPolicyNone); } // Always cancel multipart loaders cancelAll(m_multipartResourceLoaders); clearArchiveResources(); if (!loading) { // If something above restarted loading we might run into mysterious crashes like // https://bugs.webkit.org/show_bug.cgi?id=62764 and <rdar://problem/9328684> ASSERT(!isLoading()); return; } // We might run in to infinite recursion if we're stopping loading as the result of // detaching from the frame, so break out of that recursion here. // See <rdar://problem/9673866> for more details. if (m_isStopping) return; m_isStopping = true; FrameLoader* frameLoader = DocumentLoader::frameLoader(); if (isLoadingMainResource()) // Stop the main resource loader and let it send the cancelled message. cancelMainResourceLoad(frameLoader->cancelledError(m_request)); else if (!m_resourceLoaders.isEmpty()) // The main resource loader already finished loading. Set the cancelled error on the // document and let the resourceLoaders send individual cancelled messages below. setMainDocumentError(frameLoader->cancelledError(m_request)); else // If there are no resource loaders, we need to manufacture a cancelled message. // (A back/forward navigation has no resource loaders because its resources are cached.) mainReceivedError(frameLoader->cancelledError(m_request)); stopLoadingSubresources(); m_isStopping = false; }
bool DocumentLoader::isLoading() const { // FIXME: This should always be enabled, but it seems to cause // http/tests/security/feed-urls-from-remote.html to timeout on Mac WK1 // see http://webkit.org/b/110554 and http://webkit.org/b/110401 #if ENABLE(THREADED_HTML_PARSER) if (document() && document()->hasActiveParser()) return true; #endif return isLoadingMainResource() || !m_subresourceLoaders.isEmpty() || !m_plugInStreamLoaders.isEmpty(); }
void DocumentLoader::transferLoadingResourcesFromPage(Page* oldPage) { ASSERT(oldPage != m_frame->page()); FrameLoader* loader = frameLoader(); ASSERT(loader); if (isLoadingMainResource()) loader->dispatchTransferLoadingResourceFromPage(m_mainResourceLoader.get(), originalRequest(), oldPage); if (isLoadingSubresources()) { ResourceLoaderSet::const_iterator it = m_subresourceLoaders.begin(); ResourceLoaderSet::const_iterator end = m_subresourceLoaders.end(); for (; it != end; ++it) loader->dispatchTransferLoadingResourceFromPage((*it).get(), (*it)->originalRequest(), oldPage); } }
bool DocumentLoader::isLoadingInAPISense() const { // Once a frame has loaded, we no longer need to consider subresources, // but we still need to consider subframes. if (frameLoader()->state() != FrameStateComplete) { Document* doc = m_frame->document(); if ((isLoadingMainResource() || !m_frame->document()->loadEventFinished()) && isLoading()) return true; if (m_cachedResourceLoader->requestCount()) return true; if (doc->processingLoadEvent()) return true; if (doc->hasActiveParser()) return true; } return frameLoader()->subframeIsLoading(); }
bool DocumentLoader::isLoadingInAPISense() const { // Once a frame has loaded, we no longer need to consider subresources, // but we still need to consider subframes. if (frameLoader()->state() != FrameStateComplete) { if (m_frame->settings()->needsIsLoadingInAPISenseQuirk() && !m_subresourceLoaders.isEmpty()) return true; Document* doc = m_frame->document(); if ((isLoadingMainResource() || !m_frame->document()->loadEventFinished()) && isLoading()) return true; if (m_cachedResourceLoader->requestCount()) return true; if (DocumentParser* parser = doc->parser()) if (parser->processingData()) return true; } return frameLoader()->subframeIsLoading(); }
void NetworkResourceLoader::didReceiveResponseAsync(ResourceHandle* handle, const ResourceResponse& response) { ASSERT_UNUSED(handle, handle == m_handle); // FIXME (NetworkProcess): Cache the response. if (FormData* formData = request().httpBody()) formData->removeGeneratedFilesIfNeeded(); sendAbortingOnFailure(Messages::WebResourceLoader::DidReceiveResponseWithCertificateInfo(response, PlatformCertificateInfo(response), isLoadingMainResource())); // m_handle will be 0 if the request got aborted above. if (!m_handle) return; if (!isLoadingMainResource()) { // For main resources, the web process is responsible for sending back a NetworkResourceLoader::ContinueDidReceiveResponse message. m_handle->continueDidReceiveResponse(); } }
void DocumentLoader::responseReceived(CachedResource* resource, const ResourceResponse& response) { ASSERT_UNUSED(resource, m_mainResource == resource); RefPtr<DocumentLoader> protect(this); m_applicationCacheHost->didReceiveResponseForMainResource(response); // The memory cache doesn't understand the application cache or its caching rules. So if a main resource is served // from the application cache, ensure we don't save the result for future use. All responses loaded // from appcache will have a non-zero appCacheID(). if (response.appCacheID()) memoryCache()->remove(m_mainResource.get()); DEFINE_STATIC_LOCAL(AtomicString, xFrameOptionHeader, ("x-frame-options", AtomicString::ConstructFromLiteral)); HTTPHeaderMap::const_iterator it = response.httpHeaderFields().find(xFrameOptionHeader); if (it != response.httpHeaderFields().end()) { String content = it->value; ASSERT(m_mainResource); unsigned long identifier = mainResourceIdentifier(); ASSERT(identifier); if (frameLoader()->shouldInterruptLoadForXFrameOptions(content, response.url(), identifier)) { InspectorInstrumentation::continueAfterXFrameOptionsDenied(m_frame, this, identifier, response); String message = "Refused to display '" + response.url().elidedString() + "' in a frame because it set 'X-Frame-Options' to '" + content + "'."; frame()->document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, identifier); frame()->document()->enforceSandboxFlags(SandboxOrigin); if (HTMLFrameOwnerElement* ownerElement = frame()->ownerElement()) ownerElement->dispatchEvent(Event::create(eventNames().loadEvent, false, false)); // The load event might have detached this frame. In that case, the load will already have been cancelled during detach. if (frameLoader()) cancelMainResourceLoad(frameLoader()->cancelledError(m_request)); return; } } ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading()); m_response = response; if (isArchiveMIMEType(m_response.mimeType()) && m_mainResource->dataBufferingPolicy() != BufferData) m_mainResource->setDataBufferingPolicy(BufferData); if (m_identifierForLoadWithoutResourceLoader) frameLoader()->notifier()->dispatchDidReceiveResponse(this, m_identifierForLoadWithoutResourceLoader, m_response, 0); if (!shouldContinueForResponse()) { InspectorInstrumentation::continueWithPolicyIgnore(m_frame, this, m_mainResource->identifier(), m_response); stopLoadingForPolicyChange(); return; } if (m_response.isHTTP()) { int status = m_response.httpStatusCode(); if (status < 200 || status >= 300) { bool hostedByObject = frameLoader()->isHostedByObjectElement(); frameLoader()->handleFallbackContent(); // object elements are no longer rendered after we fallback, so don't // keep trying to process data from their load if (hostedByObject) cancelMainResourceLoad(frameLoader()->cancelledError(m_request)); } } if (!isStopping() && m_substituteData.isValid()) { if (m_substituteData.content()->size()) dataReceived(0, m_substituteData.content()->data(), m_substituteData.content()->size()); if (isLoadingMainResource()) finishedLoading(0); } }