diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/WebCore/loader/cache/CachedResourceLoader.cpp | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/WebCore/loader/cache/CachedResourceLoader.cpp')
-rw-r--r-- | Source/WebCore/loader/cache/CachedResourceLoader.cpp | 572 |
1 files changed, 181 insertions, 391 deletions
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp index 35127c647..bd38fe823 100644 --- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp +++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp @@ -33,17 +33,13 @@ #include "CachedImage.h" #include "CachedRawResource.h" #include "CachedResourceRequest.h" -#include "CachedSVGFont.h" #include "CachedScript.h" #include "CachedXSLStyleSheet.h" #include "Chrome.h" #include "ChromeClient.h" -#include "ContentExtensionError.h" -#include "ContentExtensionRule.h" +#include "Console.h" #include "ContentSecurityPolicy.h" #include "DOMWindow.h" -#include "DiagnosticLoggingClient.h" -#include "DiagnosticLoggingKeys.h" #include "Document.h" #include "DocumentLoader.h" #include "Frame.h" @@ -52,22 +48,16 @@ #include "HTMLElement.h" #include "HTMLFrameOwnerElement.h" #include "LoaderStrategy.h" -#include "LocalizedStrings.h" #include "Logging.h" -#include "MainFrame.h" #include "MemoryCache.h" #include "Page.h" #include "PingLoader.h" #include "PlatformStrategies.h" #include "RenderElement.h" -#include "ResourceLoadInfo.h" +#include "ResourceLoadScheduler.h" #include "ScriptController.h" #include "SecurityOrigin.h" -#include "SessionID.h" #include "Settings.h" -#include "StyleSheetContents.h" -#include "UserContentController.h" -#include "UserStyleSheet.h" #include <wtf/text/CString.h> #include <wtf/text/WTFString.h> @@ -83,50 +73,48 @@ namespace WebCore { -static CachedResource* createResource(CachedResource::Type type, ResourceRequest& request, const String& charset, SessionID sessionID) +static CachedResource* createResource(CachedResource::Type type, ResourceRequest& request, const String& charset) { switch (type) { case CachedResource::ImageResource: - return new CachedImage(request, sessionID); + return new CachedImage(request); case CachedResource::CSSStyleSheet: - return new CachedCSSStyleSheet(request, charset, sessionID); + return new CachedCSSStyleSheet(request, charset); case CachedResource::Script: - return new CachedScript(request, charset, sessionID); + return new CachedScript(request, charset); +#if ENABLE(SVG) case CachedResource::SVGDocumentResource: - return new CachedSVGDocument(request, sessionID); -#if ENABLE(SVG_FONTS) - case CachedResource::SVGFontResource: - return new CachedSVGFont(request, sessionID); + return new CachedSVGDocument(request); #endif case CachedResource::FontResource: - return new CachedFont(request, sessionID); + return new CachedFont(request); case CachedResource::RawResource: case CachedResource::MainResource: - return new CachedRawResource(request, type, sessionID); + return new CachedRawResource(request, type); #if ENABLE(XSLT) case CachedResource::XSLStyleSheet: - return new CachedXSLStyleSheet(request, sessionID); + return new CachedXSLStyleSheet(request); #endif #if ENABLE(LINK_PREFETCH) case CachedResource::LinkPrefetch: - return new CachedResource(request, CachedResource::LinkPrefetch, sessionID); + return new CachedResource(request, CachedResource::LinkPrefetch); case CachedResource::LinkSubresource: - return new CachedResource(request, CachedResource::LinkSubresource, sessionID); + return new CachedResource(request, CachedResource::LinkSubresource); #endif #if ENABLE(VIDEO_TRACK) case CachedResource::TextTrackResource: - return new CachedTextTrack(request, sessionID); + return new CachedTextTrack(request); #endif } ASSERT_NOT_REACHED(); - return nullptr; + return 0; } CachedResourceLoader::CachedResourceLoader(DocumentLoader* documentLoader) - : m_document(nullptr) + : m_document(0) , m_documentLoader(documentLoader) , m_requestCount(0) - , m_garbageCollectDocumentResourcesTimer(*this, &CachedResourceLoader::garbageCollectDocumentResources) + , m_garbageCollectDocumentResourcesTimer(this, &CachedResourceLoader::garbageCollectDocumentResourcesTimerFired) , m_autoLoadImages(true) , m_imagesEnabled(true) , m_allowStaleResources(false) @@ -135,12 +123,13 @@ CachedResourceLoader::CachedResourceLoader(DocumentLoader* documentLoader) CachedResourceLoader::~CachedResourceLoader() { - m_documentLoader = nullptr; - m_document = nullptr; + m_documentLoader = 0; + m_document = 0; clearPreloads(); - for (auto& resource : m_documentResources.values()) - resource->setOwningCachedResourceLoader(nullptr); + DocumentResourceMap::iterator end = m_documentResources.end(); + for (DocumentResourceMap::iterator it = m_documentResources.begin(); it != end; ++it) + it->value->setOwningCachedResourceLoader(0); // Make sure no requests still point to this CachedResourceLoader ASSERT(m_requestCount == 0); @@ -148,7 +137,6 @@ CachedResourceLoader::~CachedResourceLoader() CachedResource* CachedResourceLoader::cachedResource(const String& resourceURL) const { - ASSERT(!resourceURL.isNull()); URL url = m_document->completeURL(resourceURL); return cachedResource(url); } @@ -161,55 +149,38 @@ CachedResource* CachedResourceLoader::cachedResource(const URL& resourceURL) con Frame* CachedResourceLoader::frame() const { - return m_documentLoader ? m_documentLoader->frame() : nullptr; -} - -SessionID CachedResourceLoader::sessionID() const -{ - SessionID sessionID = SessionID::defaultSessionID(); - - if (Frame* f = frame()) - sessionID = f->page()->sessionID(); - - return sessionID; + return m_documentLoader ? m_documentLoader->frame() : 0; } CachedResourceHandle<CachedImage> CachedResourceLoader::requestImage(CachedResourceRequest& request) { - if (Frame* frame = this->frame()) { - if (frame->loader().pageDismissalEventBeingDispatched() != FrameLoader::PageDismissalType::None) { + if (Frame* f = frame()) { + if (f->loader().pageDismissalEventBeingDispatched() != FrameLoader::NoDismissal) { URL requestURL = request.resourceRequest().url(); if (requestURL.isValid() && canRequest(CachedResource::ImageResource, requestURL, request.options(), request.forPreload())) - PingLoader::loadImage(*frame, requestURL); - return nullptr; + PingLoader::loadImage(f, requestURL); + return 0; } } - request.setDefer(clientDefersImage(request.resourceRequest().url()) ? CachedResourceRequest::DeferredByClient : CachedResourceRequest::NoDefer); - return downcast<CachedImage>(requestResource(CachedResource::ImageResource, request).get()); + return static_cast<CachedImage*>(requestResource(CachedResource::ImageResource, request).get()); } -CachedResourceHandle<CachedFont> CachedResourceLoader::requestFont(CachedResourceRequest& request, bool isSVG) +CachedResourceHandle<CachedFont> CachedResourceLoader::requestFont(CachedResourceRequest& request) { -#if ENABLE(SVG_FONTS) - if (isSVG) - return downcast<CachedSVGFont>(requestResource(CachedResource::SVGFontResource, request).get()); -#else - UNUSED_PARAM(isSVG); -#endif - return downcast<CachedFont>(requestResource(CachedResource::FontResource, request).get()); + return static_cast<CachedFont*>(requestResource(CachedResource::FontResource, request).get()); } #if ENABLE(VIDEO_TRACK) CachedResourceHandle<CachedTextTrack> CachedResourceLoader::requestTextTrack(CachedResourceRequest& request) { - return downcast<CachedTextTrack>(requestResource(CachedResource::TextTrackResource, request).get()); + return static_cast<CachedTextTrack*>(requestResource(CachedResource::TextTrackResource, request).get()); } #endif CachedResourceHandle<CachedCSSStyleSheet> CachedResourceLoader::requestCSSStyleSheet(CachedResourceRequest& request) { - return downcast<CachedCSSStyleSheet>(requestResource(CachedResource::CSSStyleSheet, request).get()); + return static_cast<CachedCSSStyleSheet*>(requestResource(CachedResource::CSSStyleSheet, request).get()); } CachedResourceHandle<CachedCSSStyleSheet> CachedResourceLoader::requestUserCSSStyleSheet(CachedResourceRequest& request) @@ -217,48 +188,45 @@ CachedResourceHandle<CachedCSSStyleSheet> CachedResourceLoader::requestUserCSSSt URL url = MemoryCache::removeFragmentIdentifierIfNeeded(request.resourceRequest().url()); #if ENABLE(CACHE_PARTITIONING) - request.mutableResourceRequest().setDomainForCachePartition(document()->topOrigin()->domainForCachePartition()); + request.mutableResourceRequest().setCachePartition(document()->topOrigin()->cachePartition()); #endif - auto& memoryCache = MemoryCache::singleton(); - if (request.allowsCaching()) { - if (CachedResource* existing = memoryCache.resourceForRequest(request.resourceRequest(), sessionID())) { - if (is<CachedCSSStyleSheet>(*existing)) - return downcast<CachedCSSStyleSheet>(existing); - memoryCache.remove(*existing); - } + if (CachedResource* existing = memoryCache()->resourceForRequest(request.resourceRequest())) { + if (existing->type() == CachedResource::CSSStyleSheet) + return static_cast<CachedCSSStyleSheet*>(existing); + memoryCache()->remove(existing); } - if (url.string() != request.resourceRequest().url()) request.mutableResourceRequest().setURL(url); - CachedResourceHandle<CachedCSSStyleSheet> userSheet = new CachedCSSStyleSheet(request.resourceRequest(), request.charset(), sessionID()); + CachedResourceHandle<CachedCSSStyleSheet> userSheet = new CachedCSSStyleSheet(request.resourceRequest(), request.charset()); - if (request.allowsCaching()) - memoryCache.add(*userSheet); + memoryCache()->add(userSheet.get()); // FIXME: loadResource calls setOwningCachedResourceLoader() if the resource couldn't be added to cache. Does this function need to call it, too? - userSheet->load(*this, ResourceLoaderOptions(DoNotSendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForAllCredentials, ClientRequestedCredentials, SkipSecurityCheck, UseDefaultOriginRestrictionsForType, DoNotIncludeCertificateInfo, ContentSecurityPolicyImposition::SkipPolicyCheck, DefersLoadingPolicy::AllowDefersLoading, CachingPolicy::AllowCaching)); + userSheet->load(this, ResourceLoaderOptions(DoNotSendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForAllCredentials, SkipSecurityCheck, UseDefaultOriginRestrictionsForType)); return userSheet; } CachedResourceHandle<CachedScript> CachedResourceLoader::requestScript(CachedResourceRequest& request) { - return downcast<CachedScript>(requestResource(CachedResource::Script, request).get()); + return static_cast<CachedScript*>(requestResource(CachedResource::Script, request).get()); } #if ENABLE(XSLT) CachedResourceHandle<CachedXSLStyleSheet> CachedResourceLoader::requestXSLStyleSheet(CachedResourceRequest& request) { - return downcast<CachedXSLStyleSheet>(requestResource(CachedResource::XSLStyleSheet, request).get()); + return static_cast<CachedXSLStyleSheet*>(requestResource(CachedResource::XSLStyleSheet, request).get()); } #endif +#if ENABLE(SVG) CachedResourceHandle<CachedSVGDocument> CachedResourceLoader::requestSVGDocument(CachedResourceRequest& request) { - return downcast<CachedSVGDocument>(requestResource(CachedResource::SVGDocumentResource, request).get()); + return static_cast<CachedSVGDocument*>(requestResource(CachedResource::SVGDocumentResource, request).get()); } +#endif #if ENABLE(LINK_PREFETCH) CachedResourceHandle<CachedResource> CachedResourceLoader::requestLinkResource(CachedResource::Type type, CachedResourceRequest& request) @@ -271,52 +239,12 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::requestLinkResource(C CachedResourceHandle<CachedRawResource> CachedResourceLoader::requestRawResource(CachedResourceRequest& request) { - return downcast<CachedRawResource>(requestResource(CachedResource::RawResource, request).get()); + return static_cast<CachedRawResource*>(requestResource(CachedResource::RawResource, request).get()); } CachedResourceHandle<CachedRawResource> CachedResourceLoader::requestMainResource(CachedResourceRequest& request) { - return downcast<CachedRawResource>(requestResource(CachedResource::MainResource, request).get()); -} - -static MixedContentChecker::ContentType contentTypeFromResourceType(CachedResource::Type type) -{ - switch (type) { - case CachedResource::ImageResource: - return MixedContentChecker::ContentType::ActiveCanWarn; - - case CachedResource::CSSStyleSheet: - case CachedResource::Script: - case CachedResource::FontResource: - return MixedContentChecker::ContentType::Active; - -#if ENABLE(SVG_FONTS) - case CachedResource::SVGFontResource: - return MixedContentChecker::ContentType::Active; -#endif - - case CachedResource::RawResource: - case CachedResource::SVGDocumentResource: - return MixedContentChecker::ContentType::Active; -#if ENABLE(XSLT) - case CachedResource::XSLStyleSheet: - return MixedContentChecker::ContentType::Active; -#endif - -#if ENABLE(LINK_PREFETCH) - case CachedResource::LinkPrefetch: - case CachedResource::LinkSubresource: - return MixedContentChecker::ContentType::Active; -#endif - -#if ENABLE(VIDEO_TRACK) - case CachedResource::TextTrackResource: - return MixedContentChecker::ContentType::Active; -#endif - default: - ASSERT_NOT_REACHED(); - return MixedContentChecker::ContentType::Active; - } + return static_cast<CachedRawResource*>(requestResource(CachedResource::MainResource, request).get()); } bool CachedResourceLoader::checkInsecureContent(CachedResource::Type type, const URL& url) const @@ -326,7 +254,9 @@ bool CachedResourceLoader::checkInsecureContent(CachedResource::Type type, const #if ENABLE(XSLT) case CachedResource::XSLStyleSheet: #endif +#if ENABLE(SVG) case CachedResource::SVGDocumentResource: +#endif case CachedResource::CSSStyleSheet: // These resource can inject script into the current document (Script, // XSL) or exfiltrate the content of the current document (CSS). @@ -339,14 +269,11 @@ bool CachedResourceLoader::checkInsecureContent(CachedResource::Type type, const #endif case CachedResource::RawResource: case CachedResource::ImageResource: -#if ENABLE(SVG_FONTS) - case CachedResource::SVGFontResource: -#endif case CachedResource::FontResource: { // These resources can corrupt only the frame's pixels. if (Frame* f = frame()) { Frame& topFrame = f->tree().top(); - if (!topFrame.loader().mixedContentChecker().canDisplayInsecureContent(topFrame.document()->securityOrigin(), contentTypeFromResourceType(type), url)) + if (!topFrame.loader().mixedContentChecker().canDisplayInsecureContent(topFrame.document()->securityOrigin(), url)) return false; } break; @@ -368,10 +295,11 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const URL& url, if (!forPreload) FrameLoader::reportLocalLoadFailed(frame(), url.stringCenterEllipsizedToLength()); LOG(ResourceLoading, "CachedResourceLoader::requestResource URL was not allowed by SecurityOrigin::canDisplay"); - return false; + return 0; } - bool skipContentSecurityPolicyCheck = options.contentSecurityPolicyImposition() == ContentSecurityPolicyImposition::SkipPolicyCheck; + // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved. + bool shouldBypassMainWorldContentSecurityPolicy = (frame() && frame()->script().shouldBypassMainWorldContentSecurityPolicy()); // Some types of resources can be loaded only from the same origin. Other // types of resources, like Images, Scripts, and CSS, can be loaded from @@ -381,9 +309,6 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const URL& url, case CachedResource::ImageResource: case CachedResource::CSSStyleSheet: case CachedResource::Script: -#if ENABLE(SVG_FONTS) - case CachedResource::SVGFontResource: -#endif case CachedResource::FontResource: case CachedResource::RawResource: #if ENABLE(LINK_PREFETCH) @@ -393,12 +318,14 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const URL& url, #if ENABLE(VIDEO_TRACK) case CachedResource::TextTrackResource: #endif - if (options.requestOriginPolicy() == RestrictToSameOrigin && !m_document->securityOrigin()->canRequest(url)) { + if (options.requestOriginPolicy == RestrictToSameOrigin && !m_document->securityOrigin()->canRequest(url)) { printAccessDeniedMessage(url); return false; } break; +#if ENABLE(SVG) case CachedResource::SVGDocumentResource: +#endif #if ENABLE(XSLT) case CachedResource::XSLStyleSheet: if (!m_document->securityOrigin()->canRequest(url)) { @@ -412,30 +339,32 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const URL& url, switch (type) { #if ENABLE(XSLT) case CachedResource::XSLStyleSheet: - if (!m_document->contentSecurityPolicy()->allowScriptFromSource(url, skipContentSecurityPolicyCheck)) + if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowScriptFromSource(url)) return false; break; #endif case CachedResource::Script: - if (!m_document->contentSecurityPolicy()->allowScriptFromSource(url, skipContentSecurityPolicyCheck)) - return false; - if (frame() && !frame()->settings().isScriptEnabled()) + if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowScriptFromSource(url)) return false; + + if (frame()) { + if (!frame()->loader().client().allowScriptFromSource(frame()->settings().isScriptEnabled(), url)) + return false; + } break; case CachedResource::CSSStyleSheet: - if (!m_document->contentSecurityPolicy()->allowStyleFromSource(url, skipContentSecurityPolicyCheck)) + if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowStyleFromSource(url)) return false; break; +#if ENABLE(SVG) case CachedResource::SVGDocumentResource: +#endif case CachedResource::ImageResource: - if (!m_document->contentSecurityPolicy()->allowImageFromSource(url, skipContentSecurityPolicyCheck)) + if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowImageFromSource(url)) return false; break; -#if ENABLE(SVG_FONTS) - case CachedResource::SVGFontResource: -#endif case CachedResource::FontResource: { - if (!m_document->contentSecurityPolicy()->allowFontFromSource(url, skipContentSecurityPolicyCheck)) + if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowFontFromSource(url)) return false; break; } @@ -448,7 +377,7 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const URL& url, break; #if ENABLE(VIDEO_TRACK) case CachedResource::TextTrackResource: - if (!m_document->contentSecurityPolicy()->allowMediaFromSource(url, skipContentSecurityPolicyCheck)) + if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowMediaFromSource(url)) return false; break; #endif @@ -460,9 +389,6 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const URL& url, return false; } - if (!canRequestInContentDispositionAttachmentSandbox(type, url)) - return false; - // Last of all, check for insecure content. We do this last so that when // folks block insecure content with a CSP policy, they don't get a warning. // They'll still get a warning in the console about CSP blocking the load. @@ -474,95 +400,41 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const URL& url, return true; } -bool CachedResourceLoader::canRequestInContentDispositionAttachmentSandbox(CachedResource::Type type, const URL& url) const -{ - Document* document; - - // FIXME: Do we want to expand this to all resource types that the mixed content checker would consider active content? - switch (type) { - case CachedResource::MainResource: - if (auto ownerElement = frame() ? frame()->ownerElement() : nullptr) { - document = &ownerElement->document(); - break; - } - return true; - case CachedResource::CSSStyleSheet: - document = m_document; - break; - default: - return true; - } - - if (!document->shouldEnforceContentDispositionAttachmentSandbox() || document->securityOrigin()->canRequest(url)) - return true; - - String message = "Unsafe attempt to load URL " + url.stringCenterEllipsizedToLength() + " from document with Content-Disposition: attachment at URL " + document->url().stringCenterEllipsizedToLength() + "."; - document->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message); - return false; -} - -bool CachedResourceLoader::shouldContinueAfterNotifyingLoadedFromMemoryCache(const CachedResourceRequest& request, CachedResource* resource) +bool CachedResourceLoader::shouldContinueAfterNotifyingLoadedFromMemoryCache(CachedResource* resource) { if (!resource || !frame() || resource->status() != CachedResource::Cached) return true; - ResourceRequest newRequest = ResourceRequest(resource->url()); - if (request.resourceRequest().hiddenFromInspector()) - newRequest.setHiddenFromInspector(true); + ResourceRequest newRequest; frame()->loader().loadedResourceFromMemoryCache(resource, newRequest); - + // FIXME <http://webkit.org/b/113251>: If the delegate modifies the request's // URL, it is no longer appropriate to use this CachedResource. return !newRequest.isNull(); } -static inline void logMemoryCacheResourceRequest(Frame* frame, const String& description, const String& value = String()) -{ - if (!frame) - return; - if (value.isNull()) - frame->mainFrame().diagnosticLoggingClient().logDiagnosticMessage(DiagnosticLoggingKeys::resourceRequestKey(), description, ShouldSample::Yes); - else - frame->mainFrame().diagnosticLoggingClient().logDiagnosticMessageWithValue(DiagnosticLoggingKeys::resourceRequestKey(), description, value, ShouldSample::Yes); -} - CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(CachedResource::Type type, CachedResourceRequest& request) { URL url = request.resourceRequest().url(); - LOG(ResourceLoading, "CachedResourceLoader::requestResource '%s', charset '%s', priority=%d, forPreload=%u", url.stringCenterEllipsizedToLength().latin1().data(), request.charset().latin1().data(), request.priority() ? static_cast<int>(request.priority().value()) : -1, request.forPreload()); + LOG(ResourceLoading, "CachedResourceLoader::requestResource '%s', charset '%s', priority=%d, forPreload=%u", url.stringCenterEllipsizedToLength().latin1().data(), request.charset().latin1().data(), request.priority(), request.forPreload()); // If only the fragment identifiers differ, it is the same resource. url = MemoryCache::removeFragmentIdentifierIfNeeded(url); if (!url.isValid()) - return nullptr; + return 0; if (!canRequest(type, url, request.options(), request.forPreload())) - return nullptr; - -#if ENABLE(CONTENT_EXTENSIONS) - if (frame() && frame()->mainFrame().page() && frame()->mainFrame().page()->userContentController() && m_documentLoader) { - if (frame()->mainFrame().page()->userContentController()->processContentExtensionRulesForLoad(request.mutableResourceRequest(), toResourceType(type), *m_documentLoader) == ContentExtensions::BlockedStatus::Blocked) { - if (type == CachedResource::Type::MainResource) { - auto resource = createResource(type, request.mutableResourceRequest(), request.charset(), sessionID()); - ASSERT(resource); - resource->error(CachedResource::Status::LoadError); - resource->setResourceError(ResourceError(ContentExtensions::WebKitContentBlockerDomain, 0, request.resourceRequest().url(), WEB_UI_STRING("The URL was blocked by a content blocker", "WebKitErrorBlockedByContentBlocker description"))); - return resource; - } - return nullptr; - } - url = request.resourceRequest().url(); // The content extension could have changed it from http to https. - url = MemoryCache::removeFragmentIdentifierIfNeeded(url); // Might need to remove fragment identifier again. - } -#endif + return 0; + + if (Frame* f = frame()) + f->loader().client().dispatchWillRequestResource(&request); - auto& memoryCache = MemoryCache::singleton(); - if (request.allowsCaching() && memoryCache.disabled()) { + if (memoryCache()->disabled()) { DocumentResourceMap::iterator it = m_documentResources.find(url.string()); if (it != m_documentResources.end()) { - it->value->setOwningCachedResourceLoader(nullptr); + it->value->setOwningCachedResourceLoader(0); m_documentResources.remove(it); } } @@ -571,55 +443,47 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(Cache CachedResourceHandle<CachedResource> resource; #if ENABLE(CACHE_PARTITIONING) if (document()) - request.mutableResourceRequest().setDomainForCachePartition(document()->topOrigin()->domainForCachePartition()); + request.mutableResourceRequest().setCachePartition(document()->topOrigin()->cachePartition()); #endif - if (request.allowsCaching()) - resource = memoryCache.resourceForRequest(request.resourceRequest(), sessionID()); + resource = memoryCache()->resourceForRequest(request.resourceRequest()); - logMemoryCacheResourceRequest(frame(), resource ? DiagnosticLoggingKeys::inMemoryCacheKey() : DiagnosticLoggingKeys::notInMemoryCacheKey()); - - const RevalidationPolicy policy = determineRevalidationPolicy(type, request, resource.get()); + const RevalidationPolicy policy = determineRevalidationPolicy(type, request.mutableResourceRequest(), request.forPreload(), resource.get(), request.defer()); switch (policy) { case Reload: - memoryCache.remove(*resource); + memoryCache()->remove(resource.get()); FALLTHROUGH; case Load: - if (resource) - logMemoryCacheResourceRequest(frame(), DiagnosticLoggingKeys::inMemoryCacheKey(), DiagnosticLoggingKeys::unusedKey()); - resource = loadResource(type, request); + resource = loadResource(type, request, request.charset()); break; case Revalidate: - if (resource) - logMemoryCacheResourceRequest(frame(), DiagnosticLoggingKeys::inMemoryCacheKey(), DiagnosticLoggingKeys::revalidatingKey()); resource = revalidateResource(request, resource.get()); break; case Use: - if (!shouldContinueAfterNotifyingLoadedFromMemoryCache(request, resource.get())) - return nullptr; - logMemoryCacheResourceRequest(frame(), DiagnosticLoggingKeys::inMemoryCacheKey(), DiagnosticLoggingKeys::usedKey()); - memoryCache.resourceAccessed(*resource); + if (!shouldContinueAfterNotifyingLoadedFromMemoryCache(resource.get())) + return 0; + memoryCache()->resourceAccessed(resource.get()); break; } if (!resource) - return nullptr; + return 0; if (!request.forPreload() || policy != Use) resource->setLoadPriority(request.priority()); if ((policy != Use || resource->stillNeedsLoad()) && CachedResourceRequest::NoDefer == request.defer()) { - resource->load(*this, request.options()); + resource->load(this, request.options()); // We don't support immediate loads, but we do support immediate failure. if (resource->errorOccurred()) { - if (resource->allowsCaching() && resource->inCache()) - memoryCache.remove(*resource); - return nullptr; + if (resource->inCache()) + memoryCache()->remove(resource.get()); + return 0; } } - if (document() && !document()->loadEventFinished() && !request.resourceRequest().url().protocolIsData()) + if (!request.resourceRequest().url().protocolIsData()) m_validatedURLs.add(request.resourceRequest().url()); ASSERT(resource->url() == url.string()); @@ -627,29 +491,23 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(Cache return resource; } -void CachedResourceLoader::documentDidFinishLoadEvent() -{ - m_validatedURLs.clear(); -} - CachedResourceHandle<CachedResource> CachedResourceLoader::revalidateResource(const CachedResourceRequest& request, CachedResource* resource) { ASSERT(resource); ASSERT(resource->inCache()); - auto& memoryCache = MemoryCache::singleton(); - ASSERT(!memoryCache.disabled()); + ASSERT(!memoryCache()->disabled()); ASSERT(resource->canUseCacheValidator()); ASSERT(!resource->resourceToRevalidate()); - ASSERT(resource->sessionID() == sessionID()); - ASSERT(resource->allowsCaching()); - - CachedResourceHandle<CachedResource> newResource = createResource(resource->type(), resource->resourceRequest(), resource->encoding(), resource->sessionID()); - + + // Copy the URL out of the resource to be revalidated in case it gets deleted by the remove() call below. + String url = resource->url(); + CachedResourceHandle<CachedResource> newResource = createResource(resource->type(), resource->resourceRequest(), resource->encoding()); + LOG(ResourceLoading, "Resource %p created to revalidate %p", newResource.get(), resource); newResource->setResourceToRevalidate(resource); - memoryCache.remove(*resource); - memoryCache.add(*newResource); + memoryCache()->remove(resource); + memoryCache()->add(newResource.get()); #if ENABLE(RESOURCE_TIMING) storeResourceTimingInitiatorInformation(resource, request); #else @@ -658,16 +516,15 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::revalidateResource(co return newResource; } -CachedResourceHandle<CachedResource> CachedResourceLoader::loadResource(CachedResource::Type type, CachedResourceRequest& request) +CachedResourceHandle<CachedResource> CachedResourceLoader::loadResource(CachedResource::Type type, CachedResourceRequest& request, const String& charset) { - auto& memoryCache = MemoryCache::singleton(); - ASSERT(!memoryCache.resourceForRequest(request.resourceRequest(), sessionID())); + ASSERT(!memoryCache()->resourceForRequest(request.resourceRequest())); LOG(ResourceLoading, "Loading CachedResource for '%s'.", request.resourceRequest().url().stringCenterEllipsizedToLength().latin1().data()); - CachedResourceHandle<CachedResource> resource = createResource(type, request.mutableResourceRequest(), request.charset(), sessionID()); + CachedResourceHandle<CachedResource> resource = createResource(type, request.mutableResourceRequest(), charset); - if (request.allowsCaching() && !memoryCache.add(*resource)) + if (!memoryCache()->add(resource.get())) resource->setOwningCachedResourceLoader(this); #if ENABLE(RESOURCE_TIMING) storeResourceTimingInitiatorInformation(resource, request); @@ -680,7 +537,7 @@ void CachedResourceLoader::storeResourceTimingInitiatorInformation(const CachedR { if (resource->type() == CachedResource::MainResource) { // <iframe>s should report the initial navigation requested by the parent document, but not subsequent navigations. - if (frame()->ownerElement() && m_documentLoader->frameLoader()->stateMachine().committingFirstRealLoad()) { + if (frame()->ownerElement() && m_documentLoader->frameLoader()->stateMachine()->committingFirstRealLoad()) { InitiatorInfo info = { frame()->ownerElement()->localName(), monotonicallyIncreasingTime() }; m_initiatorMap.add(resource.get(), info); } @@ -691,106 +548,47 @@ void CachedResourceLoader::storeResourceTimingInitiatorInformation(const CachedR } #endif // ENABLE(RESOURCE_TIMING) -static void logRevalidation(const String& reason, DiagnosticLoggingClient& logClient) -{ - logClient.logDiagnosticMessageWithValue(DiagnosticLoggingKeys::cachedResourceRevalidationKey(), DiagnosticLoggingKeys::reasonKey(), reason, ShouldSample::Yes); -} - -static void logResourceRevalidationDecision(CachedResource::RevalidationDecision reason, const Frame* frame) +CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalidationPolicy(CachedResource::Type type, ResourceRequest& request, bool forPreload, CachedResource* existingResource, CachedResourceRequest::DeferOption defer) const { - if (!frame) - return; - auto& logClient = frame->mainFrame().diagnosticLoggingClient(); - switch (reason) { - case CachedResource::RevalidationDecision::No: - break; - case CachedResource::RevalidationDecision::YesDueToExpired: - logRevalidation(DiagnosticLoggingKeys::isExpiredKey(), logClient); - break; - case CachedResource::RevalidationDecision::YesDueToNoStore: - logRevalidation(DiagnosticLoggingKeys::noStoreKey(), logClient); - break; - case CachedResource::RevalidationDecision::YesDueToNoCache: - logRevalidation(DiagnosticLoggingKeys::noCacheKey(), logClient); - break; - case CachedResource::RevalidationDecision::YesDueToCachePolicy: - logRevalidation(DiagnosticLoggingKeys::reloadKey(), logClient); - break; - } -} - -CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalidationPolicy(CachedResource::Type type, CachedResourceRequest& cachedResourceRequest, CachedResource* existingResource) const -{ - auto& request = cachedResourceRequest.resourceRequest(); - if (!existingResource) return Load; // We already have a preload going for this URL. - if (cachedResourceRequest.forPreload() && existingResource->isPreloaded()) + 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."); - logMemoryCacheResourceRequest(frame(), DiagnosticLoggingKeys::inMemoryCacheKey(), DiagnosticLoggingKeys::unusedReasonTypeMismatchKey()); return Reload; } - auto* textDecoder = existingResource->textResourceDecoder(); - if (textDecoder && !textDecoder->hasEqualEncodingForCharset(cachedResourceRequest.charset())) + if (!existingResource->canReuse(request)) return Reload; - // FIXME: We should use the same cache policy for all resource types. The raw resource policy is overly strict - // while the normal subresource policy is too loose. - if (existingResource->isMainOrRawResource() && frame()) { - bool strictPolicyDisabled = frame()->loader().isStrictRawResourceValidationPolicyDisabledForTesting(); - bool canReuseRawResource = strictPolicyDisabled || downcast<CachedRawResource>(*existingResource).canReuse(request); - if (!canReuseRawResource) - return Reload; - } - // Conditional requests should have failed canReuse check. ASSERT(!request.isConditional()); // Do not load from cache if images are not enabled. The load for this image will be blocked // in CachedImage::load. - if (cachedResourceRequest.defer() == CachedResourceRequest::DeferredByClient) + if (CachedResourceRequest::DeferredByClient == defer) return Reload; // Don't reload resources while pasting. if (m_allowStaleResources) return Use; - // Always use preloads. + // Alwaus use preloads. if (existingResource->isPreloaded()) return Use; - - // We can find resources that are being validated from cache only when validation is just successfully completing. - if (existingResource->validationCompleting()) + + // CachePolicyHistoryBuffer uses the cache no matter what. + if (cachePolicy(type) == CachePolicyHistoryBuffer) return Use; - ASSERT(!existingResource->validationInProgress()); - - // Validate the redirect chain. - bool cachePolicyIsHistoryBuffer = cachePolicy(type) == CachePolicyHistoryBuffer; - if (!existingResource->redirectChainAllowsReuse(cachePolicyIsHistoryBuffer ? ReuseExpiredRedirection : DoNotReuseExpiredRedirection)) { - LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to not cached or expired redirections."); - logMemoryCacheResourceRequest(frame(), DiagnosticLoggingKeys::inMemoryCacheKey(), DiagnosticLoggingKeys::unusedReasonRedirectChainKey()); - return Reload; - } - - // CachePolicyHistoryBuffer uses the cache except if this is a main resource with "cache-control: no-store". - if (cachePolicyIsHistoryBuffer) { - // FIXME: Ignoring "cache-control: no-cache" for sub-resources on history navigation but not the main - // resource is inconsistent. We should probably harmonize this. - if (!existingResource->response().cacheControlContainsNoStore() || type != CachedResource::MainResource) - return Use; - } // Don't reuse resources with Cache-control: no-store. if (existingResource->response().cacheControlContainsNoStore()) { LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to Cache-control: no-store."); - logMemoryCacheResourceRequest(frame(), DiagnosticLoggingKeys::inMemoryCacheKey(), DiagnosticLoggingKeys::unusedReasonNoStoreKey()); return Reload; } @@ -802,7 +600,6 @@ CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalida // client's requests are made without CORS and some with. if (existingResource->resourceRequest().allowCookies() != request.allowCookies()) { LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to difference in credentials settings."); - logMemoryCacheResourceRequest(frame(), DiagnosticLoggingKeys::inMemoryCacheKey(), DiagnosticLoggingKeys::unusedReasonCredentialSettingsKey()); return Reload; } @@ -813,14 +610,12 @@ CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalida // CachePolicyReload always reloads if (cachePolicy(type) == CachePolicyReload) { LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to CachePolicyReload."); - logMemoryCacheResourceRequest(frame(), DiagnosticLoggingKeys::inMemoryCacheKey(), DiagnosticLoggingKeys::unusedReasonReloadKey()); 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"); - logMemoryCacheResourceRequest(frame(), DiagnosticLoggingKeys::inMemoryCacheKey(), DiagnosticLoggingKeys::unusedReasonErrorKey()); return Reload; } @@ -828,18 +623,14 @@ CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalida if (existingResource->isLoading()) return Use; - auto revalidationDecision = existingResource->makeRevalidationDecision(cachePolicy(type)); - logResourceRevalidationDecision(revalidationDecision, frame()); - // Check if the cache headers requires us to revalidate (cache expiration for example). - if (revalidationDecision != CachedResource::RevalidationDecision::No) { + if (existingResource->mustRevalidateDueToCacheHeaders(cachePolicy(type))) { // 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."); - logMemoryCacheResourceRequest(frame(), DiagnosticLoggingKeys::inMemoryCacheKey(), DiagnosticLoggingKeys::unusedReasonMustRevalidateNoValidatorKey()); + LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to missing cache validators."); return Reload; } @@ -860,7 +651,7 @@ void CachedResourceLoader::printAccessDeniedMessage(const URL& url) const else message = "Unsafe attempt to load URL " + url.stringCenterEllipsizedToLength() + " from frame with URL " + m_document->url().stringCenterEllipsizedToLength() + ". Domains, protocols and ports must match.\n"; - frame()->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message); + frame()->document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message); } void CachedResourceLoader::setAutoLoadImages(bool enable) @@ -889,26 +680,23 @@ void CachedResourceLoader::setImagesEnabled(bool enable) reloadImagesIfNotDeferred(); } -bool CachedResourceLoader::clientDefersImage(const URL&) const +bool CachedResourceLoader::clientDefersImage(const URL& url) const { - return !m_imagesEnabled; -} - -bool CachedResourceLoader::shouldPerformImageLoad(const URL& url) const -{ - return m_autoLoadImages || url.protocolIsData(); + return frame() && !frame()->loader().client().allowImage(m_imagesEnabled, url); } bool CachedResourceLoader::shouldDeferImageLoad(const URL& url) const { - return clientDefersImage(url) || !shouldPerformImageLoad(url); + return clientDefersImage(url) || !m_autoLoadImages; } void CachedResourceLoader::reloadImagesIfNotDeferred() { - for (auto& resource : m_documentResources.values()) { - if (is<CachedImage>(*resource) && resource->stillNeedsLoad() && !clientDefersImage(resource->url())) - downcast<CachedImage>(*resource).load(*this, defaultCachedResourceOptions()); + DocumentResourceMap::iterator end = m_documentResources.end(); + for (DocumentResourceMap::iterator it = m_documentResources.begin(); it != end; ++it) { + CachedResource* resource = it->value.get(); + if (resource->type() == CachedResource::ImageResource && resource->stillNeedsLoad() && !clientDefersImage(resource->url())) + const_cast<CachedResource*>(resource)->load(this, defaultCachedResourceOptions()); } } @@ -920,28 +708,19 @@ CachePolicy CachedResourceLoader::cachePolicy(CachedResource::Type type) const if (type != CachedResource::MainResource) return frame()->loader().subresourceCachePolicy(); - switch (frame()->loader().loadType()) { - case FrameLoadType::ReloadFromOrigin: - case FrameLoadType::Reload: + if (frame()->loader().loadType() == FrameLoadTypeReloadFromOrigin || frame()->loader().loadType() == FrameLoadTypeReload) return CachePolicyReload; - case FrameLoadType::Back: - case FrameLoadType::Forward: - case FrameLoadType::IndexedBackForward: - // Do not revalidate cached main resource on back/forward navigation. - return CachePolicyHistoryBuffer; - default: - return CachePolicyVerify; - } + return CachePolicyVerify; } -void CachedResourceLoader::removeCachedResource(CachedResource& resource) +void CachedResourceLoader::removeCachedResource(CachedResource* resource) const { #ifndef NDEBUG - DocumentResourceMap::iterator it = m_documentResources.find(resource.url()); + DocumentResourceMap::iterator it = m_documentResources.find(resource->url()); if (it != m_documentResources.end()) - ASSERT(it->value.get() == &resource); + ASSERT(it->value.get() == resource); #endif - m_documentResources.remove(resource.url()); + m_documentResources.remove(resource->url()); } void CachedResourceLoader::loadDone(CachedResource* resource, bool shouldPerformPostLoadActions) @@ -983,27 +762,33 @@ void CachedResourceLoader::loadDone(CachedResource* resource, bool shouldPerform // bookkeeping on CachedResources, so instead pseudo-GC them -- when the // reference count reaches 1, m_documentResources is the only reference, so // remove it from the map. +void CachedResourceLoader::garbageCollectDocumentResourcesTimerFired(Timer<CachedResourceLoader>& timer) +{ + ASSERT_UNUSED(timer, &timer == &m_garbageCollectDocumentResourcesTimer); + garbageCollectDocumentResources(); +} + void CachedResourceLoader::garbageCollectDocumentResources() { typedef Vector<String, 10> StringVector; StringVector resourcesToDelete; - for (auto& resource : m_documentResources) { - if (resource.value->hasOneHandle()) { - resourcesToDelete.append(resource.key); - resource.value->setOwningCachedResourceLoader(nullptr); + for (DocumentResourceMap::iterator it = m_documentResources.begin(); it != m_documentResources.end(); ++it) { + if (it->value->hasOneHandle()) { + resourcesToDelete.append(it->key); + it->value->setOwningCachedResourceLoader(0); } } - for (auto& resource : resourcesToDelete) - m_documentResources.remove(resource); + for (StringVector::const_iterator it = resourcesToDelete.begin(); it != resourcesToDelete.end(); ++it) + m_documentResources.remove(*it); } void CachedResourceLoader::performPostLoadActions() { checkForPendingPreloads(); - platformStrategies()->loaderStrategy()->servePendingRequests(); + platformStrategies()->loaderStrategy()->resourceLoadScheduler()->servePendingRequests(); } void CachedResourceLoader::incrementRequestCount(const CachedResource* res) @@ -1029,7 +814,7 @@ void CachedResourceLoader::preload(CachedResource::Type type, CachedResourceRequ // FIXME: We should consider adding a setting to toggle aggressive preloading behavior as opposed // to making this behavior specific to iOS. #if !PLATFORM(IOS) - bool hasRendering = m_document->bodyOrFrameset() && m_document->renderView(); + bool hasRendering = m_document->body() && m_document->renderView(); bool canBlockParser = type == CachedResource::Script || type == CachedResource::CSSStyleSheet; if (!hasRendering && !canBlockParser) { // Don't preload subresources that can't block the parser before we have something to draw. @@ -1044,10 +829,7 @@ void CachedResourceLoader::preload(CachedResource::Type type, CachedResourceRequ void CachedResourceLoader::checkForPendingPreloads() { - if (m_pendingPreloads.isEmpty()) - return; - auto* body = m_document->bodyOrFrameset(); - if (!body || !body->renderer()) + if (m_pendingPreloads.isEmpty() || !m_document->body() || !m_document->body()->renderer()) return; #if PLATFORM(IOS) // We always preload resources on iOS. See <https://bugs.webkit.org/show_bug.cgi?id=91276>. @@ -1079,7 +861,7 @@ void CachedResourceLoader::requestPreload(CachedResource::Type type, CachedResou resource->increasePreloadCount(); if (!m_preloads) - m_preloads = std::make_unique<ListHashSet<CachedResource*>>(); + m_preloads = adoptPtr(new ListHashSet<CachedResource*>); m_preloads->add(resource.get()); #if PRELOAD_DEBUG @@ -1092,13 +874,17 @@ bool CachedResourceLoader::isPreloaded(const String& urlString) const const URL& url = m_document->completeURL(urlString); if (m_preloads) { - for (auto& resource : *m_preloads) { + ListHashSet<CachedResource*>::iterator end = m_preloads->end(); + for (ListHashSet<CachedResource*>::iterator it = m_preloads->begin(); it != end; ++it) { + CachedResource* resource = *it; if (resource->url() == url) return true; } } - for (auto& pendingPreload : m_pendingPreloads) { + Deque<PendingPreload>::const_iterator dequeEnd = m_pendingPreloads.end(); + for (Deque<PendingPreload>::const_iterator it = m_pendingPreloads.begin(); it != dequeEnd; ++it) { + PendingPreload pendingPreload = *it; if (pendingPreload.m_request.resourceRequest().url() == url) return true; } @@ -1113,13 +899,15 @@ void CachedResourceLoader::clearPreloads() if (!m_preloads) return; - for (auto* resource : *m_preloads) { - resource->decreasePreloadCount(); - bool deleted = resource->deleteIfPossible(); - if (!deleted && resource->preloadResult() == CachedResource::PreloadNotReferenced) - MemoryCache::singleton().remove(*resource); + ListHashSet<CachedResource*>::iterator end = m_preloads->end(); + for (ListHashSet<CachedResource*>::iterator it = m_preloads->begin(); it != end; ++it) { + CachedResource* res = *it; + res->decreasePreloadCount(); + bool deleted = res->deleteIfPossible(); + if (!deleted && res->preloadResult() == CachedResource::PreloadNotReferenced) + memoryCache()->remove(res); } - m_preloads = nullptr; + m_preloads.clear(); } void CachedResourceLoader::clearPendingPreloads() @@ -1136,34 +924,36 @@ void CachedResourceLoader::printPreloadStats() unsigned stylesheetMisses = 0; unsigned images = 0; unsigned imageMisses = 0; - for (auto& resource : m_preloads) { - if (resource->preloadResult() == CachedResource::PreloadNotReferenced) - printf("!! UNREFERENCED PRELOAD %s\n", resource->url().latin1().data()); - else if (resource->preloadResult() == CachedResource::PreloadReferencedWhileComplete) - printf("HIT COMPLETE PRELOAD %s\n", resource->url().latin1().data()); - else if (resource->preloadResult() == CachedResource::PreloadReferencedWhileLoading) - printf("HIT LOADING PRELOAD %s\n", resource->url().latin1().data()); + ListHashSet<CachedResource*>::iterator end = m_preloads.end(); + for (ListHashSet<CachedResource*>::iterator it = m_preloads.begin(); it != end; ++it) { + CachedResource* res = *it; + if (res->preloadResult() == CachedResource::PreloadNotReferenced) + printf("!! UNREFERENCED PRELOAD %s\n", res->url().latin1().data()); + else if (res->preloadResult() == CachedResource::PreloadReferencedWhileComplete) + 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 (resource->type() == CachedResource::Script) { + if (res->type() == CachedResource::Script) { scripts++; - if (resource->preloadResult() < CachedResource::PreloadReferencedWhileLoading) + if (res->preloadResult() < CachedResource::PreloadReferencedWhileLoading) scriptMisses++; - } else if (resource->type() == CachedResource::CSSStyleSheet) { + } else if (res->type() == CachedResource::CSSStyleSheet) { stylesheets++; - if (resource->preloadResult() < CachedResource::PreloadReferencedWhileLoading) + if (res->preloadResult() < CachedResource::PreloadReferencedWhileLoading) stylesheetMisses++; } else { images++; - if (resource->preloadResult() < CachedResource::PreloadReferencedWhileLoading) + if (res->preloadResult() < CachedResource::PreloadReferencedWhileLoading) imageMisses++; } - if (resource->errorOccurred() && resource->preloadResult() == CachedResource::PreloadNotReferenced) - MemoryCache::singleton().remove(resource); + if (res->errorOccurred()) + memoryCache()->remove(res); - resource->decreasePreloadCount(); + res->decreasePreloadCount(); } - m_preloads = nullptr; + m_preloads.clear(); if (scripts) printf("SCRIPTS: %d (%d hits, hit rate %d%%)\n", scripts, scripts - scriptMisses, (scripts - scriptMisses) * 100 / scripts); @@ -1176,7 +966,7 @@ void CachedResourceLoader::printPreloadStats() const ResourceLoaderOptions& CachedResourceLoader::defaultCachedResourceOptions() { - static ResourceLoaderOptions options(SendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForAllCredentials, ClientRequestedCredentials, DoSecurityCheck, UseDefaultOriginRestrictionsForType, DoNotIncludeCertificateInfo, ContentSecurityPolicyImposition::DoPolicyCheck, DefersLoadingPolicy::AllowDefersLoading, CachingPolicy::AllowCaching); + static ResourceLoaderOptions options(SendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForAllCredentials, DoSecurityCheck, UseDefaultOriginRestrictionsForType); return options; } |