summaryrefslogtreecommitdiff
path: root/Source/WebCore/loader/cache/CachedResourceRequest.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/loader/cache/CachedResourceRequest.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/loader/cache/CachedResourceRequest.cpp')
-rw-r--r--Source/WebCore/loader/cache/CachedResourceRequest.cpp247
1 files changed, 217 insertions, 30 deletions
diff --git a/Source/WebCore/loader/cache/CachedResourceRequest.cpp b/Source/WebCore/loader/cache/CachedResourceRequest.cpp
index 55a493859..a5ac5637a 100644
--- a/Source/WebCore/loader/cache/CachedResourceRequest.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceRequest.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``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 COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. 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
@@ -27,52 +27,49 @@
#include "CachedResourceRequest.h"
#include "CachedResourceLoader.h"
+#include "ContentExtensionActions.h"
+#include "CrossOriginAccessControl.h"
#include "Document.h"
#include "Element.h"
+#include "FrameLoader.h"
+#include "HTTPHeaderValues.h"
+#include "MemoryCache.h"
+#include "SecurityPolicy.h"
+#include <wtf/NeverDestroyed.h>
namespace WebCore {
-CachedResourceRequest::CachedResourceRequest(const ResourceRequest& resourceRequest, const String& charset, ResourceLoadPriority priority)
- : m_resourceRequest(resourceRequest)
- , m_charset(charset)
- , m_options(CachedResourceLoader::defaultCachedResourceOptions())
- , m_priority(priority)
- , m_forPreload(false)
- , m_defer(NoDefer)
-{
-}
-
-CachedResourceRequest::CachedResourceRequest(const ResourceRequest& resourceRequest, const ResourceLoaderOptions& options)
- : m_resourceRequest(resourceRequest)
+CachedResourceRequest::CachedResourceRequest(ResourceRequest&& resourceRequest, const ResourceLoaderOptions& options, std::optional<ResourceLoadPriority> priority, String&& charset)
+ : m_resourceRequest(WTFMove(resourceRequest))
+ , m_charset(WTFMove(charset))
, m_options(options)
- , m_priority(ResourceLoadPriorityUnresolved)
- , m_forPreload(false)
- , m_defer(NoDefer)
-{
-}
-
-CachedResourceRequest::CachedResourceRequest(const ResourceRequest& resourceRequest, ResourceLoadPriority priority)
- : m_resourceRequest(resourceRequest)
- , m_options(CachedResourceLoader::defaultCachedResourceOptions())
, m_priority(priority)
- , m_forPreload(false)
- , m_defer(NoDefer)
+ , m_fragmentIdentifier(splitFragmentIdentifierFromRequestURL(m_resourceRequest))
{
}
-CachedResourceRequest::~CachedResourceRequest()
+String CachedResourceRequest::splitFragmentIdentifierFromRequestURL(ResourceRequest& request)
{
+ if (!MemoryCache::shouldRemoveFragmentIdentifier(request.url()))
+ return { };
+ URL url = request.url();
+ String fragmentIdentifier = url.fragmentIdentifier();
+ url.removeFragmentIdentifier();
+ request.setURL(url);
+ return fragmentIdentifier;
}
-void CachedResourceRequest::setInitiator(PassRefPtr<Element> element)
+void CachedResourceRequest::setInitiator(Element& element)
{
- ASSERT(!m_initiatorElement && m_initiatorName.isEmpty());
- m_initiatorElement = element;
+ ASSERT(!m_initiatorElement);
+ ASSERT(m_initiatorName.isEmpty());
+ m_initiatorElement = &element;
}
void CachedResourceRequest::setInitiator(const AtomicString& name)
{
- ASSERT(!m_initiatorElement && m_initiatorName.isEmpty());
+ ASSERT(!m_initiatorElement);
+ ASSERT(m_initiatorName.isEmpty());
m_initiatorName = name;
}
@@ -83,8 +80,198 @@ const AtomicString& CachedResourceRequest::initiatorName() const
if (!m_initiatorName.isEmpty())
return m_initiatorName;
- DEFINE_STATIC_LOCAL(AtomicString, defaultName, ("resource", AtomicString::ConstructFromLiteral));
+ static NeverDestroyed<AtomicString> defaultName("other", AtomicString::ConstructFromLiteral);
return defaultName;
}
+void CachedResourceRequest::setAsPotentiallyCrossOrigin(const String& mode, Document& document)
+{
+ ASSERT(m_options.mode == FetchOptions::Mode::NoCors);
+
+ m_origin = &document.securityOrigin();
+
+ if (mode.isNull())
+ return;
+
+ m_options.mode = FetchOptions::Mode::Cors;
+
+ FetchOptions::Credentials credentials = equalLettersIgnoringASCIICase(mode, "omit")
+ ? FetchOptions::Credentials::Omit : equalLettersIgnoringASCIICase(mode, "use-credentials")
+ ? FetchOptions::Credentials::Include : FetchOptions::Credentials::SameOrigin;
+ m_options.credentials = credentials;
+ m_options.allowCredentials = credentials == FetchOptions::Credentials::Include ? AllowStoredCredentials : DoNotAllowStoredCredentials;
+ WebCore::updateRequestForAccessControl(m_resourceRequest, document.securityOrigin(), m_options.allowCredentials);
+}
+
+void CachedResourceRequest::updateForAccessControl(Document& document)
+{
+ ASSERT(m_options.mode == FetchOptions::Mode::Cors);
+
+ m_origin = &document.securityOrigin();
+ WebCore::updateRequestForAccessControl(m_resourceRequest, *m_origin, m_options.allowCredentials);
+}
+
+void upgradeInsecureResourceRequestIfNeeded(ResourceRequest& request, Document& document)
+{
+ URL url = request.url();
+
+ ASSERT(document.contentSecurityPolicy());
+ document.contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(url, ContentSecurityPolicy::InsecureRequestType::Load);
+
+ if (url == request.url())
+ return;
+
+ request.setURL(url);
+}
+
+void CachedResourceRequest::upgradeInsecureRequestIfNeeded(Document& document)
+{
+ upgradeInsecureResourceRequestIfNeeded(m_resourceRequest, document);
+}
+
+void CachedResourceRequest::setDomainForCachePartition(Document& document)
+{
+ m_resourceRequest.setDomainForCachePartition(document.topOrigin().domainForCachePartition());
+}
+
+static inline String acceptHeaderValueFromType(CachedResource::Type type)
+{
+ switch (type) {
+ case CachedResource::Type::MainResource:
+ return ASCIILiteral("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
+ case CachedResource::Type::ImageResource:
+ return ASCIILiteral("image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5");
+ case CachedResource::Type::CSSStyleSheet:
+ return ASCIILiteral("text/css,*/*;q=0.1");
+ case CachedResource::Type::SVGDocumentResource:
+ return ASCIILiteral("image/svg+xml");
+#if ENABLE(XSLT)
+ case CachedResource::Type::XSLStyleSheet:
+ // FIXME: This should accept more general xml formats */*+xml, image/svg+xml for example.
+ return ASCIILiteral("text/xml,application/xml,application/xhtml+xml,text/xsl,application/rss+xml,application/atom+xml");
+#endif
+ default:
+ return ASCIILiteral("*/*");
+ }
+}
+
+void CachedResourceRequest::setAcceptHeaderIfNone(CachedResource::Type type)
+{
+ if (!m_resourceRequest.hasHTTPHeader(HTTPHeaderName::Accept))
+ m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::Accept, acceptHeaderValueFromType(type));
+}
+
+void CachedResourceRequest::updateAccordingCacheMode()
+{
+ if (m_options.cache == FetchOptions::Cache::Default
+ && (m_resourceRequest.hasHTTPHeaderField(HTTPHeaderName::IfModifiedSince)
+ || m_resourceRequest.hasHTTPHeaderField(HTTPHeaderName::IfNoneMatch)
+ || m_resourceRequest.hasHTTPHeaderField(HTTPHeaderName::IfUnmodifiedSince)
+ || m_resourceRequest.hasHTTPHeaderField(HTTPHeaderName::IfMatch)
+ || m_resourceRequest.hasHTTPHeaderField(HTTPHeaderName::IfRange)))
+ m_options.cache = FetchOptions::Cache::NoStore;
+
+ switch (m_options.cache) {
+ case FetchOptions::Cache::NoCache:
+ m_resourceRequest.setCachePolicy(RefreshAnyCacheData);
+ m_resourceRequest.addHTTPHeaderFieldIfNotPresent(HTTPHeaderName::CacheControl, HTTPHeaderValues::maxAge0());
+ break;
+ case FetchOptions::Cache::NoStore:
+ m_options.cachingPolicy = CachingPolicy::DisallowCaching;
+ m_resourceRequest.setCachePolicy(DoNotUseAnyCache);
+ m_resourceRequest.addHTTPHeaderFieldIfNotPresent(HTTPHeaderName::Pragma, HTTPHeaderValues::noCache());
+ m_resourceRequest.addHTTPHeaderFieldIfNotPresent(HTTPHeaderName::CacheControl, HTTPHeaderValues::noCache());
+ break;
+ case FetchOptions::Cache::Reload:
+ m_resourceRequest.setCachePolicy(ReloadIgnoringCacheData);
+ m_resourceRequest.addHTTPHeaderFieldIfNotPresent(HTTPHeaderName::Pragma, HTTPHeaderValues::noCache());
+ m_resourceRequest.addHTTPHeaderFieldIfNotPresent(HTTPHeaderName::CacheControl, HTTPHeaderValues::noCache());
+ break;
+ case FetchOptions::Cache::Default:
+ break;
+ case FetchOptions::Cache::ForceCache:
+ m_resourceRequest.setCachePolicy(ReturnCacheDataElseLoad);
+ break;
+ case FetchOptions::Cache::OnlyIfCached:
+ m_resourceRequest.setCachePolicy(ReturnCacheDataDontLoad);
+ break;
+ }
+}
+
+void CachedResourceRequest::removeFragmentIdentifierIfNeeded()
+{
+ URL url = MemoryCache::removeFragmentIdentifierIfNeeded(m_resourceRequest.url());
+ if (url.string() != m_resourceRequest.url())
+ m_resourceRequest.setURL(url);
+}
+
+#if ENABLE(CONTENT_EXTENSIONS)
+
+void CachedResourceRequest::applyBlockedStatus(const ContentExtensions::BlockedStatus& blockedStatus)
+{
+ ContentExtensions::applyBlockedStatusToRequest(blockedStatus, m_resourceRequest);
+}
+
+#endif
+
+void CachedResourceRequest::updateReferrerOriginAndUserAgentHeaders(FrameLoader& frameLoader, ReferrerPolicy defaultPolicy)
+{
+ // Implementing step 7 to 9 of https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
+
+ String outgoingOrigin;
+ String outgoingReferrer = m_resourceRequest.httpReferrer();
+ if (!outgoingReferrer.isNull())
+ outgoingOrigin = SecurityOrigin::createFromString(outgoingReferrer)->toString();
+ else {
+ outgoingReferrer = frameLoader.outgoingReferrer();
+ outgoingOrigin = frameLoader.outgoingOrigin();
+ }
+
+ // FIXME: Refactor SecurityPolicy::generateReferrerHeader to align with new terminology used in https://w3c.github.io/webappsec-referrer-policy.
+ switch (m_options.referrerPolicy) {
+ case FetchOptions::ReferrerPolicy::EmptyString: {
+ outgoingReferrer = SecurityPolicy::generateReferrerHeader(defaultPolicy, m_resourceRequest.url(), outgoingReferrer);
+ break; }
+ case FetchOptions::ReferrerPolicy::NoReferrerWhenDowngrade:
+ outgoingReferrer = SecurityPolicy::generateReferrerHeader(ReferrerPolicy::Default, m_resourceRequest.url(), outgoingReferrer);
+ break;
+ case FetchOptions::ReferrerPolicy::NoReferrer:
+ outgoingReferrer = String();
+ break;
+ case FetchOptions::ReferrerPolicy::Origin:
+ outgoingReferrer = SecurityPolicy::generateReferrerHeader(ReferrerPolicy::Origin, m_resourceRequest.url(), outgoingReferrer);
+ break;
+ case FetchOptions::ReferrerPolicy::OriginWhenCrossOrigin:
+ if (isRequestCrossOrigin(m_origin.get(), m_resourceRequest.url(), m_options))
+ outgoingReferrer = SecurityPolicy::generateReferrerHeader(ReferrerPolicy::Origin, m_resourceRequest.url(), outgoingReferrer);
+ break;
+ case FetchOptions::ReferrerPolicy::UnsafeUrl:
+ break;
+ };
+
+ if (outgoingReferrer.isEmpty())
+ m_resourceRequest.clearHTTPReferrer();
+ else
+ m_resourceRequest.setHTTPReferrer(outgoingReferrer);
+ FrameLoader::addHTTPOriginIfNeeded(m_resourceRequest, outgoingOrigin);
+
+ frameLoader.applyUserAgent(m_resourceRequest);
+}
+
+bool isRequestCrossOrigin(SecurityOrigin* origin, const URL& requestURL, const ResourceLoaderOptions& options)
+{
+ if (!origin)
+ return false;
+
+ // Using same origin mode guarantees the loader will not do a cross-origin load, so we let it take care of it and just return false.
+ if (options.mode == FetchOptions::Mode::SameOrigin)
+ return false;
+
+ // FIXME: We should remove options.sameOriginDataURLFlag once https://github.com/whatwg/fetch/issues/393 is fixed.
+ if (requestURL.protocolIsData() && options.sameOriginDataURLFlag == SameOriginDataURLFlag::Set)
+ return false;
+
+ return !origin->canRequest(requestURL);
+}
+
} // namespace WebCore