void NetworkResourceLoader::receivedCancellation(ResourceHandle* handle, const AuthenticationChallenge& challenge) { ASSERT_UNUSED(handle, handle == m_handle); m_handle->cancel(); didFail(m_handle.get(), cancelledError(m_request)); }
void Loader::cancelRequests(DocLoader* dl) { DeprecatedPtrListIterator<Request> pIt(m_requestsPending); while (pIt.current()) { if (pIt.current()->docLoader() == dl) { cache()->remove(pIt.current()->cachedResource()); m_requestsPending.remove(pIt); dl->decrementRequestCount(); } else ++pIt; } Vector<SubresourceLoader*, 256> loadersToCancel; RequestMap::iterator end = m_requestsLoading.end(); for (RequestMap::iterator i = m_requestsLoading.begin(); i != end; ++i) { Request* r = i->second; if (r->docLoader() == dl) loadersToCancel.append(i->first.get()); } for (unsigned i = 0; i < loadersToCancel.size(); ++i) { SubresourceLoader* loader = loadersToCancel[i]; didFail(loader, true); } if (dl->loadInProgress()) ASSERT(dl->requestCount() == 1); else ASSERT(dl->requestCount() == 0); }
void ResourceLoader::requestSynchronously() { OwnPtr<WebKit::WebURLLoader> loader = adoptPtr(WebKit::Platform::current()->createURLLoader()); ASSERT(loader); RELEASE_ASSERT(m_connectionState == ConnectionStateNew); m_connectionState = ConnectionStateStarted; WebKit::WrappedResourceRequest requestIn(m_request); requestIn.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredCredentials); WebKit::WebURLResponse responseOut; responseOut.initialize(); WebKit::WebURLError errorOut; WebKit::WebData dataOut; loader->loadSynchronously(requestIn, responseOut, errorOut, dataOut); if (errorOut.reason) { didFail(0, errorOut); return; } didReceiveResponse(0, responseOut); RefPtr<ResourceLoadInfo> resourceLoadInfo = responseOut.toResourceResponse().resourceLoadInfo(); m_host->didReceiveData(m_resource, dataOut.data(), dataOut.size(), resourceLoadInfo ? resourceLoadInfo->encodedDataLength : -1, m_options); m_resource->setResourceBuffer(dataOut); didFinishLoading(0, responseOut.responseTime()); }
void ResourceLoader::requestSynchronously() { OwnPtr<blink::WebURLLoader> loader = adoptPtr(blink::Platform::current()->createURLLoader()); ASSERT(loader); RefPtr<ResourceLoader> protect(this); RefPtr<ResourceLoaderHost> protectHost(m_host); ResourcePtr<Resource> protectResource(m_resource); RELEASE_ASSERT(m_connectionState == ConnectionStateNew); m_connectionState = ConnectionStateStarted; blink::WrappedResourceRequest requestIn(m_request); requestIn.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredCredentials); blink::WebURLResponse responseOut; responseOut.initialize(); blink::WebURLError errorOut; blink::WebData dataOut; loader->loadSynchronously(requestIn, responseOut, errorOut, dataOut); if (errorOut.reason) { didFail(0, errorOut); return; } didReceiveResponse(0, responseOut); if (m_state == Terminated) return; RefPtr<ResourceLoadInfo> resourceLoadInfo = responseOut.toResourceResponse().resourceLoadInfo(); int64 encodedDataLength = resourceLoadInfo ? resourceLoadInfo->encodedDataLength : blink::WebURLLoaderClient::kUnknownEncodedDataLength; m_host->didReceiveData(m_resource, dataOut.data(), dataOut.size(), encodedDataLength); m_resource->setResourceBuffer(dataOut); didFinishLoading(0, monotonicallyIncreasingTime(), encodedDataLength); }
void NetworkResourceLoader::continueWillSendRequest(const ResourceRequest& newRequest) { #if PLATFORM(COCOA) m_currentRequest.updateFromDelegatePreservingOldProperties(newRequest.nsURLRequest(DoNotUpdateHTTPBody)); #elif USE(SOUP) // FIXME: Implement ResourceRequest::updateFromDelegatePreservingOldProperties. See https://bugs.webkit.org/show_bug.cgi?id=126127. m_currentRequest.updateFromDelegatePreservingOldProperties(newRequest); #endif if (m_currentRequest.isNull()) { #if USE(NETWORK_SESSION) // FIXME: Do something here. notImplemented(); #else m_handle->cancel(); didFail(m_handle.get(), cancelledError(m_currentRequest)); #endif return; } #if USE(NETWORK_SESSION) // FIXME: Do something here. notImplemented(); #else m_handle->continueWillSendRequest(m_currentRequest); #endif }
bool ResourceLoader::load(const ResourceRequest& r) { ASSERT(!m_handle); ASSERT(m_deferredRequest.isNull()); ASSERT(!m_documentLoader->isSubstituteLoadPending(this)); ResourceRequest clientRequest(r); willSendRequest(clientRequest, ResourceResponse()); if (clientRequest.isNull()) { didFail(frameLoader()->cancelledError(r)); return false; } if (m_documentLoader->scheduleArchiveLoad(this, clientRequest, r.url())) return true; #if ENABLE(OFFLINE_WEB_APPLICATIONS) if (m_documentLoader->applicationCacheHost()->maybeLoadResource(this, clientRequest, r.url())) return true; #endif if (m_defersLoading) { m_deferredRequest = clientRequest; return true; } m_handle = ResourceHandle::create(clientRequest, this, m_frame.get(), m_defersLoading, m_shouldContentSniff, true); return true; }
void NetworkDataTaskBlob::didGetSize(long long size) { ASSERT(isMainThread()); if (m_state == State::Canceling || m_state == State::Completed || (!m_client && !isDownload())) { clearStream(); return; } // If the size is -1, it means the file has been moved or changed. Fail now. if (size == -1) { didFail(Error::NotFoundError); return; } // The size passed back is the size of the whole file. If the underlying item is a sliced file, we need to use the slice length. const BlobDataItem& item = m_blobData->items().at(m_sizeItemCount); size = item.length(); // Cache the size. m_itemLengthList.append(size); // Count the size. m_totalSize += size; m_totalRemainingSize += size; m_sizeItemCount++; // Continue with the next item. getSizeForNext(); }
bool ResourceLoader::load(const ResourceRequest& r) { ASSERT(!m_handle); ASSERT(m_deferredRequest.isNull()); ASSERT(!frameLoader()->isArchiveLoadPending(this)); m_originalURL = r.url(); ResourceRequest clientRequest(r); willSendRequest(clientRequest, ResourceResponse()); if (clientRequest.isNull()) { didFail(frameLoader()->cancelledError(r)); return false; } if (frameLoader()->willUseArchive(this, clientRequest, m_originalURL)) return true; if (m_defersLoading) { m_deferredRequest = clientRequest; return true; } m_handle = ResourceHandle::create(clientRequest, this, m_frame.get(), m_defersLoading, m_shouldContentSniff, true); return true; }
bool ResourceLoader::init(const ResourceRequest& r) { ASSERT(!m_handle); ASSERT(m_request.isNull()); ASSERT(m_deferredRequest.isNull()); ASSERT(!m_documentLoader->isSubstituteLoadPending(this)); ResourceRequest clientRequest(r); if (m_options.securityCheck == DoSecurityCheck && !m_frame->document()->securityOrigin()->canDisplay(clientRequest.url())) { FrameLoader::reportLocalLoadFailed(m_frame.get(), clientRequest.url().string()); releaseResources(); return false; } // https://bugs.webkit.org/show_bug.cgi?id=26391 // The various plug-in implementations call directly to ResourceLoader::load() instead of piping requests // through FrameLoader. As a result, they miss the FrameLoader::addExtraFieldsToRequest() step which sets // up the 1st party for cookies URL. Until plug-in implementations can be reigned in to pipe through that // method, we need to make sure there is always a 1st party for cookies set. if (clientRequest.firstPartyForCookies().isNull()) { if (Document* document = m_frame->document()) clientRequest.setFirstPartyForCookies(document->firstPartyForCookies()); } willSendRequest(clientRequest, ResourceResponse()); if (clientRequest.isNull()) { didFail(cancelledError()); return false; } m_originalRequest = m_request = clientRequest; return true; }
void ResourceLoader::didReceiveAuthenticationChallenge(const AuthenticationChallenge& challenge) { ASSERT(handle()->hasAuthenticationChallenge()); // Protect this in this delegate method since the additional processing can do // anything including possibly derefing this; one example of this is Radar 3266216. RefPtr<ResourceLoader> protector(this); if (m_options.allowCredentials == AllowStoredCredentials) { if (m_options.crossOriginCredentialPolicy == AskClientForCrossOriginCredentials || m_frame->document()->securityOrigin()->canRequest(originalRequest().url())) { // SRL: Event action for https request. ActionLogFormat(ActionLog::ENTER_SCOPE, "auth_recv:%s", m_request.url().lastPathComponent().ascii().data()); frameLoader()->notifier()->didReceiveAuthenticationChallenge(this, challenge); ActionLogScopeEnd(); return; } } // Only these platforms provide a way to continue without credentials. // If we can't continue with credentials, we need to cancel the load altogether. #if PLATFORM(MAC) || USE(CFNETWORK) || USE(CURL) handle()->receivedRequestToContinueWithoutCredential(challenge); ASSERT(!handle()->hasAuthenticationChallenge()); #else didFail(blockedError()); #endif }
void ResourceLoader::didFail(const WebURLError& error, int64_t encodedDataLength, int64_t encodedBodyLength) { m_resource->setEncodedDataLength(encodedDataLength); m_resource->addToEncodedBodyLength(encodedBodyLength); didFail(error); }
void ResourceLoader::cannotShowURL(ResourceHandle*) { if (!fastMallocSize(documentLoader()->applicationCacheHost())) CRASH(); if (!fastMallocSize(documentLoader()->frame())) CRASH(); didFail(cannotShowURLError()); }
void ResourceLoader::wasBlocked(ResourceHandle*) { if (!fastMallocSize(documentLoader()->applicationCacheHost())) CRASH(); if (!fastMallocSize(documentLoader()->frame())) CRASH(); didFail(blockedError()); }
void ResourceLoader::didFail(ResourceHandle*, const ResourceError& error) { #if ENABLE(OFFLINE_WEB_APPLICATIONS) if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForError(this, error)) return; #endif didFail(error); }
void ResourceLoader::willSendRequestInternal(ResourceRequest& request, const ResourceResponse& redirectResponse) { // Protect this in this delegate method since the additional processing can do // anything including possibly derefing this; one example of this is Radar 3266216. Ref<ResourceLoader> protect(*this); ASSERT(!m_reachedTerminalState); #if ENABLE(CONTENT_EXTENSIONS) ASSERT(m_resourceType != ResourceType::Invalid); #endif // We need a resource identifier for all requests, even if FrameLoader is never going to see it (such as with CORS preflight requests). bool createdResourceIdentifier = false; if (!m_identifier) { m_identifier = m_frame->page()->progress().createUniqueIdentifier(); createdResourceIdentifier = true; } #if ENABLE(CONTENT_EXTENSIONS) if (frameLoader()) { Page* page = frameLoader()->frame().page(); if (page && m_documentLoader) { auto* userContentController = page->userContentController(); if (userContentController) userContentController->processContentExtensionRulesForLoad(*page, request, m_resourceType, *m_documentLoader); } } #endif if (request.isNull()) { didFail(cannotShowURLError()); return; } if (m_options.sendLoadCallbacks() == SendCallbacks) { if (createdResourceIdentifier) frameLoader()->notifier().assignIdentifierToInitialRequest(m_identifier, documentLoader(), request); #if PLATFORM(IOS) // If this ResourceLoader was stopped as a result of assignIdentifierToInitialRequest, bail out if (m_reachedTerminalState) return; #endif frameLoader()->notifier().willSendRequest(this, request, redirectResponse); } else InspectorInstrumentation::willSendRequest(m_frame.get(), m_identifier, m_frame->loader().documentLoader(), request, redirectResponse); if (!redirectResponse.isNull()) platformStrategies()->loaderStrategy()->resourceLoadScheduler()->crossOriginRedirectReceived(this, request.url()); m_request = request; if (!redirectResponse.isNull() && !m_documentLoader->isCommitted()) frameLoader()->client().dispatchDidReceiveServerRedirectForProvisionalLoad(); }
void ResourceLoader::didFail(ResourceHandle*, const ResourceError& error) { if (!fastMallocSize(documentLoader()->applicationCacheHost())) CRASH(); if (!fastMallocSize(documentLoader()->frame())) CRASH(); if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForError(this, error)) return; didFail(error); }
void ResourceLoader::cancelForRedirectAccessCheckError( const KURL& newURL, ResourceRequestBlockedReason blockedReason) { m_resource->willNotFollowRedirect(); if (m_loader) { didFail( ResourceError::cancelledDueToAccessCheckError(newURL, blockedReason)); } }
void ResourceLoader::didReceiveResponse(const ResourceResponse& r) { ASSERT(!m_reachedTerminalState); // Protect this in this delegate method since the additional processing can do // anything including possibly derefing this; one example of this is Radar 3266216. Ref<ResourceLoader> protectedThis(*this); logResourceResponseSource(m_frame.get(), r.source()); m_response = r; if (m_response.isHttpVersion0_9()) { auto url = m_response.url(); // Non-HTTP responses are interpreted as HTTP/0.9 which may allow exfiltration of data // from non-HTTP services. Therefore cancel if the document was loaded with different // HTTP version or if the resource request was to a non-default port. if (!m_documentLoader->response().isHttpVersion0_9()) { String message = "Cancelled resource load from '" + url.string() + "' because it is using HTTP/0.9 and the document was loaded with a different HTTP version."; m_frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message, identifier()); ResourceError error(emptyString(), 0, url, message); didFail(error); return; } if (!isDefaultPortForProtocol(url.port(), url.protocol())) { String message = "Cancelled resource load from '" + url.string() + "' because it is using HTTP/0.9 on a non-default port."; m_frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message, identifier()); ResourceError error(emptyString(), 0, url, message); didFail(error); return; } String message = "Sandboxing '" + m_response.url().string() + "' because it is using HTTP/0.9."; m_frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message, m_identifier); frameLoader()->forceSandboxFlags(SandboxScripts | SandboxPlugins); } if (FormData* data = m_request.httpBody()) data->removeGeneratedFilesIfNeeded(); if (m_options.sendLoadCallbacks() == SendCallbacks) frameLoader()->notifier().didReceiveResponse(this, m_response); }
void ResourceLoader::didFail(ResourceHandle*, const ResourceError& error) { #if ENABLE(OFFLINE_WEB_APPLICATIONS) if (!error.isCancellation()) { if (documentLoader()->scheduleLoadFallbackResourceFromApplicationCache(this, m_request)) return; } #endif didFail(error); }
void DocumentThreadableLoader::cancel() { if (m_client) { ResourceError error(errorDomainWebKitInternal, 0, m_resource->url(), "Load cancelled"); error.setIsCancellation(true); didFail(error); } clearResource(); m_client = 0; }
void DocumentThreadableLoader::notifyFinished(CachedResource* resource) { ASSERT(m_client); ASSERT_UNUSED(resource, resource == m_resource); if (m_resource->errorOccurred()) didFail(m_resource->identifier(), m_resource->resourceError()); else didFinishLoading(m_resource->identifier(), m_resource->loadFinishTime()); }
void DocumentThreadableLoader::notifyFinished(Resource* resource) { ASSERT(m_client); ASSERT(resource == this->resource()); m_timeoutTimer.stop(); if (resource->errorOccurred()) didFail(resource->identifier(), resource->resourceError()); else didFinishLoading(resource->identifier(), resource->loadFinishTime()); }
void NetworkDataTaskBlob::resume() { ASSERT(m_state != State::Running); if (m_state == State::Canceling || m_state == State::Completed) return; m_state = State::Running; if (m_scheduledFailureType != NoFailure) { ASSERT(m_failureTimer.isActive()); return; } RunLoop::main().dispatch([this, protectedThis = makeRef(*this)] { if (m_state == State::Canceling || m_state == State::Completed || !m_client) { clearStream(); return; } if (!equalLettersIgnoringASCIICase(m_firstRequest.httpMethod(), "get")) { didFail(Error::MethodNotAllowed); return; } // If the blob data is not found, fail now. if (!m_blobData) { didFail(Error::NotFoundError); return; } // Parse the "Range" header we care about. String range = m_firstRequest.httpHeaderField(HTTPHeaderName::Range); if (!range.isEmpty() && !parseRange(range, m_rangeOffset, m_rangeEnd, m_rangeSuffixLength)) { didReceiveResponse(Error::RangeError); return; } getSizeForNext(); }); }
void DocumentThreadableLoader::cancel() { RefPtr<DocumentThreadableLoader> protect(this); // Cancel can re-enter and m_resource might be null here as a result. if (m_client && m_resource) { ResourceError error(errorDomainWebKitInternal, 0, m_resource->url(), "Load cancelled"); error.setIsCancellation(true); didFail(error); } clearResource(); m_client = 0; }
void DocumentThreadableLoader::notifyFinished(CachedResource* resource) { ASSERT(m_client); ASSERT_UNUSED(resource, resource == m_resource); if (m_resource && (m_resource->errorOccurred() || m_resource->wasCanceled())) { ResourceError error("Network Request Failed", 0, m_resource->url(), "Resource failed to load"); if (m_resource->wasCanceled()) error.setIsCancellation(true); didFail(error); } else didFinishLoading(m_resource->identifier(), m_resource->loadFinishTime()); }
void DocumentThreadableLoader::cancel() { Ref<DocumentThreadableLoader> protectedThis(*this); // Cancel can re-enter and m_resource might be null here as a result. if (m_client && m_resource) { // FIXME: This error is sent to the client in didFail(), so it should not be an internal one. Use FrameLoaderClient::cancelledError() instead. ResourceError error(errorDomainWebKitInternal, 0, m_resource->url(), "Load cancelled"); error.setIsCancellation(true); didFail(m_resource->identifier(), error); } clearResource(); m_client = nullptr; }
void WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader(PassOwnPtr<CrossThreadResourceRequestData> requestData, ThreadableLoaderOptions options, ResourceLoaderOptions resourceLoaderOptions, const ReferrerPolicy referrerPolicy, const String& outgoingReferrer, ExecutionContext* context) { ASSERT(isMainThread()); Document* document = toDocument(context); OwnPtr<ResourceRequest> request(ResourceRequest::adopt(requestData)); request->setHTTPReferrer(SecurityPolicy::generateReferrer(referrerPolicy, request->url(), outgoingReferrer)); resourceLoaderOptions.requestInitiatorContext = WorkerContext; m_mainThreadLoader = DocumentThreadableLoader::create(*document, this, *request, options, resourceLoaderOptions); if (!m_mainThreadLoader) { // DocumentThreadableLoader::create may return 0 when the document loader has been already changed. didFail(ResourceError(errorDomainBlinkInternal, 0, request->url().string(), "Can't create DocumentThreadableLoader")); } }
void NetworkDataTaskBlob::didRead(int bytesRead) { if (m_state == State::Canceling || m_state == State::Completed || (!m_client && !isDownload())) { clearStream(); return; } if (bytesRead < 0) { didFail(Error::NotReadableError); return; } Ref<NetworkDataTaskBlob> protectedThis(*this); consumeData(m_buffer.data(), bytesRead); }
void NetworkDataTaskBlob::didOpen(bool success) { if (m_state == State::Canceling || m_state == State::Completed || (!m_client && !isDownload())) { clearStream(); return; } if (!success) { didFail(Error::NotReadableError); return; } Ref<NetworkDataTaskBlob> protectedThis(*this); read(); }
bool ResourceLoader::willFollowRedirect( WebURLRequest& passedNewRequest, const WebURLResponse& passedRedirectResponse) { DCHECK(!passedNewRequest.isNull()); DCHECK(!passedRedirectResponse.isNull()); if (m_isCacheAwareLoadingActivated) { // Fail as cache miss if cached response is a redirect. didFail( ResourceError::cacheMissError(m_resource->lastResourceRequest().url())); return false; } ResourceRequest& newRequest(passedNewRequest.toMutableResourceRequest()); const ResourceResponse& redirectResponse( passedRedirectResponse.toResourceResponse()); newRequest.setRedirectStatus( ResourceRequest::RedirectStatus::FollowedRedirect); const KURL originalURL = newRequest.url(); ResourceRequestBlockedReason blockedReason = m_fetcher->willFollowRedirect( m_resource.get(), newRequest, redirectResponse); if (blockedReason != ResourceRequestBlockedReason::None) { cancelForRedirectAccessCheckError(newRequest.url(), blockedReason); return false; } // ResourceFetcher::willFollowRedirect() may rewrite the URL to // something else not for rejecting redirect but for other reasons. // E.g. WebFrameTestClient::willSendRequest() and // RenderFrameImpl::willSendRequest(). We should reflect the // rewriting but currently we cannot. So, return false to make the // redirect fail. if (newRequest.url() != originalURL) { cancelForRedirectAccessCheckError(newRequest.url(), ResourceRequestBlockedReason::Other); return false; } if (!m_resource->willFollowRedirect(newRequest, redirectResponse)) { cancelForRedirectAccessCheckError(newRequest.url(), ResourceRequestBlockedReason::Other); return false; } return true; }