diff options
Diffstat (limited to 'Source/WebCore/loader')
-rw-r--r-- | Source/WebCore/loader/FrameLoader.cpp | 46 | ||||
-rw-r--r-- | Source/WebCore/loader/FrameLoader.h | 11 | ||||
-rw-r--r-- | Source/WebCore/loader/ImageLoader.cpp | 23 | ||||
-rw-r--r-- | Source/WebCore/loader/ImageLoader.h | 2 | ||||
-rw-r--r-- | Source/WebCore/loader/MainResourceLoader.cpp | 2 | ||||
-rw-r--r-- | Source/WebCore/loader/MixedContentChecker.cpp | 108 | ||||
-rw-r--r-- | Source/WebCore/loader/MixedContentChecker.h | 64 | ||||
-rw-r--r-- | Source/WebCore/loader/SubframeLoader.cpp | 4 | ||||
-rw-r--r-- | Source/WebCore/loader/SubresourceLoader.cpp | 37 | ||||
-rw-r--r-- | Source/WebCore/loader/cache/CachedRawResource.cpp | 38 | ||||
-rwxr-xr-x | Source/WebCore/loader/cache/CachedResource.cpp | 65 | ||||
-rw-r--r-- | Source/WebCore/loader/cache/CachedResource.h | 4 | ||||
-rw-r--r-- | Source/WebCore/loader/cache/CachedResourceLoader.cpp | 4 | ||||
-rw-r--r-- | Source/WebCore/loader/icon/IconController.cpp | 2 |
14 files changed, 289 insertions, 121 deletions
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp index 8ab3d8922..a84c508eb 100644 --- a/Source/WebCore/loader/FrameLoader.cpp +++ b/Source/WebCore/loader/FrameLoader.cpp @@ -212,6 +212,7 @@ FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client) , m_notifer(frame) , m_subframeLoader(frame) , m_icon(frame) + , m_mixedContentChecker(frame) , m_state(FrameStateCommittedPage) , m_loadType(FrameLoadTypeStandard) , m_delegateIsHandlingProvisionalLoadError(false) @@ -914,51 +915,6 @@ String FrameLoader::outgoingOrigin() const return m_frame->document()->securityOrigin()->toString(); } -bool FrameLoader::isMixedContent(SecurityOrigin* context, const KURL& url) -{ - if (context->protocol() != "https") - return false; // We only care about HTTPS security origins. - - // We're in a secure context, so |url| is mixed content if it's insecure. - return !SecurityOrigin::isSecure(url); -} - -bool FrameLoader::checkIfDisplayInsecureContent(SecurityOrigin* context, const KURL& url) -{ - if (!isMixedContent(context, url)) - return true; - - Settings* settings = m_frame->settings(); - bool allowed = m_client->allowDisplayingInsecureContent(settings && settings->allowDisplayOfInsecureContent(), context, url); - String message = (allowed ? emptyString() : "[blocked] ") + "The page at " + - m_frame->document()->url().string() + " displayed insecure content from " + url.string() + ".\n"; - - m_frame->document()->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel, message); - - if (allowed) - m_client->didDisplayInsecureContent(); - - return allowed; -} - -bool FrameLoader::checkIfRunInsecureContent(SecurityOrigin* context, const KURL& url) -{ - if (!isMixedContent(context, url)) - return true; - - Settings* settings = m_frame->settings(); - bool allowed = m_client->allowRunningInsecureContent(settings && settings->allowRunningOfInsecureContent(), context, url); - String message = (allowed ? emptyString() : "[blocked] ") + "The page at " + - m_frame->document()->url().string() + " ran insecure content from " + url.string() + ".\n"; - - m_frame->document()->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel, message); - - if (allowed) - m_client->didRunInsecureContent(context, url); - - return allowed; -} - bool FrameLoader::checkIfFormActionAllowedByCSP(const KURL& url) const { if (m_submittedFormURL.isEmpty()) diff --git a/Source/WebCore/loader/FrameLoader.h b/Source/WebCore/loader/FrameLoader.h index 4f140a184..e78ee4e9e 100644 --- a/Source/WebCore/loader/FrameLoader.h +++ b/Source/WebCore/loader/FrameLoader.h @@ -39,6 +39,7 @@ #include "IconController.h" #include "IconURL.h" #include "LayoutMilestones.h" +#include "MixedContentChecker.h" #include "PolicyChecker.h" #include "ResourceHandle.h" #include "ResourceLoadNotifier.h" @@ -93,6 +94,7 @@ public: ResourceLoadNotifier* notifier() const { return &m_notifer; } SubframeLoader* subframeLoader() const { return &m_subframeLoader; } IconController* icon() const { return &m_icon; } + MixedContentChecker* mixedContentChecker() const { return &m_mixedContentChecker; } void prepareForHistoryNavigation(); void setupForReplace(); @@ -213,11 +215,6 @@ public: void forceSandboxFlags(SandboxFlags flags) { m_forcedSandboxFlags |= flags; } SandboxFlags effectiveSandboxFlags() const; - // Mixed content related functions. - static bool isMixedContent(SecurityOrigin* context, const KURL&); - bool checkIfDisplayInsecureContent(SecurityOrigin* context, const KURL&); - bool checkIfRunInsecureContent(SecurityOrigin* context, const KURL&); - bool checkIfFormActionAllowedByCSP(const KURL&) const; Frame* opener(); @@ -374,12 +371,16 @@ private: Frame* m_frame; FrameLoaderClient* m_client; + // FIXME: These should be OwnPtr<T> to reduce build times and simplify + // header dependencies unless performance testing proves otherwise. + // Some of these could be lazily created for memory savings on devices. mutable PolicyChecker m_policyChecker; mutable HistoryController m_history; mutable ResourceLoadNotifier m_notifer; mutable SubframeLoader m_subframeLoader; mutable FrameLoaderStateMachine m_stateMachine; mutable IconController m_icon; + mutable MixedContentChecker m_mixedContentChecker; class FrameProgressTracker; OwnPtr<FrameProgressTracker> m_progressTracker; diff --git a/Source/WebCore/loader/ImageLoader.cpp b/Source/WebCore/loader/ImageLoader.cpp index 0523b3a89..a6da61e65 100644 --- a/Source/WebCore/loader/ImageLoader.cpp +++ b/Source/WebCore/loader/ImageLoader.cpp @@ -129,7 +129,7 @@ void ImageLoader::setImage(CachedImage* newImage) // Only consider updating the protection ref-count of the Element immediately before returning // from this function as doing so might result in the destruction of this ImageLoader. - updatedHasPendingLoadEvent(); + updatedHasPendingEvent(); } void ImageLoader::setImageWithoutConsideringPendingLoadEvent(CachedImage* newImage) @@ -248,7 +248,7 @@ void ImageLoader::updateFromElement() // Only consider updating the protection ref-count of the Element immediately before returning // from this function as doing so might result in the destruction of this ImageLoader. - updatedHasPendingLoadEvent(); + updatedHasPendingEvent(); } void ImageLoader::updateFromElementIgnoringPreviousError() @@ -286,7 +286,7 @@ void ImageLoader::notifyFinished(CachedResource* resource) // Only consider updating the protection ref-count of the Element immediately before returning // from this function as doing so might result in the destruction of this ImageLoader. - updatedHasPendingLoadEvent(); + updatedHasPendingEvent(); return; } @@ -294,7 +294,7 @@ void ImageLoader::notifyFinished(CachedResource* resource) m_hasPendingLoadEvent = false; // Only consider updating the protection ref-count of the Element immediately before returning // from this function as doing so might result in the destruction of this ImageLoader. - updatedHasPendingLoadEvent(); + updatedHasPendingEvent(); return; } @@ -341,18 +341,17 @@ void ImageLoader::updateRenderer() imageResource->setCachedImage(m_image.get()); } -void ImageLoader::updatedHasPendingLoadEvent() +void ImageLoader::updatedHasPendingEvent() { - // If an Element that does image loading is removed from the DOM the load event for the image is still observable. + // If an Element that does image loading is removed from the DOM the load/error event for the image is still observable. // As long as the ImageLoader is actively loading, the Element itself needs to be ref'ed to keep it from being // destroyed by DOM manipulation or garbage collection. // If such an Element wishes for the load to stop when removed from the DOM it needs to stop the ImageLoader explicitly. - - if (m_hasPendingLoadEvent == m_elementIsProtected) + bool wasProtected = m_elementIsProtected; + m_elementIsProtected = m_hasPendingLoadEvent || m_hasPendingErrorEvent; + if (wasProtected == m_elementIsProtected) return; - m_elementIsProtected = m_hasPendingLoadEvent; - if (m_elementIsProtected) client()->refSourceElement(); else @@ -397,7 +396,7 @@ void ImageLoader::dispatchPendingBeforeLoadEvent() // Only consider updating the protection ref-count of the Element immediately before returning // from this function as doing so might result in the destruction of this ImageLoader. - updatedHasPendingLoadEvent(); + updatedHasPendingEvent(); } void ImageLoader::dispatchPendingLoadEvent() @@ -413,7 +412,7 @@ void ImageLoader::dispatchPendingLoadEvent() // Only consider updating the protection ref-count of the Element immediately before returning // from this function as doing so might result in the destruction of this ImageLoader. - updatedHasPendingLoadEvent(); + updatedHasPendingEvent(); } void ImageLoader::dispatchPendingErrorEvent() diff --git a/Source/WebCore/loader/ImageLoader.h b/Source/WebCore/loader/ImageLoader.h index 910744416..bc85915b9 100644 --- a/Source/WebCore/loader/ImageLoader.h +++ b/Source/WebCore/loader/ImageLoader.h @@ -82,7 +82,7 @@ private: virtual void dispatchLoadEvent() = 0; virtual String sourceURI(const AtomicString&) const = 0; - void updatedHasPendingLoadEvent(); + void updatedHasPendingEvent(); void dispatchPendingBeforeLoadEvent(); void dispatchPendingLoadEvent(); diff --git a/Source/WebCore/loader/MainResourceLoader.cpp b/Source/WebCore/loader/MainResourceLoader.cpp index 1f9bb4652..485aaa2c1 100644 --- a/Source/WebCore/loader/MainResourceLoader.cpp +++ b/Source/WebCore/loader/MainResourceLoader.cpp @@ -236,7 +236,7 @@ void MainResourceLoader::willSendRequest(ResourceRequest& newRequest, const Reso Frame* top = m_frame->tree()->top(); if (top != m_frame) { - if (!frameLoader()->checkIfDisplayInsecureContent(top->document()->securityOrigin(), newRequest.url())) { + if (!frameLoader()->mixedContentChecker()->canDisplayInsecureContent(top->document()->securityOrigin(), newRequest.url())) { cancel(); return; } diff --git a/Source/WebCore/loader/MixedContentChecker.cpp b/Source/WebCore/loader/MixedContentChecker.cpp new file mode 100644 index 000000000..71fd2b36e --- /dev/null +++ b/Source/WebCore/loader/MixedContentChecker.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2012 Google 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "MixedContentChecker.h" + +#include "Console.h" +#include "DOMWindow.h" +#include "Document.h" +#include "Frame.h" +#include "FrameLoaderClient.h" +#include "SchemeRegistry.h" +#include "SecurityOrigin.h" +#include "Settings.h" +#include <wtf/text/CString.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +MixedContentChecker::MixedContentChecker(Frame* frame) + : m_frame(frame) +{ +} + +FrameLoaderClient* MixedContentChecker::client() const +{ + return m_frame->loader()->client(); +} + +static inline CString asUTF8(const KURL& url) +{ + return url.string().utf8(); +} + +bool MixedContentChecker::isMixedContent(SecurityOrigin* securityOrigin, const KURL& url) +{ + if (securityOrigin->protocol() != "https") + return false; // We only care about HTTPS security origins. + + // We're in a secure context, so |url| is mixed content if it's insecure. + return !SecurityOrigin::isSecure(url); +} + +bool MixedContentChecker::canDisplayInsecureContent(SecurityOrigin* securityOrigin, const KURL& url) const +{ + if (!isMixedContent(securityOrigin, url)) + return true; + + Settings* settings = m_frame->settings(); + bool allowed = client()->allowDisplayingInsecureContent(settings && settings->allowDisplayOfInsecureContent(), securityOrigin, url); + logWarning(allowed, "displayed", url); + + if (allowed) + client()->didDisplayInsecureContent(); + + return allowed; +} + +bool MixedContentChecker::canRunInsecureContent(SecurityOrigin* securityOrigin, const KURL& url) const +{ + if (!isMixedContent(securityOrigin, url)) + return true; + + Settings* settings = m_frame->settings(); + bool allowed = client()->allowRunningInsecureContent(settings && settings->allowRunningOfInsecureContent(), securityOrigin, url); + logWarning(allowed, "ran", url); + + if (allowed) + client()->didRunInsecureContent(securityOrigin, url); + + return allowed; +} + +void MixedContentChecker::logWarning(bool allowed, const String& action, const KURL& target) const +{ + Console* console = m_frame->document()->domWindow()->console(); + // FIXME: Why does this message not have a source URL or a line number? webkit.org/b/97979 + String message = String::format("%sThe page at %s %s insecure content from %s.\n", + (allowed ? "" : "[blocked] "), asUTF8(m_frame->document()->url()).data(), action.utf8().data(), asUTF8(target).data()); + console->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel, message); +} + +} // namespace WebCore diff --git a/Source/WebCore/loader/MixedContentChecker.h b/Source/WebCore/loader/MixedContentChecker.h new file mode 100644 index 000000000..ee7daf619 --- /dev/null +++ b/Source/WebCore/loader/MixedContentChecker.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2012 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 MixedContentChecker_h +#define MixedContentChecker_h + +#include <wtf/text/WTFString.h> + +namespace WebCore { + +class Frame; +class FrameLoaderClient; +class KURL; +class SecurityOrigin; + +class MixedContentChecker { + WTF_MAKE_NONCOPYABLE(MixedContentChecker); +public: + MixedContentChecker(Frame*); + + bool canDisplayInsecureContent(SecurityOrigin*, const KURL&) const; + bool canRunInsecureContent(SecurityOrigin*, const KURL&) const; + +private: + // FIXME: This should probably have a separate client from FrameLoader. + FrameLoaderClient* client() const; + + static bool isMixedContent(SecurityOrigin*, const KURL&); + void logWarning(bool allowed, const String& action, const KURL&) const; + + Frame* m_frame; +}; + +} // namespace WebCore + +#endif // MixedContentChecker_h + diff --git a/Source/WebCore/loader/SubframeLoader.cpp b/Source/WebCore/loader/SubframeLoader.cpp index c3b38a87c..ab461f6d6 100644 --- a/Source/WebCore/loader/SubframeLoader.cpp +++ b/Source/WebCore/loader/SubframeLoader.cpp @@ -136,7 +136,7 @@ bool SubframeLoader::pluginIsLoadable(HTMLPlugInImageElement* pluginElement, con return false; } - if (m_frame->loader() && !m_frame->loader()->checkIfRunInsecureContent(document()->securityOrigin(), url)) + if (m_frame->loader() && !m_frame->loader()->mixedContentChecker()->canRunInsecureContent(document()->securityOrigin(), url)) return false; } @@ -265,7 +265,7 @@ PassRefPtr<Widget> SubframeLoader::loadMediaPlayerProxyPlugin(Node* node, const else if (mediaElement->isVideo()) size = RenderVideo::defaultSize(); - if (!m_frame->loader()->checkIfRunInsecureContent(m_frame->document()->securityOrigin(), completedURL)) + if (!m_frame->loader()->mixedContentChecker()->canRunInsecureContent(m_frame->document()->securityOrigin(), completedURL)) return 0; RefPtr<Widget> widget = m_frame->loader()->client()->createMediaPlayerProxyPlugin(size, mediaElement, completedURL, diff --git a/Source/WebCore/loader/SubresourceLoader.cpp b/Source/WebCore/loader/SubresourceLoader.cpp index 36b367660..50975794e 100644 --- a/Source/WebCore/loader/SubresourceLoader.cpp +++ b/Source/WebCore/loader/SubresourceLoader.cpp @@ -33,12 +33,9 @@ #include "Document.h" #include "DocumentLoader.h" #include "Frame.h" -#include "FrameLoader.h" #include "Logging.h" #include "MemoryCache.h" #include "ResourceBuffer.h" -#include "SecurityOrigin.h" -#include "SecurityPolicy.h" #include "WebCoreMemoryInstrumentation.h" #include <wtf/RefCountedLeakCounter.h> #include <wtf/StdLibExtras.h> @@ -83,40 +80,8 @@ SubresourceLoader::~SubresourceLoader() PassRefPtr<SubresourceLoader> SubresourceLoader::create(Frame* frame, CachedResource* resource, const ResourceRequest& request, const ResourceLoaderOptions& options) { - if (!frame) - return 0; - - FrameLoader* frameLoader = frame->loader(); - if (options.securityCheck == DoSecurityCheck && (frameLoader->state() == FrameStateProvisional || !frameLoader->activeDocumentLoader() || frameLoader->activeDocumentLoader()->isStopping())) - return 0; - - ResourceRequest newRequest = request; - - // Note: We skip the Content-Security-Policy check here because we check - // the Content-Security-Policy at the CachedResourceLoader layer so we can - // handle different resource types differently. - - String outgoingReferrer; - String outgoingOrigin; - if (request.httpReferrer().isNull()) { - outgoingReferrer = frameLoader->outgoingReferrer(); - outgoingOrigin = frameLoader->outgoingOrigin(); - } else { - outgoingReferrer = request.httpReferrer(); - outgoingOrigin = SecurityOrigin::createFromString(outgoingReferrer)->toString(); - } - - outgoingReferrer = SecurityPolicy::generateReferrerHeader(frame->document()->referrerPolicy(), request.url(), outgoingReferrer); - if (outgoingReferrer.isEmpty()) - newRequest.clearHTTPReferrer(); - else if (!request.httpReferrer()) - newRequest.setHTTPReferrer(outgoingReferrer); - FrameLoader::addHTTPOriginIfNeeded(newRequest, outgoingOrigin); - - frameLoader->addExtraFieldsToSubresourceRequest(newRequest); - RefPtr<SubresourceLoader> subloader(adoptRef(new SubresourceLoader(frame, resource, options))); - if (!subloader->init(newRequest)) + if (!subloader->init(request)) return 0; return subloader.release(); } diff --git a/Source/WebCore/loader/cache/CachedRawResource.cpp b/Source/WebCore/loader/cache/CachedRawResource.cpp index 6d6c1297f..194b15f89 100644 --- a/Source/WebCore/loader/cache/CachedRawResource.cpp +++ b/Source/WebCore/loader/cache/CachedRawResource.cpp @@ -129,6 +129,24 @@ void CachedRawResource::setDefersLoading(bool defers) m_loader->setDefersLoading(defers); } +static bool shouldIgnoreHeaderForCacheReuse(AtomicString headerName) +{ + // FIXME: This list of headers that don't affect cache policy almost certainly isn't complete. + DEFINE_STATIC_LOCAL(HashSet<AtomicString>, m_headers, ()); + if (m_headers.isEmpty()) { + m_headers.add("Accept"); + m_headers.add("Cache-Control"); + m_headers.add("If-Modified-Since"); + m_headers.add("If-None-Match"); + m_headers.add("Origin"); + m_headers.add("Pragma"); + m_headers.add("Purpose"); + m_headers.add("Referer"); + m_headers.add("User-Agent"); + } + return m_headers.contains(headerName); +} + bool CachedRawResource::canReuse(const ResourceRequest& newRequest) const { if (m_options.shouldBufferData == DoNotBufferData) @@ -143,20 +161,24 @@ bool CachedRawResource::canReuse(const ResourceRequest& newRequest) const if (m_resourceRequest.allowCookies() != newRequest.allowCookies()) return false; - // Ensure all headers match the existing headers before continuing. - // Note that only headers set by our client will be present in either - // ResourceRequest, since SubresourceLoader creates a separate copy - // for its purposes. - // FIXME: There might be some headers that shouldn't block reuse. + // Ensure most headers match the existing headers before continuing. + // Note that the list of ignored headers includes some headers explicitly related to caching. + // A more detailed check of caching policy will be performed later, this is simply a list of + // headers that we might permit to be different and still reuse the existing CachedResource. const HTTPHeaderMap& newHeaders = newRequest.httpHeaderFields(); const HTTPHeaderMap& oldHeaders = m_resourceRequest.httpHeaderFields(); - if (newHeaders.size() != oldHeaders.size()) - return false; HTTPHeaderMap::const_iterator end = newHeaders.end(); for (HTTPHeaderMap::const_iterator i = newHeaders.begin(); i != end; ++i) { AtomicString headerName = i->key; - if (i->value != oldHeaders.get(headerName)) + if (!shouldIgnoreHeaderForCacheReuse(headerName) && i->value != oldHeaders.get(headerName)) + return false; + } + + end = oldHeaders.end(); + for (HTTPHeaderMap::const_iterator i = oldHeaders.begin(); i != end; ++i) { + AtomicString headerName = i->key; + if (!shouldIgnoreHeaderForCacheReuse(headerName) && i->value != newHeaders.get(headerName)) return false; } return true; diff --git a/Source/WebCore/loader/cache/CachedResource.cpp b/Source/WebCore/loader/cache/CachedResource.cpp index 58115e058..703c42836 100755 --- a/Source/WebCore/loader/cache/CachedResource.cpp +++ b/Source/WebCore/loader/cache/CachedResource.cpp @@ -32,6 +32,7 @@ #include "CachedResourceLoader.h" #include "CrossOriginAccessControl.h" #include "Document.h" +#include "DocumentLoader.h" #include "FrameLoaderClient.h" #include "InspectorInstrumentation.h" #include "KURL.h" @@ -40,6 +41,8 @@ #include "ResourceBuffer.h" #include "ResourceHandle.h" #include "ResourceLoadScheduler.h" +#include "SecurityOrigin.h" +#include "SecurityPolicy.h" #include "SubresourceLoader.h" #include "WebCoreMemoryInstrumentation.h" #include <wtf/CurrentTime.h> @@ -190,8 +193,55 @@ CachedResource::~CachedResource() m_owningCachedResourceLoader->removeCachedResource(this); } +void CachedResource::failBeforeStarting() +{ + // FIXME: What if resources in other frames were waiting for this revalidation? + LOG(ResourceLoading, "Cannot start loading '%s'", url().string().latin1().data()); + if (m_resourceToRevalidate) + memoryCache()->revalidationFailed(this); + error(CachedResource::LoadError); +} + +void CachedResource::addAdditionalRequestHeaders(CachedResourceLoader* cachedResourceLoader) +{ + // Note: We skip the Content-Security-Policy check here because we check + // the Content-Security-Policy at the CachedResourceLoader layer so we can + // handle different resource types differently. + + FrameLoader* frameLoader = cachedResourceLoader->frame()->loader(); + String outgoingReferrer; + String outgoingOrigin; + if (m_resourceRequest.httpReferrer().isNull()) { + outgoingReferrer = frameLoader->outgoingReferrer(); + outgoingOrigin = frameLoader->outgoingOrigin(); + } else { + outgoingReferrer = m_resourceRequest.httpReferrer(); + outgoingOrigin = SecurityOrigin::createFromString(outgoingReferrer)->toString(); + } + + outgoingReferrer = SecurityPolicy::generateReferrerHeader(cachedResourceLoader->document()->referrerPolicy(), m_resourceRequest.url(), outgoingReferrer); + if (outgoingReferrer.isEmpty()) + m_resourceRequest.clearHTTPReferrer(); + else if (!m_resourceRequest.httpReferrer()) + m_resourceRequest.setHTTPReferrer(outgoingReferrer); + FrameLoader::addHTTPOriginIfNeeded(m_resourceRequest, outgoingOrigin); + + frameLoader->addExtraFieldsToSubresourceRequest(m_resourceRequest); +} + void CachedResource::load(CachedResourceLoader* cachedResourceLoader, const ResourceLoaderOptions& options) { + if (!cachedResourceLoader->frame()) { + failBeforeStarting(); + return; + } + + FrameLoader* frameLoader = cachedResourceLoader->frame()->loader(); + if (options.securityCheck == DoSecurityCheck && (frameLoader->state() == FrameStateProvisional || !frameLoader->activeDocumentLoader() || frameLoader->activeDocumentLoader()->isStopping())) { + failBeforeStarting(); + return; + } + m_options = options; m_loading = true; @@ -225,14 +275,11 @@ void CachedResource::load(CachedResourceLoader* cachedResourceLoader, const Reso m_resourceRequest.setHTTPHeaderField("Purpose", "prefetch"); #endif m_resourceRequest.setPriority(loadPriority()); - - m_loader = resourceLoadScheduler()->scheduleSubresourceLoad(cachedResourceLoader->document()->frame(), this, m_resourceRequest, m_resourceRequest.priority(), options); + addAdditionalRequestHeaders(cachedResourceLoader); + + m_loader = resourceLoadScheduler()->scheduleSubresourceLoad(cachedResourceLoader->frame(), this, m_resourceRequest, m_resourceRequest.priority(), options); if (!m_loader) { - // FIXME: What if resources in other frames were waiting for this revalidation? - LOG(ResourceLoading, "Cannot start loading '%s'", url().string().latin1().data()); - if (m_resourceToRevalidate) - memoryCache()->revalidationFailed(this); - error(CachedResource::LoadError); + failBeforeStarting(); return; } @@ -293,9 +340,9 @@ double CachedResource::currentAge() const // RFC2616 13.2.3 // No compensation for latency as that is not terribly important in practice double dateValue = m_response.date(); - double apparentAge = isfinite(dateValue) ? max(0., m_responseTimestamp - dateValue) : 0; + double apparentAge = isfinite(dateValue) ? std::max(0., m_responseTimestamp - dateValue) : 0; double ageValue = m_response.age(); - double correctedReceivedAge = isfinite(ageValue) ? max(apparentAge, ageValue) : apparentAge; + double correctedReceivedAge = isfinite(ageValue) ? std::max(apparentAge, ageValue) : apparentAge; double residentTime = currentTime() - m_responseTimestamp; return correctedReceivedAge + residentTime; } diff --git a/Source/WebCore/loader/cache/CachedResource.h b/Source/WebCore/loader/cache/CachedResource.h index 9c5d365ca..c3d093a2f 100644 --- a/Source/WebCore/loader/cache/CachedResource.h +++ b/Source/WebCore/loader/cache/CachedResource.h @@ -255,6 +255,8 @@ public: protected: virtual void checkNotify(); + virtual void addAdditionalRequestHeaders(CachedResourceLoader*); + void setEncodedSize(unsigned); void setDecodedSize(unsigned); void didAccessDecodedData(double timeStamp); @@ -301,6 +303,8 @@ private: double currentAge() const; double freshnessLifetime() const; + void failBeforeStarting(); + RefPtr<CachedMetadata> m_cachedMetadata; double m_lastDecodedAccessTime; // Used as a "thrash guard" in the cache diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp index c6ce406b6..7c420c066 100644 --- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp +++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp @@ -261,7 +261,7 @@ bool CachedResourceLoader::checkInsecureContent(CachedResource::Type type, const // These resource can inject script into the current document (Script, // XSL) or exfiltrate the content of the current document (CSS). if (Frame* f = frame()) - if (!f->loader()->checkIfRunInsecureContent(m_document->securityOrigin(), url)) + if (!f->loader()->mixedContentChecker()->canRunInsecureContent(m_document->securityOrigin(), url)) return false; break; #if ENABLE(VIDEO_TRACK) @@ -276,7 +276,7 @@ bool CachedResourceLoader::checkInsecureContent(CachedResource::Type type, const // These resources can corrupt only the frame's pixels. if (Frame* f = frame()) { Frame* top = f->tree()->top(); - if (!top->loader()->checkIfDisplayInsecureContent(top->document()->securityOrigin(), url)) + if (!top->loader()->mixedContentChecker()->canDisplayInsecureContent(top->document()->securityOrigin(), url)) return false; } break; diff --git a/Source/WebCore/loader/icon/IconController.cpp b/Source/WebCore/loader/icon/IconController.cpp index b4a72c63b..74faa959c 100644 --- a/Source/WebCore/loader/icon/IconController.cpp +++ b/Source/WebCore/loader/icon/IconController.cpp @@ -213,6 +213,8 @@ void IconController::continueLoadWithDecision(IconLoadDecision iconLoadDecision) if (iconLoadDecision == IconLoadNo) { KURL iconURL(url()); String urlString(iconURL.string()); + if (urlString.isEmpty()) + return; LOG(IconDatabase, "IconController::startLoader() - Told not to load this icon, committing iconURL %s to database for pageURL mapping", urlString.ascii().data()); commitToDatabase(iconURL); |