summaryrefslogtreecommitdiff
path: root/Source/WebCore/loader/ResourceLoader.cpp
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2013-09-13 12:51:20 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-19 20:50:05 +0200
commitd441d6f39bb846989d95bcf5caf387b42414718d (patch)
treee367e64a75991c554930278175d403c072de6bb8 /Source/WebCore/loader/ResourceLoader.cpp
parent0060b2994c07842f4c59de64b5e3e430525c4b90 (diff)
downloadqtwebkit-d441d6f39bb846989d95bcf5caf387b42414718d.tar.gz
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit. Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/WebCore/loader/ResourceLoader.cpp')
-rw-r--r--Source/WebCore/loader/ResourceLoader.cpp202
1 files changed, 96 insertions, 106 deletions
diff --git a/Source/WebCore/loader/ResourceLoader.cpp b/Source/WebCore/loader/ResourceLoader.cpp
index e499d42c5..8fc4a8476 100644
--- a/Source/WebCore/loader/ResourceLoader.cpp
+++ b/Source/WebCore/loader/ResourceLoader.cpp
@@ -32,6 +32,7 @@
#include "ApplicationCacheHost.h"
#include "AsyncFileStream.h"
+#include "AuthenticationChallenge.h"
#include "DocumentLoader.h"
#include "Frame.h"
#include "FrameLoader.h"
@@ -51,19 +52,13 @@
namespace WebCore {
-PassRefPtr<ResourceBuffer> ResourceLoader::resourceData()
-{
- return m_resourceData;
-}
-
ResourceLoader::ResourceLoader(Frame* frame, ResourceLoaderOptions options)
: m_frame(frame)
, m_documentLoader(frame->loader()->activeDocumentLoader())
, m_identifier(0)
, m_reachedTerminalState(false)
- , m_calledWillCancel(false)
- , m_cancelled(false)
, m_notifiedLoadComplete(false)
+ , m_cancellationStatus(NotCancelled)
, m_defersLoading(frame->page()->defersLoading())
, m_options(options)
{
@@ -91,13 +86,8 @@ void ResourceLoader::releaseResources()
// the resources to prevent a double dealloc of WebView <rdar://problem/4372628>
m_reachedTerminalState = true;
-#if USE(PLATFORM_STRATEGIES)
platformStrategies()->loaderStrategy()->resourceLoadScheduler()->remove(this);
-#endif
m_identifier = 0;
-#if !USE(PLATFORM_STRATEGIES)
- resourceLoadScheduler()->remove(this);
-#endif
if (m_handle) {
// Clear out the ResourceHandle's client so that it doesn't try to call
@@ -154,7 +144,7 @@ void ResourceLoader::start()
ASSERT(m_deferredRequest.isNull());
#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
- if (m_documentLoader->scheduleArchiveLoad(this, m_request, m_request.url()))
+ if (m_documentLoader->scheduleArchiveLoad(this, m_request))
return;
#endif
@@ -189,30 +179,34 @@ FrameLoader* ResourceLoader::frameLoader() const
return m_frame->loader();
}
-void ResourceLoader::setShouldBufferData(DataBufferingPolicy shouldBufferData)
+void ResourceLoader::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy)
{
- m_options.shouldBufferData = shouldBufferData;
+ m_options.dataBufferingPolicy = dataBufferingPolicy;
// Reset any already buffered data
- if (!shouldBufferData)
+ if (dataBufferingPolicy == DoNotBufferData)
m_resourceData = 0;
}
-void ResourceLoader::addData(const char* data, int length, bool allAtOnce)
+void ResourceLoader::addDataOrBuffer(const char* data, int length, SharedBuffer* buffer, DataPayloadType dataPayloadType)
{
- if (m_options.shouldBufferData == DoNotBufferData)
+ if (m_options.dataBufferingPolicy == DoNotBufferData)
return;
- if (allAtOnce) {
- m_resourceData = ResourceBuffer::create(data, length);
+ if (dataPayloadType == DataPayloadWholeResource) {
+ m_resourceData = buffer ? ResourceBuffer::adoptSharedBuffer(buffer) : ResourceBuffer::create(data, length);
return;
}
if (!m_resourceData)
- m_resourceData = ResourceBuffer::create(data, length);
- else
- m_resourceData->append(data, length);
+ m_resourceData = buffer ? ResourceBuffer::adoptSharedBuffer(buffer) : ResourceBuffer::create(data, length);
+ else {
+ if (buffer)
+ m_resourceData->append(buffer);
+ else
+ m_resourceData->append(data, length);
+ }
}
void ResourceLoader::clearResourceData()
@@ -234,23 +228,31 @@ void ResourceLoader::willSendRequest(ResourceRequest& request, const ResourceRes
ASSERT(!m_reachedTerminalState);
+ // 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 (m_options.sendLoadCallbacks == SendCallbacks) {
- if (!m_identifier) {
- m_identifier = m_frame->page()->progress()->createUniqueIdentifier();
+ if (createdResourceIdentifier)
frameLoader()->notifier()->assignIdentifierToInitialRequest(m_identifier, documentLoader(), request);
- }
frameLoader()->notifier()->willSendRequest(this, request, redirectResponse);
}
+#if ENABLE(INSPECTOR)
+ else
+ InspectorInstrumentation::willSendRequest(m_frame.get(), m_identifier, m_frame->loader()->documentLoader(), request, redirectResponse);
+#endif
- if (!redirectResponse.isNull()) {
-#if USE(PLATFORM_STRATEGIES)
+ if (!redirectResponse.isNull())
platformStrategies()->loaderStrategy()->resourceLoadScheduler()->crossOriginRedirectReceived(this, request.url());
-#else
- resourceLoadScheduler()->crossOriginRedirectReceived(this, request.url());
-#endif
- }
+
m_request = request;
+
+ if (!redirectResponse.isNull() && !m_documentLoader->isCommitted())
+ frameLoader()->client()->dispatchDidReceiveServerRedirectForProvisionalLoad();
}
void ResourceLoader::didSendData(unsigned long long, unsigned long long)
@@ -274,7 +276,7 @@ void ResourceLoader::didReceiveResponse(const ResourceResponse& r)
frameLoader()->notifier()->didReceiveResponse(this, m_response);
}
-void ResourceLoader::didReceiveData(const char* data, int length, long long encodedDataLength, bool allAtOnce)
+void ResourceLoader::didReceiveData(const char* data, int 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
@@ -282,21 +284,36 @@ void ResourceLoader::didReceiveData(const char* data, int length, long long enco
// ASSERT(con == connection);
// ASSERT(!m_reachedTerminalState);
+ didReceiveDataOrBuffer(data, length, 0, encodedDataLength, dataPayloadType);
+}
+
+void ResourceLoader::didReceiveBuffer(PassRefPtr<SharedBuffer> buffer, long long encodedDataLength, DataPayloadType dataPayloadType)
+{
+ didReceiveDataOrBuffer(0, 0, buffer, encodedDataLength, dataPayloadType);
+}
+
+void ResourceLoader::didReceiveDataOrBuffer(const char* data, int 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);
+ RefPtr<SharedBuffer> buffer = prpBuffer;
- addData(data, length, allAtOnce);
+ 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.
if (m_options.sendLoadCallbacks == SendCallbacks && m_frame)
- frameLoader()->notifier()->didReceiveData(this, data, length, static_cast<int>(encodedDataLength));
+ 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.shouldBufferData == DoNotBufferData)
+ if (m_options.dataBufferingPolicy == DoNotBufferData)
return;
ASSERT(!m_resourceData);
@@ -309,7 +326,7 @@ void ResourceLoader::didFinishLoading(double finishTime)
// If the load has been cancelled by a delegate in response to didFinishLoad(), do not release
// the resources a second time, they have been released by cancel.
- if (m_cancelled)
+ if (wasCancelled())
return;
releaseResources();
}
@@ -318,7 +335,7 @@ void ResourceLoader::didFinishLoadingOnePart(double finishTime)
{
// If load has been cancelled after finishing (which could happen with a
// JavaScript that changes the window location), do nothing.
- if (m_cancelled)
+ if (wasCancelled())
return;
ASSERT(!m_reachedTerminalState);
@@ -331,7 +348,7 @@ void ResourceLoader::didFinishLoadingOnePart(double finishTime)
void ResourceLoader::didFail(const ResourceError& error)
{
- if (m_cancelled)
+ if (wasCancelled())
return;
ASSERT(!m_reachedTerminalState);
@@ -339,16 +356,28 @@ void ResourceLoader::didFail(const ResourceError& error)
// anything including possibly derefing this; one example of this is Radar 3266216.
RefPtr<ResourceLoader> protector(this);
+ cleanupForError(error);
+ releaseResources();
+}
+
+void ResourceLoader::cleanupForError(const ResourceError& error)
+{
if (FormData* data = m_request.httpBody())
data->removeGeneratedFilesIfNeeded();
- if (!m_notifiedLoadComplete) {
- m_notifiedLoadComplete = true;
- if (m_options.sendLoadCallbacks == SendCallbacks)
- frameLoader()->notifier()->didFailToLoad(this, error);
- }
+ if (m_notifiedLoadComplete)
+ return;
+ m_notifiedLoadComplete = true;
+ if (m_options.sendLoadCallbacks == SendCallbacks && m_identifier)
+ frameLoader()->notifier()->didFailToLoad(this, error);
+}
- releaseResources();
+void ResourceLoader::didChangePriority(ResourceLoadPriority loadPriority)
+{
+ if (handle()) {
+ frameLoader()->client()->dispatchDidChangeResourcePriority(identifier(), loadPriority);
+ handle()->didChangePriority(loadPriority);
+ }
}
void ResourceLoader::cancel()
@@ -370,19 +399,16 @@ void ResourceLoader::cancel(const ResourceError& error)
// If we re-enter cancel() from inside willCancel(), we want to pick up from where we left
// off without re-running willCancel()
- if (!m_calledWillCancel) {
- m_calledWillCancel = true;
+ if (m_cancellationStatus == NotCancelled) {
+ m_cancellationStatus = CalledWillCancel;
willCancel(nonNullError);
}
// If we re-enter cancel() from inside didFailToLoad(), we want to pick up from where we
// left off without redoing any of this work.
- if (!m_cancelled) {
- m_cancelled = true;
-
- if (FormData* data = m_request.httpBody())
- data->removeGeneratedFilesIfNeeded();
+ if (m_cancellationStatus == CalledWillCancel) {
+ m_cancellationStatus = Cancelled;
if (m_handle)
m_handle->clearAuthentication();
@@ -392,9 +418,7 @@ void ResourceLoader::cancel(const ResourceError& error)
m_handle->cancel();
m_handle = 0;
}
-
- if (m_options.sendLoadCallbacks == SendCallbacks && m_identifier && !m_notifiedLoadComplete)
- frameLoader()->notifier()->didFailToLoad(this, nonNullError);
+ cleanupForError(nonNullError);
}
// If cancel() completed from within the call to willCancel() or didFailToLoad(),
@@ -403,7 +427,11 @@ void ResourceLoader::cancel(const ResourceError& error)
return;
didCancel(nonNullError);
-
+
+ if (m_cancellationStatus == FinishedCancel)
+ return;
+ m_cancellationStatus = FinishedCancel;
+
releaseResources();
}
@@ -444,7 +472,14 @@ void ResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse&
void ResourceLoader::didReceiveData(ResourceHandle*, const char* data, int length, int encodedDataLength)
{
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceData(m_frame.get(), identifier(), encodedDataLength);
- didReceiveData(data, length, encodedDataLength, false);
+ 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);
}
@@ -481,14 +516,14 @@ bool ResourceLoader::shouldUseCredentialStorage()
void ResourceLoader::didReceiveAuthenticationChallenge(const AuthenticationChallenge& challenge)
{
- ASSERT(!handle() || handle()->hasAuthenticationChallenge());
+ 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())) {
+ if (m_options.clientCredentialPolicy == AskClientForAllCredentials || (m_options.clientCredentialPolicy == DoNotAskClientForCrossOriginCredentials && m_frame->document()->securityOrigin()->canRequest(originalRequest().url()))) {
frameLoader()->notifier()->didReceiveAuthenticationChallenge(this, challenge);
return;
}
@@ -496,8 +531,8 @@ void ResourceLoader::didReceiveAuthenticationChallenge(const AuthenticationChall
// 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)
- handle()->receivedRequestToContinueWithoutCredential(challenge);
- ASSERT(!handle()->hasAuthenticationChallenge());
+ challenge.authenticationClient()->receivedRequestToContinueWithoutCredential(challenge);
+ ASSERT(!handle() || !handle()->hasAuthenticationChallenge());
#else
didFail(blockedError());
#endif
@@ -524,49 +559,4 @@ void ResourceLoader::receivedCancellation(const AuthenticationChallenge&)
cancel();
}
-void ResourceLoader::willCacheResponse(ResourceHandle*, CacheStoragePolicy& policy)
-{
- // <rdar://problem/7249553> - There are reports of crashes with this method being called
- // with a null m_frame->settings(), which can only happen if the frame doesn't have a page.
- // Sadly we have no reproducible cases of this.
- // We think that any frame without a page shouldn't have any loads happening in it, yet
- // there is at least one code path where that is not true.
- ASSERT(m_frame->settings());
-
- // When in private browsing mode, prevent caching to disk
- if (policy == StorageAllowed && m_frame->settings() && m_frame->settings()->privateBrowsingEnabled())
- policy = StorageAllowedInMemoryOnly;
-}
-
-#if ENABLE(BLOB)
-AsyncFileStream* ResourceLoader::createAsyncFileStream(FileStreamClient* client)
-{
- // It is OK to simply return a pointer since AsyncFileStream::create adds an extra ref.
- return AsyncFileStream::create(m_frame->document()->scriptExecutionContext(), client).get();
-}
-#endif
-
-void ResourceLoader::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
-{
- MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Loader);
- info.addMember(m_handle.get());
- info.addMember(m_frame);
- info.addMember(m_documentLoader);
- info.addMember(m_request);
- info.addMember(m_originalRequest);
- info.addMember(m_resourceData);
- info.addMember(m_deferredRequest);
- info.addMember(m_options);
-}
-
-#if PLATFORM(MAC)
-void ResourceLoader::setIdentifier(unsigned long identifier)
-{
- // FIXME (NetworkProcess): This is temporary to allow WebKit to directly set the identifier on a ResourceLoader.
- // More permanently we'll want the identifier to be piped through ResourceLoader::init/start so
- // it always has it, especially in willSendRequest.
- m_identifier = identifier;
-}
-#endif
-
}