diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/loader/cache/CachedResourceRequest.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/loader/cache/CachedResourceRequest.cpp')
-rw-r--r-- | Source/WebCore/loader/cache/CachedResourceRequest.cpp | 247 |
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 |