void DocumentLoader::dataReceived(Resource* resource, const char* data, unsigned length) { ASSERT(data); ASSERT(length); ASSERT_UNUSED(resource, resource == m_mainResource); ASSERT(!m_response.isNull()); ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading()); // Both unloading the old page and parsing the new page may execute JavaScript which destroys the datasource // by starting a new load, so retain temporarily. RefPtrWillBeRawPtr<LocalFrame> protectFrame(m_frame); RefPtr<DocumentLoader> protectLoader(this); m_applicationCacheHost->mainResourceDataReceived(data, length); m_timeOfLastDataReceived = monotonicallyIncreasingTime(); if (isArchiveMIMEType(response().mimeType())) return; commitIfReady(); if (!frameLoader()) return; commitData(data, length); // If we are sending data to MediaDocument, we should stop here // and cancel the request. if (m_frame && m_frame->document()->isMediaDocument()) cancelMainResourceLoad(ResourceError::cancelledError(m_request.url())); }
// 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() { // In some rare cases, calling FrameLoader::stopLoading could set m_loading to 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 = m_loading; 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_multipartSubresourceLoaders); // Appcache uses ResourceHandle directly, DocumentLoader doesn't count these loads. m_applicationCacheHost->stopLoadingInFrame(m_frame); 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(!m_loading); 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; RefPtr<Frame> protectFrame(m_frame); RefPtr<DocumentLoader> protectLoader(this); m_isStopping = true; FrameLoader* frameLoader = DocumentLoader::frameLoader(); if (m_mainResourceLoader) // Stop the main resource loader and let it send the cancelled message. m_mainResourceLoader->cancel(); else if (!m_subresourceLoaders.isEmpty()) // The main resource loader already finished loading. Set the cancelled error on the // document and let the subresourceLoaders 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), true); stopLoadingSubresources(); stopLoadingPlugIns(); m_isStopping = false; }
// 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(DatabasePolicy databasePolicy) { // In some rare cases, calling FrameLoader::stopLoading could set m_loading to 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 = m_loading; 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, databasePolicy); } // Always cancel multipart loaders cancelAll(m_multipartSubresourceLoaders); // Appcache uses ResourceHandle directly, DocumentLoader doesn't count these loads. #if ENABLE(OFFLINE_WEB_APPLICATIONS) m_applicationCacheHost->stopLoadingInFrame(m_frame); #endif if (!loading) return; RefPtr<Frame> protectFrame(m_frame); RefPtr<DocumentLoader> protectLoader(this); m_isStopping = true; FrameLoader* frameLoader = DocumentLoader::frameLoader(); if (m_mainResourceLoader) // Stop the main resource loader and let it send the cancelled message. m_mainResourceLoader->cancel(); else if (!m_subresourceLoaders.isEmpty()) // The main resource loader already finished loading. Set the cancelled error on the // document and let the subresourceLoaders 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), true); stopLoadingSubresources(); stopLoadingPlugIns(); m_isStopping = false; }
void DocumentLoader::detachFromFrame() { ASSERT(m_frame); RefPtr<Frame> protectFrame(m_frame); RefPtr<DocumentLoader> protectLoader(this); // It never makes sense to have a document loader that is detached from its // frame have any loads active, so go ahead and kill all the loads. stopLoading(); m_applicationCacheHost->setDOMApplicationCache(0); InspectorInstrumentation::loaderDetachedFromFrame(m_frame, this); m_frame = 0; }
void DocumentLoader::commitLoad(const char* data, int length) { // Both unloading the old page and parsing the new page may execute JavaScript which destroys the datasource // by starting a new load, so retain temporarily. RefPtr<Frame> protectFrame(m_frame); RefPtr<DocumentLoader> protectLoader(this); commitIfReady(); FrameLoader* frameLoader = DocumentLoader::frameLoader(); if (!frameLoader) return; if (isArchiveMIMEType(response().mimeType())) return; frameLoader->client()->committedLoad(this, data, length); }
// 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() { RefPtrWillBeRawPtr<LocalFrame> 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(); } if (!loading) { m_fetcher->stopFetching(); return; } if (m_loadingMainResource) { // Stop the main resource loader and let it send the cancelled message. cancelMainResourceLoad(ResourceError::cancelledError(m_request.url())); } else if (m_fetcher->isFetching()) { // The main resource loader already finished loading. Set the cancelled error on the // document and let the resourceLoaders send individual cancelled messages below. setMainDocumentError(ResourceError::cancelledError(m_request.url())); } 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(ResourceError::cancelledError(m_request.url())); } m_fetcher->stopFetching(); }