summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/loader/cache/CachedResourceLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/loader/cache/CachedResourceLoader.cpp')
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.cpp195
1 files changed, 105 insertions, 90 deletions
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
index fe25a93..6511b5e 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
@@ -55,24 +55,28 @@
namespace WebCore {
-static CachedResource* createResource(CachedResource::Type type, const KURL& url, const String& charset)
+static CachedResource* createResource(CachedResource::Type type, ResourceRequest& request, const String& charset)
{
switch (type) {
case CachedResource::ImageResource:
- return new CachedImage(url.string());
+ return new CachedImage(request);
case CachedResource::CSSStyleSheet:
- return new CachedCSSStyleSheet(url.string(), charset);
+ return new CachedCSSStyleSheet(request, charset);
case CachedResource::Script:
- return new CachedScript(url.string(), charset);
+ return new CachedScript(request, charset);
case CachedResource::FontResource:
- return new CachedFont(url.string());
+ return new CachedFont(request);
#if ENABLE(XSLT)
case CachedResource::XSLStyleSheet:
- return new CachedXSLStyleSheet(url.string());
+ return new CachedXSLStyleSheet(request);
#endif
#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkResource:
- return new CachedResource(url.string(), CachedResource::LinkResource);
+ case CachedResource::LinkPrefetch:
+ return new CachedResource(request, CachedResource::LinkPrefetch);
+ case CachedResource::LinkPrerender:
+ return new CachedResource(request, CachedResource::LinkPrerender);
+ case CachedResource::LinkSubresource:
+ return new CachedResource(request, CachedResource::LinkSubresource);
#endif
}
ASSERT_NOT_REACHED();
@@ -106,16 +110,16 @@ CachedResourceLoader::~CachedResourceLoader()
ASSERT(m_requestCount == 0);
}
-CachedResource* CachedResourceLoader::cachedResource(const String& resourceURL) const
+CachedResource* CachedResourceLoader::cachedResource(const String& resourceURL) const
{
KURL url = m_document->completeURL(resourceURL);
- return cachedResource(url);
+ return cachedResource(url);
}
CachedResource* CachedResourceLoader::cachedResource(const KURL& resourceURL) const
{
KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(resourceURL);
- return m_documentResources.get(url).get();
+ return m_documentResources.get(url).get();
}
Frame* CachedResourceLoader::frame() const
@@ -123,7 +127,7 @@ Frame* CachedResourceLoader::frame() const
return m_document ? m_document->frame() : 0;
}
-CachedImage* CachedResourceLoader::requestImage(const String& url)
+CachedImage* CachedResourceLoader::requestImage(ResourceRequest& request)
{
if (Frame* f = frame()) {
Settings* settings = f->settings();
@@ -131,22 +135,22 @@ CachedImage* CachedResourceLoader::requestImage(const String& url)
return 0;
if (f->loader()->pageDismissalEventBeingDispatched()) {
- KURL completeURL = m_document->completeURL(url);
- if (completeURL.isValid() && canRequest(CachedResource::ImageResource, completeURL))
- PingLoader::loadImage(f, completeURL);
+ KURL requestURL = request.url();
+ if (requestURL.isValid() && canRequest(CachedResource::ImageResource, requestURL))
+ PingLoader::loadImage(f, requestURL);
return 0;
}
}
- CachedImage* resource = static_cast<CachedImage*>(requestResource(CachedResource::ImageResource, url, String()));
+ CachedImage* resource = static_cast<CachedImage*>(requestResource(CachedResource::ImageResource, request, String()));
if (resource) {
#ifdef ANDROID_BLOCK_NETWORK_IMAGE
- resource->setAutoLoadWasPreventedBySettings(!autoLoadImages() || shouldBlockNetworkImage(url));
+ resource->setAutoLoadWasPreventedBySettings(!autoLoadImages() || shouldBlockNetworkImage(request.url()));
#else
resource->setAutoLoadWasPreventedBySettings(!autoLoadImages());
#endif
if (autoLoadImages() && resource->stillNeedsLoad()) {
#ifdef ANDROID_BLOCK_NETWORK_IMAGE
- if (shouldBlockNetworkImage(url)) {
+ if (shouldBlockNetworkImage(request.url())) {
return resource;
}
#endif
@@ -157,56 +161,60 @@ CachedImage* CachedResourceLoader::requestImage(const String& url)
return resource;
}
-CachedFont* CachedResourceLoader::requestFont(const String& url)
+CachedFont* CachedResourceLoader::requestFont(ResourceRequest& request)
{
- return static_cast<CachedFont*>(requestResource(CachedResource::FontResource, url, String()));
+ return static_cast<CachedFont*>(requestResource(CachedResource::FontResource, request, String()));
}
-CachedCSSStyleSheet* CachedResourceLoader::requestCSSStyleSheet(const String& url, const String& charset, ResourceLoadPriority priority)
+CachedCSSStyleSheet* CachedResourceLoader::requestCSSStyleSheet(ResourceRequest& request, const String& charset, ResourceLoadPriority priority)
{
- return static_cast<CachedCSSStyleSheet*>(requestResource(CachedResource::CSSStyleSheet, url, charset, priority));
+ return static_cast<CachedCSSStyleSheet*>(requestResource(CachedResource::CSSStyleSheet, request, charset, priority));
}
-CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(const String& requestURL, const String& charset)
+CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(ResourceRequest& request, const String& charset)
{
- KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(KURL(KURL(), requestURL));
+ KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(request.url());
if (CachedResource* existing = memoryCache()->resourceForURL(url)) {
if (existing->type() == CachedResource::CSSStyleSheet)
return static_cast<CachedCSSStyleSheet*>(existing);
memoryCache()->remove(existing);
}
- CachedCSSStyleSheet* userSheet = new CachedCSSStyleSheet(url, charset);
-
+ if (url.string() != request.url())
+ request.setURL(url);
+
+ CachedCSSStyleSheet* userSheet = new CachedCSSStyleSheet(request, charset);
+
bool inCache = memoryCache()->add(userSheet);
if (!inCache)
userSheet->setInCache(true);
-
+
userSheet->load(this, /*incremental*/ false, SkipSecurityCheck, /*sendResourceLoadCallbacks*/ false);
if (!inCache)
userSheet->setInCache(false);
-
+
return userSheet;
}
-CachedScript* CachedResourceLoader::requestScript(const String& url, const String& charset)
+CachedScript* CachedResourceLoader::requestScript(ResourceRequest& request, const String& charset)
{
- return static_cast<CachedScript*>(requestResource(CachedResource::Script, url, charset));
+ return static_cast<CachedScript*>(requestResource(CachedResource::Script, request, charset));
}
#if ENABLE(XSLT)
-CachedXSLStyleSheet* CachedResourceLoader::requestXSLStyleSheet(const String& url)
+CachedXSLStyleSheet* CachedResourceLoader::requestXSLStyleSheet(ResourceRequest& request)
{
- return static_cast<CachedXSLStyleSheet*>(requestResource(CachedResource::XSLStyleSheet, url, String()));
+ return static_cast<CachedXSLStyleSheet*>(requestResource(CachedResource::XSLStyleSheet, request, String()));
}
#endif
#if ENABLE(LINK_PREFETCH)
-CachedResource* CachedResourceLoader::requestLinkResource(const String& url, ResourceLoadPriority priority)
+CachedResource* CachedResourceLoader::requestLinkResource(CachedResource::Type type, ResourceRequest& request, ResourceLoadPriority priority)
{
ASSERT(frame());
- return requestResource(CachedResource::LinkResource, url, String(), priority);
+ ASSERT(type == CachedResource::LinkPrefetch || type == CachedResource::LinkPrerender || type == CachedResource::LinkSubresource);
+ return requestResource(type, request, String(), priority);
}
#endif
@@ -221,7 +229,9 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
case CachedResource::Script:
case CachedResource::FontResource:
#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkResource:
+ case CachedResource::LinkPrefetch:
+ case CachedResource::LinkPrerender:
+ case CachedResource::LinkSubresource:
#endif
// These types of resources can be loaded from any origin.
// FIXME: Are we sure about CachedResource::FontResource?
@@ -242,7 +252,7 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
// Note: Currently, we always allow mixed content, but we generate a
// callback to the FrameLoaderClient in case the embedder wants to
// update any security indicators.
- //
+ //
switch (type) {
case CachedResource::Script:
#if ENABLE(XSLT)
@@ -263,7 +273,9 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
break;
}
#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkResource:
+ case CachedResource::LinkPrefetch:
+ case CachedResource::LinkPrerender:
+ case CachedResource::LinkSubresource:
// Prefetch cannot affect the current document.
break;
#endif
@@ -292,9 +304,9 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
break;
}
#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkResource:
- if (!m_document->settings()->linkPrefetchEnabled())
- return false;
+ case CachedResource::LinkPrefetch:
+ case CachedResource::LinkPrerender:
+ case CachedResource::LinkSubresource:
break;
#endif
}
@@ -302,18 +314,18 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
return true;
}
-CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type, const String& resourceURL, const String& charset, ResourceLoadPriority priority, bool forPreload)
+CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type, ResourceRequest& request, const String& charset, ResourceLoadPriority priority, bool forPreload)
{
- KURL url = m_document->completeURL(resourceURL);
-
+ KURL url = request.url();
+
LOG(ResourceLoading, "CachedResourceLoader::requestResource '%s', charset '%s', priority=%d, forPreload=%u", url.string().latin1().data(), charset.latin1().data(), priority, forPreload);
-
+
// If only the fragment identifiers differ, it is the same resource.
url = MemoryCache::removeFragmentIdentifierIfNeeded(url);
if (!url.isValid())
return 0;
-
+
if (!canRequest(type, url))
return 0;
@@ -336,13 +348,16 @@ CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type,
// See if we can use an existing resource from the cache.
CachedResource* resource = memoryCache()->resourceForURL(url);
+ if (request.url() != url)
+ request.setURL(url);
+
switch (determineRevalidationPolicy(type, forPreload, resource)) {
case Load:
- resource = loadResource(type, url, charset, priority);
+ resource = loadResource(type, request, charset, priority);
break;
case Reload:
memoryCache()->remove(resource);
- resource = loadResource(type, url, charset, priority);
+ resource = loadResource(type, request, charset, priority);
break;
case Revalidate:
resource = revalidateResource(resource, priority);
@@ -358,10 +373,10 @@ CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type,
ASSERT(resource->url() == url.string());
m_documentResources.set(resource->url(), resource);
-
+
return resource;
}
-
+
CachedResource* CachedResourceLoader::revalidateResource(CachedResource* resource, ResourceLoadPriority priority)
{
ASSERT(resource);
@@ -369,42 +384,42 @@ CachedResource* CachedResourceLoader::revalidateResource(CachedResource* resourc
ASSERT(!memoryCache()->disabled());
ASSERT(resource->canUseCacheValidator());
ASSERT(!resource->resourceToRevalidate());
-
+
// 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());
-
+ CachedResource* newResource = createResource(resource->type(), resource->resourceRequest(), resource->encoding());
+
LOG(ResourceLoading, "Resource %p created to revalidate %p", newResource, resource);
newResource->setResourceToRevalidate(resource);
-
+
memoryCache()->remove(resource);
memoryCache()->add(newResource);
-
+
newResource->setLoadPriority(priority);
newResource->load(this);
-
+
m_validatedURLs.add(url);
return newResource;
}
-CachedResource* CachedResourceLoader::loadResource(CachedResource::Type type, const KURL& url, const String& charset, ResourceLoadPriority priority)
+CachedResource* CachedResourceLoader::loadResource(CachedResource::Type type, ResourceRequest& request, const String& charset, ResourceLoadPriority priority)
{
- ASSERT(!memoryCache()->resourceForURL(url));
-
- LOG(ResourceLoading, "Loading CachedResource for '%s'.", url.string().latin1().data());
-
- CachedResource* resource = createResource(type, url, charset);
-
+ ASSERT(!memoryCache()->resourceForURL(request.url()));
+
+ LOG(ResourceLoading, "Loading CachedResource for '%s'.", request.url().string().latin1().data());
+
+ CachedResource* resource = createResource(type, request, charset);
+
bool inCache = memoryCache()->add(resource);
-
+
// Pretend the resource is in the cache, to prevent it from being deleted during the load() call.
// FIXME: CachedResource should just use normal refcounting instead.
if (!inCache)
resource->setInCache(true);
-
+
resource->setLoadPriority(priority);
resource->load(this);
-
+
if (!inCache) {
resource->setOwningCachedResourceLoader(this);
resource->setInCache(false);
@@ -419,7 +434,7 @@ CachedResource* CachedResourceLoader::loadResource(CachedResource::Type type, co
return 0;
}
- m_validatedURLs.add(url.string());
+ m_validatedURLs.add(request.url());
return resource;
}
@@ -427,25 +442,25 @@ CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalida
{
if (!existingResource)
return Load;
-
+
// We already have a preload going for this URL.
if (forPreload && existingResource->isPreloaded())
return Use;
-
+
// If the same URL has been loaded as a different type, we need to reload.
if (existingResource->type() != type) {
LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to type mismatch.");
return Reload;
}
-
+
// Don't reload resources while pasting.
if (m_allowStaleResources)
return Use;
-
+
// Alwaus use preloads.
if (existingResource->isPreloaded())
return Use;
-
+
// CachePolicyHistoryBuffer uses the cache no matter what.
if (cachePolicy() == CachePolicyHistoryBuffer)
return Use;
@@ -459,19 +474,19 @@ CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalida
// Avoid loading the same resource multiple times for a single document, even if the cache policies would tell us to.
if (m_validatedURLs.contains(existingResource->url()))
return Use;
-
+
// CachePolicyReload always reloads
if (cachePolicy() == CachePolicyReload) {
LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to CachePolicyReload.");
return Reload;
}
-
+
// We'll try to reload the resource if it failed last time.
if (existingResource->errorOccurred()) {
LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicye reloading due to resource being in the error state");
return Reload;
}
-
+
// For resources that are not yet loaded we ignore the cache policy.
if (existingResource->isLoading())
return Use;
@@ -481,9 +496,9 @@ CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalida
// See if the resource has usable ETag or Last-modified headers.
if (existingResource->canUseCacheValidator())
return Revalidate;
-
+
// No, must reload.
- LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to missing cache validators.");
+ LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to missing cache validators.");
return Reload;
}
@@ -675,8 +690,8 @@ int CachedResourceLoader::requestCount()
return m_requestCount + 1;
return m_requestCount;
}
-
-void CachedResourceLoader::preload(CachedResource::Type type, const String& url, const String& charset, bool referencedFromBody)
+
+void CachedResourceLoader::preload(CachedResource::Type type, ResourceRequest& request, const String& charset, bool referencedFromBody)
{
// FIXME: Rip this out when we are sure it is no longer necessary (even for mobile).
UNUSED_PARAM(referencedFromBody);
@@ -686,33 +701,33 @@ void CachedResourceLoader::preload(CachedResource::Type type, const String& url,
if (!hasRendering && !canBlockParser) {
// Don't preload subresources that can't block the parser before we have something to draw.
// This helps prevent preloads from delaying first display when bandwidth is limited.
- PendingPreload pendingPreload = { type, url, charset };
+ PendingPreload pendingPreload = { type, request, charset };
m_pendingPreloads.append(pendingPreload);
return;
}
- requestPreload(type, url, charset);
+ requestPreload(type, request, charset);
}
-void CachedResourceLoader::checkForPendingPreloads()
+void CachedResourceLoader::checkForPendingPreloads()
{
if (m_pendingPreloads.isEmpty() || !m_document->body() || !m_document->body()->renderer())
return;
while (!m_pendingPreloads.isEmpty()) {
PendingPreload preload = m_pendingPreloads.takeFirst();
// Don't request preload if the resource already loaded normally (this will result in double load if the page is being reloaded with cached results ignored).
- if (!cachedResource(m_document->completeURL(preload.m_url)))
- requestPreload(preload.m_type, preload.m_url, preload.m_charset);
+ if (!cachedResource(preload.m_request.url()))
+ requestPreload(preload.m_type, preload.m_request, preload.m_charset);
}
m_pendingPreloads.clear();
}
-void CachedResourceLoader::requestPreload(CachedResource::Type type, const String& url, const String& charset)
+void CachedResourceLoader::requestPreload(CachedResource::Type type, ResourceRequest& request, const String& charset)
{
String encoding;
if (type == CachedResource::Script || type == CachedResource::CSSStyleSheet)
encoding = charset.isEmpty() ? m_document->charset() : charset;
- CachedResource* resource = requestResource(type, url, encoding, ResourceLoadPriorityUnresolved, true);
+ CachedResource* resource = requestResource(type, request, encoding, ResourceLoadPriorityUnresolved, true);
if (!resource || (m_preloads && m_preloads->contains(resource)))
return;
resource->increasePreloadCount();
@@ -769,7 +784,7 @@ void CachedResourceLoader::printPreloadStats()
printf("HIT COMPLETE PRELOAD %s\n", res->url().latin1().data());
else if (res->preloadResult() == CachedResource::PreloadReferencedWhileLoading)
printf("HIT LOADING PRELOAD %s\n", res->url().latin1().data());
-
+
if (res->type() == CachedResource::Script) {
scripts++;
if (res->preloadResult() < CachedResource::PreloadReferencedWhileLoading)
@@ -783,14 +798,14 @@ void CachedResourceLoader::printPreloadStats()
if (res->preloadResult() < CachedResource::PreloadReferencedWhileLoading)
imageMisses++;
}
-
+
if (res->errorOccurred())
memoryCache()->remove(res);
-
+
res->decreasePreloadCount();
}
m_preloads.clear();
-
+
if (scripts)
printf("SCRIPTS: %d (%d hits, hit rate %d%%)\n", scripts, scripts - scriptMisses, (scripts - scriptMisses) * 100 / scripts);
if (stylesheets)
@@ -799,5 +814,5 @@ void CachedResourceLoader::printPreloadStats()
printf("IMAGES: %d (%d hits, hit rate %d%%)\n", images, images - imageMisses, (images - imageMisses) * 100 / images);
}
#endif
-
+
}