summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/loader
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/loader')
-rw-r--r--Source/WebCore/loader/DocumentLoader.cpp40
-rw-r--r--Source/WebCore/loader/DocumentLoader.h12
-rw-r--r--Source/WebCore/loader/DocumentThreadableLoader.cpp14
-rw-r--r--Source/WebCore/loader/DocumentThreadableLoader.h6
-rw-r--r--Source/WebCore/loader/DocumentThreadableLoaderClient.h3
-rw-r--r--Source/WebCore/loader/EmptyClients.h12
-rw-r--r--Source/WebCore/loader/FrameLoader.cpp185
-rw-r--r--Source/WebCore/loader/FrameLoader.h11
-rw-r--r--Source/WebCore/loader/FrameLoaderClient.h4
-rw-r--r--Source/WebCore/loader/FrameLoaderTypes.h2
-rw-r--r--Source/WebCore/loader/MainResourceLoader.cpp4
-rw-r--r--Source/WebCore/loader/PolicyCallback.cpp1
-rw-r--r--Source/WebCore/loader/ResourceLoadNotifier.cpp22
-rw-r--r--Source/WebCore/loader/ResourceLoadNotifier.h6
-rw-r--r--Source/WebCore/loader/ResourceLoadScheduler.cpp7
-rw-r--r--Source/WebCore/loader/ResourceLoadScheduler.h3
-rw-r--r--Source/WebCore/loader/ResourceLoader.h6
-rw-r--r--Source/WebCore/loader/SubframeLoader.cpp51
-rw-r--r--Source/WebCore/loader/SubframeLoader.h7
-rw-r--r--Source/WebCore/loader/SubresourceLoader.cpp20
-rw-r--r--Source/WebCore/loader/SubresourceLoader.h9
-rw-r--r--Source/WebCore/loader/ThreadableLoaderClientWrapper.h158
-rw-r--r--Source/WebCore/loader/WorkerThreadableLoader.cpp16
-rw-r--r--Source/WebCore/loader/WorkerThreadableLoader.h4
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCache.cpp25
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCache.h4
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp15
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCacheHost.h7
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCacheResource.cpp3
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCacheResource.h10
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp225
-rw-r--r--Source/WebCore/loader/appcache/ApplicationCacheStorage.h7
-rw-r--r--Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp6
-rw-r--r--Source/WebCore/loader/cache/CachedFont.cpp4
-rw-r--r--Source/WebCore/loader/cache/CachedFont.h3
-rw-r--r--Source/WebCore/loader/cache/CachedImage.cpp10
-rw-r--r--Source/WebCore/loader/cache/CachedImage.h2
-rw-r--r--Source/WebCore/loader/cache/CachedResource.cpp33
-rw-r--r--Source/WebCore/loader/cache/CachedResource.h7
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.cpp32
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.h3
-rw-r--r--Source/WebCore/loader/cache/CachedScript.cpp14
-rw-r--r--Source/WebCore/loader/cache/CachedScript.h2
-rw-r--r--Source/WebCore/loader/cf/SubresourceLoaderCF.cpp53
-rw-r--r--Source/WebCore/loader/icon/IconDatabase.cpp184
-rw-r--r--Source/WebCore/loader/icon/IconDatabase.h92
-rw-r--r--Source/WebCore/loader/icon/IconDatabaseBase.cpp69
-rw-r--r--Source/WebCore/loader/icon/IconDatabaseBase.h221
-rw-r--r--Source/WebCore/loader/icon/IconDatabaseClient.h19
-rw-r--r--Source/WebCore/loader/icon/IconDatabaseNone.cpp218
-rw-r--r--Source/WebCore/loader/mac/ResourceLoaderMac.mm42
51 files changed, 1256 insertions, 657 deletions
diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp
index e223765..121045b 100644
--- a/Source/WebCore/loader/DocumentLoader.cpp
+++ b/Source/WebCore/loader/DocumentLoader.cpp
@@ -112,6 +112,10 @@ FrameLoader* DocumentLoader::frameLoader() const
DocumentLoader::~DocumentLoader()
{
ASSERT(!m_frame || frameLoader()->activeDocumentLoader() != this || !frameLoader()->isLoading());
+ if (m_iconLoadDecisionCallback)
+ m_iconLoadDecisionCallback->invalidate();
+ if (m_iconDataCallback)
+ m_iconDataCallback->invalidate();
}
PassRefPtr<SharedBuffer> DocumentLoader::mainResourceData() const
@@ -836,7 +840,41 @@ void DocumentLoader::transferLoadingResourcesFromPage(Page* oldPage)
void DocumentLoader::iconLoadDecisionAvailable()
{
if (m_frame)
- m_frame->loader()->iconLoadDecisionAvailable();
+ m_frame->loader()->iconLoadDecisionReceived(iconDatabase().synchronousLoadDecisionForIconURL(KURL(frameLoader()->iconURL()), this));
}
+static void iconLoadDecisionCallback(IconLoadDecision decision, void* context)
+{
+ static_cast<DocumentLoader*>(context)->continueIconLoadWithDecision(decision);
+}
+
+void DocumentLoader::getIconLoadDecisionForIconURL(const String& urlString)
+{
+ if (m_iconLoadDecisionCallback)
+ m_iconLoadDecisionCallback->invalidate();
+ m_iconLoadDecisionCallback = IconLoadDecisionCallback::create(this, iconLoadDecisionCallback);
+ iconDatabase().loadDecisionForIconURL(urlString, m_iconLoadDecisionCallback);
+}
+
+void DocumentLoader::continueIconLoadWithDecision(IconLoadDecision decision)
+{
+ ASSERT(m_iconLoadDecisionCallback);
+ m_iconLoadDecisionCallback = 0;
+ if (m_frame)
+ m_frame->loader()->continueIconLoadWithDecision(decision);
+}
+
+static void iconDataCallback(SharedBuffer*, void*)
+{
+ // FIXME: Implement this once we know what parts of WebCore actually need the icon data returned.
}
+
+void DocumentLoader::getIconDataForIconURL(const String& urlString)
+{
+ if (m_iconDataCallback)
+ m_iconDataCallback->invalidate();
+ m_iconDataCallback = IconDataCallback::create(this, iconDataCallback);
+ iconDatabase().iconDataForIconURL(urlString, m_iconDataCallback);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/loader/DocumentLoader.h b/Source/WebCore/loader/DocumentLoader.h
index 8e9ab8f..1f88272 100644
--- a/Source/WebCore/loader/DocumentLoader.h
+++ b/Source/WebCore/loader/DocumentLoader.h
@@ -31,6 +31,7 @@
#include "DocumentLoadTiming.h"
#include "DocumentWriter.h"
+#include "IconDatabaseBase.h"
#include "NavigationAction.h"
#include "ResourceError.h"
#include "ResourceRequest.h"
@@ -182,7 +183,7 @@ namespace WebCore {
String clientRedirectDestinationForHistory() const { return urlForHistory(); }
void setClientRedirectSourceForHistory(const String& clientedirectSourceForHistory) { m_clientRedirectSourceForHistory = clientedirectSourceForHistory; }
- String serverRedirectSourceForHistory() const { return urlForHistory() == url() ? String() : urlForHistory(); } // null if no server redirect occurred.
+ String serverRedirectSourceForHistory() const { return urlForHistory() == url() ? String() : urlForHistory().string(); } // null if no server redirect occurred.
String serverRedirectDestinationForHistory() const { return url(); }
bool didCreateGlobalHistoryEntry() const { return m_didCreateGlobalHistoryEntry; }
@@ -193,8 +194,14 @@ namespace WebCore {
bool startLoadingMainResource(unsigned long identifier);
void cancelMainResourceLoad(const ResourceError&);
+ // Support iconDatabase in synchronous mode.
void iconLoadDecisionAvailable();
+ // Support iconDatabase in asynchronous mode.
+ void continueIconLoadWithDecision(IconLoadDecision);
+ void getIconLoadDecisionForIconURL(const String&);
+ void getIconDataForIconURL(const String&);
+
bool isLoadingMainResource() const;
bool isLoadingSubresources() const;
bool isLoadingPlugIns() const;
@@ -326,6 +333,9 @@ namespace WebCore {
bool m_didCreateGlobalHistoryEntry;
DocumentLoadTiming m_documentLoadTiming;
+
+ RefPtr<IconLoadDecisionCallback> m_iconLoadDecisionCallback;
+ RefPtr<IconDataCallback> m_iconDataCallback;
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
friend class ApplicationCacheHost; // for substitute resource delivery
diff --git a/Source/WebCore/loader/DocumentThreadableLoader.cpp b/Source/WebCore/loader/DocumentThreadableLoader.cpp
index 732a84e..73c3e80 100644
--- a/Source/WebCore/loader/DocumentThreadableLoader.cpp
+++ b/Source/WebCore/loader/DocumentThreadableLoader.cpp
@@ -51,27 +51,30 @@ namespace WebCore {
void DocumentThreadableLoader::loadResourceSynchronously(Document* document, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options)
{
// The loader will be deleted as soon as this function exits.
- RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, &client, LoadSynchronously, request, options));
+ RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, &client, LoadSynchronously, request, options, String()));
ASSERT(loader->hasOneRef());
}
-PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document* document, ThreadableLoaderClient* client, const ResourceRequest& request, const ThreadableLoaderOptions& options)
+PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document* document, ThreadableLoaderClient* client, const ResourceRequest& request, const ThreadableLoaderOptions& options, const String& optionalOutgoingReferrer)
{
- RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, client, LoadAsynchronously, request, options));
+ RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, client, LoadAsynchronously, request, options, optionalOutgoingReferrer));
if (!loader->m_loader)
loader = 0;
return loader.release();
}
-DocumentThreadableLoader::DocumentThreadableLoader(Document* document, ThreadableLoaderClient* client, BlockingBehavior blockingBehavior, const ResourceRequest& request, const ThreadableLoaderOptions& options)
+DocumentThreadableLoader::DocumentThreadableLoader(Document* document, ThreadableLoaderClient* client, BlockingBehavior blockingBehavior, const ResourceRequest& request, const ThreadableLoaderOptions& options, const String& optionalOutgoingReferrer)
: m_client(client)
, m_document(document)
, m_options(options)
+ , m_optionalOutgoingReferrer(optionalOutgoingReferrer)
, m_sameOriginRequest(document->securityOrigin()->canRequest(request.url()))
, m_async(blockingBehavior == LoadAsynchronously)
{
ASSERT(document);
ASSERT(client);
+ // Setting an outgoing referer is only supported in the async code path.
+ ASSERT(m_async || m_optionalOutgoingReferrer.isEmpty());
if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) {
loadRequest(request, DoSecurityCheck);
@@ -346,7 +349,8 @@ void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Secur
// Clear the loader so that any callbacks from SubresourceLoader::create will not have the old loader.
m_loader = 0;
- m_loader = resourceLoadScheduler()->scheduleSubresourceLoad(m_document->frame(), this, request, ResourceLoadPriorityMedium, securityCheck, sendLoadCallbacks, sniffContent);
+ m_loader = resourceLoadScheduler()->scheduleSubresourceLoad(m_document->frame(), this, request, ResourceLoadPriorityMedium, securityCheck, sendLoadCallbacks,
+ sniffContent, m_optionalOutgoingReferrer);
return;
}
diff --git a/Source/WebCore/loader/DocumentThreadableLoader.h b/Source/WebCore/loader/DocumentThreadableLoader.h
index 94884ce..c511306 100644
--- a/Source/WebCore/loader/DocumentThreadableLoader.h
+++ b/Source/WebCore/loader/DocumentThreadableLoader.h
@@ -39,6 +39,7 @@
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
+#include <wtf/text/WTFString.h>
namespace WebCore {
class Document;
@@ -50,7 +51,7 @@ namespace WebCore {
WTF_MAKE_FAST_ALLOCATED;
public:
static void loadResourceSynchronously(Document*, const ResourceRequest&, ThreadableLoaderClient&, const ThreadableLoaderOptions&);
- static PassRefPtr<DocumentThreadableLoader> create(Document*, ThreadableLoaderClient*, const ResourceRequest&, const ThreadableLoaderOptions&);
+ static PassRefPtr<DocumentThreadableLoader> create(Document*, ThreadableLoaderClient*, const ResourceRequest&, const ThreadableLoaderOptions&, const String& optionalOutgoingReferrer = String());
virtual ~DocumentThreadableLoader();
virtual void cancel();
@@ -69,7 +70,7 @@ namespace WebCore {
LoadAsynchronously
};
- DocumentThreadableLoader(Document*, ThreadableLoaderClient*, BlockingBehavior blockingBehavior, const ResourceRequest&, const ThreadableLoaderOptions& options);
+ DocumentThreadableLoader(Document*, ThreadableLoaderClient*, BlockingBehavior, const ResourceRequest&, const ThreadableLoaderOptions&, const String& optionalOutgoingReferrer);
virtual void willSendRequest(SubresourceLoader*, ResourceRequest&, const ResourceResponse& redirectResponse);
virtual void didSendData(SubresourceLoader*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
@@ -97,6 +98,7 @@ namespace WebCore {
ThreadableLoaderClient* m_client;
Document* m_document;
ThreadableLoaderOptions m_options;
+ String m_optionalOutgoingReferrer;
bool m_sameOriginRequest;
bool m_async;
OwnPtr<ResourceRequest> m_actualRequest; // non-null during Access Control preflight checks
diff --git a/Source/WebCore/loader/DocumentThreadableLoaderClient.h b/Source/WebCore/loader/DocumentThreadableLoaderClient.h
index 4551b84..146a166 100644
--- a/Source/WebCore/loader/DocumentThreadableLoaderClient.h
+++ b/Source/WebCore/loader/DocumentThreadableLoaderClient.h
@@ -45,6 +45,9 @@ public:
virtual bool isDocumentThreadableLoaderClient() { return true; }
virtual void willSendRequest(ResourceRequest& /*newRequest*/, const ResourceResponse& /*redirectResponse*/) { }
+
+protected:
+ DocumentThreadableLoaderClient() { }
};
} // namespace WebCore
diff --git a/Source/WebCore/loader/EmptyClients.h b/Source/WebCore/loader/EmptyClients.h
index 41a5df7..cabb4ae 100644
--- a/Source/WebCore/loader/EmptyClients.h
+++ b/Source/WebCore/loader/EmptyClients.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Eric Seidel (eric@webkit.org)
- * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
*
* Redistribution and use in source and binary forms, with or without
@@ -165,7 +165,7 @@ public:
virtual void invalidateContentsForSlowScroll(const IntRect&, bool) {};
virtual void scroll(const IntSize&, const IntRect&, const IntRect&) { }
#if ENABLE(TILED_BACKING_STORE)
- virtual void delegatedScrollRequested(const IntSize&) { }
+ virtual void delegatedScrollRequested(const IntPoint&) { }
#endif
#if ENABLE(REQUEST_ANIMATION_FRAME)
virtual void scheduleAnimation() { }
@@ -374,7 +374,7 @@ public:
virtual void showMediaPlayerProxyPlugin(Widget*) { }
#endif
- virtual ObjectContentType objectContentType(const KURL&, const String&) { return ObjectContentType(); }
+ virtual ObjectContentType objectContentType(const KURL&, const String&, bool) { return ObjectContentType(); }
virtual String overrideMediaType() const { return String(); }
virtual void redirectDataToPlugin(Widget*) { }
@@ -414,7 +414,7 @@ public:
virtual String getAutoCorrectSuggestionForMisspelledWord(const String&) { return String(); }
virtual void checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*) { }
-#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+#if USE(UNIFIED_TEXT_CHECKING)
virtual void checkTextOfParagraph(const UChar*, int, uint64_t, Vector<TextCheckingResult>&) { };
#endif
@@ -519,9 +519,9 @@ public:
TextCheckerClient* textChecker() { return &m_textCheckerClient; }
#if SUPPORT_AUTOCORRECTION_PANEL
- virtual void showCorrectionPanel(CorrectionPanelInfo::PanelType, const FloatRect&, const String&, const String&, const Vector<String>&, Editor*) { }
+ virtual void showCorrectionPanel(CorrectionPanelInfo::PanelType, const FloatRect&, const String&, const String&, const Vector<String>&) { }
virtual void dismissCorrectionPanel(ReasonForDismissingCorrectionPanel) { }
- virtual bool isShowingCorrectionPanel() { return false; }
+ virtual String dismissCorrectionPanelSoon(ReasonForDismissingCorrectionPanel) { return String(); }
virtual void recordAutocorrectionResponse(AutocorrectionResponseType, const String&, const String&) { }
#endif
virtual void updateSpellingUIWithGrammarString(const String&, const GrammarDetail&) { }
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
index 61f421f..6819e71 100644
--- a/Source/WebCore/loader/FrameLoader.cpp
+++ b/Source/WebCore/loader/FrameLoader.cpp
@@ -1,9 +1,10 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
* Copyright (C) 2008 Alp Toker <alp@atoker.com>
* Copyright (C) Research In Motion Limited 2009. All rights reserved.
+ * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -40,6 +41,7 @@
#include "CachedPage.h"
#include "CachedResourceLoader.h"
#include "Chrome.h"
+#include "ContentSecurityPolicy.h"
#include "DOMImplementation.h"
#include "DOMWindow.h"
#include "Document.h"
@@ -83,6 +85,7 @@
#include "ResourceHandle.h"
#include "ResourceRequest.h"
#include "SchemeRegistry.h"
+#include "ScrollAnimator.h"
#include "ScriptController.h"
#include "ScriptSourceCode.h"
#include "SecurityOrigin.h"
@@ -130,9 +133,9 @@ using namespace SVGNames;
#endif
#if ENABLE(XHTMLMP)
-static const char defaultAcceptHeader[] = "application/xml,application/vnd.wap.xhtml+xml,application/xhtml+xml;profile='http://www.wapforum.org/xhtml',text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
+static const char defaultAcceptHeader[] = "application/vnd.wap.xhtml+xml,application/xhtml+xml;profile='http://www.wapforum.org/xhtml',text/html,application/xml;q=0.9,*/*;q=0.8";
#else
-static const char defaultAcceptHeader[] = "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
+static const char defaultAcceptHeader[] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
#endif
static double storedTimeOfLastCompletedLoad;
@@ -258,13 +261,6 @@ void FrameLoader::setDefersLoading(bool defers)
m_frame->navigationScheduler()->startTimer();
startCheckCompleteTimer();
}
-
- // This code is not logically part of load deferring, but we do not want JS code executed beneath modal
- // windows or sheets, which is exactly when PageGroupLoadDeferrer is used.
- if (defers)
- m_frame->document()->suspendScheduledTasks();
- else
- m_frame->document()->resumeScheduledTasks();
}
bool FrameLoader::canHandleRequest(const ResourceRequest& request)
@@ -691,12 +687,13 @@ void FrameLoader::didEndDocument()
m_isLoadingMainResource = false;
}
-void FrameLoader::iconLoadDecisionAvailable()
+// Callback for the old-style synchronous IconDatabase interface.
+void FrameLoader::iconLoadDecisionReceived(IconLoadDecision iconLoadDecision)
{
if (!m_mayLoadIconLater)
return;
LOG(IconDatabase, "FrameLoader %p was told a load decision is available for its icon", this);
- startIconLoader();
+ continueIconLoadWithDecision(iconLoadDecision);
m_mayLoadIconLater = false;
}
@@ -715,48 +712,77 @@ void FrameLoader::startIconLoader()
if (urlString.isEmpty())
return;
- // If we're not reloading and the icon database doesn't say to load now then bail before we actually start the load
- if (loadType() != FrameLoadTypeReload && loadType() != FrameLoadTypeReloadFromOrigin) {
- IconLoadDecision decision = iconDatabase().loadDecisionForIconURL(urlString, m_documentLoader.get());
- if (decision == IconLoadNo) {
- LOG(IconDatabase, "FrameLoader::startIconLoader() - Told not to load this icon, committing iconURL %s to database for pageURL mapping", urlString.ascii().data());
- commitIconURLToIconDatabase(url);
-
- // We were told not to load this icon - that means this icon is already known by the database
- // If the icon data hasn't been read in from disk yet, kick off the read of the icon from the database to make sure someone
- // has done it. This is after registering for the notification so the WebView can call the appropriate delegate method.
- // Otherwise if the icon data *is* available, notify the delegate
- if (!iconDatabase().iconDataKnownForIconURL(urlString)) {
- LOG(IconDatabase, "Told not to load icon %s but icon data is not yet available - registering for notification and requesting load from disk", urlString.ascii().data());
- m_client->registerForIconNotification();
- iconDatabase().iconForPageURL(m_frame->document()->url().string(), IntSize(0, 0));
- iconDatabase().iconForPageURL(originalRequestURL().string(), IntSize(0, 0));
- } else
- m_client->dispatchDidReceiveIcon();
-
- return;
- }
-
- if (decision == IconLoadUnknown) {
- // In this case, we may end up loading the icon later, but we still want to commit the icon url mapping to the database
- // just in case we don't end up loading later - if we commit the mapping a second time after the load, that's no big deal
- // We also tell the client to register for the notification that the icon is received now so it isn't missed in case the
- // icon is later read in from disk
- LOG(IconDatabase, "FrameLoader %p might load icon %s later", this, urlString.ascii().data());
- m_mayLoadIconLater = true;
- m_client->registerForIconNotification();
- commitIconURLToIconDatabase(url);
- return;
- }
- }
-
// People who want to avoid loading images generally want to avoid loading all images.
// Now that we've accounted for URL mapping, avoid starting the network load if images aren't set to display automatically.
Settings* settings = m_frame->settings();
if (settings && !settings->loadsImagesAutomatically())
return;
- // This is either a reload or the icon database said "yes, load the icon", so kick off the load!
+ // If we're reloading the page, always start the icon load now.
+ if (loadType() == FrameLoadTypeReload && loadType() == FrameLoadTypeReloadFromOrigin) {
+ continueIconLoadWithDecision(IconLoadYes);
+ return;
+ }
+
+ if (iconDatabase().supportsAsynchronousMode()) {
+ m_documentLoader->getIconLoadDecisionForIconURL(urlString);
+ // Commit the icon url mapping to the database just in case we don't end up loading later.
+ commitIconURLToIconDatabase(url);
+ return;
+ }
+
+ IconLoadDecision decision = iconDatabase().synchronousLoadDecisionForIconURL(urlString, m_documentLoader.get());
+
+ if (decision == IconLoadUnknown) {
+ // In this case, we may end up loading the icon later, but we still want to commit the icon url mapping to the database
+ // just in case we don't end up loading later - if we commit the mapping a second time after the load, that's no big deal
+ // We also tell the client to register for the notification that the icon is received now so it isn't missed in case the
+ // icon is later read in from disk
+ LOG(IconDatabase, "FrameLoader %p might load icon %s later", this, urlString.ascii().data());
+ m_mayLoadIconLater = true;
+ m_client->registerForIconNotification();
+ commitIconURLToIconDatabase(url);
+ return;
+ }
+
+ continueIconLoadWithDecision(decision);
+}
+
+void FrameLoader::continueIconLoadWithDecision(IconLoadDecision iconLoadDecision)
+{
+ ASSERT(iconLoadDecision != IconLoadUnknown);
+
+ // FIXME (<rdar://problem/9168605>) - We should support in-memory-only private browsing icons in asynchronous icon database mode.
+ if (iconDatabase().supportsAsynchronousMode() && m_frame->page()->settings()->privateBrowsingEnabled())
+ return;
+
+ if (iconLoadDecision == IconLoadNo) {
+ KURL url(iconURL());
+ String urlString(url.string());
+
+ LOG(IconDatabase, "FrameLoader::startIconLoader() - Told not to load this icon, committing iconURL %s to database for pageURL mapping", urlString.ascii().data());
+ commitIconURLToIconDatabase(url);
+
+ if (iconDatabase().supportsAsynchronousMode()) {
+ m_documentLoader->getIconDataForIconURL(urlString);
+ return;
+ }
+
+ // We were told not to load this icon - that means this icon is already known by the database
+ // If the icon data hasn't been read in from disk yet, kick off the read of the icon from the database to make sure someone
+ // has done it. This is after registering for the notification so the WebView can call the appropriate delegate method.
+ // Otherwise if the icon data *is* available, notify the delegate
+ if (!iconDatabase().synchronousIconDataKnownForIconURL(urlString)) {
+ LOG(IconDatabase, "Told not to load icon %s but icon data is not yet available - registering for notification and requesting load from disk", urlString.ascii().data());
+ m_client->registerForIconNotification();
+ iconDatabase().synchronousIconForPageURL(m_frame->document()->url().string(), IntSize(0, 0));
+ iconDatabase().synchronousIconForPageURL(originalRequestURL().string(), IntSize(0, 0));
+ } else
+ m_client->dispatchDidReceiveIcon();
+
+ return;
+ }
+
if (!m_iconLoader)
m_iconLoader = IconLoader::create(m_frame);
@@ -966,7 +992,7 @@ void FrameLoader::loadArchive(PassRefPtr<Archive> prpArchive)
}
#endif // ENABLE(WEB_ARCHIVE)
-ObjectContentType FrameLoader::defaultObjectContentType(const KURL& url, const String& mimeTypeIn)
+ObjectContentType FrameLoader::defaultObjectContentType(const KURL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages)
{
String mimeType = mimeTypeIn;
String extension = url.path().substring(url.path().reverseFind('.') + 1);
@@ -983,13 +1009,17 @@ ObjectContentType FrameLoader::defaultObjectContentType(const KURL& url, const S
if (mimeType.isEmpty())
return ObjectContentFrame; // Go ahead and hope that we can display the content.
+#if !PLATFORM(MAC) && !PLATFORM(CHROMIUM) && !PLATFORM(EFL) // Mac has no PluginDatabase, nor does Chromium or EFL
+ bool plugInSupportsMIMEType = PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType);
+#else
+ bool plugInSupportsMIMEType = false;
+#endif
+
if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
- return WebCore::ObjectContentImage;
+ return shouldPreferPlugInsForImages && plugInSupportsMIMEType ? WebCore::ObjectContentNetscapePlugin : WebCore::ObjectContentImage;
-#if !PLATFORM(MAC) && !PLATFORM(CHROMIUM) && !PLATFORM(EFL) // Mac has no PluginDatabase, nor does Chromium or EFL
- if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType))
+ if (plugInSupportsMIMEType)
return WebCore::ObjectContentNetscapePlugin;
-#endif
if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
return WebCore::ObjectContentFrame;
@@ -1392,7 +1422,7 @@ void FrameLoader::load(const ResourceRequest& request, const SubstituteData& sub
m_loadType = FrameLoadTypeStandard;
RefPtr<DocumentLoader> loader = m_client->createDocumentLoader(request, substituteData);
if (lockHistory && m_documentLoader)
- loader->setClientRedirectSourceForHistory(m_documentLoader->didCreateGlobalHistoryEntry() ? m_documentLoader->urlForHistory() : m_documentLoader->clientRedirectSourceForHistory());
+ loader->setClientRedirectSourceForHistory(m_documentLoader->didCreateGlobalHistoryEntry() ? m_documentLoader->urlForHistory().string() : m_documentLoader->clientRedirectSourceForHistory());
load(loader.get());
}
@@ -1416,7 +1446,7 @@ void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const
{
RefPtr<DocumentLoader> loader = m_client->createDocumentLoader(request, SubstituteData());
if (lockHistory && m_documentLoader)
- loader->setClientRedirectSourceForHistory(m_documentLoader->didCreateGlobalHistoryEntry() ? m_documentLoader->urlForHistory() : m_documentLoader->clientRedirectSourceForHistory());
+ loader->setClientRedirectSourceForHistory(m_documentLoader->didCreateGlobalHistoryEntry() ? m_documentLoader->urlForHistory().string() : m_documentLoader->clientRedirectSourceForHistory());
loader->setTriggeringAction(action);
if (m_documentLoader)
@@ -1530,7 +1560,7 @@ bool FrameLoader::willLoadMediaElementURL(KURL& url)
unsigned long identifier;
ResourceError error;
requestFromDelegate(request, identifier, error);
- notifier()->sendRemainingDelegateMessages(m_documentLoader.get(), identifier, ResourceResponse(url, String(), -1, String(), String()), -1, error);
+ notifier()->sendRemainingDelegateMessages(m_documentLoader.get(), identifier, ResourceResponse(url, String(), -1, String(), String()), -1, -1, error);
url = request.url();
@@ -1947,7 +1977,7 @@ void FrameLoader::commitProvisionalLoad()
// 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.
- notifier()->sendRemainingDelegateMessages(m_documentLoader.get(), identifier, response, static_cast<int>(response.expectedContentLength()), error);
+ notifier()->sendRemainingDelegateMessages(m_documentLoader.get(), identifier, response, static_cast<int>(response.expectedContentLength()), 0, error);
}
pageCache()->remove(history()->currentItem());
@@ -1967,6 +1997,9 @@ void FrameLoader::transitionToCommitted(PassRefPtr<CachedPage> cachedPage)
if (m_state != FrameStateProvisional)
return;
+ if (m_frame->view())
+ m_frame->view()->scrollAnimator()->cancelAnimations();
+
m_client->setCopiesOnScroll();
history()->updateForCommit();
@@ -2178,8 +2211,11 @@ void FrameLoader::open(CachedFrameBase& cachedFrame)
view->setWasScrolledByUser(false);
// Use the current ScrollView's frame rect.
- if (m_frame->view())
- view->setFrameRect(m_frame->view()->frameRect());
+ if (m_frame->view()) {
+ IntRect rect = m_frame->view()->frameRect();
+ view->setFrameRect(rect);
+ view->setBoundsSize(rect.size());
+ }
m_frame->setView(view);
m_frame->setDocument(document);
@@ -2338,12 +2374,9 @@ CachePolicy FrameLoader::subresourceCachePolicy() const
return parentCachePolicy;
}
- // FIXME: POST documents are always Reloads, but their subresources should still be Revalidate.
- // If we bring the CachePolicy.h and ResourceRequest cache policy enums in sync with each other and
- // remember "Revalidate" in ResourceRequests, we can remove this "POST" check and return either "Reload"
- // or "Revalidate" if the DocumentLoader was requested with either.
const ResourceRequest& request(documentLoader()->request());
- if (request.cachePolicy() == ReloadIgnoringCacheData && !equalIgnoringCase(request.httpMethod(), "post"))
+ Settings* settings = m_frame->settings();
+ if (settings && settings->useQuickLookResourceCachingQuirks() && request.cachePolicy() == ReloadIgnoringCacheData && !equalIgnoringCase(request.httpMethod(), "post"))
return CachePolicyRevalidate;
if (m_loadType == FrameLoadTypeReload)
@@ -2382,16 +2415,15 @@ void FrameLoader::checkLoadCompleteForThisFrame()
// Only reset if we aren't already going to a new provisional item.
bool shouldReset = !history()->provisionalItem();
- if (!(pdl->isLoadingInAPISense() && !pdl->isStopping())) {
+ if (!pdl->isLoadingInAPISense() || pdl->isStopping()) {
m_delegateIsHandlingProvisionalLoadError = true;
m_client->dispatchDidFailProvisionalLoad(error);
m_delegateIsHandlingProvisionalLoadError = false;
- // FIXME: can stopping loading here possibly have any effect, if isLoading is false,
- // which it must be to be in this branch of the if? And is it OK to just do a full-on
- // stopAllLoaders instead of stopLoadingSubframes?
- stopLoadingSubframes(ShouldNotClearProvisionalItem);
- pdl->stopLoading();
+ ASSERT(!pdl->isLoading());
+ ASSERT(!pdl->isLoadingMainResource());
+ ASSERT(!pdl->isLoadingSubresources());
+ ASSERT(!pdl->isLoadingPlugIns());
// If we're in the middle of loading multipart data, we need to restore the document loader.
if (isReplacing() && !m_documentLoader.get())
@@ -2741,12 +2773,6 @@ void FrameLoader::loadPostRequest(const ResourceRequest& inRequest, const String
{
RefPtr<FormState> formState = prpFormState;
- // When posting, use the NSURLRequestReloadIgnoringCacheData load flag.
- // This prevents a potential bug which may cause a page with a form that uses itself
- // as an action to be returned from the cache without submitting.
-
- // FIXME: Where's the code that implements what the comment above says?
-
// Previously when this method was reached, the original FrameLoadRequest had been deconstructed to build a
// bunch of parameters that would come in here and then be built back up to a ResourceRequest. In case
// any caller depends on the immutability of the original ResourceRequest, I'm rebuilding a ResourceRequest
@@ -2813,8 +2839,7 @@ unsigned long FrameLoader::loadResourceSynchronously(const ResourceRequest& requ
}
#endif
}
-
- notifier()->sendRemainingDelegateMessages(m_documentLoader.get(), identifier, response, data.size(), error);
+ notifier()->sendRemainingDelegateMessages(m_documentLoader.get(), identifier, response, data.size(), static_cast<int>(response.expectedContentLength()), error);
return identifier;
}
@@ -3007,7 +3032,7 @@ void FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest&, Pass
if (!m_frame->page())
return;
-#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
+#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC) && ENABLE(INSPECTOR)
if (Page* page = m_frame->page()) {
if (page->mainFrame() == m_frame)
m_frame->page()->inspectorController()->resume();
@@ -3107,7 +3132,7 @@ void FrameLoader::loadedResourceFromMemoryCache(const CachedResource* resource)
ResourceError error;
requestFromDelegate(request, identifier, error);
InspectorInstrumentation::markResourceAsCached(page, identifier);
- notifier()->sendRemainingDelegateMessages(m_documentLoader.get(), identifier, resource->response(), resource->encodedSize(), error);
+ notifier()->sendRemainingDelegateMessages(m_documentLoader.get(), identifier, resource->response(), resource->encodedSize(), 0, error);
}
void FrameLoader::applyUserAgent(ResourceRequest& request)
diff --git a/Source/WebCore/loader/FrameLoader.h b/Source/WebCore/loader/FrameLoader.h
index d59eb16..1fb9e3c 100644
--- a/Source/WebCore/loader/FrameLoader.h
+++ b/Source/WebCore/loader/FrameLoader.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
* Copyright (C) Research In Motion Limited 2009. All rights reserved.
*
@@ -35,6 +35,7 @@
#include "FrameLoaderStateMachine.h"
#include "FrameLoaderTypes.h"
#include "HistoryController.h"
+#include "IconDatabaseBase.h"
#include "PolicyChecker.h"
#include "ResourceLoadNotifier.h"
#include "SubframeLoader.h"
@@ -289,13 +290,13 @@ public:
FrameLoaderStateMachine* stateMachine() const { return &m_stateMachine; }
- void iconLoadDecisionAvailable();
+ void startIconLoader();
+ void iconLoadDecisionReceived(IconLoadDecision);
+ void continueIconLoadWithDecision(IconLoadDecision);
bool shouldAllowNavigation(Frame* targetFrame) const;
Frame* findFrameForNavigation(const AtomicString& name);
- void startIconLoader();
-
void applyUserAgent(ResourceRequest& request);
bool shouldInterruptLoadForXFrameOptions(const String&, const KURL&);
@@ -322,7 +323,7 @@ public:
bool suppressOpenerInNewFrame() const { return m_suppressOpenerInNewFrame; }
- static ObjectContentType defaultObjectContentType(const KURL& url, const String& mimeType);
+ static ObjectContentType defaultObjectContentType(const KURL&, const String& mimeType, bool shouldPreferPlugInsForImages);
void clear(bool clearWindowProperties = true, bool clearScriptObjects = true, bool clearFrameView = true);
diff --git a/Source/WebCore/loader/FrameLoaderClient.h b/Source/WebCore/loader/FrameLoaderClient.h
index 4a0bcbf..e89056d 100644
--- a/Source/WebCore/loader/FrameLoaderClient.h
+++ b/Source/WebCore/loader/FrameLoaderClient.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -259,7 +259,7 @@ namespace WebCore {
virtual void showMediaPlayerProxyPlugin(Widget*) = 0;
#endif
- virtual ObjectContentType objectContentType(const KURL& url, const String& mimeType) = 0;
+ virtual ObjectContentType objectContentType(const KURL&, const String& mimeType, bool shouldPreferPlugInsForImages) = 0;
virtual String overrideMediaType() const = 0;
virtual void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*) = 0;
diff --git a/Source/WebCore/loader/FrameLoaderTypes.h b/Source/WebCore/loader/FrameLoaderTypes.h
index 79c05dc..d13f375 100644
--- a/Source/WebCore/loader/FrameLoaderTypes.h
+++ b/Source/WebCore/loader/FrameLoaderTypes.h
@@ -42,7 +42,7 @@ namespace WebCore {
enum PolicyAction {
PolicyUse,
PolicyDownload,
- PolicyIgnore,
+ PolicyIgnore
};
// NOTE: Keep in sync with WebKit/mac/WebView/WebFramePrivate.h and WebKit/win/Interfaces/IWebFramePrivate.idl
diff --git a/Source/WebCore/loader/MainResourceLoader.cpp b/Source/WebCore/loader/MainResourceLoader.cpp
index c3c8d62..0cdbc21 100644
--- a/Source/WebCore/loader/MainResourceLoader.cpp
+++ b/Source/WebCore/loader/MainResourceLoader.cpp
@@ -118,7 +118,9 @@ ResourceError MainResourceLoader::interruptionForPolicyChangeError() const
void MainResourceLoader::stopLoadingForPolicyChange()
{
- cancel(interruptionForPolicyChangeError());
+ ResourceError error = interruptionForPolicyChangeError();
+ error.setIsCancellation(true);
+ cancel(error);
}
void MainResourceLoader::callContinueAfterNavigationPolicy(void* argument, const ResourceRequest& request, PassRefPtr<FormState>, bool shouldContinue)
diff --git a/Source/WebCore/loader/PolicyCallback.cpp b/Source/WebCore/loader/PolicyCallback.cpp
index 4ec2c84..45fdbb0 100644
--- a/Source/WebCore/loader/PolicyCallback.cpp
+++ b/Source/WebCore/loader/PolicyCallback.cpp
@@ -42,6 +42,7 @@ PolicyCallback::PolicyCallback()
: m_navigationFunction(0)
, m_newWindowFunction(0)
, m_contentFunction(0)
+ , m_argument(0)
{
}
diff --git a/Source/WebCore/loader/ResourceLoadNotifier.cpp b/Source/WebCore/loader/ResourceLoadNotifier.cpp
index c928557..3a02aa3 100644
--- a/Source/WebCore/loader/ResourceLoadNotifier.cpp
+++ b/Source/WebCore/loader/ResourceLoadNotifier.cpp
@@ -74,12 +74,12 @@ void ResourceLoadNotifier::didReceiveResponse(ResourceLoader* loader, const Reso
dispatchDidReceiveResponse(loader->documentLoader(), loader->identifier(), r);
}
-void ResourceLoadNotifier::didReceiveData(ResourceLoader* loader, const char* data, int length, int lengthReceived)
+void ResourceLoadNotifier::didReceiveData(ResourceLoader* loader, const char* data, int dataLength, int lengthReceived)
{
if (Page* page = m_frame->page())
- page->progress()->incrementProgress(loader->identifier(), data, length);
+ page->progress()->incrementProgress(loader->identifier(), data, dataLength);
- dispatchDidReceiveContentLength(loader->documentLoader(), loader->identifier(), lengthReceived);
+ dispatchDidReceiveContentLength(loader->documentLoader(), loader->identifier(), dataLength, lengthReceived);
}
void ResourceLoadNotifier::didFinishLoad(ResourceLoader* loader, double finishTime)
@@ -103,8 +103,6 @@ void ResourceLoadNotifier::didFailToLoad(ResourceLoader* loader, const ResourceE
void ResourceLoadNotifier::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
{
m_frame->loader()->client()->assignIdentifierToInitialRequest(identifier, loader, request);
-
- InspectorInstrumentation::identifierForInitialRequest(m_frame, identifier, loader, request);
}
void ResourceLoadNotifier::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
@@ -118,7 +116,7 @@ void ResourceLoadNotifier::dispatchWillSendRequest(DocumentLoader* loader, unsig
if (!request.isNull() && oldRequestURL != request.url().string().impl())
m_frame->loader()->documentLoader()->didTellClientAboutLoad(request.url());
- InspectorInstrumentation::willSendRequest(m_frame, identifier, request, redirectResponse);
+ InspectorInstrumentation::willSendRequest(m_frame, identifier, loader, request, redirectResponse);
// Report WebTiming for all frames.
if (loader && !request.isNull() && request.url() == loader->requestURL())
@@ -132,11 +130,11 @@ void ResourceLoadNotifier::dispatchDidReceiveResponse(DocumentLoader* loader, un
InspectorInstrumentation::didReceiveResourceResponse(cookie, identifier, loader, r);
}
-void ResourceLoadNotifier::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int length)
+void ResourceLoadNotifier::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int dataLength, int lengthReceived)
{
- m_frame->loader()->client()->dispatchDidReceiveContentLength(loader, identifier, length);
+ m_frame->loader()->client()->dispatchDidReceiveContentLength(loader, identifier, dataLength);
- InspectorInstrumentation::didReceiveContentLength(m_frame, identifier, length);
+ InspectorInstrumentation::didReceiveContentLength(m_frame, identifier, dataLength, lengthReceived);
}
void ResourceLoadNotifier::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier, double finishTime)
@@ -154,13 +152,13 @@ void ResourceLoadNotifier::dispatchTransferLoadingResourceFromPage(unsigned long
oldPage->progress()->completeProgress(identifier);
}
-void ResourceLoadNotifier::sendRemainingDelegateMessages(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response, int length, const ResourceError& error)
+void ResourceLoadNotifier::sendRemainingDelegateMessages(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response, int dataLength, int lengthReceived, const ResourceError& error)
{
if (!response.isNull())
dispatchDidReceiveResponse(loader, identifier, response);
- if (length > 0)
- dispatchDidReceiveContentLength(loader, identifier, length);
+ if (dataLength > 0)
+ dispatchDidReceiveContentLength(loader, identifier, dataLength, lengthReceived);
if (error.isNull())
dispatchDidFinishLoading(loader, identifier, 0);
diff --git a/Source/WebCore/loader/ResourceLoadNotifier.h b/Source/WebCore/loader/ResourceLoadNotifier.h
index a6d92fb..5753c28 100644
--- a/Source/WebCore/loader/ResourceLoadNotifier.h
+++ b/Source/WebCore/loader/ResourceLoadNotifier.h
@@ -53,18 +53,18 @@ public:
void willSendRequest(ResourceLoader*, ResourceRequest&, const ResourceResponse& redirectResponse);
void didReceiveResponse(ResourceLoader*, const ResourceResponse&);
- void didReceiveData(ResourceLoader*, const char*, int, int lengthReceived);
+ void didReceiveData(ResourceLoader*, const char*, int dataLength, int lengthReceived);
void didFinishLoad(ResourceLoader*, double finishTime);
void didFailToLoad(ResourceLoader*, const ResourceError&);
void assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest&);
void dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse);
void dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&);
- void dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int length);
+ void dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int dataLength, int lengthReceived);
void dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier, double finishTime);
void dispatchTransferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*);
- void sendRemainingDelegateMessages(DocumentLoader*, unsigned long identifier, const ResourceResponse&, int length, const ResourceError&);
+ void sendRemainingDelegateMessages(DocumentLoader*, unsigned long identifier, const ResourceResponse&, int dataLength, int lengthReceived, const ResourceError&);
private:
Frame* m_frame;
diff --git a/Source/WebCore/loader/ResourceLoadScheduler.cpp b/Source/WebCore/loader/ResourceLoadScheduler.cpp
index dbb6914..7cceff7 100644
--- a/Source/WebCore/loader/ResourceLoadScheduler.cpp
+++ b/Source/WebCore/loader/ResourceLoadScheduler.cpp
@@ -83,12 +83,13 @@ ResourceLoadScheduler::ResourceLoadScheduler()
#endif
}
-PassRefPtr<SubresourceLoader> ResourceLoadScheduler::scheduleSubresourceLoad(Frame* frame, SubresourceLoaderClient* client, const ResourceRequest& request, ResourceLoadPriority priority, SecurityCheckPolicy securityCheck, bool sendResourceLoadCallbacks, bool shouldContentSniff)
+PassRefPtr<SubresourceLoader> ResourceLoadScheduler::scheduleSubresourceLoad(Frame* frame, SubresourceLoaderClient* client, const ResourceRequest& request, ResourceLoadPriority priority, SecurityCheckPolicy securityCheck,
+ bool sendResourceLoadCallbacks, bool shouldContentSniff, const String& optionalOutgoingReferrer)
{
- PassRefPtr<SubresourceLoader> loader = SubresourceLoader::create(frame, client, request, securityCheck, sendResourceLoadCallbacks, shouldContentSniff);
+ RefPtr<SubresourceLoader> loader = SubresourceLoader::create(frame, client, request, securityCheck, sendResourceLoadCallbacks, shouldContentSniff, optionalOutgoingReferrer);
if (loader)
scheduleLoad(loader.get(), priority);
- return loader;
+ return loader.release();
}
PassRefPtr<NetscapePlugInStreamLoader> ResourceLoadScheduler::schedulePluginStreamLoad(Frame* frame, NetscapePlugInStreamLoaderClient* client, const ResourceRequest& request)
diff --git a/Source/WebCore/loader/ResourceLoadScheduler.h b/Source/WebCore/loader/ResourceLoadScheduler.h
index f2e627f..49a4546 100644
--- a/Source/WebCore/loader/ResourceLoadScheduler.h
+++ b/Source/WebCore/loader/ResourceLoadScheduler.h
@@ -32,6 +32,7 @@
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
#include <wtf/text/StringHash.h>
+#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -49,7 +50,7 @@ class ResourceLoadScheduler {
public:
friend ResourceLoadScheduler* resourceLoadScheduler();
- PassRefPtr<SubresourceLoader> scheduleSubresourceLoad(Frame*, SubresourceLoaderClient*, const ResourceRequest&, ResourceLoadPriority = ResourceLoadPriorityLow, SecurityCheckPolicy = DoSecurityCheck, bool sendResourceLoadCallbacks = true, bool shouldContentSniff = true);
+ PassRefPtr<SubresourceLoader> scheduleSubresourceLoad(Frame*, SubresourceLoaderClient*, const ResourceRequest&, ResourceLoadPriority = ResourceLoadPriorityLow, SecurityCheckPolicy = DoSecurityCheck, bool sendResourceLoadCallbacks = true, bool shouldContentSniff = true, const String& optionalOutgoingReferrer = String());
PassRefPtr<NetscapePlugInStreamLoader> schedulePluginStreamLoad(Frame*, NetscapePlugInStreamLoaderClient*, const ResourceRequest&);
void addMainResourceLoad(ResourceLoader*);
void remove(ResourceLoader*);
diff --git a/Source/WebCore/loader/ResourceLoader.h b/Source/WebCore/loader/ResourceLoader.h
index e5c5d3f..339b130 100644
--- a/Source/WebCore/loader/ResourceLoader.h
+++ b/Source/WebCore/loader/ResourceLoader.h
@@ -88,6 +88,9 @@ namespace WebCore {
void willStopBufferingData(const char*, int);
virtual void didFinishLoading(double finishTime);
virtual void didFail(const ResourceError&);
+#if HAVE(CFNETWORK_DATA_ARRAY_CALLBACK)
+ virtual void didReceiveDataArray(CFArrayRef dataArray);
+#endif
virtual bool shouldUseCredentialStorage();
virtual void didReceiveAuthenticationChallenge(const AuthenticationChallenge&);
@@ -111,6 +114,9 @@ namespace WebCore {
virtual bool shouldUseCredentialStorage(ResourceHandle*) { return shouldUseCredentialStorage(); }
virtual void didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge& challenge) { didReceiveAuthenticationChallenge(challenge); }
virtual void didCancelAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge& challenge) { didCancelAuthenticationChallenge(challenge); }
+#if HAVE(CFNETWORK_DATA_ARRAY_CALLBACK)
+ virtual void didReceiveDataArray(ResourceHandle*, CFArrayRef dataArray);
+#endif
#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
virtual bool canAuthenticateAgainstProtectionSpace(ResourceHandle*, const ProtectionSpace& protectionSpace) { return canAuthenticateAgainstProtectionSpace(protectionSpace); }
#endif
diff --git a/Source/WebCore/loader/SubframeLoader.cpp b/Source/WebCore/loader/SubframeLoader.cpp
index 8bfd474..e7f851f 100644
--- a/Source/WebCore/loader/SubframeLoader.cpp
+++ b/Source/WebCore/loader/SubframeLoader.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
* Copyright (C) 2008 Alp Toker <alp@atoker.com>
@@ -88,17 +88,35 @@ bool SubframeLoader::requestFrame(HTMLFrameOwnerElement* ownerElement, const Str
return true;
}
-bool SubframeLoader::resourceWillUsePlugin(const String& url, const String& mimeType)
+bool SubframeLoader::resourceWillUsePlugin(const String& url, const String& mimeType, bool shouldPreferPlugInsForImages)
{
KURL completedURL;
if (!url.isEmpty())
completedURL = completeURL(url);
+
bool useFallback;
- return shouldUsePlugin(completedURL, mimeType, false, useFallback);
+ return shouldUsePlugin(completedURL, mimeType, shouldPreferPlugInsForImages, false, useFallback);
}
-bool SubframeLoader::requestObject(HTMLPlugInImageElement* ownerElement, const String& url, const AtomicString& frameName,
- const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues)
+bool SubframeLoader::requestPlugin(HTMLPlugInImageElement* ownerElement, const KURL& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback)
+{
+ Settings* settings = m_frame->settings();
+ if ((!allowPlugins(AboutToInstantiatePlugin)
+ // Application plug-ins are plug-ins implemented by the user agent, for example Qt plug-ins,
+ // as opposed to third-party code such as Flash. The user agent decides whether or not they are
+ // permitted, rather than WebKit.
+ && !MIMETypeRegistry::isApplicationPluginMIMEType(mimeType))
+ || (!settings->isJavaEnabled() && MIMETypeRegistry::isJavaAppletMIMEType(mimeType)))
+ return false;
+
+ if (m_frame->document() && m_frame->document()->securityOrigin()->isSandboxed(SandboxPlugins))
+ return false;
+
+ ASSERT(ownerElement->hasTagName(objectTag) || ownerElement->hasTagName(embedTag));
+ return loadPlugin(ownerElement, url, mimeType, paramNames, paramValues, useFallback);
+}
+
+bool SubframeLoader::requestObject(HTMLPlugInImageElement* ownerElement, const String& url, const AtomicString& frameName, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues)
{
if (url.isEmpty() && mimeType.isEmpty())
return false;
@@ -114,23 +132,8 @@ bool SubframeLoader::requestObject(HTMLPlugInImageElement* ownerElement, const S
completedURL = completeURL(url);
bool useFallback;
- if (shouldUsePlugin(completedURL, mimeType, renderer->hasFallbackContent(), useFallback)) {
- Settings* settings = m_frame->settings();
- if ((!allowPlugins(AboutToInstantiatePlugin)
- // Application plugins are plugins implemented by the user agent, for example Qt plugins,
- // as opposed to third-party code such as flash. The user agent decides whether or not they are
- // permitted, rather than WebKit.
- && !MIMETypeRegistry::isApplicationPluginMIMEType(mimeType))
- || (!settings->isJavaEnabled() && MIMETypeRegistry::isJavaAppletMIMEType(mimeType)))
- return false;
- if (m_frame->document() && m_frame->document()->securityOrigin()->isSandboxed(SandboxPlugins))
- return false;
-
- ASSERT(ownerElement->hasTagName(objectTag) || ownerElement->hasTagName(embedTag));
- HTMLPlugInImageElement* pluginElement = static_cast<HTMLPlugInImageElement*>(ownerElement);
-
- return loadPlugin(pluginElement, completedURL, mimeType, paramNames, paramValues, useFallback);
- }
+ if (shouldUsePlugin(completedURL, mimeType, ownerElement->shouldPreferPlugInsForImages(), renderer->hasFallbackContent(), useFallback))
+ return requestPlugin(ownerElement, completedURL, mimeType, paramNames, paramValues, useFallback);
// If the plug-in element already contains a subframe, loadOrRedirectSubframe will re-use it. Otherwise,
// it will create a new frame and set it as the RenderPart's widget, causing what was previously
@@ -289,7 +292,7 @@ bool SubframeLoader::allowPlugins(ReasonForCallingAllowPlugins reason)
return allowed;
}
-bool SubframeLoader::shouldUsePlugin(const KURL& url, const String& mimeType, bool hasFallback, bool& useFallback)
+bool SubframeLoader::shouldUsePlugin(const KURL& url, const String& mimeType, bool shouldPreferPlugInsForImages, bool hasFallback, bool& useFallback)
{
if (m_frame->loader()->client()->shouldUsePluginDocument(mimeType)) {
useFallback = false;
@@ -305,7 +308,7 @@ bool SubframeLoader::shouldUsePlugin(const KURL& url, const String& mimeType, bo
return true;
}
- ObjectContentType objectType = m_frame->loader()->client()->objectContentType(url, mimeType);
+ ObjectContentType objectType = m_frame->loader()->client()->objectContentType(url, mimeType, shouldPreferPlugInsForImages);
// If an object's content can't be handled and it has no fallback, let
// it be handled as a plugin to show the broken plugin icon.
useFallback = objectType == ObjectContentNone && hasFallback;
diff --git a/Source/WebCore/loader/SubframeLoader.h b/Source/WebCore/loader/SubframeLoader.h
index ba63a5c..01c59e6 100644
--- a/Source/WebCore/loader/SubframeLoader.h
+++ b/Source/WebCore/loader/SubframeLoader.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
* Copyright (C) Research In Motion Limited 2009. All rights reserved.
*
@@ -77,15 +77,16 @@ public:
bool containsPlugins() const { return m_containsPlugins; }
- bool resourceWillUsePlugin(const String& url, const String& mimeType);
+ bool resourceWillUsePlugin(const String& url, const String& mimeType, bool shouldPreferPlugInsForImages);
private:
+ bool requestPlugin(HTMLPlugInImageElement*, const KURL&, const String& serviceType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback);
Frame* loadOrRedirectSubframe(HTMLFrameOwnerElement*, const KURL&, const AtomicString& frameName, bool lockHistory, bool lockBackForwardList);
Frame* loadSubframe(HTMLFrameOwnerElement*, const KURL&, const String& name, const String& referrer);
bool loadPlugin(HTMLPlugInImageElement*, const KURL&, const String& mimeType,
const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback);
- bool shouldUsePlugin(const KURL&, const String& mimeType, bool hasFallback, bool& useFallback);
+ bool shouldUsePlugin(const KURL&, const String& mimeType, bool shouldPreferPlugInsForImages, bool hasFallback, bool& useFallback);
Document* document() const;
diff --git a/Source/WebCore/loader/SubresourceLoader.cpp b/Source/WebCore/loader/SubresourceLoader.cpp
index f948ec3..cfe8d0a 100644
--- a/Source/WebCore/loader/SubresourceLoader.cpp
+++ b/Source/WebCore/loader/SubresourceLoader.cpp
@@ -60,7 +60,7 @@ SubresourceLoader::~SubresourceLoader()
#endif
}
-PassRefPtr<SubresourceLoader> SubresourceLoader::create(Frame* frame, SubresourceLoaderClient* client, const ResourceRequest& request, SecurityCheckPolicy securityCheck, bool sendResourceLoadCallbacks, bool shouldContentSniff)
+PassRefPtr<SubresourceLoader> SubresourceLoader::create(Frame* frame, SubresourceLoaderClient* client, const ResourceRequest& request, SecurityCheckPolicy securityCheck, bool sendResourceLoadCallbacks, bool shouldContentSniff, const String& optionalOutgoingReferrer)
{
if (!frame)
return 0;
@@ -75,12 +75,22 @@ PassRefPtr<SubresourceLoader> SubresourceLoader::create(Frame* frame, Subresourc
FrameLoader::reportLocalLoadFailed(frame, request.url().string());
return 0;
}
-
- if (SecurityOrigin::shouldHideReferrer(request.url(), fl->outgoingReferrer()))
+
+ String outgoingReferrer;
+ String outgoingOrigin;
+ if (optionalOutgoingReferrer.isNull()) {
+ outgoingReferrer = fl->outgoingReferrer();
+ outgoingOrigin = fl->outgoingOrigin();
+ } else {
+ outgoingReferrer = optionalOutgoingReferrer;
+ outgoingOrigin = SecurityOrigin::createFromString(outgoingReferrer)->toString();
+ }
+
+ if (SecurityOrigin::shouldHideReferrer(request.url(), outgoingReferrer))
newRequest.clearHTTPReferrer();
else if (!request.httpReferrer())
- newRequest.setHTTPReferrer(fl->outgoingReferrer());
- FrameLoader::addHTTPOriginIfNeeded(newRequest, fl->outgoingOrigin());
+ newRequest.setHTTPReferrer(outgoingReferrer);
+ FrameLoader::addHTTPOriginIfNeeded(newRequest, outgoingOrigin);
fl->addExtraFieldsToSubresourceRequest(newRequest);
diff --git a/Source/WebCore/loader/SubresourceLoader.h b/Source/WebCore/loader/SubresourceLoader.h
index cb7ed81..b3aefb6 100644
--- a/Source/WebCore/loader/SubresourceLoader.h
+++ b/Source/WebCore/loader/SubresourceLoader.h
@@ -31,6 +31,8 @@
#include "FrameLoaderTypes.h"
#include "ResourceLoader.h"
+
+#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -39,7 +41,7 @@ namespace WebCore {
class SubresourceLoader : public ResourceLoader {
public:
- static PassRefPtr<SubresourceLoader> create(Frame*, SubresourceLoaderClient*, const ResourceRequest&, SecurityCheckPolicy = DoSecurityCheck, bool sendResourceLoadCallbacks = true, bool shouldContentSniff = true);
+ static PassRefPtr<SubresourceLoader> create(Frame*, SubresourceLoaderClient*, const ResourceRequest&, SecurityCheckPolicy = DoSecurityCheck, bool sendResourceLoadCallbacks = true, bool shouldContentSniff = true, const String& optionalOutgoingReferrer = String());
void clearClient() { m_client = 0; }
@@ -59,6 +61,11 @@ namespace WebCore {
virtual void receivedCancellation(const AuthenticationChallenge&);
virtual void didCancel(const ResourceError&);
+#if HAVE(CFNETWORK_DATA_ARRAY_CALLBACK)
+ virtual bool supportsDataArray() { return true; }
+ virtual void didReceiveDataArray(CFArrayRef);
+#endif
+
SubresourceLoaderClient* m_client;
bool m_loadingMultipartContent;
};
diff --git a/Source/WebCore/loader/ThreadableLoaderClientWrapper.h b/Source/WebCore/loader/ThreadableLoaderClientWrapper.h
index 664e0b3..d765fa0 100644
--- a/Source/WebCore/loader/ThreadableLoaderClientWrapper.h
+++ b/Source/WebCore/loader/ThreadableLoaderClientWrapper.h
@@ -38,85 +38,85 @@
namespace WebCore {
- class ThreadableLoaderClientWrapper : public ThreadSafeShared<ThreadableLoaderClientWrapper> {
- public:
- static PassRefPtr<ThreadableLoaderClientWrapper> create(ThreadableLoaderClient* client)
- {
- return adoptRef(new ThreadableLoaderClientWrapper(client));
- }
-
- void clearClient()
- {
- m_done = true;
- m_client = 0;
- }
-
- bool done() const
- {
- return m_done;
- }
-
- void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
- {
- if (m_client)
- m_client->didSendData(bytesSent, totalBytesToBeSent);
- }
-
- void didReceiveResponse(const ResourceResponse& response)
- {
- if (m_client)
- m_client->didReceiveResponse(response);
- }
-
- void didReceiveData(const char* data, int dataLength)
- {
- if (m_client)
- m_client->didReceiveData(data, dataLength);
- }
-
- void didReceiveCachedMetadata(const char* data, int dataLength)
- {
- if (m_client)
- m_client->didReceiveCachedMetadata(data, dataLength);
- }
-
- void didFinishLoading(unsigned long identifier, double finishTime)
- {
- m_done = true;
- if (m_client)
- m_client->didFinishLoading(identifier, finishTime);
- }
-
- void didFail(const ResourceError& error)
- {
- m_done = true;
- if (m_client)
- m_client->didFail(error);
- }
-
- void didFailRedirectCheck()
- {
- m_done = true;
- if (m_client)
- m_client->didFailRedirectCheck();
- }
-
- void didReceiveAuthenticationCancellation(const ResourceResponse& response)
- {
- if (m_client)
- m_client->didReceiveResponse(response);
- }
-
- protected:
- ThreadableLoaderClientWrapper(ThreadableLoaderClient* client)
- : m_client(client)
- , m_done(false)
- {
- }
-
- ThreadableLoaderClient* m_client;
- bool m_done;
- };
+class ThreadableLoaderClientWrapper : public ThreadSafeRefCounted<ThreadableLoaderClientWrapper> {
+public:
+ static PassRefPtr<ThreadableLoaderClientWrapper> create(ThreadableLoaderClient* client)
+ {
+ return adoptRef(new ThreadableLoaderClientWrapper(client));
+ }
+
+ void clearClient()
+ {
+ m_done = true;
+ m_client = 0;
+ }
+
+ bool done() const
+ {
+ return m_done;
+ }
+
+ void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
+ {
+ if (m_client)
+ m_client->didSendData(bytesSent, totalBytesToBeSent);
+ }
+
+ void didReceiveResponse(const ResourceResponse& response)
+ {
+ if (m_client)
+ m_client->didReceiveResponse(response);
+ }
+
+ void didReceiveData(const char* data, int dataLength)
+ {
+ if (m_client)
+ m_client->didReceiveData(data, dataLength);
+ }
+
+ void didReceiveCachedMetadata(const char* data, int dataLength)
+ {
+ if (m_client)
+ m_client->didReceiveCachedMetadata(data, dataLength);
+ }
+
+ void didFinishLoading(unsigned long identifier, double finishTime)
+ {
+ m_done = true;
+ if (m_client)
+ m_client->didFinishLoading(identifier, finishTime);
+ }
+
+ void didFail(const ResourceError& error)
+ {
+ m_done = true;
+ if (m_client)
+ m_client->didFail(error);
+ }
+
+ void didFailRedirectCheck()
+ {
+ m_done = true;
+ if (m_client)
+ m_client->didFailRedirectCheck();
+ }
+
+ void didReceiveAuthenticationCancellation(const ResourceResponse& response)
+ {
+ if (m_client)
+ m_client->didReceiveResponse(response);
+ }
+
+protected:
+ ThreadableLoaderClientWrapper(ThreadableLoaderClient* client)
+ : m_client(client)
+ , m_done(false)
+ {
+ }
+
+ ThreadableLoaderClient* m_client;
+ bool m_done;
+};
} // namespace WebCore
diff --git a/Source/WebCore/loader/WorkerThreadableLoader.cpp b/Source/WebCore/loader/WorkerThreadableLoader.cpp
index 6c61318..d753ecb 100644
--- a/Source/WebCore/loader/WorkerThreadableLoader.cpp
+++ b/Source/WebCore/loader/WorkerThreadableLoader.cpp
@@ -34,6 +34,8 @@
#include "WorkerThreadableLoader.h"
+#include "Document.h"
+#include "DocumentThreadableLoader.h"
#include "CrossThreadTask.h"
#include "ResourceError.h"
#include "ResourceRequest.h"
@@ -55,7 +57,7 @@ static const char loadResourceSynchronouslyMode[] = "loadResourceSynchronouslyMo
WorkerThreadableLoader::WorkerThreadableLoader(WorkerContext* workerContext, ThreadableLoaderClient* client, const String& taskMode, const ResourceRequest& request, const ThreadableLoaderOptions& options)
: m_workerContext(workerContext)
, m_workerClientWrapper(ThreadableLoaderClientWrapper::create(client))
- , m_bridge(*(new MainThreadBridge(m_workerClientWrapper, m_workerContext->thread()->workerLoaderProxy(), taskMode, request, options)))
+ , m_bridge(*(new MainThreadBridge(m_workerClientWrapper, m_workerContext->thread()->workerLoaderProxy(), taskMode, request, options, workerContext->url().strippedForUseAsReferrer())))
{
}
@@ -87,32 +89,30 @@ void WorkerThreadableLoader::cancel()
}
WorkerThreadableLoader::MainThreadBridge::MainThreadBridge(PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, WorkerLoaderProxy& loaderProxy, const String& taskMode,
- const ResourceRequest& request, const ThreadableLoaderOptions& options)
+ const ResourceRequest& request, const ThreadableLoaderOptions& options, const String& outgoingReferrer)
: m_workerClientWrapper(workerClientWrapper)
, m_loaderProxy(loaderProxy)
, m_taskMode(taskMode.crossThreadString())
{
ASSERT(m_workerClientWrapper.get());
- m_loaderProxy.postTaskToLoader(createCallbackTask(&MainThreadBridge::mainThreadCreateLoader, this, request, options));
+ m_loaderProxy.postTaskToLoader(createCallbackTask(&MainThreadBridge::mainThreadCreateLoader, this, request, options, outgoingReferrer));
}
WorkerThreadableLoader::MainThreadBridge::~MainThreadBridge()
{
}
-void WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader(ScriptExecutionContext* context, MainThreadBridge* thisPtr, PassOwnPtr<CrossThreadResourceRequestData> requestData, ThreadableLoaderOptions options)
+void WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader(ScriptExecutionContext* context, MainThreadBridge* thisPtr, PassOwnPtr<CrossThreadResourceRequestData> requestData, ThreadableLoaderOptions options, const String& outgoingReferrer)
{
ASSERT(isMainThread());
ASSERT(context->isDocument());
+ Document* document = static_cast<Document*>(context);
- // FIXME: the created loader has no knowledge of the origin of the worker doing the load request.
- // Basically every setting done in SubresourceLoader::create (including the contents of addExtraFieldsToRequest)
- // needs to be examined for how it should take into account a different originator.
OwnPtr<ResourceRequest> request(ResourceRequest::adopt(requestData));
// FIXME: If the a site requests a local resource, then this will return a non-zero value but the sync path
// will return a 0 value. Either this should return 0 or the other code path should do a callback with
// a failure.
- thisPtr->m_mainThreadLoader = ThreadableLoader::create(context, thisPtr, *request, options);
+ thisPtr->m_mainThreadLoader = DocumentThreadableLoader::create(document, thisPtr, *request, options, outgoingReferrer);
ASSERT(thisPtr->m_mainThreadLoader);
}
diff --git a/Source/WebCore/loader/WorkerThreadableLoader.h b/Source/WebCore/loader/WorkerThreadableLoader.h
index 2477f19..7685eed 100644
--- a/Source/WebCore/loader/WorkerThreadableLoader.h
+++ b/Source/WebCore/loader/WorkerThreadableLoader.h
@@ -98,7 +98,7 @@ namespace WebCore {
class MainThreadBridge : public ThreadableLoaderClient {
public:
// All executed on the worker context's thread.
- MainThreadBridge(PassRefPtr<ThreadableLoaderClientWrapper>, WorkerLoaderProxy&, const String& taskMode, const ResourceRequest&, const ThreadableLoaderOptions&);
+ MainThreadBridge(PassRefPtr<ThreadableLoaderClientWrapper>, WorkerLoaderProxy&, const String& taskMode, const ResourceRequest&, const ThreadableLoaderOptions&, const String& outgoingReferrer);
void cancel();
void destroy();
@@ -110,7 +110,7 @@ namespace WebCore {
static void mainThreadDestroy(ScriptExecutionContext*, MainThreadBridge*);
~MainThreadBridge();
- static void mainThreadCreateLoader(ScriptExecutionContext*, MainThreadBridge*, PassOwnPtr<CrossThreadResourceRequestData>, ThreadableLoaderOptions);
+ static void mainThreadCreateLoader(ScriptExecutionContext*, MainThreadBridge*, PassOwnPtr<CrossThreadResourceRequestData>, ThreadableLoaderOptions, const String& outgoingReferrer);
static void mainThreadCancel(ScriptExecutionContext*, MainThreadBridge*);
virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
virtual void didReceiveResponse(const ResourceResponse&);
diff --git a/Source/WebCore/loader/appcache/ApplicationCache.cpp b/Source/WebCore/loader/appcache/ApplicationCache.cpp
index 450fa10..f3479b4 100644
--- a/Source/WebCore/loader/appcache/ApplicationCache.cpp
+++ b/Source/WebCore/loader/appcache/ApplicationCache.cpp
@@ -32,6 +32,7 @@
#include "ApplicationCacheResource.h"
#include "ApplicationCacheStorage.h"
#include "ResourceRequest.h"
+#include "SecurityOrigin.h"
#include <wtf/text/CString.h>
#include <stdio.h>
@@ -182,7 +183,29 @@ void ApplicationCache::clearStorageID()
ResourceMap::const_iterator end = m_resources.end();
for (ResourceMap::const_iterator it = m_resources.begin(); it != end; ++it)
it->second->clearStorageID();
-}
+}
+
+void ApplicationCache::deleteCacheForOrigin(SecurityOrigin* origin)
+{
+ Vector<KURL> urls;
+ if (!cacheStorage().manifestURLs(&urls)) {
+ LOG_ERROR("Failed to retrieve ApplicationCache manifest URLs");
+ return;
+ }
+
+ KURL originURL(KURL(), origin->toString());
+
+ size_t count = urls.size();
+ for (size_t i = 0; i < count; ++i) {
+ if (protocolHostAndPortAreEqual(urls[i], originURL)) {
+ ApplicationCacheGroup* group = cacheStorage().findInMemoryCacheGroup(urls[i]);
+ if (group)
+ group->makeObsolete();
+ else
+ cacheStorage().deleteCacheGroup(urls[i]);
+ }
+ }
+}
#ifndef NDEBUG
void ApplicationCache::dump()
diff --git a/Source/WebCore/loader/appcache/ApplicationCache.h b/Source/WebCore/loader/appcache/ApplicationCache.h
index f073499..9d20361 100644
--- a/Source/WebCore/loader/appcache/ApplicationCache.h
+++ b/Source/WebCore/loader/appcache/ApplicationCache.h
@@ -42,12 +42,16 @@ class ApplicationCacheResource;
class DocumentLoader;
class KURL;
class ResourceRequest;
+class SecurityOrigin;
typedef Vector<std::pair<KURL, KURL> > FallbackURLVector;
class ApplicationCache : public RefCounted<ApplicationCache> {
public:
static PassRefPtr<ApplicationCache> create() { return adoptRef(new ApplicationCache); }
+
+ static void deleteCacheForOrigin(SecurityOrigin*);
+
~ApplicationCache();
void addResource(PassRefPtr<ApplicationCacheResource> resource);
diff --git a/Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp b/Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp
index 514ef19..aab8927 100644
--- a/Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp
+++ b/Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp
@@ -474,9 +474,8 @@ PassRefPtr<ResourceHandle> ApplicationCacheGroup::createResourceHandle(const KUR
// Because willSendRequest only gets called during redirects, we initialize
// the identifier and the first willSendRequest here.
m_currentResourceIdentifier = m_frame->page()->progress()->createUniqueIdentifier();
- InspectorInstrumentation::identifierForInitialRequest(m_frame, m_currentResourceIdentifier, m_frame->loader()->documentLoader(), handle->firstRequest());
ResourceResponse redirectResponse = ResourceResponse();
- InspectorInstrumentation::willSendRequest(m_frame, m_currentResourceIdentifier, request, redirectResponse);
+ InspectorInstrumentation::willSendRequest(m_frame, m_currentResourceIdentifier, m_frame->loader()->documentLoader(), request, redirectResponse);
#endif
return handle;
}
@@ -512,7 +511,7 @@ void ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, const Res
if (m_newestCache && response.httpStatusCode() == 304) { // Not modified.
ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(url);
if (newestCachedResource) {
- m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data()));
+ m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data(), newestCachedResource->path()));
m_pendingEntries.remove(m_currentHandle->firstRequest().url());
m_currentHandle->cancel();
m_currentHandle = 0;
@@ -540,7 +539,7 @@ void ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, const Res
ASSERT(m_newestCache);
ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(handle->firstRequest().url());
ASSERT(newestCachedResource);
- m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data()));
+ m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data(), newestCachedResource->path()));
m_pendingEntries.remove(m_currentHandle->firstRequest().url());
m_currentHandle->cancel();
m_currentHandle = 0;
@@ -555,8 +554,10 @@ void ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, const Res
void ApplicationCacheGroup::didReceiveData(ResourceHandle* handle, const char* data, int length, int lengthReceived)
{
+ UNUSED_PARAM(lengthReceived);
+
#if ENABLE(INSPECTOR)
- InspectorInstrumentation::didReceiveContentLength(m_frame, m_currentResourceIdentifier, lengthReceived);
+ InspectorInstrumentation::didReceiveContentLength(m_frame, m_currentResourceIdentifier, length, 0);
#endif
if (handle == m_manifestHandle) {
@@ -642,7 +643,7 @@ void ApplicationCacheGroup::didFail(ResourceHandle* handle, const ResourceError&
ASSERT(m_newestCache);
ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(url);
ASSERT(newestCachedResource);
- m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data()));
+ m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data(), newestCachedResource->path()));
// Load the next resource, if any.
startLoadingEntry();
}
@@ -866,7 +867,7 @@ void ApplicationCacheGroup::checkIfLoadIsComplete()
}
ApplicationCacheStorage::FailureReason failureReason;
- RefPtr<ApplicationCache> oldNewestCache = (m_newestCache == m_cacheBeingUpdated) ? 0 : m_newestCache;
+ RefPtr<ApplicationCache> oldNewestCache = (m_newestCache == m_cacheBeingUpdated) ? RefPtr<ApplicationCache>() : m_newestCache;
setNewestCache(m_cacheBeingUpdated.release());
if (cacheStorage().storeNewestCache(this, oldNewestCache.get(), failureReason)) {
// New cache stored, now remove the old cache.
diff --git a/Source/WebCore/loader/appcache/ApplicationCacheHost.h b/Source/WebCore/loader/appcache/ApplicationCacheHost.h
index a1f2841..56a5f57 100644
--- a/Source/WebCore/loader/appcache/ApplicationCacheHost.h
+++ b/Source/WebCore/loader/appcache/ApplicationCacheHost.h
@@ -156,6 +156,11 @@ namespace WebCore {
CacheInfo applicationCacheInfo();
#endif
+#if !PLATFORM(CHROMIUM)
+ bool shouldLoadResourceFromApplicationCache(const ResourceRequest&, ApplicationCacheResource*&);
+ bool getApplicationCacheFallbackResource(const ResourceRequest&, ApplicationCacheResource*&, ApplicationCache* = 0);
+#endif
+
private:
bool isApplicationCacheEnabled();
DocumentLoader* documentLoader() const { return m_documentLoader; }
@@ -182,8 +187,6 @@ namespace WebCore {
friend class ApplicationCacheStorage;
bool scheduleLoadFallbackResourceFromApplicationCache(ResourceLoader*, ApplicationCache* = 0);
- bool shouldLoadResourceFromApplicationCache(const ResourceRequest&, ApplicationCacheResource*&);
- bool getApplicationCacheFallbackResource(const ResourceRequest&, ApplicationCacheResource*&, ApplicationCache* = 0);
void setCandidateApplicationCacheGroup(ApplicationCacheGroup* group);
ApplicationCacheGroup* candidateApplicationCacheGroup() const { return m_candidateApplicationCacheGroup; }
void setApplicationCache(PassRefPtr<ApplicationCache> applicationCache);
diff --git a/Source/WebCore/loader/appcache/ApplicationCacheResource.cpp b/Source/WebCore/loader/appcache/ApplicationCacheResource.cpp
index 03c5c83..c0df573 100644
--- a/Source/WebCore/loader/appcache/ApplicationCacheResource.cpp
+++ b/Source/WebCore/loader/appcache/ApplicationCacheResource.cpp
@@ -31,11 +31,12 @@
namespace WebCore {
-ApplicationCacheResource::ApplicationCacheResource(const KURL& url, const ResourceResponse& response, unsigned type, PassRefPtr<SharedBuffer> data)
+ApplicationCacheResource::ApplicationCacheResource(const KURL& url, const ResourceResponse& response, unsigned type, PassRefPtr<SharedBuffer> data, const String& path)
: SubstituteResource(url, response, data)
, m_type(type)
, m_storageID(0)
, m_estimatedSizeInStorage(0)
+ , m_path(path)
{
}
diff --git a/Source/WebCore/loader/appcache/ApplicationCacheResource.h b/Source/WebCore/loader/appcache/ApplicationCacheResource.h
index 2ca7846..6633c6c 100644
--- a/Source/WebCore/loader/appcache/ApplicationCacheResource.h
+++ b/Source/WebCore/loader/appcache/ApplicationCacheResource.h
@@ -42,10 +42,10 @@ public:
Fallback = 1 << 4
};
- static PassRefPtr<ApplicationCacheResource> create(const KURL& url, const ResourceResponse& response, unsigned type, PassRefPtr<SharedBuffer> buffer = SharedBuffer::create())
+ static PassRefPtr<ApplicationCacheResource> create(const KURL& url, const ResourceResponse& response, unsigned type, PassRefPtr<SharedBuffer> buffer = SharedBuffer::create(), const String& path = String())
{
ASSERT(!url.hasFragmentIdentifier());
- return adoptRef(new ApplicationCacheResource(url, response, type, buffer));
+ return adoptRef(new ApplicationCacheResource(url, response, type, buffer, path));
}
unsigned type() const { return m_type; }
@@ -56,16 +56,20 @@ public:
void clearStorageID() { m_storageID = 0; }
int64_t estimatedSizeInStorage();
+ const String& path() const { return m_path; }
+ void setPath(const String& path) { m_path = path; }
+
#ifndef NDEBUG
static void dumpType(unsigned type);
#endif
private:
- ApplicationCacheResource(const KURL& url, const ResourceResponse& response, unsigned type, PassRefPtr<SharedBuffer> buffer);
+ ApplicationCacheResource(const KURL&, const ResourceResponse&, unsigned type, PassRefPtr<SharedBuffer>, const String& path);
unsigned m_type;
unsigned m_storageID;
int64_t m_estimatedSizeInStorage;
+ String m_path;
};
} // namespace WebCore
diff --git a/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp b/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp
index 5c6937e..a126f8a 100644
--- a/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp
+++ b/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp
@@ -38,6 +38,7 @@
#include "SQLiteStatement.h"
#include "SQLiteTransaction.h"
#include "SecurityOrigin.h"
+#include "UUID.h"
#include <wtf/text/CString.h>
#include <wtf/StdLibExtras.h>
#include <wtf/StringExtras.h>
@@ -46,6 +47,8 @@ using namespace std;
namespace WebCore {
+static const char flatFileSubdirectory[] = "ApplicationCache";
+
template <class T>
class StorageIDJournal {
public:
@@ -90,7 +93,7 @@ static unsigned urlHostHash(const KURL& url)
unsigned hostStart = url.hostStart();
unsigned hostEnd = url.hostEnd();
- return AlreadyHashed::avoidDeletedValue(WTF::StringHasher::createHash(url.string().characters() + hostStart, hostEnd - hostStart));
+ return AlreadyHashed::avoidDeletedValue(StringHasher::computeHash(url.string().characters() + hostStart, hostEnd - hostStart));
}
ApplicationCacheGroup* ApplicationCacheStorage::loadCacheGroup(const KURL& manifestURL)
@@ -153,6 +156,11 @@ ApplicationCacheGroup* ApplicationCacheStorage::findOrCreateCacheGroup(const KUR
return group;
}
+ApplicationCacheGroup* ApplicationCacheStorage::findInMemoryCacheGroup(const KURL& manifestURL) const
+{
+ return m_cachesInMemory.get(manifestURL);
+}
+
void ApplicationCacheStorage::loadManifestHostHashes()
{
static bool hasLoadedHashes = false;
@@ -389,7 +397,7 @@ int64_t ApplicationCacheStorage::spaceNeeded(int64_t cacheToSave)
if (!getFileSize(m_cacheFile, fileSize))
return 0;
- int64_t currentSize = fileSize;
+ int64_t currentSize = fileSize + flatFileAreaSize();
// Determine the amount of free space we have available.
int64_t totalAvailableSize = 0;
@@ -555,7 +563,7 @@ bool ApplicationCacheStorage::executeSQLCommand(const String& sql)
// Update the schemaVersion when the schema of any the Application Cache
// SQLite tables changes. This allows the database to be rebuilt when
// a new, incompatible change has been introduced to the database schema.
-static const int schemaVersion = 6;
+static const int schemaVersion = 7;
void ApplicationCacheStorage::verifySchemaVersion()
{
@@ -563,7 +571,7 @@ void ApplicationCacheStorage::verifySchemaVersion()
if (version == schemaVersion)
return;
- m_database.clearAllTables();
+ deleteTables();
// Update user version.
SQLiteTransaction setDatabaseVersion(m_database);
@@ -613,7 +621,8 @@ void ApplicationCacheStorage::openDatabase(bool createIfDoesNotExist)
executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheEntries (cache INTEGER NOT NULL ON CONFLICT FAIL, type INTEGER, resource INTEGER NOT NULL)");
executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheResources (id INTEGER PRIMARY KEY AUTOINCREMENT, url TEXT NOT NULL ON CONFLICT FAIL, "
"statusCode INTEGER NOT NULL, responseURL TEXT NOT NULL, mimeType TEXT, textEncodingName TEXT, headers TEXT, data INTEGER NOT NULL ON CONFLICT FAIL)");
- executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheResourceData (id INTEGER PRIMARY KEY AUTOINCREMENT, data BLOB)");
+ executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheResourceData (id INTEGER PRIMARY KEY AUTOINCREMENT, data BLOB, path TEXT)");
+ executeSQLCommand("CREATE TABLE IF NOT EXISTS DeletedCacheResources (id INTEGER PRIMARY KEY AUTOINCREMENT, path TEXT)");
executeSQLCommand("CREATE TABLE IF NOT EXISTS Origins (origin TEXT UNIQUE ON CONFLICT IGNORE, quota INTEGER NOT NULL ON CONFLICT FAIL)");
// When a cache is deleted, all its entries and its whitelist should be deleted.
@@ -636,6 +645,15 @@ void ApplicationCacheStorage::openDatabase(bool createIfDoesNotExist)
" FOR EACH ROW BEGIN"
" DELETE FROM CacheResourceData WHERE id = OLD.data;"
" END");
+
+ // When a cache resource is deleted, if it contains a non-empty path, that path should
+ // be added to the DeletedCacheResources table so the flat file at that path can
+ // be deleted at a later time.
+ executeSQLCommand("CREATE TRIGGER IF NOT EXISTS CacheResourceDataDeleted AFTER DELETE ON CacheResourceData"
+ " FOR EACH ROW"
+ " WHEN OLD.path NOT NULL BEGIN"
+ " INSERT INTO DeletedCacheResources (path) values (OLD.path);"
+ " END");
}
bool ApplicationCacheStorage::executeStatement(SQLiteStatement& statement)
@@ -767,15 +785,43 @@ bool ApplicationCacheStorage::store(ApplicationCacheResource* resource, unsigned
return false;
// First, insert the data
- SQLiteStatement dataStatement(m_database, "INSERT INTO CacheResourceData (data) VALUES (?)");
+ SQLiteStatement dataStatement(m_database, "INSERT INTO CacheResourceData (data, path) VALUES (?, ?)");
if (dataStatement.prepare() != SQLResultOk)
return false;
- if (resource->data()->size())
- dataStatement.bindBlob(1, resource->data()->data(), resource->data()->size());
+
+ String fullPath;
+ if (!resource->path().isEmpty())
+ dataStatement.bindText(2, pathGetFileName(resource->path()));
+ else if (shouldStoreResourceAsFlatFile(resource)) {
+ // First, check to see if creating the flat file would violate the maximum total quota. We don't need
+ // to check the per-origin quota here, as it was already checked in storeNewestCache().
+ if (m_database.totalSize() + flatFileAreaSize() + resource->data()->size() > m_maximumSize) {
+ m_isMaximumSizeReached = true;
+ return false;
+ }
+
+ String flatFileDirectory = pathByAppendingComponent(m_cacheDirectory, flatFileSubdirectory);
+ makeAllDirectories(flatFileDirectory);
+ String path;
+ if (!writeDataToUniqueFileInDirectory(resource->data(), flatFileDirectory, path))
+ return false;
+
+ fullPath = pathByAppendingComponent(flatFileDirectory, path);
+ resource->setPath(fullPath);
+ dataStatement.bindText(2, path);
+ } else {
+ if (resource->data()->size())
+ dataStatement.bindBlob(1, resource->data()->data(), resource->data()->size());
+ }
- if (!dataStatement.executeCommand())
+ if (!dataStatement.executeCommand()) {
+ // Clean up the file which we may have written to:
+ if (!fullPath.isEmpty())
+ deleteFile(fullPath);
+
return false;
+ }
unsigned dataId = static_cast<unsigned>(m_database.lastInsertRowID());
@@ -826,6 +872,12 @@ bool ApplicationCacheStorage::store(ApplicationCacheResource* resource, unsigned
if (!executeStatement(entryStatement))
return false;
+ // Did we successfully write the resource data to a file? If so,
+ // release the resource's data and free up a potentially large amount
+ // of memory:
+ if (!fullPath.isEmpty())
+ resource->data()->clear();
+
resource->setStorageID(resourceId);
return true;
}
@@ -856,7 +908,7 @@ bool ApplicationCacheStorage::store(ApplicationCacheResource* resource, Applicat
return false;
m_isMaximumSizeReached = false;
- m_database.setMaximumSize(m_maximumSize);
+ m_database.setMaximumSize(m_maximumSize - flatFileAreaSize());
SQLiteTransaction storeResourceTransaction(m_database);
storeResourceTransaction.begin();
@@ -903,7 +955,7 @@ bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group, App
return false;
m_isMaximumSizeReached = false;
- m_database.setMaximumSize(m_maximumSize);
+ m_database.setMaximumSize(m_maximumSize - flatFileAreaSize());
SQLiteTransaction storeCacheTransaction(m_database);
@@ -1003,7 +1055,7 @@ static inline void parseHeaders(const String& headers, ResourceResponse& respons
PassRefPtr<ApplicationCache> ApplicationCacheStorage::loadCache(unsigned storageID)
{
SQLiteStatement cacheStatement(m_database,
- "SELECT url, type, mimeType, textEncodingName, headers, CacheResourceData.data FROM CacheEntries INNER JOIN CacheResources ON CacheEntries.resource=CacheResources.id "
+ "SELECT url, type, mimeType, textEncodingName, headers, CacheResourceData.data, CacheResourceData.path FROM CacheEntries INNER JOIN CacheResources ON CacheEntries.resource=CacheResources.id "
"INNER JOIN CacheResourceData ON CacheResourceData.id=CacheResources.data WHERE CacheEntries.cache=?");
if (cacheStatement.prepare() != SQLResultOk) {
LOG_ERROR("Could not prepare cache statement, error \"%s\"", m_database.lastErrorMsg());
@@ -1013,7 +1065,9 @@ PassRefPtr<ApplicationCache> ApplicationCacheStorage::loadCache(unsigned storage
cacheStatement.bindInt64(1, storageID);
RefPtr<ApplicationCache> cache = ApplicationCache::create();
-
+
+ String flatFileDirectory = pathByAppendingComponent(m_cacheDirectory, flatFileSubdirectory);
+
int result;
while ((result = cacheStatement.step()) == SQLResultRow) {
KURL url(ParsedURLString, cacheStatement.getColumnText(0));
@@ -1025,15 +1079,24 @@ PassRefPtr<ApplicationCache> ApplicationCacheStorage::loadCache(unsigned storage
RefPtr<SharedBuffer> data = SharedBuffer::adoptVector(blob);
+ String path = cacheStatement.getColumnText(6);
+ long long size = 0;
+ if (path.isEmpty())
+ size = data->size();
+ else {
+ path = pathByAppendingComponent(flatFileDirectory, path);
+ getFileSize(path, size);
+ }
+
String mimeType = cacheStatement.getColumnText(2);
String textEncodingName = cacheStatement.getColumnText(3);
- ResourceResponse response(url, mimeType, data->size(), textEncodingName, "");
+ ResourceResponse response(url, mimeType, size, textEncodingName, "");
String headers = cacheStatement.getColumnText(4);
parseHeaders(headers, response);
- RefPtr<ApplicationCacheResource> resource = ApplicationCacheResource::create(url, response, type, data.release());
+ RefPtr<ApplicationCacheResource> resource = ApplicationCacheResource::create(url, response, type, data.release(), path);
if (type & ApplicationCacheResource::Manifest)
cache->setManifestResource(resource.release());
@@ -1127,6 +1190,8 @@ void ApplicationCacheStorage::remove(ApplicationCache* cache)
cache->group()->clearStorageID();
}
+
+ checkForDeletedResources();
}
void ApplicationCacheStorage::empty()
@@ -1147,7 +1212,51 @@ void ApplicationCacheStorage::empty()
CacheGroupMap::const_iterator end = m_cachesInMemory.end();
for (CacheGroupMap::const_iterator it = m_cachesInMemory.begin(); it != end; ++it)
it->second->clearStorageID();
-}
+
+ checkForDeletedResources();
+}
+
+void ApplicationCacheStorage::deleteTables()
+{
+ empty();
+ m_database.clearAllTables();
+}
+
+bool ApplicationCacheStorage::shouldStoreResourceAsFlatFile(ApplicationCacheResource* resource)
+{
+ return resource->response().mimeType().startsWith("audio/", false)
+ || resource->response().mimeType().startsWith("video/", false);
+}
+
+bool ApplicationCacheStorage::writeDataToUniqueFileInDirectory(SharedBuffer* data, const String& directory, String& path)
+{
+ String fullPath;
+
+ do {
+ path = encodeForFileName(createCanonicalUUIDString());
+ // Guard against the above function being called on a platform which does not implement
+ // createCanonicalUUIDString().
+ ASSERT(!path.isEmpty());
+ if (path.isEmpty())
+ return false;
+
+ fullPath = pathByAppendingComponent(directory, path);
+ } while (directoryName(fullPath) != directory || fileExists(fullPath));
+
+ PlatformFileHandle handle = openFile(fullPath, OpenForWrite);
+ if (!handle)
+ return false;
+
+ int64_t writtenBytes = writeToFile(handle, data->data(), data->size());
+ closeFile(handle);
+
+ if (writtenBytes != static_cast<int64_t>(data->size())) {
+ deleteFile(fullPath);
+ return false;
+ }
+
+ return true;
+}
bool ApplicationCacheStorage::storeCopyOfCache(const String& cacheDirectory, ApplicationCacheHost* cacheHost)
{
@@ -1166,7 +1275,7 @@ bool ApplicationCacheStorage::storeCopyOfCache(const String& cacheDirectory, App
for (ApplicationCache::ResourceMap::const_iterator it = cache->begin(); it != end; ++it) {
ApplicationCacheResource* resource = it->second.get();
- RefPtr<ApplicationCacheResource> resourceCopy = ApplicationCacheResource::create(resource->url(), resource->response(), resource->type(), resource->data());
+ RefPtr<ApplicationCacheResource> resourceCopy = ApplicationCacheResource::create(resource->url(), resource->response(), resource->type(), resource->data(), resource->path());
cacheCopy->addResource(resourceCopy.release());
}
@@ -1274,6 +1383,9 @@ bool ApplicationCacheStorage::deleteCacheGroup(const String& manifestURL)
}
deleteTransaction.commit();
+
+ checkForDeletedResources();
+
return true;
}
@@ -1291,25 +1403,73 @@ void ApplicationCacheStorage::checkForMaxSizeReached()
if (m_database.lastError() == SQLResultFull)
m_isMaximumSizeReached = true;
}
-
-void ApplicationCacheStorage::getOriginsWithCache(HashSet<RefPtr<SecurityOrigin>, SecurityOriginHash>& origins)
+
+void ApplicationCacheStorage::checkForDeletedResources()
{
- Vector<KURL> urls;
- if (!manifestURLs(&urls)) {
- LOG_ERROR("Failed to retrieve ApplicationCache manifest URLs");
+ openDatabase(false);
+ if (!m_database.isOpen())
return;
+
+ // Select only the paths in DeletedCacheResources that do not also appear in CacheResourceData:
+ SQLiteStatement selectPaths(m_database, "SELECT DeletedCacheResources.path "
+ "FROM DeletedCacheResources "
+ "LEFT JOIN CacheResourceData "
+ "ON DeletedCacheResources.path = CacheResourceData.path "
+ "WHERE (SELECT DeletedCacheResources.path == CacheResourceData.path) IS NULL");
+
+ if (selectPaths.prepare() != SQLResultOk)
+ return;
+
+ if (selectPaths.step() != SQLResultRow)
+ return;
+
+ do {
+ String path = selectPaths.getColumnText(0);
+ if (path.isEmpty())
+ continue;
+
+ String flatFileDirectory = pathByAppendingComponent(m_cacheDirectory, flatFileSubdirectory);
+ String fullPath = pathByAppendingComponent(flatFileDirectory, path);
+
+ // Don't exit the flatFileDirectory! This should only happen if the "path" entry contains a directory
+ // component, but protect against it regardless.
+ if (directoryName(fullPath) != flatFileDirectory)
+ continue;
+
+ deleteFile(fullPath);
+ } while (selectPaths.step() == SQLResultRow);
+
+ executeSQLCommand("DELETE FROM DeletedCacheResources");
+}
+
+long long ApplicationCacheStorage::flatFileAreaSize()
+{
+ openDatabase(false);
+ if (!m_database.isOpen())
+ return 0;
+
+ SQLiteStatement selectPaths(m_database, "SELECT path FROM CacheResourceData WHERE path NOT NULL");
+
+ if (selectPaths.prepare() != SQLResultOk) {
+ LOG_ERROR("Could not load flat file cache resource data, error \"%s\"", m_database.lastErrorMsg());
+ return 0;
}
- // Multiple manifest URLs might share the same SecurityOrigin, so we might be creating extra, wasted origins here.
- // The current schema doesn't allow for a more efficient way of building this list.
- size_t count = urls.size();
- for (size_t i = 0; i < count; ++i) {
- RefPtr<SecurityOrigin> origin = SecurityOrigin::create(urls[i]);
- origins.add(origin);
+ long long totalSize = 0;
+ String flatFileDirectory = pathByAppendingComponent(m_cacheDirectory, flatFileSubdirectory);
+ while (selectPaths.step() == SQLResultRow) {
+ String path = selectPaths.getColumnText(0);
+ String fullPath = pathByAppendingComponent(flatFileDirectory, path);
+ long long pathSize = 0;
+ if (!getFileSize(fullPath, pathSize))
+ continue;
+ totalSize += pathSize;
}
+
+ return totalSize;
}
-void ApplicationCacheStorage::deleteEntriesForOrigin(SecurityOrigin* origin)
+void ApplicationCacheStorage::getOriginsWithCache(HashSet<RefPtr<SecurityOrigin>, SecurityOriginHash>& origins)
{
Vector<KURL> urls;
if (!manifestURLs(&urls)) {
@@ -1318,12 +1478,11 @@ void ApplicationCacheStorage::deleteEntriesForOrigin(SecurityOrigin* origin)
}
// Multiple manifest URLs might share the same SecurityOrigin, so we might be creating extra, wasted origins here.
- // The current schema doesn't allow for a more efficient way of deleting by origin.
+ // The current schema doesn't allow for a more efficient way of building this list.
size_t count = urls.size();
for (size_t i = 0; i < count; ++i) {
- RefPtr<SecurityOrigin> manifestOrigin = SecurityOrigin::create(urls[i]);
- if (manifestOrigin->isSameSchemeHostPort(origin))
- deleteCacheGroup(urls[i]);
+ RefPtr<SecurityOrigin> origin = SecurityOrigin::create(urls[i]);
+ origins.add(origin);
}
}
diff --git a/Source/WebCore/loader/appcache/ApplicationCacheStorage.h b/Source/WebCore/loader/appcache/ApplicationCacheStorage.h
index f283670..3136b52 100644
--- a/Source/WebCore/loader/appcache/ApplicationCacheStorage.h
+++ b/Source/WebCore/loader/appcache/ApplicationCacheStorage.h
@@ -74,6 +74,7 @@ public:
ApplicationCacheGroup* fallbackCacheGroupForURL(const KURL&); // Cache that has a fallback entry to load a main resource from if normal loading fails.
ApplicationCacheGroup* findOrCreateCacheGroup(const KURL& manifestURL);
+ ApplicationCacheGroup* findInMemoryCacheGroup(const KURL& manifestURL) const;
void cacheGroupDestroyed(ApplicationCacheGroup*);
void cacheGroupMadeObsolete(ApplicationCacheGroup*);
@@ -95,7 +96,6 @@ public:
void vacuumDatabaseFile();
void getOriginsWithCache(HashSet<RefPtr<SecurityOrigin>, SecurityOriginHash>&);
- void deleteEntriesForOrigin(SecurityOrigin*);
void deleteAllEntries();
static int64_t unknownQuota() { return -1; }
@@ -113,6 +113,9 @@ private:
bool store(ApplicationCacheResource*, unsigned cacheStorageID);
bool ensureOriginRecord(const SecurityOrigin*);
+ bool shouldStoreResourceAsFlatFile(ApplicationCacheResource*);
+ void deleteTables();
+ bool writeDataToUniqueFileInDirectory(SharedBuffer*, const String& directory, String& outFilename);
void loadManifestHostHashes();
@@ -124,6 +127,8 @@ private:
bool executeSQLCommand(const String&);
void checkForMaxSizeReached();
+ void checkForDeletedResources();
+ long long flatFileAreaSize();
String m_cacheDirectory;
String m_cacheFile;
diff --git a/Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp b/Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp
index 7979423..6e0a1eb 100644
--- a/Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp
+++ b/Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp
@@ -546,9 +546,9 @@ PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(const String& markupString
// Add favicon if one exists for this page, if we are archiving the entire page.
if (nodesSize && nodes[0]->isDocumentNode() && iconDatabase().isEnabled()) {
- const String& iconURL = iconDatabase().iconURLForPageURL(responseURL);
- if (!iconURL.isEmpty() && iconDatabase().iconDataKnownForIconURL(iconURL)) {
- if (Image* iconImage = iconDatabase().iconForPageURL(responseURL, IntSize(16, 16))) {
+ const String& iconURL = iconDatabase().synchronousIconURLForPageURL(responseURL);
+ if (!iconURL.isEmpty() && iconDatabase().synchronousIconDataKnownForIconURL(iconURL)) {
+ if (Image* iconImage = iconDatabase().synchronousIconForPageURL(responseURL, IntSize(16, 16))) {
if (RefPtr<ArchiveResource> resource = ArchiveResource::create(iconImage->data(), KURL(ParsedURLString, iconURL), "image/x-icon", "", ""))
subresources.append(resource.release());
}
diff --git a/Source/WebCore/loader/cache/CachedFont.cpp b/Source/WebCore/loader/cache/CachedFont.cpp
index 19eb3ba..ea2ee14 100644
--- a/Source/WebCore/loader/cache/CachedFont.cpp
+++ b/Source/WebCore/loader/cache/CachedFont.cpp
@@ -117,7 +117,7 @@ bool CachedFont::ensureCustomFontData()
return m_fontData;
}
-FontPlatformData CachedFont::platformDataFromCustomData(float size, bool bold, bool italic, FontOrientation orientation, FontWidthVariant widthVariant, FontRenderingMode renderingMode)
+FontPlatformData CachedFont::platformDataFromCustomData(float size, bool bold, bool italic, FontOrientation orientation, TextOrientation textOrientation, FontWidthVariant widthVariant, FontRenderingMode renderingMode)
{
#if ENABLE(SVG_FONTS)
if (m_externalSVGDocument)
@@ -125,7 +125,7 @@ FontPlatformData CachedFont::platformDataFromCustomData(float size, bool bold, b
#endif
#ifdef STORE_FONT_CUSTOM_PLATFORM_DATA
ASSERT(m_fontData);
- return m_fontData->fontPlatformData(static_cast<int>(size), bold, italic, orientation, widthVariant, renderingMode);
+ return m_fontData->fontPlatformData(static_cast<int>(size), bold, italic, orientation, textOrientation, widthVariant, renderingMode);
#else
return FontPlatformData();
#endif
diff --git a/Source/WebCore/loader/cache/CachedFont.h b/Source/WebCore/loader/cache/CachedFont.h
index cdc32ba..d677f7b 100644
--- a/Source/WebCore/loader/cache/CachedFont.h
+++ b/Source/WebCore/loader/cache/CachedFont.h
@@ -30,6 +30,7 @@
#include "FontOrientation.h"
#include "FontRenderingMode.h"
#include "FontWidthVariant.h"
+#include "TextOrientation.h"
#include <wtf/Vector.h>
#if ENABLE(SVG_FONTS)
@@ -64,7 +65,7 @@ public:
void beginLoadIfNeeded(CachedResourceLoader* dl);
bool ensureCustomFontData();
- FontPlatformData platformDataFromCustomData(float size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
+ FontPlatformData platformDataFromCustomData(float size, bool bold, bool italic, FontOrientation = Horizontal, TextOrientation = TextOrientationVerticalRight, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
#if ENABLE(SVG_FONTS)
bool isSVGFont() const { return m_isSVGFont; }
diff --git a/Source/WebCore/loader/cache/CachedImage.cpp b/Source/WebCore/loader/cache/CachedImage.cpp
index b309ae6..cc49415 100644
--- a/Source/WebCore/loader/cache/CachedImage.cpp
+++ b/Source/WebCore/loader/cache/CachedImage.cpp
@@ -325,16 +325,6 @@ void CachedImage::error(CachedResource::Status status)
checkNotify();
}
-void CachedImage::checkNotify()
-{
- if (isLoading())
- return;
-
- CachedResourceClientWalker w(m_clients);
- while (CachedResourceClient* c = w.next())
- c->notifyFinished(this);
-}
-
void CachedImage::destroyDecodedData()
{
bool canDeleteImage = !m_image || (m_image->hasOneRef() && m_image->isBitmapImage());
diff --git a/Source/WebCore/loader/cache/CachedImage.h b/Source/WebCore/loader/cache/CachedImage.h
index 3242409..42c7814 100644
--- a/Source/WebCore/loader/cache/CachedImage.h
+++ b/Source/WebCore/loader/cache/CachedImage.h
@@ -71,8 +71,6 @@ public:
// For compatibility, images keep loading even if there are HTTP errors.
virtual bool shouldIgnoreHTTPStatusCodeErrors() const { return true; }
- void checkNotify();
-
virtual bool isImage() const { return true; }
void clear();
diff --git a/Source/WebCore/loader/cache/CachedResource.cpp b/Source/WebCore/loader/cache/CachedResource.cpp
index 0f9ff45..9413472 100644
--- a/Source/WebCore/loader/cache/CachedResource.cpp
+++ b/Source/WebCore/loader/cache/CachedResource.cpp
@@ -93,8 +93,8 @@ CachedResource::CachedResource(const String& url, Type type)
, m_loading(false)
, m_type(type)
, m_status(Pending)
- , m_deleted(false)
#ifndef NDEBUG
+ , m_deleted(false)
, m_lruIndex(0)
#endif
, m_nextInAllResourcesList(0)
@@ -118,13 +118,8 @@ CachedResource::~CachedResource()
ASSERT(!m_deleted);
ASSERT(url().isNull() || memoryCache()->resourceForURL(KURL(ParsedURLString, url())) != this);
- if (m_deleted) {
- // FIXME: Remove when http://webkit.org/b/53045 is fixed.
- CRASH();
- }
-
- m_deleted = true;
#ifndef NDEBUG
+ m_deleted = true;
cachedResourceLeakCounter.decrement();
#endif
@@ -139,15 +134,33 @@ void CachedResource::load(CachedResourceLoader* cachedResourceLoader, bool incre
m_loading = true;
}
+void CachedResource::checkNotify()
+{
+ if (isLoading())
+ return;
+
+ CachedResourceClientWalker w(m_clients);
+ while (CachedResourceClient* c = w.next())
+ c->notifyFinished(this);
+}
+
void CachedResource::data(PassRefPtr<SharedBuffer>, bool allDataReceived)
{
if (!allDataReceived)
return;
setLoading(false);
- CachedResourceClientWalker w(m_clients);
- while (CachedResourceClient* c = w.next())
- c->notifyFinished(this);
+ checkNotify();
+}
+
+void CachedResource::error(CachedResource::Status status)
+{
+ setStatus(status);
+ ASSERT(errorOccurred());
+ m_data.clear();
+
+ setLoading(false);
+ checkNotify();
}
void CachedResource::finish()
diff --git a/Source/WebCore/loader/cache/CachedResource.h b/Source/WebCore/loader/cache/CachedResource.h
index 3379f8c..16920a5 100644
--- a/Source/WebCore/loader/cache/CachedResource.h
+++ b/Source/WebCore/loader/cache/CachedResource.h
@@ -86,7 +86,7 @@ public:
virtual void setEncoding(const String&) { }
virtual String encoding() const { return String(); }
virtual void data(PassRefPtr<SharedBuffer> data, bool allDataReceived);
- virtual void error(CachedResource::Status) { }
+ virtual void error(CachedResource::Status);
virtual bool shouldIgnoreHTTPStatusCodeErrors() const { return false; }
@@ -217,6 +217,8 @@ public:
void updateResponseAfterRevalidation(const ResourceResponse& validatingResponse);
protected:
+ void checkNotify();
+
void setEncodedSize(unsigned);
void setDecodedSize(unsigned);
void didAccessDecodedData(double timeStamp);
@@ -266,9 +268,8 @@ private:
unsigned m_type : 3; // Type
unsigned m_status : 3; // Status
- // FIXME: Move m_deleted back inside NDEBUG when http://webkit.org/b/53045 is fixed.
- bool m_deleted;
#ifndef NDEBUG
+ bool m_deleted;
unsigned m_lruIndex;
#endif
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
index 56715c6..3b6a0b2 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
@@ -34,6 +34,7 @@
#include "CachedScript.h"
#include "CachedXSLStyleSheet.h"
#include "Console.h"
+#include "ContentSecurityPolicy.h"
#include "DOMWindow.h"
#include "Document.h"
#include "Frame.h"
@@ -41,7 +42,6 @@
#include "FrameLoaderClient.h"
#include "HTMLElement.h"
#include "Logging.h"
-#include "NestingLevelIncrementer.h"
#include "MemoryCache.h"
#include "PingLoader.h"
#include "ResourceLoadScheduler.h"
@@ -85,21 +85,18 @@ CachedResourceLoader::CachedResourceLoader(Document* document)
, m_autoLoadImages(true)
, m_loadFinishing(false)
, m_allowStaleResources(false)
+<<<<<<< HEAD
#ifdef ANDROID_BLOCK_NETWORK_IMAGE
, m_blockNetworkImage(false)
#endif
, m_isInMethod(0)
+=======
+>>>>>>> webkit.org at r82507
{
}
CachedResourceLoader::~CachedResourceLoader()
{
- // Try to catch https://bugs.webkit.org/show_bug.cgi?id=54486
- // Crashes under CachedResourceLoader::revalidateResource
- // FIXME: Remove this and the related code when it has served its purpose.
- if (m_isInMethod)
- CRASH();
-
m_document = 0;
cancelRequests();
@@ -131,7 +128,6 @@ Frame* CachedResourceLoader::frame() const
CachedImage* CachedResourceLoader::requestImage(const String& url)
{
- NestingLevelIncrementer debugIncrementer(m_isInMethod);
if (Frame* f = frame()) {
Settings* settings = f->settings();
if (!f->loader()->client()->allowImages(!settings || settings->areImagesEnabled()))
@@ -169,7 +165,6 @@ CachedCSSStyleSheet* CachedResourceLoader::requestCSSStyleSheet(const String& ur
CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(const String& requestURL, const String& charset)
{
- NestingLevelIncrementer debugIncrementer(m_isInMethod);
KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(KURL(KURL(), requestURL));
if (CachedResource* existing = memoryCache()->resourceForURL(url)) {
@@ -235,9 +230,6 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
}
break;
#endif
- default:
- ASSERT_NOT_REACHED();
- break;
}
// Given that the load is allowed by the same-origin policy, we should
@@ -271,17 +263,17 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
// Prefetch cannot affect the current document.
break;
#endif
- default:
- ASSERT_NOT_REACHED();
- break;
}
// FIXME: Consider letting the embedder block mixed content loads.
+
+ if (type == CachedResource::Script && !m_document->contentSecurityPolicy()->allowScriptFromSource(url))
+ return false;
+
return true;
}
CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type, const String& resourceURL, const String& charset, ResourceLoadPriority priority, bool forPreload)
{
- NestingLevelIncrementer debugIncrementer(m_isInMethod);
KURL url = m_document->completeURL(resourceURL);
LOG(ResourceLoading, "CachedResourceLoader::requestResource '%s', charset '%s', priority=%d, forPreload=%u", url.string().latin1().data(), charset.latin1().data(), priority, forPreload);
@@ -348,7 +340,8 @@ CachedResource* CachedResourceLoader::revalidateResource(CachedResource* resourc
ASSERT(resource->canUseCacheValidator());
ASSERT(!resource->resourceToRevalidate());
- const String& url = resource->url();
+ // Copy the URL out of the resource to be revalidated in case it gets deleted by the remove() call below.
+ String url = resource->url();
CachedResource* newResource = createResource(resource->type(), KURL(ParsedURLString, url), resource->encoding());
LOG(ResourceLoading, "Resource %p created to revalidate %p", newResource, resource);
@@ -489,7 +482,6 @@ void CachedResourceLoader::printAccessDeniedMessage(const KURL& url) const
void CachedResourceLoader::setAutoLoadImages(bool enable)
{
- NestingLevelIncrementer debugIncrementer(m_isInMethod);
if (enable == m_autoLoadImages)
return;
@@ -566,7 +558,6 @@ void CachedResourceLoader::removeCachedResource(CachedResource* resource) const
void CachedResourceLoader::load(CachedResource* resource, bool incremental, SecurityCheckPolicy securityCheck, bool sendResourceLoadCallbacks)
{
- NestingLevelIncrementer debugIncrementer(m_isInMethod);
incrementRequestCount(resource);
RefPtr<CachedResourceRequest> request = CachedResourceRequest::load(this, resource, incremental, securityCheck, sendResourceLoadCallbacks);
@@ -576,7 +567,6 @@ void CachedResourceLoader::load(CachedResource* resource, bool incremental, Secu
void CachedResourceLoader::loadDone(CachedResourceRequest* request)
{
- NestingLevelIncrementer debugIncrementer(m_isInMethod);
m_loadFinishing = false;
RefPtr<CachedResourceRequest> protect(request);
if (request)
@@ -653,7 +643,6 @@ int CachedResourceLoader::requestCount()
void CachedResourceLoader::preload(CachedResource::Type type, const String& url, const String& charset, bool referencedFromBody)
{
- NestingLevelIncrementer debugIncrementer(m_isInMethod);
bool hasRendering = m_document->body() && m_document->body()->renderer();
if (!hasRendering && (referencedFromBody || type == CachedResource::ImageResource)) {
// Don't preload images or body resources before we have something to draw. This prevents
@@ -680,7 +669,6 @@ void CachedResourceLoader::checkForPendingPreloads()
void CachedResourceLoader::requestPreload(CachedResource::Type type, const String& url, const String& charset)
{
- NestingLevelIncrementer debugIncrementer(m_isInMethod);
String encoding;
if (type == CachedResource::Script || type == CachedResource::CSSStyleSheet)
encoding = charset.isEmpty() ? m_document->charset() : charset;
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.h b/Source/WebCore/loader/cache/CachedResourceLoader.h
index 0302010..a68ebd3 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.h
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.h
@@ -153,12 +153,15 @@ private:
bool m_autoLoadImages : 1;
bool m_loadFinishing : 1;
bool m_allowStaleResources : 1;
+<<<<<<< HEAD
#ifdef ANDROID_BLOCK_NETWORK_IMAGE
bool m_blockNetworkImage : 1;
#endif
// FIME: For debugging, remove.
unsigned m_isInMethod;
+=======
+>>>>>>> webkit.org at r82507
};
}
diff --git a/Source/WebCore/loader/cache/CachedScript.cpp b/Source/WebCore/loader/cache/CachedScript.cpp
index bfd39c5..e1a8a32 100644
--- a/Source/WebCore/loader/cache/CachedScript.cpp
+++ b/Source/WebCore/loader/cache/CachedScript.cpp
@@ -88,6 +88,8 @@ const String& CachedScript::script()
m_script += m_decoder->flush();
setDecodedSize(m_script.length() * sizeof(UChar));
}
+ m_decodedDataDeletionTimer.startOneShot(0);
+
return m_script;
}
@@ -102,16 +104,6 @@ void CachedScript::data(PassRefPtr<SharedBuffer> data, bool allDataReceived)
checkNotify();
}
-void CachedScript::checkNotify()
-{
- if (isLoading())
- return;
-
- CachedResourceClientWalker w(m_clients);
- while (CachedResourceClient* c = w.next())
- c->notifyFinished(this);
-}
-
void CachedScript::error(CachedResource::Status status)
{
setStatus(status);
@@ -125,7 +117,7 @@ void CachedScript::destroyDecodedData()
m_script = String();
unsigned extraSize = 0;
#if USE(JSC)
- if (m_sourceProviderCache)
+ if (m_sourceProviderCache && m_clients.isEmpty())
m_sourceProviderCache->clear();
extraSize = m_sourceProviderCache ? m_sourceProviderCache->byteSize() : 0;
diff --git a/Source/WebCore/loader/cache/CachedScript.h b/Source/WebCore/loader/cache/CachedScript.h
index 85c3805..a4ea453 100644
--- a/Source/WebCore/loader/cache/CachedScript.h
+++ b/Source/WebCore/loader/cache/CachedScript.h
@@ -55,8 +55,6 @@ namespace WebCore {
virtual void data(PassRefPtr<SharedBuffer> data, bool allDataReceived);
virtual void error(Status);
- void checkNotify();
-
virtual void destroyDecodedData();
#if USE(JSC)
// Allows JSC to cache additional information about the source.
diff --git a/Source/WebCore/loader/cf/SubresourceLoaderCF.cpp b/Source/WebCore/loader/cf/SubresourceLoaderCF.cpp
new file mode 100644
index 0000000..f6ce93f
--- /dev/null
+++ b/Source/WebCore/loader/cf/SubresourceLoaderCF.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SubresourceLoader.h"
+
+#include "SubresourceLoaderClient.h"
+
+namespace WebCore {
+
+#if HAVE(CFNETWORK_DATA_ARRAY_CALLBACK)
+void SubresourceLoader::didReceiveDataArray(CFArrayRef dataArray)
+{
+ // Reference the object in this method since the additional processing can do
+ // anything including removing the last reference to this object; one example of this is 3266216.
+ RefPtr<SubresourceLoader> protect(this);
+
+ ResourceLoader::didReceiveDataArray(dataArray);
+
+ // A subresource loader does not load multipart sections progressively.
+ // So don't deliver any data to the loader yet.
+ if (!m_loadingMultipartContent && m_client) {
+ CFIndex arrayCount = CFArrayGetCount(dataArray);
+ for (CFIndex i = 0; i < arrayCount; ++i) {
+ CFDataRef data = reinterpret_cast<CFDataRef>(CFArrayGetValueAtIndex(dataArray, i));
+ m_client->didReceiveData(this, reinterpret_cast<const char *>(CFDataGetBytePtr(data)), static_cast<int>(CFDataGetLength(data)));
+ }
+ }
+}
+#endif
+
+}
diff --git a/Source/WebCore/loader/icon/IconDatabase.cpp b/Source/WebCore/loader/icon/IconDatabase.cpp
index 26f3bb7..e5578e0 100644
--- a/Source/WebCore/loader/icon/IconDatabase.cpp
+++ b/Source/WebCore/loader/icon/IconDatabase.cpp
@@ -58,7 +58,6 @@
namespace WebCore {
-static IconDatabase* sharedIconDatabase = 0;
static int databaseCleanupCounter = 0;
// This version number is in the DB and marks the current generation of the schema
@@ -85,21 +84,22 @@ static String urlForLogging(const String& url)
}
#endif
+class DefaultIconDatabaseClient : public IconDatabaseClient {
+public:
+ virtual bool performImport() { return true; }
+ virtual void didImportIconURLForPageURL(const String&) { }
+ virtual void didImportIconDataForPageURL(const String&) { }
+ virtual void didChangeIconForPageURL(const String&) { }
+ virtual void didRemoveAllIcons() { }
+ virtual void didFinishURLImport() { }
+};
+
static IconDatabaseClient* defaultClient()
{
- static IconDatabaseClient* defaultClient = new IconDatabaseClient();
+ static IconDatabaseClient* defaultClient = new DefaultIconDatabaseClient();
return defaultClient;
}
-IconDatabase& iconDatabase()
-{
- if (!sharedIconDatabase) {
- ScriptController::initializeThreading();
- sharedIconDatabase = new IconDatabase;
- }
- return *sharedIconDatabase;
-}
-
// ************************
// *** Main Thread Only ***
// ************************
@@ -117,7 +117,7 @@ void IconDatabase::setClient(IconDatabaseClient* client)
m_client = client;
}
-bool IconDatabase::open(const String& databasePath)
+bool IconDatabase::open(const String& directory, const String& filename)
{
ASSERT_NOT_SYNC_THREAD();
@@ -129,10 +129,10 @@ bool IconDatabase::open(const String& databasePath)
return false;
}
- m_databaseDirectory = databasePath.crossThreadString();
+ m_databaseDirectory = directory.crossThreadString();
// Formulate the full path for the database file
- m_completeDatabasePath = pathByAppendingComponent(m_databaseDirectory, defaultDatabaseFilename());
+ m_completeDatabasePath = pathByAppendingComponent(m_databaseDirectory, filename);
// Lock here as well as first thing in the thread so the thread doesn't actually commence until the createThread() call
// completes and m_syncThreadRunning is properly set
@@ -217,7 +217,7 @@ void IconDatabase::removeAllIcons()
wakeSyncThread();
}
-Image* IconDatabase::iconForPageURL(const String& pageURLOriginal, const IntSize& size)
+Image* IconDatabase::synchronousIconForPageURL(const String& pageURLOriginal, const IntSize& size)
{
ASSERT_NOT_SYNC_THREAD();
@@ -301,10 +301,10 @@ void IconDatabase::readIconForPageURLFromDisk(const String& pageURL)
// The effect of asking for an Icon for a pageURL automatically queues it to be read from disk
// if it hasn't already been set in memory. The special IntSize (0, 0) is a special way of telling
// that method "I don't care about the actual Image, i just want you to make sure you're getting it from disk.
- iconForPageURL(pageURL, IntSize(0,0));
+ synchronousIconForPageURL(pageURL, IntSize(0, 0));
}
-String IconDatabase::iconURLForPageURL(const String& pageURLOriginal)
+String IconDatabase::synchronousIconURLForPageURL(const String& pageURLOriginal)
{
ASSERT_NOT_SYNC_THREAD();
@@ -565,7 +565,7 @@ void IconDatabase::setIconDataForIconURL(PassRefPtr<SharedBuffer> dataOriginal,
for (unsigned i = 0; i < pageURLs.size(); ++i) {
LOG(IconDatabase, "Dispatching notification that retaining pageURL %s has a new icon", urlForLogging(pageURLs[i]).ascii().data());
- m_client->dispatchDidAddIconForPageURL(pageURLs[i]);
+ m_client->didChangeIconForPageURL(pageURLs[i]);
pool.cycle();
}
@@ -637,11 +637,11 @@ void IconDatabase::setIconURLForPageURL(const String& iconURLOriginal, const Str
LOG(IconDatabase, "Dispatching notification that we changed an icon mapping for url %s", urlForLogging(pageURL).ascii().data());
AutodrainedPool pool;
- m_client->dispatchDidAddIconForPageURL(pageURL);
+ m_client->didChangeIconForPageURL(pageURL);
}
}
-IconLoadDecision IconDatabase::loadDecisionForIconURL(const String& iconURL, DocumentLoader* notificationDocumentLoader)
+IconLoadDecision IconDatabase::synchronousLoadDecisionForIconURL(const String& iconURL, DocumentLoader* notificationDocumentLoader)
{
ASSERT_NOT_SYNC_THREAD();
@@ -667,12 +667,13 @@ IconLoadDecision IconDatabase::loadDecisionForIconURL(const String& iconURL, Doc
// Otherwise - since we refuse to perform I/O on the main thread to find out for sure - we return the answer that says
// "You might be asked to load this later, so flag that"
LOG(IconDatabase, "Don't know if we should load %s or not - adding %p to the set of document loaders waiting on a decision", iconURL.ascii().data(), notificationDocumentLoader);
- m_loadersPendingDecision.add(notificationDocumentLoader);
+ if (notificationDocumentLoader)
+ m_loadersPendingDecision.add(notificationDocumentLoader);
return IconLoadUnknown;
}
-bool IconDatabase::iconDataKnownForIconURL(const String& iconURL)
+bool IconDatabase::synchronousIconDataKnownForIconURL(const String& iconURL)
{
ASSERT_NOT_SYNC_THREAD();
@@ -775,6 +776,7 @@ IconDatabase::IconDatabase()
, m_imported(false)
, m_isImportedSet(false)
{
+ LOG(IconDatabase, "Creating IconDatabase %p", this);
ASSERT(isMainThread());
}
@@ -1257,7 +1259,7 @@ void IconDatabase::performURLImport()
{
MutexLocker locker(m_pendingReadingLock);
if (m_pageURLsPendingImport.contains(pageURL)) {
- m_client->dispatchDidAddIconForPageURL(pageURL);
+ dispatchDidImportIconURLForPageURLOnMainThread(pageURL);
m_pageURLsPendingImport.remove(pageURL);
pool.cycle();
@@ -1292,7 +1294,6 @@ void IconDatabase::performURLImport()
// Loop through the urls pending import
// Remove unretained ones if database cleanup is allowed
// Keep a set of ones that are retained and pending notification
-
{
MutexLocker locker(m_urlAndIconLock);
@@ -1331,13 +1332,16 @@ void IconDatabase::performURLImport()
// Now that we don't hold any locks, perform the actual notifications
for (unsigned i = 0; i < urlsToNotify.size(); ++i) {
LOG(IconDatabase, "Notifying icon info known for pageURL %s", urlsToNotify[i].ascii().data());
- m_client->dispatchDidAddIconForPageURL(urlsToNotify[i]);
+ dispatchDidImportIconURLForPageURLOnMainThread(urlsToNotify[i]);
if (shouldStopThreadActivity())
return;
pool.cycle();
}
+ // Notify the client that the URL import is complete in case it's managing its own pending notifications.
+ dispatchDidFinishURLImportOnMainThread();
+
// Notify all DocumentLoaders that were waiting for an icon load decision on the main thread
callOnMainThread(notifyPendingLoadDecisionsOnMainThread, this);
}
@@ -1540,7 +1544,7 @@ bool IconDatabase::readFromDatabase()
HashSet<String>::iterator end = urlsToNotify.end();
for (unsigned iteration = 0; iter != end; ++iter, ++iteration) {
LOG(IconDatabase, "Notifying icon received for pageURL %s", urlForLogging(*iter).ascii().data());
- m_client->dispatchDidAddIconForPageURL(*iter);
+ dispatchDidImportIconDataForPageURLOnMainThread(*iter);
if (shouldStopThreadActivity())
return didAnyWork;
@@ -1738,7 +1742,7 @@ void IconDatabase::removeAllIconsOnThread()
createDatabaseTables(m_syncDB);
LOG(IconDatabase, "Dispatching notification that we removed all icons");
- m_client->dispatchDidRemoveAllIcons();
+ dispatchDidRemoveAllIconsOnMainThread();
}
void IconDatabase::deleteAllPreparedStatements()
@@ -2111,6 +2115,132 @@ void IconDatabase::setWasExcludedFromBackup()
SQLiteStatement(m_syncDB, "INSERT INTO IconDatabaseInfo (key, value) VALUES ('ExcludedFromBackup', 1)").executeCommand();
}
+class ClientWorkItem {
+public:
+ ClientWorkItem(IconDatabaseClient* client)
+ : m_client(client)
+ { }
+ virtual void performWork() = 0;
+ virtual ~ClientWorkItem() { }
+
+protected:
+ IconDatabaseClient* m_client;
+};
+
+class ImportedIconURLForPageURLWorkItem : public ClientWorkItem {
+public:
+ ImportedIconURLForPageURLWorkItem(IconDatabaseClient* client, const String& pageURL)
+ : ClientWorkItem(client)
+ , m_pageURL(new String(pageURL.threadsafeCopy()))
+ { }
+
+ virtual ~ImportedIconURLForPageURLWorkItem()
+ {
+ delete m_pageURL;
+ }
+
+ virtual void performWork()
+ {
+ ASSERT(m_client);
+ m_client->didImportIconURLForPageURL(*m_pageURL);
+ m_client = 0;
+ }
+
+private:
+ String* m_pageURL;
+};
+
+class ImportedIconDataForPageURLWorkItem : public ClientWorkItem {
+public:
+ ImportedIconDataForPageURLWorkItem(IconDatabaseClient* client, const String& pageURL)
+ : ClientWorkItem(client)
+ , m_pageURL(new String(pageURL.threadsafeCopy()))
+ { }
+
+ virtual ~ImportedIconDataForPageURLWorkItem()
+ {
+ delete m_pageURL;
+ }
+
+ virtual void performWork()
+ {
+ ASSERT(m_client);
+ m_client->didImportIconDataForPageURL(*m_pageURL);
+ m_client = 0;
+ }
+
+private:
+ String* m_pageURL;
+};
+
+class RemovedAllIconsWorkItem : public ClientWorkItem {
+public:
+ RemovedAllIconsWorkItem(IconDatabaseClient* client)
+ : ClientWorkItem(client)
+ { }
+
+ virtual void performWork()
+ {
+ ASSERT(m_client);
+ m_client->didRemoveAllIcons();
+ m_client = 0;
+ }
+};
+
+class FinishedURLImport : public ClientWorkItem {
+public:
+ FinishedURLImport(IconDatabaseClient* client)
+ : ClientWorkItem(client)
+ { }
+
+ virtual void performWork()
+ {
+ ASSERT(m_client);
+ m_client->didFinishURLImport();
+ m_client = 0;
+ }
+};
+
+static void performWorkItem(void* context)
+{
+ ClientWorkItem* item = static_cast<ClientWorkItem*>(context);
+ item->performWork();
+ delete item;
+}
+
+void IconDatabase::dispatchDidImportIconURLForPageURLOnMainThread(const String& pageURL)
+{
+ ASSERT_ICON_SYNC_THREAD();
+
+ ImportedIconURLForPageURLWorkItem* work = new ImportedIconURLForPageURLWorkItem(m_client, pageURL);
+ callOnMainThread(performWorkItem, work);
+}
+
+void IconDatabase::dispatchDidImportIconDataForPageURLOnMainThread(const String& pageURL)
+{
+ ASSERT_ICON_SYNC_THREAD();
+
+ ImportedIconDataForPageURLWorkItem* work = new ImportedIconDataForPageURLWorkItem(m_client, pageURL);
+ callOnMainThread(performWorkItem, work);
+}
+
+void IconDatabase::dispatchDidRemoveAllIconsOnMainThread()
+{
+ ASSERT_ICON_SYNC_THREAD();
+
+ RemovedAllIconsWorkItem* work = new RemovedAllIconsWorkItem(m_client);
+ callOnMainThread(performWorkItem, work);
+}
+
+void IconDatabase::dispatchDidFinishURLImportOnMainThread()
+{
+ ASSERT_ICON_SYNC_THREAD();
+
+ FinishedURLImport* work = new FinishedURLImport(m_client);
+ callOnMainThread(performWorkItem, work);
+}
+
+
} // namespace WebCore
#endif // ENABLE(ICONDATABASE)
diff --git a/Source/WebCore/loader/icon/IconDatabase.h b/Source/WebCore/loader/icon/IconDatabase.h
index 8617430..7392245 100644
--- a/Source/WebCore/loader/icon/IconDatabase.h
+++ b/Source/WebCore/loader/icon/IconDatabase.h
@@ -27,17 +27,20 @@
#ifndef IconDatabase_h
#define IconDatabase_h
+#include "IconDatabaseBase.h"
#include "Timer.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/text/StringHash.h>
+#include <wtf/text/WTFString.h>
#if ENABLE(ICONDATABASE)
#include "SQLiteDatabase.h"
#include <wtf/Threading.h>
-#endif
+#endif // ENABLE(ICONDATABASE)
namespace WebCore {
@@ -56,41 +59,48 @@ class SharedBuffer;
class SQLTransaction;
#endif
-enum IconLoadDecision {
- IconLoadYes,
- IconLoadNo,
- IconLoadUnknown
+#if !ENABLE(ICONDATABASE)
+// For builds with IconDatabase disabled, they'll just use a default derivation of IconDatabaseBase. Which does nothing.
+class IconDatabase : public IconDatabaseBase {
+public:
+ static void delayDatabaseCleanup() { }
+ static String defaultDatabaseFilename() { return "WebpageIcons.db"; }
};
+#else
-class IconDatabase {
- WTF_MAKE_NONCOPYABLE(IconDatabase); WTF_MAKE_FAST_ALLOCATED;
+class IconDatabase : public IconDatabaseBase {
+ WTF_MAKE_FAST_ALLOCATED;
+
// *** Main Thread Only ***
public:
- void setClient(IconDatabaseClient*);
+ static PassOwnPtr<IconDatabase> create() { return new IconDatabase; }
+ ~IconDatabase();
+
+ virtual void setClient(IconDatabaseClient*);
- bool open(const String& path);
- void close();
+ virtual bool open(const String& directory, const String& filename);
+ virtual void close();
- void removeAllIcons();
+ virtual void removeAllIcons();
- Image* iconForPageURL(const String&, const IntSize&);
void readIconForPageURLFromDisk(const String&);
- String iconURLForPageURL(const String&);
- Image* defaultIcon(const IntSize&);
- void retainIconForPageURL(const String&);
- void releaseIconForPageURL(const String&);
+ virtual Image* defaultIcon(const IntSize&);
- void setIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String&);
- void setIconURLForPageURL(const String& iconURL, const String& pageURL);
+ virtual void retainIconForPageURL(const String&);
+ virtual void releaseIconForPageURL(const String&);
+ virtual void setIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String&);
+ virtual void setIconURLForPageURL(const String& iconURL, const String& pageURL);
- IconLoadDecision loadDecisionForIconURL(const String&, DocumentLoader*);
- bool iconDataKnownForIconURL(const String&);
+ virtual Image* synchronousIconForPageURL(const String&, const IntSize&);
+ virtual String synchronousIconURLForPageURL(const String&);
+ virtual bool synchronousIconDataKnownForIconURL(const String&);
+ virtual IconLoadDecision synchronousLoadDecisionForIconURL(const String&, DocumentLoader*);
- void setEnabled(bool enabled);
- bool isEnabled() const;
+ virtual void setEnabled(bool);
+ virtual bool isEnabled() const;
- void setPrivateBrowsingEnabled(bool flag);
+ virtual void setPrivateBrowsingEnabled(bool flag);
bool isPrivateBrowsingEnabled() const;
static void delayDatabaseCleanup();
@@ -98,17 +108,15 @@ public:
static void checkIntegrityBeforeOpening();
// Support for WebCoreStatistics in WebKit
- size_t pageURLMappingCount();
- size_t retainedPageURLCount();
- size_t iconRecordCount();
- size_t iconRecordCountWithData();
+ virtual size_t pageURLMappingCount();
+ virtual size_t retainedPageURLCount();
+ virtual size_t iconRecordCount();
+ virtual size_t iconRecordCountWithData();
private:
IconDatabase();
- ~IconDatabase();
- friend IconDatabase& iconDatabase();
+ friend IconDatabaseBase& iconDatabase();
-#if ENABLE(ICONDATABASE)
static void notifyPendingLoadDecisionsOnMainThread(void*);
void notifyPendingLoadDecisions();
@@ -123,15 +131,13 @@ private:
HashSet<RefPtr<DocumentLoader> > m_loadersPendingDecision;
RefPtr<IconRecord> m_defaultIconRecord;
-#endif // ENABLE(ICONDATABASE)
// *** Any Thread ***
public:
- bool isOpen() const;
- String databasePath() const;
+ virtual bool isOpen() const;
+ virtual String databasePath() const;
static String defaultDatabaseFilename();
-#if ENABLE(ICONDATABASE)
private:
PassRefPtr<IconRecord> getOrCreateIconRecord(const String& iconURL);
PageURLRecord* getOrCreatePageURLRecord(const String& pageURL);
@@ -166,17 +172,15 @@ private:
HashSet<String> m_pageURLsPendingImport;
HashSet<String> m_pageURLsInterestedInIcons;
HashSet<IconRecord*> m_iconsPendingReading;
-#endif // ENABLE(ICONDATABASE)
// *** Sync Thread Only ***
public:
// Should be used only on the sync thread and only by the Safari 2 Icons import procedure
- void importIconURLForPageURL(const String& iconURL, const String& pageURL);
- void importIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String& iconURL);
+ virtual void importIconURLForPageURL(const String& iconURL, const String& pageURL);
+ virtual void importIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String& iconURL);
- bool shouldStopThreadActivity() const;
+ virtual bool shouldStopThreadActivity() const;
-#if ENABLE(ICONDATABASE)
private:
static void* iconDatabaseSyncThreadStart(void *);
void* iconDatabaseSyncThread();
@@ -213,6 +217,12 @@ private:
void removeIconFromSQLDatabase(const String& iconURL);
void writeIconSnapshotToSQLDatabase(const IconSnapshot&);
+ // Methods to dispatch client callbacks on the main thread
+ void dispatchDidImportIconURLForPageURLOnMainThread(const String&);
+ void dispatchDidImportIconDataForPageURLOnMainThread(const String&);
+ void dispatchDidRemoveAllIconsOnMainThread();
+ void dispatchDidFinishURLImportOnMainThread();
+
// The client is set by the main thread before the thread starts, and from then on is only used by the sync thread
IconDatabaseClient* m_client;
@@ -236,11 +246,9 @@ private:
OwnPtr<SQLiteStatement> m_updateIconDataStatement;
OwnPtr<SQLiteStatement> m_setIconInfoStatement;
OwnPtr<SQLiteStatement> m_setIconDataStatement;
-#endif // ENABLE(ICONDATABASE)
};
-// Function to obtain the global icon database.
-IconDatabase& iconDatabase();
+#endif // !ENABLE(ICONDATABASE)
} // namespace WebCore
diff --git a/Source/WebCore/loader/icon/IconDatabaseBase.cpp b/Source/WebCore/loader/icon/IconDatabaseBase.cpp
new file mode 100644
index 0000000..f552412
--- /dev/null
+++ b/Source/WebCore/loader/icon/IconDatabaseBase.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "IconDatabaseBase.h"
+
+#include "IconDatabase.h"
+#include "SharedBuffer.h"
+
+namespace WebCore {
+
+String IconDatabaseBase::synchronousIconURLForPageURL(const String&)
+{
+ return String();
+}
+
+String IconDatabaseBase::databasePath() const
+{
+ return String();
+}
+
+bool IconDatabaseBase::open(const String&, const String&)
+{
+ return false;
+}
+
+static IconDatabaseBase* globalDatabase = 0;
+
+// Functions to get/set the global icon database.
+IconDatabaseBase& iconDatabase()
+{
+ if (globalDatabase)
+ return *globalDatabase;
+
+ static IconDatabaseBase* defaultDatabase = 0;
+ if (!defaultDatabase)
+ defaultDatabase = new IconDatabase;
+
+ return *defaultDatabase;
+}
+
+void setGlobalIconDatabase(IconDatabaseBase* newGlobalDatabase)
+{
+ globalDatabase = newGlobalDatabase;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/loader/icon/IconDatabaseBase.h b/Source/WebCore/loader/icon/IconDatabaseBase.h
new file mode 100644
index 0000000..bc665ba
--- /dev/null
+++ b/Source/WebCore/loader/icon/IconDatabaseBase.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef IconDatabaseBase_h
+#define IconDatabaseBase_h
+
+#include "SharedBuffer.h"
+
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class DocumentLoader;
+class IconDatabaseClient;
+class Image;
+class IntSize;
+
+enum IconLoadDecision {
+ IconLoadYes,
+ IconLoadNo,
+ IconLoadUnknown
+};
+
+class CallbackBase : public RefCounted<CallbackBase> {
+public:
+ virtual ~CallbackBase()
+ {
+ }
+
+ uint64_t callbackID() const { return m_callbackID; }
+
+protected:
+ CallbackBase(void* context)
+ : m_context(context)
+ , m_callbackID(generateCallbackID())
+ {
+ }
+
+ void* context() const { return m_context; }
+
+private:
+ static uint64_t generateCallbackID()
+ {
+ static uint64_t uniqueCallbackID = 1;
+ return uniqueCallbackID++;
+ }
+
+ void* m_context;
+ uint64_t m_callbackID;
+};
+
+template<typename EnumType>
+class EnumCallback : public CallbackBase {
+public:
+ typedef void (*CallbackFunction)(EnumType, void*);
+
+ static PassRefPtr<EnumCallback> create(void* context, CallbackFunction callback)
+ {
+ return adoptRef(new EnumCallback(context, callback));
+ }
+
+ virtual ~EnumCallback()
+ {
+ ASSERT(!m_callback);
+ }
+
+ void performCallback(EnumType result)
+ {
+ if (!m_callback)
+ return;
+ m_callback(result, context());
+ m_callback = 0;
+ }
+
+ void invalidate()
+ {
+ m_callback = 0;
+ }
+
+private:
+ EnumCallback(void* context, CallbackFunction callback)
+ : CallbackBase(context)
+ , m_callback(callback)
+ {
+ ASSERT(m_callback);
+ }
+
+ CallbackFunction m_callback;
+};
+
+template<typename ObjectType>
+class ObjectCallback : public CallbackBase {
+public:
+ typedef void (*CallbackFunction)(ObjectType, void*);
+
+ static PassRefPtr<ObjectCallback> create(void* context, CallbackFunction callback)
+ {
+ return adoptRef(new ObjectCallback(context, callback));
+ }
+
+ virtual ~ObjectCallback()
+ {
+ ASSERT(!m_callback);
+ }
+
+ void performCallback(ObjectType result)
+ {
+ if (!m_callback)
+ return;
+ m_callback(result, context());
+ m_callback = 0;
+ }
+
+ void invalidate()
+ {
+ m_callback = 0;
+ }
+
+private:
+ ObjectCallback(void* context, CallbackFunction callback)
+ : CallbackBase(context)
+ , m_callback(callback)
+ {
+ ASSERT(m_callback);
+ }
+
+ CallbackFunction m_callback;
+};
+
+typedef EnumCallback<IconLoadDecision> IconLoadDecisionCallback;
+typedef ObjectCallback<SharedBuffer*> IconDataCallback;
+
+class IconDatabaseBase {
+ WTF_MAKE_NONCOPYABLE(IconDatabaseBase);
+
+protected:
+ IconDatabaseBase() { }
+
+public:
+ virtual ~IconDatabaseBase() { }
+
+ // Used internally by WebCore
+ virtual bool isEnabled() const { return false; }
+
+ virtual void retainIconForPageURL(const String&) { }
+ virtual void releaseIconForPageURL(const String&) { }
+
+ virtual void setIconURLForPageURL(const String&, const String&) { }
+ virtual void setIconDataForIconURL(PassRefPtr<SharedBuffer>, const String&) { }
+
+ // Synchronous calls used internally by WebCore.
+ // Usage should be replaced by asynchronous calls.
+ virtual String synchronousIconURLForPageURL(const String&);
+ virtual bool synchronousIconDataKnownForIconURL(const String&) { return false; }
+ virtual IconLoadDecision synchronousLoadDecisionForIconURL(const String&, DocumentLoader*) { return IconLoadNo; }
+ virtual Image* synchronousIconForPageURL(const String&, const IntSize&) { return 0; }
+
+ // Asynchronous calls we should use to replace the above when supported.
+ virtual bool supportsAsynchronousMode() { return false; }
+ virtual void loadDecisionForIconURL(const String&, PassRefPtr<IconLoadDecisionCallback>) { }
+ virtual void iconDataForIconURL(const String&, PassRefPtr<IconDataCallback>) { }
+
+
+ // Used within one or more WebKit ports.
+ // We should try to remove these dependencies from the IconDatabaseBase class.
+ virtual void setEnabled(bool) { }
+
+ virtual Image* defaultIcon(const IntSize&) { return 0; }
+
+ virtual size_t pageURLMappingCount() { return 0; }
+ virtual size_t retainedPageURLCount() { return 0; }
+ virtual size_t iconRecordCount() { return 0; }
+ virtual size_t iconRecordCountWithData() { return 0; }
+
+ virtual void importIconURLForPageURL(const String&, const String&) { }
+ virtual void importIconDataForIconURL(PassRefPtr<SharedBuffer>, const String&) { }
+ virtual bool shouldStopThreadActivity() const { return true; }
+
+ virtual bool open(const String& directory, const String& filename);
+ virtual void close() { }
+ virtual void removeAllIcons() { }
+
+ virtual void setPrivateBrowsingEnabled(bool) { }
+ virtual void setClient(IconDatabaseClient*) { }
+
+ virtual bool isOpen() const { return false; }
+ virtual String databasePath() const;
+
+};
+
+// Functions to get/set the global icon database.
+IconDatabaseBase& iconDatabase();
+void setGlobalIconDatabase(IconDatabaseBase*);
+
+} // namespace WebCore
+
+#endif // IconDatabaseBase_h
diff --git a/Source/WebCore/loader/icon/IconDatabaseClient.h b/Source/WebCore/loader/icon/IconDatabaseClient.h
index f97a2a8..3d5f349 100644
--- a/Source/WebCore/loader/icon/IconDatabaseClient.h
+++ b/Source/WebCore/loader/icon/IconDatabaseClient.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,23 +29,20 @@
#ifndef IconDatabaseClient_h
#define IconDatabaseClient_h
-#include <wtf/FastAllocBase.h>
#include <wtf/Forward.h>
-#include <wtf/Noncopyable.h>
-
-// All of these client methods will be called from a non-main thread
-// Take appropriate measures
namespace WebCore {
class IconDatabaseClient {
- WTF_MAKE_NONCOPYABLE(IconDatabaseClient); WTF_MAKE_FAST_ALLOCATED;
public:
- IconDatabaseClient() { }
virtual ~IconDatabaseClient() { }
- virtual bool performImport() { return true; }
- virtual void dispatchDidRemoveAllIcons() { }
- virtual void dispatchDidAddIconForPageURL(const String& /*pageURL*/) { }
+
+ virtual bool performImport() = 0;
+ virtual void didImportIconURLForPageURL(const String&) = 0;
+ virtual void didImportIconDataForPageURL(const String&) = 0;
+ virtual void didChangeIconForPageURL(const String&) = 0;
+ virtual void didRemoveAllIcons() = 0;
+ virtual void didFinishURLImport() = 0;
};
} // namespace WebCore
diff --git a/Source/WebCore/loader/icon/IconDatabaseNone.cpp b/Source/WebCore/loader/icon/IconDatabaseNone.cpp
deleted file mode 100644
index de28cdd..0000000
--- a/Source/WebCore/loader/icon/IconDatabaseNone.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "IconDatabase.h"
-
-#if !ENABLE(ICONDATABASE)
-
-#include "PlatformString.h"
-#include "SharedBuffer.h"
-#include <wtf/StdLibExtras.h>
-
-namespace WebCore {
-
-static IconDatabase* sharedIconDatabase = 0;
-
-// This version number is in the DB and marks the current generation of the schema
-// Theoretically once the switch is flipped this should never change
-// Currently, an out-of-date schema causes the DB to be wiped and reset. This isn't
-// so bad during development but in the future, we would need to write a conversion
-// function to advance older released schemas to "current"
-const int currentDatabaseVersion = 5;
-
-// Icons expire once a day
-const int iconExpirationTime = 60*60*24;
-// Absent icons are rechecked once a week
-const int missingIconExpirationTime = 60*60*24*7;
-
-const int updateTimerDelay = 5;
-
-String IconDatabase::defaultDatabaseFilename()
-{
- DEFINE_STATIC_LOCAL(String, defaultDatabaseFilename, ("Icons.db"));
- return defaultDatabaseFilename.threadsafeCopy();
-}
-
-IconDatabase& iconDatabase()
-{
- if (!sharedIconDatabase)
- sharedIconDatabase = new IconDatabase;
- return *sharedIconDatabase;
-}
-
-IconDatabase::IconDatabase()
-{
-}
-
-bool IconDatabase::open(const String& /*databasePath*/)
-{
- return false;
-}
-
-bool IconDatabase::isOpen() const
-{
- return false;
-}
-
-void IconDatabase::close()
-{
-}
-
-String IconDatabase::databasePath() const
-{
- return String();
-}
-
-void IconDatabase::removeAllIcons()
-{
-}
-
-void IconDatabase::setPrivateBrowsingEnabled(bool /*flag*/)
-{
-}
-
-bool IconDatabase::isPrivateBrowsingEnabled() const
-{
- return false;
-}
-
-void IconDatabase::readIconForPageURLFromDisk(const String&)
-{
-
-}
-
-Image* IconDatabase::iconForPageURL(const String& /*pageURL*/, const IntSize& size)
-{
- return defaultIcon(size);
-}
-
-
-IconLoadDecision IconDatabase::loadDecisionForIconURL(const String&, DocumentLoader*)
-{
- return IconLoadNo;
-}
-
-bool IconDatabase::iconDataKnownForIconURL(const String&)
-{
- return false;
-}
-
-String IconDatabase::iconURLForPageURL(const String& /*pageURL*/)
-{
- return String();
-}
-
-Image* IconDatabase::defaultIcon(const IntSize& /*size*/)
-{
- return 0;
-}
-
-void IconDatabase::retainIconForPageURL(const String& /*pageURL*/)
-{
-}
-
-void IconDatabase::releaseIconForPageURL(const String& /*pageURL*/)
-{
-}
-
-void IconDatabase::setIconDataForIconURL(PassRefPtr<SharedBuffer> /*data*/, const String& /*iconURL*/)
-{
-}
-
-void IconDatabase::setIconURLForPageURL(const String& /*iconURL*/, const String& /*pageURL*/)
-{
-}
-
-void IconDatabase::setEnabled(bool /*enabled*/)
-{
-}
-
-bool IconDatabase::isEnabled() const
-{
- return false;
-}
-
-IconDatabase::~IconDatabase()
-{
- ASSERT_NOT_REACHED();
-}
-
-void IconDatabase::checkIntegrityBeforeOpening()
-{
-}
-
-void IconDatabase::delayDatabaseCleanup()
-{
-}
-
-void IconDatabase::allowDatabaseCleanup()
-{
-}
-
-size_t IconDatabase::pageURLMappingCount()
-{
- return 0;
-}
-
-size_t IconDatabase::retainedPageURLCount()
-{
- return 0;
-}
-
-size_t IconDatabase::iconRecordCount()
-{
- return 0;
-}
-
-size_t IconDatabase::iconRecordCountWithData()
-{
- return 0;
-}
-
-void IconDatabase::setClient(IconDatabaseClient*)
-{
-}
-
-// ************************
-// *** Sync Thread Only ***
-// ************************
-
-void IconDatabase::importIconURLForPageURL(const String&, const String&)
-{
-}
-
-void IconDatabase::importIconDataForIconURL(PassRefPtr<SharedBuffer>, const String&)
-{
-}
-
-bool IconDatabase::shouldStopThreadActivity() const
-{
- return true;
-}
-
-} // namespace WebCore
-
-#endif // !ENABLE(ICONDATABASE)
diff --git a/Source/WebCore/loader/mac/ResourceLoaderMac.mm b/Source/WebCore/loader/mac/ResourceLoaderMac.mm
index 3835517..b42f8e0 100644
--- a/Source/WebCore/loader/mac/ResourceLoaderMac.mm
+++ b/Source/WebCore/loader/mac/ResourceLoaderMac.mm
@@ -35,6 +35,10 @@
#include "FrameLoaderClient.h"
#include "ResourceHandle.h"
+#if HAVE(CFNETWORK_DATA_ARRAY_CALLBACK)
+#include "InspectorInstrumentation.h"
+#endif
+
namespace WebCore {
NSCachedURLResponse* ResourceLoader::willCacheResponse(ResourceHandle*, NSCachedURLResponse* response)
@@ -44,6 +48,44 @@ NSCachedURLResponse* ResourceLoader::willCacheResponse(ResourceHandle*, NSCached
return frameLoader()->client()->willCacheResponse(documentLoader(), identifier(), response);
}
+#if HAVE(CFNETWORK_DATA_ARRAY_CALLBACK)
+
+void ResourceLoader::didReceiveDataArray(CFArrayRef dataArray)
+{
+ // 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_shouldBufferData)
+ return;
+
+ if (!m_resourceData)
+ m_resourceData = SharedBuffer::create();
+
+ CFIndex arrayCount = CFArrayGetCount(dataArray);
+ for (CFIndex i = 0; i < arrayCount; ++i) {
+ CFDataRef data = static_cast<CFDataRef>(CFArrayGetValueAtIndex(dataArray, i));
+ int dataLen = static_cast<int>(CFDataGetLength(data));
+
+ m_resourceData->append(data);
+
+ // 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_sendResourceLoadCallbacks && m_frame)
+ frameLoader()->notifier()->didReceiveData(this, reinterpret_cast<const char*>(CFDataGetBytePtr(data)), dataLen, dataLen);
+ }
+}
+
+void ResourceLoader::didReceiveDataArray(ResourceHandle*, CFArrayRef dataArray)
+{
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceData(m_frame.get(), identifier());
+ didReceiveDataArray(dataArray);
+ InspectorInstrumentation::didReceiveResourceData(cookie);
+}
+
+#endif
+
}
#endif // !USE(CFNETWORK)