diff options
Diffstat (limited to 'Source/WebCore/loader/cache/CachedResourceLoader.cpp')
-rw-r--r-- | Source/WebCore/loader/cache/CachedResourceLoader.cpp | 195 |
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 - + } |