diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/WebCore/loader/ResourceLoader.cpp | |
parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
download | qtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz |
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f
Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/WebCore/loader/ResourceLoader.cpp')
-rw-r--r-- | Source/WebCore/loader/ResourceLoader.cpp | 395 |
1 files changed, 295 insertions, 100 deletions
diff --git a/Source/WebCore/loader/ResourceLoader.cpp b/Source/WebCore/loader/ResourceLoader.cpp index 8fc4a8476..d0c820ad4 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,47 @@ #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 "ResourceLoadInfo.h" +#include "UserContentController.h" +#endif namespace WebCore { ResourceLoader::ResourceLoader(Frame* frame, ResourceLoaderOptions options) : m_frame(frame) - , m_documentLoader(frame->loader()->activeDocumentLoader()) + , m_documentLoader(frame->loader().activeDocumentLoader()) , m_identifier(0) , m_reachedTerminalState(false) , m_notifiedLoadComplete(false) , m_cancellationStatus(NotCancelled) - , m_defersLoading(frame->page()->defersLoading()) + , m_defersLoading(options.defersLoadingPolicy() == DefersLoadingPolicy::AllowDefersLoading && frame->page()->defersLoading()) , m_options(options) + , m_isQuickLookResource(false) +#if ENABLE(CONTENT_EXTENSIONS) + , m_resourceType(ResourceType::Invalid) +#endif { } @@ -69,6 +80,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); @@ -77,27 +99,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. - RefPtr<ResourceLoader> protector(this); + Ref<ResourceLoader> protect(*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(); } @@ -109,9 +124,19 @@ bool ResourceLoader::init(const ResourceRequest& r) ASSERT(!m_documentLoader->isSubstituteLoadPending(this)); ResourceRequest clientRequest(r); + +#if PLATFORM(IOS) + // If the documentLoader was detached while this ResourceLoader was waiting its turn + // in ResourceLoadScheduler queue, don't continue. + if (!m_documentLoader->frame()) { + cancel(); + return false; + } +#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; @@ -127,7 +152,14 @@ 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. + if (m_reachedTerminalState) + return false; +#endif + if (clientRequest.isNull()) { cancel(); return false; @@ -137,11 +169,30 @@ bool ResourceLoader::init(const ResourceRequest& r) return true; } +void ResourceLoader::deliverResponseAndData(const ResourceResponse& response, RefPtr<SharedBuffer>&& buffer) +{ + Ref<ResourceLoader> protect(*this); + + didReceiveResponse(response); + if (reachedTerminalState()) + return; + + if (buffer) { + unsigned size = buffer->size(); + didReceiveBuffer(buffer.release(), 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)) @@ -156,12 +207,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); @@ -170,37 +231,80 @@ void ResourceLoader::setDefersLoading(bool defers) m_deferredRequest = ResourceRequest(); start(); } + + platformStrategies()->loaderStrategy()->setDefersLoading(this, defers); } FrameLoader* ResourceLoader::frameLoader() const { if (!m_frame) - return 0; - return m_frame->loader(); + return nullptr; + return &m_frame->loader(); +} + +void ResourceLoader::loadDataURL() +{ + auto url = m_request.url(); + ASSERT(url.protocolIsData()); + + RefPtr<ResourceLoader> loader(this); + DataURLDecoder::ScheduleContext scheduleContext; +#if HAVE(RUNLOOP_TIMER) + if (auto* scheduledPairs = m_frame->page()->scheduledRunLoopPairs()) + scheduleContext.scheduledPairs = *scheduledPairs; +#endif + DataURLDecoder::decode(url, scheduleContext, [loader, url] (Optional<DataURLDecoder::Result> decodeResult) { + if (loader->reachedTerminalState()) + return; + if (!decodeResult) { + loader->didFail(ResourceError(errorDomainWebKitInternal, 0, url, "Data URL decoding failed")); + return; + } + if (loader->wasCancelled()) + return; + auto& result = decodeResult.value(); + auto dataSize = result.data->size(); + + ResourceResponse dataResponse { url, result.mimeType, dataSize, result.charset }; + loader->didReceiveResponse(dataResponse); + + if (!loader->reachedTerminalState() && dataSize) + loader->didReceiveBuffer(result.data.get(), dataSize, DataPayloadWholeResource); + + if (!loader->reachedTerminalState()) + loader->didFinishLoading(currentTime()); + }); } void ResourceLoader::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy) { - m_options.dataBufferingPolicy = dataBufferingPolicy; + m_options.setDataBufferingPolicy(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, int length, SharedBuffer* buffer, DataPayloadType dataPayloadType) +void ResourceLoader::addDataOrBuffer(const char* data, unsigned length, SharedBuffer* buffer, DataPayloadType dataPayloadType) { - if (m_options.dataBufferingPolicy == DoNotBufferData) + if (m_options.dataBufferingPolicy() == DoNotBufferData) return; if (dataPayloadType == DataPayloadWholeResource) { - m_resourceData = buffer ? ResourceBuffer::adoptSharedBuffer(buffer) : ResourceBuffer::create(data, length); + m_resourceData = buffer ? buffer : SharedBuffer::create(data, length); return; } if (!m_resourceData) - m_resourceData = buffer ? ResourceBuffer::adoptSharedBuffer(buffer) : ResourceBuffer::create(data, length); + m_resourceData = buffer ? buffer : SharedBuffer::create(data, length); else { if (buffer) m_resourceData->append(buffer); @@ -220,63 +324,135 @@ 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. - RefPtr<ResourceLoader> protector(this); + 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(); + m_identifier = m_frame->page()->progress().createUniqueIdentifier(); createdResourceIdentifier = true; } - if (m_options.sendLoadCallbacks == SendCallbacks) { +#if ENABLE(CONTENT_EXTENSIONS) + if (frameLoader()) { + Page* page = frameLoader()->frame().page(); + if (page && m_documentLoader) { + auto* userContentController = page->userContentController(); + if (userContentController && userContentController->processContentExtensionRulesForLoad(request, m_resourceType, *m_documentLoader) == ContentExtensions::BlockedStatus::Blocked) + request = { }; + } + } +#endif + + if (request.isNull()) { + didFail(cannotShowURLError()); + return; + } + + if (m_options.sendLoadCallbacks() == SendCallbacks) { if (createdResourceIdentifier) - frameLoader()->notifier()->assignIdentifierToInitialRequest(m_identifier, documentLoader(), request); + 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); + frameLoader()->notifier().willSendRequest(this, request, redirectResponse); } -#if ENABLE(INSPECTOR) else - InspectorInstrumentation::willSendRequest(m_frame.get(), m_identifier, m_frame->loader()->documentLoader(), request, redirectResponse); -#endif + InspectorInstrumentation::willSendRequest(m_frame.get(), m_identifier, m_frame->loader().documentLoader(), request, redirectResponse); - 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) + 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->mainFrame().diagnosticLoggingClient().logDiagnosticMessageWithValue(DiagnosticLoggingKeys::resourceResponseKey(), DiagnosticLoggingKeys::sourceKey(), 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. - RefPtr<ResourceLoader> protector(this); + Ref<ResourceLoader> protect(*this); + + logResourceResponseSource(m_frame.get(), r.source()); m_response = r; + if (m_response.isHttpVersion0_9()) { + 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); + if (m_options.sendLoadCallbacks() == SendCallbacks) + frameLoader()->notifier().didReceiveResponse(this, m_response); } -void ResourceLoader::didReceiveData(const char* data, int length, long long encodedDataLength, DataPayloadType dataPayloadType) +void ResourceLoader::didReceiveData(const char* data, unsigned length, long long encodedDataLength, DataPayloadType dataPayloadType) { // The following assertions are not quite valid here, since a subclass // might override didReceiveData in a way that invalidates them. This @@ -292,14 +468,14 @@ void ResourceLoader::didReceiveBuffer(PassRefPtr<SharedBuffer> buffer, long long didReceiveDataOrBuffer(0, 0, buffer, encodedDataLength, dataPayloadType); } -void ResourceLoader::didReceiveDataOrBuffer(const char* data, int length, PassRefPtr<SharedBuffer> prpBuffer, long long encodedDataLength, DataPayloadType dataPayloadType) +void ResourceLoader::didReceiveDataOrBuffer(const char* data, unsigned length, PassRefPtr<SharedBuffer> prpBuffer, long long encodedDataLength, DataPayloadType dataPayloadType) { // This method should only get data+length *OR* a SharedBuffer. ASSERT(!prpBuffer || (!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. - RefPtr<ResourceLoader> protector(this); + Ref<ResourceLoader> protect(*this); RefPtr<SharedBuffer> buffer = prpBuffer; addDataOrBuffer(data, length, buffer.get(), dataPayloadType); @@ -307,17 +483,8 @@ void ResourceLoader::didReceiveDataOrBuffer(const char* data, int length, PassRe // 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. - if (m_options.sendLoadCallbacks == SendCallbacks && m_frame) - frameLoader()->notifier()->didReceiveData(this, buffer ? buffer->data() : data, buffer ? buffer->size() : length, static_cast<int>(encodedDataLength)); -} - -void ResourceLoader::willStopBufferingData(const char* data, int length) -{ - if (m_options.dataBufferingPolicy == DoNotBufferData) - return; - - ASSERT(!m_resourceData); - m_resourceData = ResourceBuffer::create(data, length); + if (m_options.sendLoadCallbacks() == SendCallbacks && m_frame) + frameLoader()->notifier().didReceiveData(this, buffer ? buffer->data() : data, buffer ? buffer->size() : length, static_cast<int>(encodedDataLength)); } void ResourceLoader::didFinishLoading(double finishTime) @@ -342,8 +509,8 @@ void ResourceLoader::didFinishLoadingOnePart(double finishTime) if (m_notifiedLoadComplete) return; m_notifiedLoadComplete = true; - if (m_options.sendLoadCallbacks == SendCallbacks) - frameLoader()->notifier()->didFinishLoad(this, finishTime); + if (m_options.sendLoadCallbacks() == SendCallbacks) + frameLoader()->notifier().didFinishLoad(this, finishTime); } void ResourceLoader::didFail(const ResourceError& error) @@ -354,7 +521,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. - RefPtr<ResourceLoader> protector(this); + Ref<ResourceLoader> protect(*this); cleanupForError(error); releaseResources(); @@ -368,16 +535,8 @@ void ResourceLoader::cleanupForError(const ResourceError& error) if (m_notifiedLoadComplete) return; m_notifiedLoadComplete = true; - if (m_options.sendLoadCallbacks == SendCallbacks && m_identifier) - frameLoader()->notifier()->didFailToLoad(this, error); -} - -void ResourceLoader::didChangePriority(ResourceLoadPriority loadPriority) -{ - if (handle()) { - frameLoader()->client()->dispatchDidChangeResourcePriority(identifier(), loadPriority); - handle()->didChangePriority(loadPriority); - } + if (m_options.sendLoadCallbacks() == SendCallbacks && m_identifier) + frameLoader()->notifier().didFailToLoad(this, error); } void ResourceLoader::cancel() @@ -395,7 +554,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. - RefPtr<ResourceLoader> protector(this); + Ref<ResourceLoader> protect(*this); // If we re-enter cancel() from inside willCancel(), we want to pick up from where we left // off without re-running willCancel() @@ -416,7 +575,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); } @@ -442,19 +601,19 @@ ResourceError ResourceLoader::cancelledError() ResourceError ResourceLoader::blockedError() { - return frameLoader()->client()->blockedError(m_request); + return frameLoader()->client().blockedError(m_request); } ResourceError ResourceLoader::cannotShowURLError() { - return frameLoader()->client()->cannotShowURLError(m_request); + return frameLoader()->client().cannotShowURLError(m_request); } void ResourceLoader::willSendRequest(ResourceHandle*, ResourceRequest& request, const ResourceResponse& redirectResponse) { if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForRedirect(this, request, redirectResponse)) return; - willSendRequest(request, redirectResponse); + willSendRequestInternal(request, redirectResponse); } void ResourceLoader::didSendData(ResourceHandle*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) @@ -469,18 +628,14 @@ void ResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& didReceiveResponse(response); } -void ResourceLoader::didReceiveData(ResourceHandle*, const char* data, int length, int encodedDataLength) +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) { - InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceData(m_frame.get(), identifier(), encodedDataLength); didReceiveBuffer(buffer, encodedDataLength, DataPayloadBytes); - InspectorInstrumentation::didReceiveResourceData(cookie); } void ResourceLoader::didFinishLoading(ResourceHandle*, double finishTime) @@ -507,32 +662,37 @@ void ResourceLoader::cannotShowURL(ResourceHandle*) bool ResourceLoader::shouldUseCredentialStorage() { - if (m_options.allowCredentials == DoNotAllowStoredCredentials) + if (m_options.allowCredentials() == DoNotAllowStoredCredentials) return false; - RefPtr<ResourceLoader> protector(this); - return frameLoader()->client()->shouldUseCredentialStorage(documentLoader(), identifier()); + Ref<ResourceLoader> protect(*this); + return frameLoader()->client().shouldUseCredentialStorage(documentLoader(), identifier()); +} + +bool ResourceLoader::isAllowedToAskUserForCredentials() const +{ + return m_options.clientCredentialPolicy() == AskClientForAllCredentials || (m_options.clientCredentialPolicy() == DoNotAskClientForCrossOriginCredentials && 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. - RefPtr<ResourceLoader> protector(this); + Ref<ResourceLoader> protect(*this); - if (m_options.allowCredentials == AllowStoredCredentials) { - if (m_options.clientCredentialPolicy == AskClientForAllCredentials || (m_options.clientCredentialPolicy == DoNotAskClientForCrossOriginCredentials && m_frame->document()->securityOrigin()->canRequest(originalRequest().url()))) { - frameLoader()->notifier()->didReceiveAuthenticationChallenge(this, challenge); + if (m_options.allowCredentials() == AllowStoredCredentials) { + 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) +#if PLATFORM(COCOA) || USE(CFNETWORK) || USE(CURL) || PLATFORM(GTK) || PLATFORM(EFL) challenge.authenticationClient()->receivedRequestToContinueWithoutCredential(challenge); - ASSERT(!handle() || !handle()->hasAuthenticationChallenge()); + ASSERT(!m_handle || !m_handle->hasAuthenticationChallenge()); #else didFail(blockedError()); #endif @@ -542,16 +702,27 @@ void ResourceLoader::didCancelAuthenticationChallenge(const AuthenticationChalle { // 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); - frameLoader()->notifier()->didCancelAuthenticationChallenge(this, challenge); + Ref<ResourceLoader> protect(*this); + frameLoader()->notifier().didCancelAuthenticationChallenge(this, challenge); } #if USE(PROTECTION_SPACE_AUTH_CALLBACK) + bool ResourceLoader::canAuthenticateAgainstProtectionSpace(const ProtectionSpace& protectionSpace) { - RefPtr<ResourceLoader> protector(this); - return frameLoader()->client()->canAuthenticateAgainstProtectionSpace(documentLoader(), identifier(), protectionSpace); + Ref<ResourceLoader> protect(*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&) @@ -559,4 +730,28 @@ void ResourceLoader::receivedCancellation(const AuthenticationChallenge&) cancel(); } +#if PLATFORM(COCOA) && !USE(CFNETWORK) + +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) +void ResourceLoader::didCreateQuickLookHandle(QuickLookHandle& handle) +{ + m_isQuickLookResource = true; + frameLoader()->client().didCreateQuickLookHandle(handle); +} +#endif + } |