diff options
Diffstat (limited to 'Source/WebCore/loader/ResourceLoader.cpp')
-rw-r--r-- | Source/WebCore/loader/ResourceLoader.cpp | 424 |
1 files changed, 293 insertions, 131 deletions
diff --git a/Source/WebCore/loader/ResourceLoader.cpp b/Source/WebCore/loader/ResourceLoader.cpp index ebef76f47..0fbb0c38e 100644 --- a/Source/WebCore/loader/ResourceLoader.cpp +++ b/Source/WebCore/loader/ResourceLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2010, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2006-2007, 2010-2011, 2016 Apple Inc. All rights reserved. * (C) 2007 Graham Dennis (graham.dennis@gmail.com) * * Redistribution and use in source and binary forms, with or without @@ -11,7 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -31,36 +31,41 @@ #include "ResourceLoader.h" #include "ApplicationCacheHost.h" -#include "AsyncFileStream.h" #include "AuthenticationChallenge.h" +#include "DataURLDecoder.h" +#include "DiagnosticLoggingClient.h" +#include "DiagnosticLoggingKeys.h" #include "DocumentLoader.h" #include "Frame.h" #include "FrameLoader.h" #include "FrameLoaderClient.h" #include "InspectorInstrumentation.h" #include "LoaderStrategy.h" +#include "MainFrame.h" #include "Page.h" #include "PlatformStrategies.h" #include "ProgressTracker.h" -#include "ResourceBuffer.h" #include "ResourceError.h" #include "ResourceHandle.h" -#include "ResourceLoadScheduler.h" #include "SecurityOrigin.h" -#include "Settings.h" #include "SharedBuffer.h" #include <wtf/Ref.h> +#if ENABLE(CONTENT_EXTENSIONS) +#include "UserContentController.h" +#endif + +#if USE(QUICK_LOOK) +#include "PreviewConverter.h" +#include "QuickLook.h" +#endif + namespace WebCore { -ResourceLoader::ResourceLoader(Frame* frame, ResourceLoaderOptions options) - : m_frame(frame) - , m_documentLoader(frame->loader().activeDocumentLoader()) - , m_identifier(0) - , m_reachedTerminalState(false) - , m_notifiedLoadComplete(false) - , m_cancellationStatus(NotCancelled) - , m_defersLoading(frame->page()->defersLoading()) +ResourceLoader::ResourceLoader(Frame& frame, ResourceLoaderOptions options) + : m_frame(&frame) + , m_documentLoader(frame.loader().activeDocumentLoader()) + , m_defersLoading(options.defersLoadingPolicy == DefersLoadingPolicy::AllowDefersLoading && frame.page()->defersLoading()) , m_options(options) { } @@ -70,6 +75,17 @@ ResourceLoader::~ResourceLoader() ASSERT(m_reachedTerminalState); } +void ResourceLoader::finishNetworkLoad() +{ + platformStrategies()->loaderStrategy()->remove(this); + + if (m_handle) { + ASSERT(m_handle->client() == this); + m_handle->clearClient(); + m_handle = nullptr; + } +} + void ResourceLoader::releaseResources() { ASSERT(!m_reachedTerminalState); @@ -78,27 +94,20 @@ void ResourceLoader::releaseResources() // deallocated and release the last reference to this object. // We need to retain to avoid accessing the object after it // has been deallocated and also to avoid reentering this method. - Ref<ResourceLoader> protect(*this); + Ref<ResourceLoader> protectedThis(*this); - m_frame = 0; - m_documentLoader = 0; + m_frame = nullptr; + m_documentLoader = nullptr; // We need to set reachedTerminalState to true before we release // the resources to prevent a double dealloc of WebView <rdar://problem/4372628> m_reachedTerminalState = true; - platformStrategies()->loaderStrategy()->resourceLoadScheduler()->remove(this); - m_identifier = 0; + finishNetworkLoad(); - if (m_handle) { - // Clear out the ResourceHandle's client so that it doesn't try to call - // us back after we release it, unless it has been replaced by someone else. - if (m_handle->client() == this) - m_handle->setClient(0); - m_handle = 0; - } + m_identifier = 0; - m_resourceData = 0; + m_resourceData = nullptr; m_deferredRequest = ResourceRequest(); } @@ -111,6 +120,8 @@ bool ResourceLoader::init(const ResourceRequest& r) ResourceRequest clientRequest(r); + m_loadTiming.markStartTimeAndFetchStart(); + #if PLATFORM(IOS) // If the documentLoader was detached while this ResourceLoader was waiting its turn // in ResourceLoadScheduler queue, don't continue. @@ -120,8 +131,9 @@ bool ResourceLoader::init(const ResourceRequest& r) } #endif - m_defersLoading = m_frame->page()->defersLoading(); - if (m_options.securityCheck == DoSecurityCheck && !m_frame->document()->securityOrigin()->canDisplay(clientRequest.url())) { + m_defersLoading = m_options.defersLoadingPolicy == DefersLoadingPolicy::AllowDefersLoading && m_frame->page()->defersLoading(); + + if (m_options.securityCheck == DoSecurityCheck && !m_frame->document()->securityOrigin().canDisplay(clientRequest.url())) { FrameLoader::reportLocalLoadFailed(m_frame.get(), clientRequest.url().string()); releaseResources(); return false; @@ -137,7 +149,7 @@ bool ResourceLoader::init(const ResourceRequest& r) clientRequest.setFirstPartyForCookies(document->firstPartyForCookies()); } - willSendRequest(clientRequest, ResourceResponse()); + willSendRequestInternal(clientRequest, ResourceResponse()); #if PLATFORM(IOS) // If this ResourceLoader was stopped as a result of willSendRequest, bail out. @@ -154,18 +166,37 @@ bool ResourceLoader::init(const ResourceRequest& r) return true; } +void ResourceLoader::deliverResponseAndData(const ResourceResponse& response, RefPtr<SharedBuffer>&& buffer) +{ + Ref<ResourceLoader> protectedThis(*this); + + didReceiveResponse(response); + if (reachedTerminalState()) + return; + + if (buffer) { + unsigned size = buffer->size(); + didReceiveBuffer(buffer.releaseNonNull(), size, DataPayloadWholeResource); + if (reachedTerminalState()) + return; + } + + didFinishLoading(0); +} + void ResourceLoader::start() { ASSERT(!m_handle); ASSERT(!m_request.isNull()); ASSERT(m_deferredRequest.isNull()); + ASSERT(frameLoader()); #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML) - if (m_documentLoader->scheduleArchiveLoad(this, m_request)) + if (m_documentLoader->scheduleArchiveLoad(*this, m_request)) return; #endif - if (m_documentLoader->applicationCacheHost()->maybeLoadResource(this, m_request, m_request.url())) + if (m_documentLoader->applicationCacheHost().maybeLoadResource(*this, m_request, m_request.url())) return; if (m_defersLoading) { @@ -173,12 +204,22 @@ void ResourceLoader::start() return; } - if (!m_reachedTerminalState) - m_handle = ResourceHandle::create(m_frame->loader().networkingContext(), m_request, this, m_defersLoading, m_options.sniffContent == SniffContent); + if (m_reachedTerminalState) + return; + + if (m_request.url().protocolIsData()) { + loadDataURL(); + return; + } + + m_handle = ResourceHandle::create(frameLoader()->networkingContext(), m_request, this, m_defersLoading, m_options.sniffContent == SniffContent); } void ResourceLoader::setDefersLoading(bool defers) { + if (m_options.defersLoadingPolicy == DefersLoadingPolicy::DisallowDefersLoading) + return; + m_defersLoading = defers; if (m_handle) m_handle->setDefersLoading(defers); @@ -187,43 +228,88 @@ void ResourceLoader::setDefersLoading(bool defers) m_deferredRequest = ResourceRequest(); start(); } + + platformStrategies()->loaderStrategy()->setDefersLoading(this, defers); } FrameLoader* ResourceLoader::frameLoader() const { if (!m_frame) - return 0; + return nullptr; return &m_frame->loader(); } +void ResourceLoader::loadDataURL() +{ + auto url = m_request.url(); + ASSERT(url.protocolIsData()); + + RefPtr<ResourceLoader> protectedThis(this); + DataURLDecoder::ScheduleContext scheduleContext; +#if HAVE(RUNLOOP_TIMER) + if (auto* scheduledPairs = m_frame->page()->scheduledRunLoopPairs()) + scheduleContext.scheduledPairs = *scheduledPairs; +#endif + DataURLDecoder::decode(url, scheduleContext, [protectedThis, url](auto decodeResult) { + if (protectedThis->reachedTerminalState()) + return; + if (!decodeResult) { + protectedThis->didFail(ResourceError(errorDomainWebKitInternal, 0, url, "Data URL decoding failed")); + return; + } + if (protectedThis->wasCancelled()) + return; + auto& result = decodeResult.value(); + auto dataSize = result.data ? result.data->size() : 0; + + ResourceResponse dataResponse { url, result.mimeType, dataSize, result.charset }; + dataResponse.setHTTPStatusCode(200); + dataResponse.setHTTPStatusText(ASCIILiteral("OK")); + dataResponse.setHTTPHeaderField(HTTPHeaderName::ContentType, result.contentType); + protectedThis->didReceiveResponse(dataResponse); + + if (!protectedThis->reachedTerminalState() && dataSize) + protectedThis->didReceiveBuffer(result.data.releaseNonNull(), dataSize, DataPayloadWholeResource); + + if (!protectedThis->reachedTerminalState()) + protectedThis->didFinishLoading(currentTime()); + }); +} + void ResourceLoader::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy) -{ - m_options.dataBufferingPolicy = dataBufferingPolicy; +{ + m_options.dataBufferingPolicy = dataBufferingPolicy; // Reset any already buffered data if (dataBufferingPolicy == DoNotBufferData) - m_resourceData = 0; + m_resourceData = nullptr; +} + +void ResourceLoader::willSwitchToSubstituteResource() +{ + ASSERT(!m_documentLoader->isSubstituteLoadPending(this)); + platformStrategies()->loaderStrategy()->remove(this); + if (m_handle) + m_handle->cancel(); } - void ResourceLoader::addDataOrBuffer(const char* data, unsigned length, SharedBuffer* buffer, DataPayloadType dataPayloadType) { if (m_options.dataBufferingPolicy == DoNotBufferData) return; - if (dataPayloadType == DataPayloadWholeResource) { - m_resourceData = buffer ? ResourceBuffer::adoptSharedBuffer(buffer) : ResourceBuffer::create(data, length); - return; - } - - if (!m_resourceData) - m_resourceData = buffer ? ResourceBuffer::adoptSharedBuffer(buffer) : ResourceBuffer::create(data, length); - else { + if (!m_resourceData || dataPayloadType == DataPayloadWholeResource) { if (buffer) - m_resourceData->append(buffer); + m_resourceData = buffer; else - m_resourceData->append(data, length); + m_resourceData = SharedBuffer::create(data, length); + return; } + + if (buffer) + m_resourceData->append(*buffer); + else + m_resourceData->append(data, length); } void ResourceLoader::clearResourceData() @@ -237,26 +323,15 @@ bool ResourceLoader::isSubresourceLoader() return false; } -void ResourceLoader::willSendRequest(ResourceRequest& request, const ResourceResponse& redirectResponse) +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); + Ref<ResourceLoader> protectedThis(*this); ASSERT(!m_reachedTerminalState); - -#if PLATFORM(IOS) - // Ensure an identifier is always set. This ensures that this assetion is not hit: - // <rdar://problem/11059794> ASSERTION FAILED: !HashTranslator::equal(KeyTraits::emptyValue(), key) in WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace loading the attached web archive - // This is not needed in WebKit2, as it doesn't use m_identifier in WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace - if (!m_identifier) { - m_identifier = m_frame->page()->progress().createUniqueIdentifier(); - frameLoader()->notifier().assignIdentifierToInitialRequest(m_identifier, documentLoader(), request); - - // If this ResourceLoader was stopped as a result of assignIdentifierToInitialRequest, bail out - if (m_reachedTerminalState) - return; - } +#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). @@ -266,43 +341,115 @@ void ResourceLoader::willSendRequest(ResourceRequest& request, const ResourceRes createdResourceIdentifier = true; } +#if ENABLE(CONTENT_EXTENSIONS) + if (frameLoader()) { + Page* page = frameLoader()->frame().page(); + if (page && m_documentLoader) { + auto blockedStatus = page->userContentProvider().processContentExtensionRulesForLoad(request.url(), m_resourceType, *m_documentLoader); + applyBlockedStatusToRequest(blockedStatus, request); + if (blockedStatus.blockedLoad) { + request = { }; + didFail(blockedByContentBlockerError()); + return; + } + } + } +#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); } -#if ENABLE(INSPECTOR) else InspectorInstrumentation::willSendRequest(m_frame.get(), m_identifier, m_frame->loader().documentLoader(), request, redirectResponse); + +#if USE(QUICK_LOOK) + if (auto previewConverter = m_documentLoader->previewConverter()) + request = previewConverter->safeRequest(request); #endif - if (!redirectResponse.isNull()) - platformStrategies()->loaderStrategy()->resourceLoadScheduler()->crossOriginRedirectReceived(this, request.url()); + bool isRedirect = !redirectResponse.isNull(); + if (isRedirect) + platformStrategies()->loaderStrategy()->crossOriginRedirectReceived(this, request.url()); m_request = request; - if (!redirectResponse.isNull() && !m_documentLoader->isCommitted()) - frameLoader()->client().dispatchDidReceiveServerRedirectForProvisionalLoad(); + if (isRedirect) { + auto& redirectURL = request.url(); + if (!m_documentLoader->isCommitted()) + frameLoader()->client().dispatchDidReceiveServerRedirectForProvisionalLoad(); + + if (redirectURL.protocolIsData()) { + // Handle data URL decoding locally. + finishNetworkLoad(); + loadDataURL(); + } + } +} + +void ResourceLoader::willSendRequest(ResourceRequest&& request, const ResourceResponse& redirectResponse, std::function<void(ResourceRequest&&)>&& callback) +{ + willSendRequestInternal(request, redirectResponse); + callback(WTFMove(request)); } void ResourceLoader::didSendData(unsigned long long, unsigned long long) { } +static void logResourceResponseSource(Frame* frame, ResourceResponse::Source source) +{ + if (!frame || !frame->page()) + return; + + String sourceKey; + switch (source) { + case ResourceResponse::Source::Network: + sourceKey = DiagnosticLoggingKeys::networkKey(); + break; + case ResourceResponse::Source::DiskCache: + sourceKey = DiagnosticLoggingKeys::diskCacheKey(); + break; + case ResourceResponse::Source::DiskCacheAfterValidation: + sourceKey = DiagnosticLoggingKeys::diskCacheAfterValidationKey(); + break; + case ResourceResponse::Source::MemoryCache: + case ResourceResponse::Source::MemoryCacheAfterValidation: + case ResourceResponse::Source::Unknown: + return; + } + + frame->page()->diagnosticLoggingClient().logDiagnosticMessage(DiagnosticLoggingKeys::resourceResponseSourceKey(), sourceKey, ShouldSample::Yes); +} + 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> protect(*this); + Ref<ResourceLoader> protectedThis(*this); + + logResourceResponseSource(m_frame.get(), r.source()); m_response = r; if (FormData* data = m_request.httpBody()) data->removeGeneratedFilesIfNeeded(); - + if (m_options.sendLoadCallbacks == SendCallbacks) frameLoader()->notifier().didReceiveResponse(this, m_response); } @@ -315,26 +462,25 @@ void ResourceLoader::didReceiveData(const char* data, unsigned length, long long // ASSERT(con == connection); // ASSERT(!m_reachedTerminalState); - didReceiveDataOrBuffer(data, length, 0, encodedDataLength, dataPayloadType); + didReceiveDataOrBuffer(data, length, nullptr, encodedDataLength, dataPayloadType); } -void ResourceLoader::didReceiveBuffer(PassRefPtr<SharedBuffer> buffer, long long encodedDataLength, DataPayloadType dataPayloadType) +void ResourceLoader::didReceiveBuffer(Ref<SharedBuffer>&& buffer, long long encodedDataLength, DataPayloadType dataPayloadType) { - didReceiveDataOrBuffer(0, 0, buffer, encodedDataLength, dataPayloadType); + didReceiveDataOrBuffer(nullptr, 0, WTFMove(buffer), encodedDataLength, dataPayloadType); } -void ResourceLoader::didReceiveDataOrBuffer(const char* data, unsigned length, PassRefPtr<SharedBuffer> prpBuffer, long long encodedDataLength, DataPayloadType dataPayloadType) +void ResourceLoader::didReceiveDataOrBuffer(const char* data, unsigned length, RefPtr<SharedBuffer>&& buffer, long long encodedDataLength, DataPayloadType dataPayloadType) { // This method should only get data+length *OR* a SharedBuffer. - ASSERT(!prpBuffer || (!data && !length)); + ASSERT(!buffer || (!data && !length)); // 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); - RefPtr<SharedBuffer> buffer = prpBuffer; + Ref<ResourceLoader> protectedThis(*this); addDataOrBuffer(data, length, buffer.get(), dataPayloadType); - + // FIXME: If we get a resource with more than 2B bytes, this code won't do the right thing. // However, with today's computers and networking speeds, this won't happen in practice. // Could be an issue with a giant local file. @@ -342,15 +488,6 @@ void ResourceLoader::didReceiveDataOrBuffer(const char* data, unsigned length, P frameLoader()->notifier().didReceiveData(this, buffer ? buffer->data() : data, buffer ? buffer->size() : length, static_cast<int>(encodedDataLength)); } -void ResourceLoader::willStopBufferingData(const char* data, unsigned length) -{ - if (m_options.dataBufferingPolicy == DoNotBufferData) - return; - - ASSERT(!m_resourceData); - m_resourceData = ResourceBuffer::create(data, length); -} - void ResourceLoader::didFinishLoading(double finishTime) { didFinishLoadingOnePart(finishTime); @@ -385,7 +522,7 @@ void ResourceLoader::didFail(const ResourceError& error) // 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); + Ref<ResourceLoader> protectedThis(*this); cleanupForError(error); releaseResources(); @@ -403,12 +540,6 @@ void ResourceLoader::cleanupForError(const ResourceError& error) frameLoader()->notifier().didFailToLoad(this, error); } -void ResourceLoader::didChangePriority(ResourceLoadPriority loadPriority) -{ - if (handle()) - handle()->didChangePriority(loadPriority); -} - void ResourceLoader::cancel() { cancel(ResourceError()); @@ -424,7 +555,7 @@ void ResourceLoader::cancel(const ResourceError& error) // willCancel() and didFailToLoad() both call out to clients that might do // something causing the last reference to this object to go away. - Ref<ResourceLoader> protect(*this); + Ref<ResourceLoader> protectedThis(*this); // If we re-enter cancel() from inside willCancel(), we want to pick up from where we left // off without re-running willCancel() @@ -445,7 +576,7 @@ void ResourceLoader::cancel(const ResourceError& error) m_documentLoader->cancelPendingSubstituteLoad(this); if (m_handle) { m_handle->cancel(); - m_handle = 0; + m_handle = nullptr; } cleanupForError(nonNullError); } @@ -474,16 +605,22 @@ ResourceError ResourceLoader::blockedError() return frameLoader()->client().blockedError(m_request); } +ResourceError ResourceLoader::blockedByContentBlockerError() +{ + return frameLoader()->client().blockedByContentBlockerError(m_request); +} + ResourceError ResourceLoader::cannotShowURLError() { return frameLoader()->client().cannotShowURLError(m_request); } -void ResourceLoader::willSendRequest(ResourceHandle*, ResourceRequest& request, const ResourceResponse& redirectResponse) +ResourceRequest ResourceLoader::willSendRequest(ResourceHandle*, ResourceRequest&& request, ResourceResponse&& redirectResponse) { - if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForRedirect(this, request, redirectResponse)) - return; - willSendRequest(request, redirectResponse); + if (documentLoader()->applicationCacheHost().maybeLoadFallbackForRedirect(this, request, redirectResponse)) + return WTFMove(request); + willSendRequestInternal(request, redirectResponse); + return WTFMove(request); } void ResourceLoader::didSendData(ResourceHandle*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) @@ -491,25 +628,21 @@ void ResourceLoader::didSendData(ResourceHandle*, unsigned long long bytesSent, didSendData(bytesSent, totalBytesToBeSent); } -void ResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response) +void ResourceLoader::didReceiveResponse(ResourceHandle*, ResourceResponse&& response) { - if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForResponse(this, response)) + if (documentLoader()->applicationCacheHost().maybeLoadFallbackForResponse(this, response)) return; didReceiveResponse(response); } void ResourceLoader::didReceiveData(ResourceHandle*, const char* data, unsigned length, int encodedDataLength) { - InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceData(m_frame.get(), identifier(), encodedDataLength); didReceiveData(data, length, encodedDataLength, DataPayloadBytes); - InspectorInstrumentation::didReceiveResourceData(cookie); } -void ResourceLoader::didReceiveBuffer(ResourceHandle*, PassRefPtr<SharedBuffer> buffer, int encodedDataLength) +void ResourceLoader::didReceiveBuffer(ResourceHandle*, Ref<SharedBuffer>&& buffer, int encodedDataLength) { - InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceData(m_frame.get(), identifier(), encodedDataLength); - didReceiveBuffer(buffer, encodedDataLength, DataPayloadBytes); - InspectorInstrumentation::didReceiveResourceData(cookie); + didReceiveBuffer(WTFMove(buffer), encodedDataLength, DataPayloadBytes); } void ResourceLoader::didFinishLoading(ResourceHandle*, double finishTime) @@ -519,7 +652,7 @@ void ResourceLoader::didFinishLoading(ResourceHandle*, double finishTime) void ResourceLoader::didFail(ResourceHandle*, const ResourceError& error) { - if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForError(this, error)) + if (documentLoader()->applicationCacheHost().maybeLoadFallbackForError(this, error)) return; didFail(error); } @@ -538,56 +671,53 @@ bool ResourceLoader::shouldUseCredentialStorage() { if (m_options.allowCredentials == DoNotAllowStoredCredentials) return false; - - Ref<ResourceLoader> protect(*this); + + Ref<ResourceLoader> protectedThis(*this); return frameLoader()->client().shouldUseCredentialStorage(documentLoader(), identifier()); } +bool ResourceLoader::isAllowedToAskUserForCredentials() const +{ + if (m_options.clientCredentialPolicy == ClientCredentialPolicy::CannotAskClientForCredentials) + return false; + return m_options.credentials == FetchOptions::Credentials::Include || (m_options.credentials == FetchOptions::Credentials::SameOrigin && m_frame->document()->securityOrigin().canRequest(originalRequest().url())); +} + void ResourceLoader::didReceiveAuthenticationChallenge(const AuthenticationChallenge& challenge) { - ASSERT(handle()->hasAuthenticationChallenge()); + ASSERT(m_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. - Ref<ResourceLoader> protect(*this); + Ref<ResourceLoader> protectedThis(*this); if (m_options.allowCredentials == AllowStoredCredentials) { - if (m_options.clientCredentialPolicy == AskClientForAllCredentials || (m_options.clientCredentialPolicy == DoNotAskClientForCrossOriginCredentials && m_frame->document()->securityOrigin()->canRequest(originalRequest().url()))) { + if (isAllowedToAskUserForCredentials()) { frameLoader()->notifier().didReceiveAuthenticationChallenge(this, challenge); 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) || PLATFORM(GTK) || PLATFORM(EFL) challenge.authenticationClient()->receivedRequestToContinueWithoutCredential(challenge); - ASSERT(!handle() || !handle()->hasAuthenticationChallenge()); -#else - didFail(blockedError()); -#endif -} - -void ResourceLoader::didCancelAuthenticationChallenge(const AuthenticationChallenge& challenge) -{ - // 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); - frameLoader()->notifier().didCancelAuthenticationChallenge(this, challenge); + ASSERT(!m_handle || !m_handle->hasAuthenticationChallenge()); } #if USE(PROTECTION_SPACE_AUTH_CALLBACK) + bool ResourceLoader::canAuthenticateAgainstProtectionSpace(const ProtectionSpace& protectionSpace) { - Ref<ResourceLoader> protect(*this); + Ref<ResourceLoader> protectedThis(*this); return frameLoader()->client().canAuthenticateAgainstProtectionSpace(documentLoader(), identifier(), protectionSpace); } + #endif #if PLATFORM(IOS) + RetainPtr<CFDictionaryRef> ResourceLoader::connectionProperties(ResourceHandle*) { return frameLoader()->connectionProperties(this); } + #endif void ResourceLoader::receivedCancellation(const AuthenticationChallenge&) @@ -595,4 +725,36 @@ void ResourceLoader::receivedCancellation(const AuthenticationChallenge&) cancel(); } +#if PLATFORM(COCOA) && !USE(CFURLCONNECTION) + +void ResourceLoader::schedule(SchedulePair& pair) +{ + if (m_handle) + m_handle->schedule(pair); +} + +void ResourceLoader::unschedule(SchedulePair& pair) +{ + if (m_handle) + m_handle->unschedule(pair); +} + +#endif + +#if USE(QUICK_LOOK) +bool ResourceLoader::isQuickLookResource() const +{ + return !!m_quickLookHandle; +} +#endif + +bool ResourceLoader::isAlwaysOnLoggingAllowed() const +{ + return frameLoader() && frameLoader()->isAlwaysOnLoggingAllowed(); +} + +void ResourceLoader::didRetrieveDerivedDataFromCache(const String&, SharedBuffer&) +{ +} + } |