summaryrefslogtreecommitdiff
path: root/Source/WebCore/loader
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/loader')
-rw-r--r--Source/WebCore/loader/FrameLoader.cpp46
-rw-r--r--Source/WebCore/loader/FrameLoader.h11
-rw-r--r--Source/WebCore/loader/ImageLoader.cpp23
-rw-r--r--Source/WebCore/loader/ImageLoader.h2
-rw-r--r--Source/WebCore/loader/MainResourceLoader.cpp2
-rw-r--r--Source/WebCore/loader/MixedContentChecker.cpp108
-rw-r--r--Source/WebCore/loader/MixedContentChecker.h64
-rw-r--r--Source/WebCore/loader/SubframeLoader.cpp4
-rw-r--r--Source/WebCore/loader/SubresourceLoader.cpp37
-rw-r--r--Source/WebCore/loader/cache/CachedRawResource.cpp38
-rwxr-xr-xSource/WebCore/loader/cache/CachedResource.cpp65
-rw-r--r--Source/WebCore/loader/cache/CachedResource.h4
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.cpp4
-rw-r--r--Source/WebCore/loader/icon/IconController.cpp2
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);