Modified: trunk/Source/WebCore/loader/DocumentLoader.cpp (146238 => 146239)
--- trunk/Source/WebCore/loader/DocumentLoader.cpp 2013-03-19 19:36:49 UTC (rev 146238)
+++ trunk/Source/WebCore/loader/DocumentLoader.cpp 2013-03-19 19:39:44 UTC (rev 146239)
@@ -51,6 +51,7 @@
#include "MainResourceLoader.h"
#include "MemoryCache.h"
#include "Page.h"
+#include "ProgressTracker.h"
#include "ResourceBuffer.h"
#include "SchemeRegistry.h"
#include "Settings.h"
@@ -112,6 +113,8 @@
, m_substituteResourceDeliveryTimer(this, &DocumentLoader::substituteResourceDeliveryTimerFired)
, m_didCreateGlobalHistoryEntry(false)
, m_timeOfLastDataReceived(0.0)
+ , m_identifierForLoadWithoutResourceLoader(0)
+ , m_dataLoadTimer(this, &DocumentLoader::handleSubstituteDataLoadNow)
, m_waitingForContentPolicy(false)
, m_applicationCacheHost(adoptPtr(new ApplicationCacheHost(this)))
{
@@ -216,7 +219,20 @@
void DocumentLoader::mainReceivedError(const ResourceError& error)
{
ASSERT(!error.isNull());
+ if (m_applicationCacheHost->maybeLoadFallbackForMainError(request(), error))
+ return;
+ if (m_identifierForLoadWithoutResourceLoader) {
+ ASSERT(!mainResourceLoader());
+ frameLoader()->client()->dispatchDidFailLoading(this, m_identifierForLoadWithoutResourceLoader, error);
+ }
+
+ // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
+ // See <rdar://problem/6304600> for more details.
+#if !USE(CF)
+ ASSERT(!m_frame->page()->defersLoading());
+#endif
+
m_applicationCacheHost->failedLoadingMainResource();
if (!frameLoader())
@@ -278,7 +294,7 @@
if (m_mainResourceLoader)
// Stop the main resource loader and let it send the cancelled message.
- m_mainResourceLoader->cancel(frameLoader->cancelledError(m_request));
+ cancelMainResourceLoad(frameLoader->cancelledError(m_request));
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.
@@ -324,9 +340,9 @@
RefPtr<DocumentLoader> protect(this);
- if (m_mainResourceLoader && m_mainResourceLoader->identifierForLoadWithoutResourceLoader()) {
- frameLoader()->notifier()->dispatchDidFinishLoading(this, m_mainResourceLoader->identifier(), finishTime);
- m_mainResourceLoader->clearIdentifierForLoadWithoutResourceLoader();
+ if (m_identifierForLoadWithoutResourceLoader) {
+ frameLoader()->notifier()->dispatchDidFinishLoading(this, m_identifierForLoadWithoutResourceLoader, finishTime);
+ m_identifierForLoadWithoutResourceLoader = 0;
}
#if USE(CONTENT_FILTERING)
@@ -389,6 +405,33 @@
return false;
}
+void DocumentLoader::handleSubstituteDataLoadNow(DocumentLoaderTimer*)
+{
+ KURL url = ""
+ if (url.isEmpty())
+ url = ""
+ ResourceResponse response(url, m_substituteData.mimeType(), m_substituteData.content()->size(), m_substituteData.textEncoding(), "");
+ responseReceived(response);
+}
+
+void DocumentLoader::startDataLoadTimer()
+{
+ m_dataLoadTimer.startOneShot(0);
+
+#if HAVE(RUNLOOP_TIMER)
+ if (SchedulePairHashSet* scheduledPairs = m_frame->page()->scheduledRunLoopPairs())
+ m_dataLoadTimer.schedule(*scheduledPairs);
+#endif
+}
+
+void DocumentLoader::handleSubstituteDataLoadSoon()
+{
+ if (deferMainResourceDataLoad())
+ startDataLoadTimer();
+ else
+ handleSubstituteDataLoadNow(0);
+}
+
void DocumentLoader::willSendRequest(ResourceRequest& newRequest, const ResourceResponse& redirectResponse)
{
// Note that there are no asserts here as there are for the other callbacks. This is due to the
@@ -442,7 +485,7 @@
ASSERT(!m_substituteData.isValid());
m_applicationCacheHost->maybeLoadMainResourceForRedirect(newRequest, m_substituteData);
if (m_substituteData.isValid())
- m_mainResourceLoader->takeIdentifierFromResourceLoader();
+ m_identifierForLoadWithoutResourceLoader = mainResourceLoader()->identifier();
}
// FIXME: Ideally we'd stop the I/O until we hear back from the navigation policy delegate
@@ -458,7 +501,7 @@
static_cast<DocumentLoader*>(argument)->continueAfterNavigationPolicy(request, shouldContinue);
}
-void DocumentLoader::continueAfterNavigationPolicy(const ResourceRequest& request, bool shouldContinue)
+void DocumentLoader::continueAfterNavigationPolicy(const ResourceRequest&, bool shouldContinue)
{
if (!shouldContinue)
stopLoadingForPolicyChange();
@@ -477,7 +520,7 @@
resourceLoader->setSendCallbackPolicy(DoNotSendCallbacks);
m_mainResourceLoader->clearResource();
resourceLoader->setSendCallbackPolicy(SendCallbacks);
- m_mainResourceLoader->handleSubstituteDataLoadSoon(request);
+ handleSubstituteDataLoadSoon();
}
}
@@ -504,7 +547,7 @@
HTTPHeaderMap::const_iterator it = response.httpHeaderFields().find(xFrameOptionHeader);
if (it != response.httpHeaderFields().end()) {
String content = it->value;
- unsigned long identifier = m_mainResourceLoader->identifier();
+ unsigned long identifier = m_identifierForLoadWithoutResourceLoader ? m_identifierForLoadWithoutResourceLoader : mainResourceLoader()->identifier();
if (frameLoader()->shouldInterruptLoadForXFrameOptions(content, response.url(), identifier)) {
InspectorInstrumentation::continueAfterXFrameOptionsDenied(m_frame, this, identifier, response);
String message = "Refused to display '" + response.url().elidedString() + "' in a frame because it set 'X-Frame-Options' to '" + content + "'.";
@@ -530,8 +573,8 @@
setResponse(response);
- if (m_mainResourceLoader->identifierForLoadWithoutResourceLoader())
- frameLoader()->notifier()->dispatchDidReceiveResponse(this, m_mainResourceLoader->identifierForLoadWithoutResourceLoader(), m_response, 0);
+ if (m_identifierForLoadWithoutResourceLoader)
+ frameLoader()->notifier()->dispatchDidReceiveResponse(this, m_identifierForLoadWithoutResourceLoader, m_response, 0);
ASSERT(!m_waitingForContentPolicy);
m_waitingForContentPolicy = true;
@@ -780,8 +823,8 @@
}
#endif
- if (m_mainResourceLoader->identifierForLoadWithoutResourceLoader())
- frameLoader()->notifier()->dispatchDidReceiveData(this, m_mainResourceLoader->identifier(), data, length, -1);
+ if (m_identifierForLoadWithoutResourceLoader)
+ frameLoader()->notifier()->dispatchDidReceiveData(this, m_identifierForLoadWithoutResourceLoader, data, length, -1);
m_applicationCacheHost->mainResourceDataReceived(data, length, -1, false);
m_timeOfLastDataReceived = monotonicallyIncreasingTime();
@@ -1311,6 +1354,15 @@
m_applicationCacheHost->maybeLoadMainResource(m_request, m_substituteData);
+ if (m_substituteData.isValid()) {
+ m_identifierForLoadWithoutResourceLoader = m_frame->page()->progress()->createUniqueIdentifier();
+ frameLoader()->notifier()->assignIdentifierToInitialRequest(m_identifierForLoadWithoutResourceLoader, this, m_request);
+ frameLoader()->notifier()->dispatchWillSendRequest(this, m_identifierForLoadWithoutResourceLoader, m_request, ResourceResponse());
+ handleSubstituteDataLoadSoon();
+ return;
+ }
+
+ ResourceRequest request(m_request);
m_mainResourceLoader->load(m_request);
if (m_request.isNull()) {
@@ -1320,19 +1372,41 @@
// a new ApplicationCacheHost.
m_applicationCacheHost = adoptPtr(new ApplicationCacheHost(this));
maybeLoadEmpty();
+ return;
}
+
+ if (!mainResourceLoader()) {
+ m_identifierForLoadWithoutResourceLoader = m_frame->page()->progress()->createUniqueIdentifier();
+ frameLoader()->notifier()->assignIdentifierToInitialRequest(m_identifierForLoadWithoutResourceLoader, this, request);
+ frameLoader()->notifier()->dispatchWillSendRequest(this, m_identifierForLoadWithoutResourceLoader, request, ResourceResponse());
+ }
+
+ // A bunch of headers are set when the underlying ResourceLoader is created, and m_request needs to include those.
+ if (mainResourceLoader())
+ request = mainResourceLoader()->originalRequest();
+ // If there was a fragment identifier on m_request, the cache will have stripped it. m_request should include
+ // the fragment identifier, so add that back in.
+ if (equalIgnoringFragmentIdentifier(m_request.url(), request.url()))
+ request.setURL(m_request.url());
+ setRequest(request);
}
void DocumentLoader::cancelMainResourceLoad(const ResourceError& error)
{
ASSERT(!error.isNull());
+ RefPtr<DocumentLoader> protect(this);
+ m_dataLoadTimer.stop();
if (m_waitingForContentPolicy) {
frameLoader()->policyChecker()->cancelCheck();
ASSERT(m_waitingForContentPolicy);
m_waitingForContentPolicy = false;
}
- m_mainResourceLoader->cancel(error);
+
+ if (mainResourceLoader())
+ mainResourceLoader()->cancel(error);
+
+ mainReceivedError(error);
}
void DocumentLoader::subresourceLoaderFinishedLoadingOnePart(ResourceLoader* loader)
Modified: trunk/Source/WebCore/loader/MainResourceLoader.cpp (146238 => 146239)
--- trunk/Source/WebCore/loader/MainResourceLoader.cpp 2013-03-19 19:36:49 UTC (rev 146238)
+++ trunk/Source/WebCore/loader/MainResourceLoader.cpp 2013-03-19 19:39:44 UTC (rev 146239)
@@ -66,9 +66,7 @@
namespace WebCore {
MainResourceLoader::MainResourceLoader(DocumentLoader* documentLoader)
- : m_dataLoadTimer(this, &MainResourceLoader::handleSubstituteDataLoadNow)
- , m_documentLoader(documentLoader)
- , m_identifierForLoadWithoutResourceLoader(0)
+ : m_documentLoader(documentLoader)
{
}
@@ -82,42 +80,6 @@
return adoptRef(new MainResourceLoader(documentLoader));
}
-void MainResourceLoader::receivedError(const ResourceError& error)
-{
- // Calling receivedMainResourceError will likely result in the last reference to this object to go away.
- RefPtr<MainResourceLoader> protect(this);
- RefPtr<Frame> protectFrame(m_documentLoader->frame());
-
- if (m_identifierForLoadWithoutResourceLoader) {
- ASSERT(!loader());
- frameLoader()->client()->dispatchDidFailLoading(documentLoader(), m_identifierForLoadWithoutResourceLoader, error);
- }
-
- // It is important that we call DocumentLoader::mainReceivedError before calling
- // ResourceLoadNotifier::didFailToLoad because mainReceivedError clears out the relevant
- // document loaders. Also, mainReceivedError ends up calling a FrameLoadDelegate method
- // and didFailToLoad calls a ResourceLoadDelegate method and they need to be in the correct order.
- documentLoader()->mainReceivedError(error);
-}
-
-void MainResourceLoader::cancel()
-{
- cancel(ResourceError());
-}
-
-void MainResourceLoader::cancel(const ResourceError& error)
-{
- RefPtr<MainResourceLoader> protect(this);
- ResourceError resourceError = error.isNull() ? frameLoader()->cancelledError(request()) : error;
-
- m_dataLoadTimer.stop();
- if (loader())
- loader()->cancel(resourceError);
-
- clearResource();
- receivedError(resourceError);
-}
-
void MainResourceLoader::clearResource()
{
if (m_resource) {
@@ -177,18 +139,7 @@
return;
}
#endif
-
- const ResourceError& error = m_resource->resourceError();
- if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForMainError(request(), error))
- return;
-
- // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
- // See <rdar://problem/6304600> for more details.
-#if !USE(CF)
- ASSERT(!defersLoading());
-#endif
-
- receivedError(error);
+ m_documentLoader->mainReceivedError(m_resource->resourceError());
}
void MainResourceLoader::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
@@ -196,59 +147,13 @@
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Loader);
info.addMember(m_resource, "resource");
info.addMember(m_initialRequest, "initialRequest");
- info.addMember(m_dataLoadTimer, "dataLoadTimer");
info.addMember(m_documentLoader, "documentLoader");
}
-void MainResourceLoader::handleSubstituteDataLoadNow(MainResourceLoaderTimer*)
-{
- RefPtr<MainResourceLoader> protect(this);
-
- KURL url = ""
- if (url.isEmpty())
- url = ""
-
- // Clear the initial request here so that subsequent entries into the
- // loader will not think there's still a deferred load left to do.
- m_initialRequest = ResourceRequest();
-
- ResourceResponse response(url, m_documentLoader->substituteData().mimeType(), m_documentLoader->substituteData().content()->size(), m_documentLoader->substituteData().textEncoding(), "");
- responseReceived(0, response);
-}
-
-void MainResourceLoader::startDataLoadTimer()
-{
- m_dataLoadTimer.startOneShot(0);
-
-#if HAVE(RUNLOOP_TIMER)
- if (SchedulePairHashSet* scheduledPairs = m_documentLoader->frame()->page()->scheduledRunLoopPairs())
- m_dataLoadTimer.schedule(*scheduledPairs);
-#endif
-}
-
-void MainResourceLoader::handleSubstituteDataLoadSoon(const ResourceRequest& r)
-{
- m_initialRequest = r;
-
- if (m_documentLoader->deferMainResourceDataLoad())
- startDataLoadTimer();
- else
- handleSubstituteDataLoadNow(0);
-}
-
void MainResourceLoader::load(const ResourceRequest& initialRequest)
{
- RefPtr<MainResourceLoader> protect(this);
ResourceRequest request(initialRequest);
- if (m_documentLoader->substituteData().isValid()) {
- m_identifierForLoadWithoutResourceLoader = m_documentLoader->frame()->page()->progress()->createUniqueIdentifier();
- frameLoader()->notifier()->assignIdentifierToInitialRequest(m_identifierForLoadWithoutResourceLoader, documentLoader(), request);
- frameLoader()->notifier()->dispatchWillSendRequest(documentLoader(), m_identifierForLoadWithoutResourceLoader, request, ResourceResponse());
- handleSubstituteDataLoadSoon(request);
- return;
- }
-
DEFINE_STATIC_LOCAL(ResourceLoaderOptions, mainResourceLoadOptions,
(SendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck));
CachedResourceRequest cachedResourceRequest(request, mainResourceLoadOptions);
@@ -257,21 +162,7 @@
documentLoader()->setRequest(ResourceRequest());
return;
}
- if (!loader()) {
- m_identifierForLoadWithoutResourceLoader = m_documentLoader->frame()->page()->progress()->createUniqueIdentifier();
- frameLoader()->notifier()->assignIdentifierToInitialRequest(m_identifierForLoadWithoutResourceLoader, documentLoader(), request);
- frameLoader()->notifier()->dispatchWillSendRequest(documentLoader(), m_identifierForLoadWithoutResourceLoader, request, ResourceResponse());
- }
m_resource->addClient(this);
-
- // A bunch of headers are set when the underlying ResourceLoader is created, and DocumentLoader::m_request needs to include those.
- if (loader())
- request = loader()->originalRequest();
- // If there was a fragment identifier on initialRequest, the cache will have stripped it. DocumentLoader::m_request should include
- // the fragment identifier, so add that back in.
- if (equalIgnoringFragmentIdentifier(initialRequest.url(), request.url()))
- request.setURL(initialRequest.url());
- documentLoader()->setRequest(request);
}
void MainResourceLoader::setDefersLoading(bool defers)
@@ -298,9 +189,6 @@
unsigned long MainResourceLoader::identifier() const
{
- ASSERT(!m_identifierForLoadWithoutResourceLoader || !loader() || !loader()->identifier());
- if (m_identifierForLoadWithoutResourceLoader)
- return m_identifierForLoadWithoutResourceLoader;
if (ResourceLoader* resourceLoader = loader())
return resourceLoader->identifier();
return 0;
Modified: trunk/Source/WebCore/loader/MainResourceLoader.h (146238 => 146239)
--- trunk/Source/WebCore/loader/MainResourceLoader.h 2013-03-19 19:36:49 UTC (rev 146238)
+++ trunk/Source/WebCore/loader/MainResourceLoader.h 2013-03-19 19:39:44 UTC (rev 146239)
@@ -36,12 +36,6 @@
#include "SubstituteData.h"
#include <wtf/Forward.h>
-#if HAVE(RUNLOOP_TIMER)
-#include <wtf/RunLoopTimer.h>
-#else
-#include "Timer.h"
-#endif
-
namespace WebCore {
class ResourceRequest;
@@ -53,30 +47,18 @@
virtual ~MainResourceLoader();
void load(const ResourceRequest&);
- void cancel();
- void cancel(const ResourceError&);
ResourceLoader* loader() const;
PassRefPtr<ResourceBuffer> resourceData();
void setDefersLoading(bool);
void setDataBufferingPolicy(DataBufferingPolicy);
-#if HAVE(RUNLOOP_TIMER)
- typedef RunLoopTimer<MainResourceLoader> MainResourceLoaderTimer;
-#else
- typedef Timer<MainResourceLoader> MainResourceLoaderTimer;
-#endif
-
CachedRawResource* cachedMainResource() { return m_resource.get(); }
- unsigned long identifierForLoadWithoutResourceLoader() const { return m_identifierForLoadWithoutResourceLoader; }
- void clearIdentifierForLoadWithoutResourceLoader() { m_identifierForLoadWithoutResourceLoader = 0; }
unsigned long identifier() const;
void reportMemoryUsage(MemoryObjectInfo*) const;
- void takeIdentifierFromResourceLoader() { m_identifierForLoadWithoutResourceLoader = identifier(); }
- void handleSubstituteDataLoadSoon(const ResourceRequest&);
void clearResource();
private:
@@ -87,16 +69,6 @@
virtual void dataReceived(CachedResource*, const char* data, int dataLength) OVERRIDE;
virtual void notifyFinished(CachedResource*) OVERRIDE;
- void handleSubstituteDataLoadNow(MainResourceLoaderTimer*);
-
- void startDataLoadTimer();
-
- void receivedError(const ResourceError&);
-
-#if PLATFORM(QT)
- void substituteMIMETypeFromPluginDatabase(const ResourceResponse&);
-#endif
-
FrameLoader* frameLoader() const;
DocumentLoader* documentLoader() const { return m_documentLoader.get(); }
@@ -108,10 +80,7 @@
ResourceRequest m_initialRequest;
- MainResourceLoaderTimer m_dataLoadTimer;
RefPtr<DocumentLoader> m_documentLoader;
-
- unsigned long m_identifierForLoadWithoutResourceLoader;
};
}