oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 1 | /* |
bbudge@chromium.org | a596392 | 2012-03-27 07:38:47 +0000 | [diff] [blame] | 2 | * Copyright (C) 2011, 2012 Google Inc. All rights reserved. |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 3 | * |
| 4 | * Redistribution and use in source and binary forms, with or without |
| 5 | * modification, are permitted provided that the following conditions are |
| 6 | * met: |
| 7 | * |
| 8 | * * Redistributions of source code must retain the above copyright |
| 9 | * notice, this list of conditions and the following disclaimer. |
| 10 | * * Redistributions in binary form must reproduce the above |
| 11 | * copyright notice, this list of conditions and the following disclaimer |
| 12 | * in the documentation and/or other materials provided with the |
| 13 | * distribution. |
| 14 | * * Neither the name of Google Inc. nor the names of its |
| 15 | * contributors may be used to endorse or promote products derived from |
| 16 | * this software without specific prior written permission. |
| 17 | * |
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 | */ |
| 30 | |
| 31 | #include "config.h" |
| 32 | #include "DocumentThreadableLoader.h" |
| 33 | |
japhet@chromium.org | 43f85fe | 2011-10-25 19:50:25 +0000 | [diff] [blame] | 34 | #include "CachedRawResource.h" |
| 35 | #include "CachedResourceLoader.h" |
commit-queue@webkit.org | 5e7ea1b | 2012-10-22 23:35:28 +0000 | [diff] [blame] | 36 | #include "CachedResourceRequest.h" |
cdumez@apple.com | 9ba621d | 2015-03-13 17:58:50 +0000 | [diff] [blame] | 37 | #include "CachedResourceRequestInitiators.h" |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 38 | #include "CrossOriginAccessControl.h" |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 39 | #include "CrossOriginPreflightChecker.h" |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 40 | #include "CrossOriginPreflightResultCache.h" |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 41 | #include "DOMWindow.h" |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 42 | #include "Document.h" |
levin@chromium.org | 682c11a | 2009-02-25 18:06:20 +0000 | [diff] [blame] | 43 | #include "Frame.h" |
| 44 | #include "FrameLoader.h" |
vsevik@chromium.org | eb15eaa | 2012-09-14 11:24:01 +0000 | [diff] [blame] | 45 | #include "InspectorInstrumentation.h" |
achristensen@apple.com | d40fd88 | 2019-10-04 19:30:08 +0000 | [diff] [blame] | 46 | #include "LegacySchemeRegistry.h" |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 47 | #include "LoadTiming.h" |
youenn@apple.com | b9709cc | 2018-04-16 21:50:26 +0000 | [diff] [blame] | 48 | #include "LoaderStrategy.h" |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 49 | #include "Performance.h" |
commit-queue@webkit.org | 1d99293 | 2018-09-11 17:14:07 +0000 | [diff] [blame] | 50 | #include "PlatformStrategies.h" |
ossy@webkit.org | d77a314 | 2015-01-21 08:45:11 +0000 | [diff] [blame] | 51 | #include "ProgressTracker.h" |
japhet@chromium.org | 43f85fe | 2011-10-25 19:50:25 +0000 | [diff] [blame] | 52 | #include "ResourceError.h" |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 53 | #include "ResourceRequest.h" |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 54 | #include "ResourceTiming.h" |
achristensen@apple.com | 84fc952 | 2018-08-01 03:57:07 +0000 | [diff] [blame] | 55 | #include "RuntimeApplicationChecks.h" |
yoav@yoav.ws | 4ea6dc8 | 2016-05-02 08:21:50 +0000 | [diff] [blame] | 56 | #include "RuntimeEnabledFeatures.h" |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 57 | #include "SecurityOrigin.h" |
cdumez@apple.com | fc8fdf3 | 2019-12-06 21:05:12 +0000 | [diff] [blame] | 58 | #include "Settings.h" |
annulen@yandex.ru | dd15e81 | 2017-06-23 16:11:24 +0000 | [diff] [blame] | 59 | #include "SharedBuffer.h" |
weinig@apple.com | b50adaa | 2017-05-09 22:53:13 +0000 | [diff] [blame] | 60 | #include "SubresourceIntegrity.h" |
vsevik@chromium.org | c5c37b9 | 2012-09-14 10:41:35 +0000 | [diff] [blame] | 61 | #include "SubresourceLoader.h" |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 62 | #include "ThreadableLoaderClient.h" |
japhet@chromium.org | 43f85fe | 2011-10-25 19:50:25 +0000 | [diff] [blame] | 63 | #include <wtf/Assertions.h> |
akling@apple.com | f851598 | 2013-09-02 18:50:01 +0000 | [diff] [blame] | 64 | #include <wtf/Ref.h> |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 65 | |
ap@apple.com | 1e847592 | 2018-10-18 21:38:50 +0000 | [diff] [blame] | 66 | #if PLATFORM(IOS_FAMILY) |
achristensen@apple.com | 84fc952 | 2018-08-01 03:57:07 +0000 | [diff] [blame] | 67 | #include <wtf/spi/darwin/dyldSPI.h> |
| 68 | #endif |
| 69 | |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 70 | namespace WebCore { |
| 71 | |
commit-queue@webkit.org | 9b57957 | 2016-08-01 07:02:35 +0000 | [diff] [blame] | 72 | void DocumentThreadableLoader::loadResourceSynchronously(Document& document, ResourceRequest&& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options, RefPtr<SecurityOrigin>&& origin, std::unique_ptr<ContentSecurityPolicy>&& contentSecurityPolicy) |
levin@chromium.org | 682c11a | 2009-02-25 18:06:20 +0000 | [diff] [blame] | 73 | { |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 74 | // The loader will be deleted as soon as this function exits. |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 75 | Ref<DocumentThreadableLoader> loader = adoptRef(*new DocumentThreadableLoader(document, client, LoadSynchronously, WTFMove(request), options, WTFMove(origin), WTFMove(contentSecurityPolicy), String(), ShouldLogError::Yes)); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 76 | ASSERT(loader->hasOneRef()); |
levin@chromium.org | 682c11a | 2009-02-25 18:06:20 +0000 | [diff] [blame] | 77 | } |
| 78 | |
commit-queue@webkit.org | 9b57957 | 2016-08-01 07:02:35 +0000 | [diff] [blame] | 79 | void DocumentThreadableLoader::loadResourceSynchronously(Document& document, ResourceRequest&& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options) |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 80 | { |
commit-queue@webkit.org | 9b57957 | 2016-08-01 07:02:35 +0000 | [diff] [blame] | 81 | loadResourceSynchronously(document, WTFMove(request), client, options, nullptr, nullptr); |
dbates@webkit.org | 25ec4da | 2016-02-09 01:26:56 +0000 | [diff] [blame] | 82 | } |
| 83 | |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 84 | RefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document& document, ThreadableLoaderClient& client, |
| 85 | ResourceRequest&& request, const ThreadableLoaderOptions& options, RefPtr<SecurityOrigin>&& origin, |
| 86 | std::unique_ptr<ContentSecurityPolicy>&& contentSecurityPolicy, String&& referrer, ShouldLogError shouldLogError) |
dbates@webkit.org | 25ec4da | 2016-02-09 01:26:56 +0000 | [diff] [blame] | 87 | { |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 88 | RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, client, LoadAsynchronously, WTFMove(request), options, WTFMove(origin), WTFMove(contentSecurityPolicy), WTFMove(referrer), shouldLogError)); |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 89 | if (!loader->isLoading()) |
cdumez@apple.com | d839ea1 | 2015-07-04 19:42:18 +0000 | [diff] [blame] | 90 | loader = nullptr; |
youenn.fablet@crf.canon.fr | 02d1055 | 2016-03-04 08:27:36 +0000 | [diff] [blame] | 91 | return loader; |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 92 | } |
| 93 | |
commit-queue@webkit.org | 1526523 | 2016-09-16 07:33:44 +0000 | [diff] [blame] | 94 | RefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document& document, ThreadableLoaderClient& client, ResourceRequest&& request, const ThreadableLoaderOptions& options, String&& referrer) |
dbates@webkit.org | 25ec4da | 2016-02-09 01:26:56 +0000 | [diff] [blame] | 95 | { |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 96 | return create(document, client, WTFMove(request), options, nullptr, nullptr, WTFMove(referrer), ShouldLogError::Yes); |
dbates@webkit.org | 25ec4da | 2016-02-09 01:26:56 +0000 | [diff] [blame] | 97 | } |
| 98 | |
dbates@webkit.org | 2d7873d | 2018-05-11 05:34:20 +0000 | [diff] [blame] | 99 | static inline bool shouldPerformSecurityChecks() |
youenn@apple.com | c37e622 | 2018-04-27 18:10:18 +0000 | [diff] [blame] | 100 | { |
dbates@webkit.org | 2d7873d | 2018-05-11 05:34:20 +0000 | [diff] [blame] | 101 | return platformStrategies()->loaderStrategy()->shouldPerformSecurityChecks(); |
youenn@apple.com | c37e622 | 2018-04-27 18:10:18 +0000 | [diff] [blame] | 102 | } |
| 103 | |
| 104 | bool DocumentThreadableLoader::shouldSetHTTPHeadersToKeep() const |
| 105 | { |
dbates@webkit.org | 2d7873d | 2018-05-11 05:34:20 +0000 | [diff] [blame] | 106 | if (m_options.mode == FetchOptions::Mode::Cors && shouldPerformSecurityChecks()) |
youenn@apple.com | c37e622 | 2018-04-27 18:10:18 +0000 | [diff] [blame] | 107 | return true; |
| 108 | |
| 109 | #if ENABLE(SERVICE_WORKER) |
| 110 | if (m_options.serviceWorkersMode == ServiceWorkersMode::All && m_async) |
| 111 | return m_options.serviceWorkerRegistrationIdentifier || m_document.activeServiceWorker(); |
| 112 | #endif |
| 113 | |
| 114 | return false; |
| 115 | } |
| 116 | |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 117 | DocumentThreadableLoader::DocumentThreadableLoader(Document& document, ThreadableLoaderClient& client, BlockingBehavior blockingBehavior, ResourceRequest&& request, const ThreadableLoaderOptions& options, RefPtr<SecurityOrigin>&& origin, std::unique_ptr<ContentSecurityPolicy>&& contentSecurityPolicy, String&& referrer, ShouldLogError shouldLogError) |
akling@apple.com | 4cd57b5 | 2014-02-07 12:02:15 +0000 | [diff] [blame] | 118 | : m_client(&client) |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 119 | , m_document(document) |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 120 | , m_options(options) |
commit-queue@webkit.org | 996973b | 2016-06-29 06:25:59 +0000 | [diff] [blame] | 121 | , m_origin(WTFMove(origin)) |
commit-queue@webkit.org | f89b11d | 2016-08-02 07:20:23 +0000 | [diff] [blame] | 122 | , m_referrer(WTFMove(referrer)) |
ryanhaddad@apple.com | 439d09f | 2017-10-26 17:45:19 +0000 | [diff] [blame] | 123 | , m_sameOriginRequest(securityOrigin().canRequest(request.url())) |
bbudge@chromium.org | a596392 | 2012-03-27 07:38:47 +0000 | [diff] [blame] | 124 | , m_simpleRequest(true) |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 125 | , m_async(blockingBehavior == LoadAsynchronously) |
weinig@apple.com | b50adaa | 2017-05-09 22:53:13 +0000 | [diff] [blame] | 126 | , m_delayCallbacksForIntegrityCheck(!m_options.integrity.isEmpty()) |
dbates@webkit.org | 25ec4da | 2016-02-09 01:26:56 +0000 | [diff] [blame] | 127 | , m_contentSecurityPolicy(WTFMove(contentSecurityPolicy)) |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 128 | , m_shouldLogError(shouldLogError) |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 129 | { |
beidson@apple.com | a7ce3be | 2017-02-15 00:20:37 +0000 | [diff] [blame] | 130 | relaxAdoptionRequirement(); |
| 131 | |
commit-queue@webkit.org | 1526523 | 2016-09-16 07:33:44 +0000 | [diff] [blame] | 132 | // Setting a referrer header is only supported in the async code path. |
| 133 | ASSERT(m_async || m_referrer.isEmpty()); |
| 134 | |
cdumez@apple.com | fc8fdf3 | 2019-12-06 21:05:12 +0000 | [diff] [blame] | 135 | if (document.settings().disallowSyncXHRDuringPageDismissalEnabled() && !m_async && (!document.page() || !document.page()->areSynchronousLoadsAllowed())) { |
cdumez@apple.com | 3ed7764 | 2020-01-15 23:55:04 +0000 | [diff] [blame] | 136 | document.didRejectSyncXHRDuringPageDismissal(); |
cdumez@apple.com | fc8fdf3 | 2019-12-06 21:05:12 +0000 | [diff] [blame] | 137 | logErrorAndFail(ResourceError(errorDomainWebKitInternal, 0, request.url(), "Synchronous loads are not allowed at this time")); |
| 138 | return; |
| 139 | } |
| 140 | |
commit-queue@webkit.org | 1526523 | 2016-09-16 07:33:44 +0000 | [diff] [blame] | 141 | // Referrer and Origin headers should be set after the preflight if any. |
| 142 | ASSERT(!request.hasHTTPReferrer() && !request.hasHTTPOrigin()); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 143 | |
commit-queue@webkit.org | 03af195 | 2016-09-22 08:28:37 +0000 | [diff] [blame] | 144 | ASSERT_WITH_SECURITY_IMPLICATION(isAllowedByContentSecurityPolicy(request.url(), ContentSecurityPolicy::RedirectResponseReceived::No)); |
dbates@webkit.org | 25ec4da | 2016-02-09 01:26:56 +0000 | [diff] [blame] | 145 | |
cdumez@apple.com | 22964df | 2017-09-25 21:17:43 +0000 | [diff] [blame] | 146 | m_options.storedCredentialsPolicy = (m_options.credentials == FetchOptions::Credentials::Include || (m_options.credentials == FetchOptions::Credentials::SameOrigin && m_sameOriginRequest)) ? StoredCredentialsPolicy::Use : StoredCredentialsPolicy::DoNotUse; |
commit-queue@webkit.org | bfb64e2 | 2016-07-29 14:12:03 +0000 | [diff] [blame] | 147 | |
commit-queue@webkit.org | 1a5288b | 2016-08-21 13:36:48 +0000 | [diff] [blame] | 148 | ASSERT(!request.httpHeaderFields().contains(HTTPHeaderName::Origin)); |
| 149 | |
| 150 | // Copy headers if we need to replay the request after a redirection. |
youenn@apple.com | c37e622 | 2018-04-27 18:10:18 +0000 | [diff] [blame] | 151 | if (m_options.mode == FetchOptions::Mode::Cors) |
commit-queue@webkit.org | 1a5288b | 2016-08-21 13:36:48 +0000 | [diff] [blame] | 152 | m_originalHeaders = request.httpHeaderFields(); |
| 153 | |
youenn@apple.com | c37e622 | 2018-04-27 18:10:18 +0000 | [diff] [blame] | 154 | if (shouldSetHTTPHeadersToKeep()) |
commit-queue@webkit.org | 88b80fc | 2017-12-19 18:37:44 +0000 | [diff] [blame] | 155 | m_options.httpHeadersToKeep = httpHeadersToKeepFromCleaning(request.httpHeaderFields()); |
commit-queue@webkit.org | 88b80fc | 2017-12-19 18:37:44 +0000 | [diff] [blame] | 156 | |
achristensen@apple.com | 2170fa4 | 2020-01-02 21:14:02 +0000 | [diff] [blame] | 157 | bool shouldDisableCORS = document.isRunningUserScripts() && LegacySchemeRegistry::isUserExtensionScheme(request.url().protocol().toStringWithoutCopying()); |
| 158 | if (auto* page = document.page()) |
| 159 | shouldDisableCORS |= page->shouldDisableCorsForRequestTo(request.url()); |
| 160 | |
| 161 | if (shouldDisableCORS) { |
commit-queue@webkit.org | 5bd2ba6 | 2017-02-07 00:25:00 +0000 | [diff] [blame] | 162 | m_options.mode = FetchOptions::Mode::NoCors; |
| 163 | m_options.filteringPolicy = ResponseFilteringPolicy::Disable; |
| 164 | } |
| 165 | |
youenn@apple.com | c37e622 | 2018-04-27 18:10:18 +0000 | [diff] [blame] | 166 | m_options.cspResponseHeaders = m_options.contentSecurityPolicyEnforcement != ContentSecurityPolicyEnforcement::DoNotEnforce ? this->contentSecurityPolicy().responseHeaders() : ContentSecurityPolicyResponseHeaders { }; |
youenn@apple.com | 14b2bc6 | 2018-04-24 03:22:53 +0000 | [diff] [blame] | 167 | |
commit-queue@webkit.org | 416274f | 2016-08-29 08:06:28 +0000 | [diff] [blame] | 168 | // As per step 11 of https://fetch.spec.whatwg.org/#main-fetch, data scheme (if same-origin data-URL flag is set) and about scheme are considered same-origin. |
| 169 | if (request.url().protocolIsData()) |
| 170 | m_sameOriginRequest = options.sameOriginDataURLFlag == SameOriginDataURLFlag::Set; |
| 171 | |
commit-queue@webkit.org | 53c2e48 | 2017-12-12 20:43:32 +0000 | [diff] [blame] | 172 | if (m_sameOriginRequest || m_options.mode == FetchOptions::Mode::NoCors || m_options.mode == FetchOptions::Mode::Navigate) { |
simon.fraser@apple.com | 90e9625 | 2018-07-09 23:54:18 +0000 | [diff] [blame] | 173 | loadRequest(WTFMove(request), SecurityCheckPolicy::DoSecurityCheck); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 174 | return; |
| 175 | } |
| 176 | |
commit-queue@webkit.org | 449ca6b | 2016-07-21 06:12:13 +0000 | [diff] [blame] | 177 | if (m_options.mode == FetchOptions::Mode::SameOrigin) { |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 178 | logErrorAndFail(ResourceError(errorDomainWebKitInternal, 0, request.url(), "Cross origin requests are not allowed when using same-origin fetch mode.")); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 179 | return; |
| 180 | } |
bbudge@chromium.org | a596392 | 2012-03-27 07:38:47 +0000 | [diff] [blame] | 181 | |
commit-queue@webkit.org | 9b57957 | 2016-08-01 07:02:35 +0000 | [diff] [blame] | 182 | makeCrossOriginAccessRequest(WTFMove(request)); |
bbudge@chromium.org | 79360d9 | 2012-04-03 08:45:26 +0000 | [diff] [blame] | 183 | } |
| 184 | |
youenn@apple.com | c37e622 | 2018-04-27 18:10:18 +0000 | [diff] [blame] | 185 | bool DocumentThreadableLoader::checkURLSchemeAsCORSEnabled(const URL& url) |
| 186 | { |
| 187 | // Cross-origin requests are only allowed for HTTP and registered schemes. We would catch this when checking response headers later, but there is no reason to send a request that's guaranteed to be denied. |
achristensen@apple.com | d40fd88 | 2019-10-04 19:30:08 +0000 | [diff] [blame] | 188 | if (!LegacySchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(url.protocol().toStringWithoutCopying())) { |
youenn@apple.com | c37e622 | 2018-04-27 18:10:18 +0000 | [diff] [blame] | 189 | logErrorAndFail(ResourceError(errorDomainWebKitInternal, 0, url, "Cross origin requests are only supported for HTTP.", ResourceError::Type::AccessControl)); |
| 190 | return false; |
| 191 | } |
| 192 | return true; |
| 193 | } |
| 194 | |
commit-queue@webkit.org | 9b57957 | 2016-08-01 07:02:35 +0000 | [diff] [blame] | 195 | void DocumentThreadableLoader::makeCrossOriginAccessRequest(ResourceRequest&& request) |
bbudge@chromium.org | 79360d9 | 2012-04-03 08:45:26 +0000 | [diff] [blame] | 196 | { |
commit-queue@webkit.org | 449ca6b | 2016-07-21 06:12:13 +0000 | [diff] [blame] | 197 | ASSERT(m_options.mode == FetchOptions::Mode::Cors); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 198 | |
ap@apple.com | 1e847592 | 2018-10-18 21:38:50 +0000 | [diff] [blame] | 199 | #if PLATFORM(IOS_FAMILY) |
achristensen@apple.com | 84fc952 | 2018-08-01 03:57:07 +0000 | [diff] [blame] | 200 | bool needsPreflightQuirk = IOSApplication::isMoviStarPlus() && applicationSDKVersion() < DYLD_IOS_VERSION_12_0 && (m_options.preflightPolicy == PreflightPolicy::Consider || m_options.preflightPolicy == PreflightPolicy::Force); |
| 201 | #else |
| 202 | bool needsPreflightQuirk = false; |
| 203 | #endif |
| 204 | |
| 205 | if ((m_options.preflightPolicy == PreflightPolicy::Consider && isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields())) || m_options.preflightPolicy == PreflightPolicy::Prevent || (shouldPerformSecurityChecks() && !needsPreflightQuirk)) { |
youenn@apple.com | c37e622 | 2018-04-27 18:10:18 +0000 | [diff] [blame] | 206 | if (checkURLSchemeAsCORSEnabled(request.url())) |
| 207 | makeSimpleCrossOriginAccessRequest(WTFMove(request)); |
| 208 | } else { |
commit-queue@webkit.org | 8a6ce4a | 2017-11-03 23:09:28 +0000 | [diff] [blame] | 209 | #if ENABLE(SERVICE_WORKER) |
| 210 | if (m_options.serviceWorkersMode == ServiceWorkersMode::All && m_async) { |
commit-queue@webkit.org | 3e86933 | 2018-01-12 19:43:35 +0000 | [diff] [blame] | 211 | if (m_options.serviceWorkerRegistrationIdentifier || document().activeServiceWorker()) { |
commit-queue@webkit.org | 8a6ce4a | 2017-11-03 23:09:28 +0000 | [diff] [blame] | 212 | ASSERT(!m_bypassingPreflightForServiceWorkerRequest); |
| 213 | m_bypassingPreflightForServiceWorkerRequest = WTFMove(request); |
| 214 | m_options.serviceWorkersMode = ServiceWorkersMode::Only; |
simon.fraser@apple.com | 90e9625 | 2018-07-09 23:54:18 +0000 | [diff] [blame] | 215 | loadRequest(ResourceRequest { m_bypassingPreflightForServiceWorkerRequest.value() }, SecurityCheckPolicy::SkipSecurityCheck); |
commit-queue@webkit.org | 8a6ce4a | 2017-11-03 23:09:28 +0000 | [diff] [blame] | 216 | return; |
| 217 | } |
| 218 | } |
| 219 | #endif |
achristensen@apple.com | 84fc952 | 2018-08-01 03:57:07 +0000 | [diff] [blame] | 220 | if (!needsPreflightQuirk && !checkURLSchemeAsCORSEnabled(request.url())) |
youenn@apple.com | c37e622 | 2018-04-27 18:10:18 +0000 | [diff] [blame] | 221 | return; |
| 222 | |
bbudge@chromium.org | a596392 | 2012-03-27 07:38:47 +0000 | [diff] [blame] | 223 | m_simpleRequest = false; |
cdumez@apple.com | 22964df | 2017-09-25 21:17:43 +0000 | [diff] [blame] | 224 | if (CrossOriginPreflightResultCache::singleton().canSkipPreflight(securityOrigin().toString(), request.url(), m_options.storedCredentialsPolicy, request.httpMethod(), request.httpHeaderFields())) |
commit-queue@webkit.org | 9b57957 | 2016-08-01 07:02:35 +0000 | [diff] [blame] | 225 | preflightSuccess(WTFMove(request)); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 226 | else |
commit-queue@webkit.org | 9b57957 | 2016-08-01 07:02:35 +0000 | [diff] [blame] | 227 | makeCrossOriginAccessRequestWithPreflight(WTFMove(request)); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 228 | } |
| 229 | } |
| 230 | |
commit-queue@webkit.org | 9b57957 | 2016-08-01 07:02:35 +0000 | [diff] [blame] | 231 | void DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest(ResourceRequest&& request) |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 232 | { |
dbates@webkit.org | 2d7873d | 2018-05-11 05:34:20 +0000 | [diff] [blame] | 233 | ASSERT(m_options.preflightPolicy != PreflightPolicy::Force || shouldPerformSecurityChecks()); |
| 234 | ASSERT(m_options.preflightPolicy == PreflightPolicy::Prevent || isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields()) || shouldPerformSecurityChecks()); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 235 | |
cdumez@apple.com | 22964df | 2017-09-25 21:17:43 +0000 | [diff] [blame] | 236 | updateRequestForAccessControl(request, securityOrigin(), m_options.storedCredentialsPolicy); |
simon.fraser@apple.com | 90e9625 | 2018-07-09 23:54:18 +0000 | [diff] [blame] | 237 | loadRequest(WTFMove(request), SecurityCheckPolicy::DoSecurityCheck); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 238 | } |
| 239 | |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 240 | void DocumentThreadableLoader::makeCrossOriginAccessRequestWithPreflight(ResourceRequest&& request) |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 241 | { |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 242 | if (m_async) { |
utatane.tea@gmail.com | 4392696 | 2016-11-27 06:08:16 +0000 | [diff] [blame] | 243 | m_preflightChecker.emplace(*this, WTFMove(request)); |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 244 | m_preflightChecker->startPreflight(); |
| 245 | return; |
| 246 | } |
| 247 | CrossOriginPreflightChecker::doPreflight(*this, WTFMove(request)); |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 248 | } |
| 249 | |
| 250 | DocumentThreadableLoader::~DocumentThreadableLoader() |
| 251 | { |
japhet@chromium.org | 43f85fe | 2011-10-25 19:50:25 +0000 | [diff] [blame] | 252 | if (m_resource) |
commit-queue@webkit.org | 0396ac0 | 2016-10-06 16:53:58 +0000 | [diff] [blame] | 253 | m_resource->removeClient(*this); |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 254 | } |
| 255 | |
| 256 | void DocumentThreadableLoader::cancel() |
| 257 | { |
beidson@apple.com | 7bd3d3b | 2016-05-13 23:42:17 +0000 | [diff] [blame] | 258 | Ref<DocumentThreadableLoader> protectedThis(*this); |
japhet@chromium.org | e7a4ca7 | 2012-07-03 21:37:28 +0000 | [diff] [blame] | 259 | |
| 260 | // Cancel can re-enter and m_resource might be null here as a result. |
japhet@chromium.org | a1c9632 | 2012-06-20 18:42:51 +0000 | [diff] [blame] | 261 | if (m_client && m_resource) { |
ap@apple.com | 5828b84 | 2013-02-15 00:27:57 +0000 | [diff] [blame] | 262 | // FIXME: This error is sent to the client in didFail(), so it should not be an internal one. Use FrameLoaderClient::cancelledError() instead. |
youenn.fablet@crf.canon.fr | 156f9bb | 2016-06-09 06:55:26 +0000 | [diff] [blame] | 263 | ResourceError error(errorDomainWebKitInternal, 0, m_resource->url(), "Load cancelled", ResourceError::Type::Cancellation); |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 264 | m_client->didFail(error); |
japhet@chromium.org | 43f85fe | 2011-10-25 19:50:25 +0000 | [diff] [blame] | 265 | } |
| 266 | clearResource(); |
hs85.jeong@samsung.com | 1317914 | 2015-10-21 02:12:32 +0000 | [diff] [blame] | 267 | m_client = nullptr; |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 268 | } |
| 269 | |
commit-queue@webkit.org | 7c4021c | 2011-02-17 04:11:38 +0000 | [diff] [blame] | 270 | void DocumentThreadableLoader::setDefersLoading(bool value) |
| 271 | { |
japhet@chromium.org | 43f85fe | 2011-10-25 19:50:25 +0000 | [diff] [blame] | 272 | if (m_resource) |
| 273 | m_resource->setDefersLoading(value); |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 274 | if (m_preflightChecker) |
| 275 | m_preflightChecker->setDefersLoading(value); |
commit-queue@webkit.org | 7c4021c | 2011-02-17 04:11:38 +0000 | [diff] [blame] | 276 | } |
| 277 | |
japhet@chromium.org | 43f85fe | 2011-10-25 19:50:25 +0000 | [diff] [blame] | 278 | void DocumentThreadableLoader::clearResource() |
| 279 | { |
japhet@chromium.org | a1c9632 | 2012-06-20 18:42:51 +0000 | [diff] [blame] | 280 | // Script can cancel and restart a request reentrantly within removeClient(), |
| 281 | // which could lead to calling CachedResource::removeClient() multiple times for |
| 282 | // this DocumentThreadableLoader. Save off a copy of m_resource and clear it to |
| 283 | // prevent the reentrancy. |
| 284 | if (CachedResourceHandle<CachedRawResource> resource = m_resource) { |
hs85.jeong@samsung.com | 1317914 | 2015-10-21 02:12:32 +0000 | [diff] [blame] | 285 | m_resource = nullptr; |
commit-queue@webkit.org | 0396ac0 | 2016-10-06 16:53:58 +0000 | [diff] [blame] | 286 | resource->removeClient(*this); |
japhet@chromium.org | 43f85fe | 2011-10-25 19:50:25 +0000 | [diff] [blame] | 287 | } |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 288 | if (m_preflightChecker) |
cdumez@apple.com | 8b7a022 | 2018-12-20 04:41:11 +0000 | [diff] [blame] | 289 | m_preflightChecker = WTF::nullopt; |
japhet@chromium.org | 43f85fe | 2011-10-25 19:50:25 +0000 | [diff] [blame] | 290 | } |
| 291 | |
achristensen@apple.com | 858fb9c | 2017-11-10 19:23:13 +0000 | [diff] [blame] | 292 | void DocumentThreadableLoader::redirectReceived(CachedResource& resource, ResourceRequest&& request, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& completionHandler) |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 293 | { |
| 294 | ASSERT(m_client); |
commit-queue@webkit.org | 4c0caf3 | 2016-10-07 07:02:02 +0000 | [diff] [blame] | 295 | ASSERT_UNUSED(resource, &resource == m_resource); |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 296 | |
beidson@apple.com | 7bd3d3b | 2016-05-13 23:42:17 +0000 | [diff] [blame] | 297 | Ref<DocumentThreadableLoader> protectedThis(*this); |
commit-queue@webkit.org | 0958d33 | 2017-05-26 17:08:30 +0000 | [diff] [blame] | 298 | --m_options.maxRedirectCount; |
commit-queue@webkit.org | e2e5fd4 | 2016-10-06 10:00:28 +0000 | [diff] [blame] | 299 | |
| 300 | // FIXME: We restrict this check to Fetch API for the moment, as this might disrupt WorkerScriptLoader. |
| 301 | // Reassess this check based on https://github.com/whatwg/fetch/issues/393 discussions. |
| 302 | // We should also disable that check in navigation mode. |
| 303 | if (!request.url().protocolIsInHTTPFamily() && m_options.initiator == cachedResourceRequestInitiators().fetch) { |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 304 | reportRedirectionWithBadScheme(request.url()); |
commit-queue@webkit.org | e2e5fd4 | 2016-10-06 10:00:28 +0000 | [diff] [blame] | 305 | clearResource(); |
achristensen@apple.com | 858fb9c | 2017-11-10 19:23:13 +0000 | [diff] [blame] | 306 | return completionHandler(WTFMove(request)); |
commit-queue@webkit.org | e2e5fd4 | 2016-10-06 10:00:28 +0000 | [diff] [blame] | 307 | } |
| 308 | |
dbates@webkit.org | ae77ef4 | 2018-05-21 23:15:11 +0000 | [diff] [blame] | 309 | if (platformStrategies()->loaderStrategy()->havePerformedSecurityChecks(redirectResponse)) { |
| 310 | completionHandler(WTFMove(request)); |
| 311 | return; |
| 312 | } |
| 313 | |
commit-queue@webkit.org | 03af195 | 2016-09-22 08:28:37 +0000 | [diff] [blame] | 314 | if (!isAllowedByContentSecurityPolicy(request.url(), redirectResponse.isNull() ? ContentSecurityPolicy::RedirectResponseReceived::No : ContentSecurityPolicy::RedirectResponseReceived::Yes)) { |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 315 | reportContentSecurityPolicyError(redirectResponse.url()); |
commit-queue@webkit.org | 72abba7 | 2016-09-06 16:03:39 +0000 | [diff] [blame] | 316 | clearResource(); |
achristensen@apple.com | 858fb9c | 2017-11-10 19:23:13 +0000 | [diff] [blame] | 317 | return completionHandler(WTFMove(request)); |
dbates@webkit.org | 25ec4da | 2016-02-09 01:26:56 +0000 | [diff] [blame] | 318 | } |
| 319 | |
bbudge@chromium.org | 79360d9 | 2012-04-03 08:45:26 +0000 | [diff] [blame] | 320 | // Allow same origin requests to continue after allowing clients to audit the redirect. |
ryuan.choi@samsung.com | ea0c4465 | 2014-05-28 11:43:11 +0000 | [diff] [blame] | 321 | if (isAllowedRedirect(request.url())) |
achristensen@apple.com | 858fb9c | 2017-11-10 19:23:13 +0000 | [diff] [blame] | 322 | return completionHandler(WTFMove(request)); |
bbudge@chromium.org | 79360d9 | 2012-04-03 08:45:26 +0000 | [diff] [blame] | 323 | |
commit-queue@webkit.org | 9df46b9 | 2016-08-04 07:56:37 +0000 | [diff] [blame] | 324 | // Force any subsequent request to use these checks. |
| 325 | m_sameOriginRequest = false; |
bbudge@chromium.org | a596392 | 2012-03-27 07:38:47 +0000 | [diff] [blame] | 326 | |
commit-queue@webkit.org | 9df46b9 | 2016-08-04 07:56:37 +0000 | [diff] [blame] | 327 | ASSERT(m_resource); |
commit-queue@webkit.org | a23e289 | 2016-08-23 10:18:38 +0000 | [diff] [blame] | 328 | ASSERT(m_originalHeaders); |
bbudge@chromium.org | 79360d9 | 2012-04-03 08:45:26 +0000 | [diff] [blame] | 329 | |
cdumez@apple.com | fc98476 | 2017-05-25 20:53:49 +0000 | [diff] [blame] | 330 | // Use a unique for subsequent loads if needed. |
| 331 | // https://fetch.spec.whatwg.org/#concept-http-redirect-fetch (Step 10). |
| 332 | ASSERT(m_options.mode == FetchOptions::Mode::Cors); |
commit-queue@webkit.org | 0958d33 | 2017-05-26 17:08:30 +0000 | [diff] [blame] | 333 | if (!securityOrigin().canRequest(redirectResponse.url()) && !protocolHostAndPortAreEqual(redirectResponse.url(), request.url())) |
cdumez@apple.com | fc98476 | 2017-05-25 20:53:49 +0000 | [diff] [blame] | 334 | m_origin = SecurityOrigin::createUnique(); |
commit-queue@webkit.org | 9df46b9 | 2016-08-04 07:56:37 +0000 | [diff] [blame] | 335 | |
| 336 | // Except in case where preflight is needed, loading should be able to continue on its own. |
| 337 | // But we also handle credentials here if it is restricted to SameOrigin. |
commit-queue@webkit.org | a23e289 | 2016-08-23 10:18:38 +0000 | [diff] [blame] | 338 | if (m_options.credentials != FetchOptions::Credentials::SameOrigin && m_simpleRequest && isSimpleCrossOriginAccessRequest(request.httpMethod(), *m_originalHeaders)) |
achristensen@apple.com | 858fb9c | 2017-11-10 19:23:13 +0000 | [diff] [blame] | 339 | return completionHandler(WTFMove(request)); |
commit-queue@webkit.org | 9df46b9 | 2016-08-04 07:56:37 +0000 | [diff] [blame] | 340 | |
youenn@apple.com | 42c49b2 | 2018-03-23 18:06:34 +0000 | [diff] [blame] | 341 | if (m_options.credentials == FetchOptions::Credentials::SameOrigin) |
| 342 | m_options.storedCredentialsPolicy = StoredCredentialsPolicy::DoNotUse; |
commit-queue@webkit.org | 9df46b9 | 2016-08-04 07:56:37 +0000 | [diff] [blame] | 343 | |
| 344 | clearResource(); |
| 345 | |
youenn@apple.com | 727d867 | 2018-07-11 02:50:58 +0000 | [diff] [blame] | 346 | m_referrer = request.httpReferrer(); |
| 347 | if (m_referrer.isNull()) |
| 348 | m_options.referrerPolicy = ReferrerPolicy::NoReferrer; |
| 349 | |
commit-queue@webkit.org | 1a5288b | 2016-08-21 13:36:48 +0000 | [diff] [blame] | 350 | // Let's fetch the request with the original headers (equivalent to request cloning specified by fetch algorithm). |
| 351 | // Do not copy the Authorization header if removed by the network layer. |
| 352 | if (!request.httpHeaderFields().contains(HTTPHeaderName::Authorization)) |
| 353 | m_originalHeaders->remove(HTTPHeaderName::Authorization); |
| 354 | request.setHTTPHeaderFields(*m_originalHeaders); |
| 355 | |
commit-queue@webkit.org | d1a81bd | 2018-01-25 21:27:32 +0000 | [diff] [blame] | 356 | #if ENABLE(SERVICE_WORKER) |
| 357 | if (redirectResponse.source() != ResourceResponse::Source::ServiceWorker && redirectResponse.source() != ResourceResponse::Source::MemoryCache) |
| 358 | m_options.serviceWorkersMode = ServiceWorkersMode::None; |
| 359 | #endif |
commit-queue@webkit.org | 9df46b9 | 2016-08-04 07:56:37 +0000 | [diff] [blame] | 360 | makeCrossOriginAccessRequest(ResourceRequest(request)); |
achristensen@apple.com | 858fb9c | 2017-11-10 19:23:13 +0000 | [diff] [blame] | 361 | completionHandler(WTFMove(request)); |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 362 | } |
| 363 | |
commit-queue@webkit.org | 4c0caf3 | 2016-10-07 07:02:02 +0000 | [diff] [blame] | 364 | void DocumentThreadableLoader::dataSent(CachedResource& resource, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 365 | { |
| 366 | ASSERT(m_client); |
commit-queue@webkit.org | 4c0caf3 | 2016-10-07 07:02:02 +0000 | [diff] [blame] | 367 | ASSERT_UNUSED(resource, &resource == m_resource); |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 368 | m_client->didSendData(bytesSent, totalBytesToBeSent); |
| 369 | } |
| 370 | |
cdumez@apple.com | 20771b9 | 2018-03-16 18:33:48 +0000 | [diff] [blame] | 371 | void DocumentThreadableLoader::responseReceived(CachedResource& resource, const ResourceResponse& response, CompletionHandler<void()>&& completionHandler) |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 372 | { |
commit-queue@webkit.org | 4c0caf3 | 2016-10-07 07:02:02 +0000 | [diff] [blame] | 373 | ASSERT_UNUSED(resource, &resource == m_resource); |
commit-queue@webkit.org | d1c8b43 | 2017-08-05 22:11:28 +0000 | [diff] [blame] | 374 | didReceiveResponse(m_resource->identifier(), response); |
cdumez@apple.com | 20771b9 | 2018-03-16 18:33:48 +0000 | [diff] [blame] | 375 | |
| 376 | if (completionHandler) |
| 377 | completionHandler(); |
pfeldman@chromium.org | c2baad0 | 2011-06-16 16:53:03 +0000 | [diff] [blame] | 378 | } |
| 379 | |
commit-queue@webkit.org | d1c8b43 | 2017-08-05 22:11:28 +0000 | [diff] [blame] | 380 | void DocumentThreadableLoader::didReceiveResponse(unsigned long identifier, const ResourceResponse& response) |
pfeldman@chromium.org | c2baad0 | 2011-06-16 16:53:03 +0000 | [diff] [blame] | 381 | { |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 382 | ASSERT(m_client); |
commit-queue@webkit.org | 619ae67 | 2017-01-09 18:26:58 +0000 | [diff] [blame] | 383 | ASSERT(response.type() != ResourceResponse::Type::Error); |
ap@webkit.org | d43a9928 | 2009-04-14 08:11:42 +0000 | [diff] [blame] | 384 | |
joepeck@webkit.org | 5e45a19 | 2016-12-09 22:12:08 +0000 | [diff] [blame] | 385 | InspectorInstrumentation::didReceiveThreadableLoaderResponse(*this, identifier); |
| 386 | |
weinig@apple.com | b50adaa | 2017-05-09 22:53:13 +0000 | [diff] [blame] | 387 | if (m_delayCallbacksForIntegrityCheck) |
| 388 | return; |
| 389 | |
commit-queue@webkit.org | 619ae67 | 2017-01-09 18:26:58 +0000 | [diff] [blame] | 390 | if (options().filteringPolicy == ResponseFilteringPolicy::Disable) { |
| 391 | m_client->didReceiveResponse(identifier, response); |
| 392 | return; |
| 393 | } |
| 394 | |
commit-queue@webkit.org | 7965ee7 | 2016-08-27 20:47:35 +0000 | [diff] [blame] | 395 | if (response.type() == ResourceResponse::Type::Default) { |
commit-queue@webkit.org | d1c8b43 | 2017-08-05 22:11:28 +0000 | [diff] [blame] | 396 | m_client->didReceiveResponse(identifier, ResourceResponseBase::filter(response)); |
| 397 | if (response.tainting() == ResourceResponse::Tainting::Opaque) { |
commit-queue@webkit.org | 7965ee7 | 2016-08-27 20:47:35 +0000 | [diff] [blame] | 398 | clearResource(); |
| 399 | if (m_client) |
joepeck@webkit.org | ff39b7b | 2017-02-25 05:48:51 +0000 | [diff] [blame] | 400 | m_client->didFinishLoading(identifier); |
commit-queue@webkit.org | 7965ee7 | 2016-08-27 20:47:35 +0000 | [diff] [blame] | 401 | } |
commit-queue@webkit.org | 5101c2b | 2017-11-14 23:25:28 +0000 | [diff] [blame] | 402 | return; |
commit-queue@webkit.org | 5322350 | 2016-07-28 08:30:14 +0000 | [diff] [blame] | 403 | } |
commit-queue@webkit.org | 8dcc61f | 2018-01-24 18:08:02 +0000 | [diff] [blame] | 404 | ASSERT(response.type() == ResourceResponse::Type::Opaqueredirect || response.source() == ResourceResponse::Source::ServiceWorker || response.source() == ResourceResponse::Source::MemoryCache); |
commit-queue@webkit.org | 5101c2b | 2017-11-14 23:25:28 +0000 | [diff] [blame] | 405 | m_client->didReceiveResponse(identifier, response); |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 406 | } |
| 407 | |
commit-queue@webkit.org | 4c0caf3 | 2016-10-07 07:02:02 +0000 | [diff] [blame] | 408 | void DocumentThreadableLoader::dataReceived(CachedResource& resource, const char* data, int dataLength) |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 409 | { |
commit-queue@webkit.org | 4c0caf3 | 2016-10-07 07:02:02 +0000 | [diff] [blame] | 410 | ASSERT_UNUSED(resource, &resource == m_resource); |
ap@apple.com | 5828b84 | 2013-02-15 00:27:57 +0000 | [diff] [blame] | 411 | didReceiveData(m_resource->identifier(), data, dataLength); |
| 412 | } |
ap@webkit.org | d43a9928 | 2009-04-14 08:11:42 +0000 | [diff] [blame] | 413 | |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 414 | void DocumentThreadableLoader::didReceiveData(unsigned long, const char* data, int dataLength) |
ap@apple.com | 5828b84 | 2013-02-15 00:27:57 +0000 | [diff] [blame] | 415 | { |
| 416 | ASSERT(m_client); |
vsevik@chromium.org | 84ef309 | 2011-07-03 15:58:38 +0000 | [diff] [blame] | 417 | |
weinig@apple.com | b50adaa | 2017-05-09 22:53:13 +0000 | [diff] [blame] | 418 | if (m_delayCallbacksForIntegrityCheck) |
| 419 | return; |
| 420 | |
commit-queue@webkit.org | 9f62359 | 2011-04-19 16:56:17 +0000 | [diff] [blame] | 421 | m_client->didReceiveData(data, dataLength); |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 422 | } |
| 423 | |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 424 | void DocumentThreadableLoader::finishedTimingForWorkerLoad(CachedResource& resource, const ResourceTiming& resourceTiming) |
| 425 | { |
| 426 | ASSERT(m_client); |
| 427 | ASSERT_UNUSED(resource, &resource == m_resource); |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 428 | |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 429 | finishedTimingForWorkerLoad(resourceTiming); |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 430 | } |
| 431 | |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 432 | void DocumentThreadableLoader::finishedTimingForWorkerLoad(const ResourceTiming& resourceTiming) |
| 433 | { |
| 434 | ASSERT(m_options.initiatorContext == InitiatorContext::Worker); |
| 435 | |
| 436 | m_client->didFinishTiming(resourceTiming); |
| 437 | } |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 438 | |
commit-queue@webkit.org | 4c0caf3 | 2016-10-07 07:02:02 +0000 | [diff] [blame] | 439 | void DocumentThreadableLoader::notifyFinished(CachedResource& resource) |
commit-queue@webkit.org | 7c4021c | 2011-02-17 04:11:38 +0000 | [diff] [blame] | 440 | { |
| 441 | ASSERT(m_client); |
commit-queue@webkit.org | 4c0caf3 | 2016-10-07 07:02:02 +0000 | [diff] [blame] | 442 | ASSERT_UNUSED(resource, &resource == m_resource); |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 443 | |
ap@apple.com | 5828b84 | 2013-02-15 00:27:57 +0000 | [diff] [blame] | 444 | if (m_resource->errorOccurred()) |
| 445 | didFail(m_resource->identifier(), m_resource->resourceError()); |
japhet@chromium.org | a636421 | 2012-11-01 06:20:00 +0000 | [diff] [blame] | 446 | else |
joepeck@webkit.org | ff39b7b | 2017-02-25 05:48:51 +0000 | [diff] [blame] | 447 | didFinishLoading(m_resource->identifier()); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 448 | } |
| 449 | |
joepeck@webkit.org | ff39b7b | 2017-02-25 05:48:51 +0000 | [diff] [blame] | 450 | void DocumentThreadableLoader::didFinishLoading(unsigned long identifier) |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 451 | { |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 452 | ASSERT(m_client); |
weinig@apple.com | b50adaa | 2017-05-09 22:53:13 +0000 | [diff] [blame] | 453 | |
| 454 | if (m_delayCallbacksForIntegrityCheck) { |
| 455 | if (!matchIntegrityMetadata(*m_resource, m_options.integrity)) { |
commit-queue@webkit.org | fd264c2 | 2019-10-25 05:05:54 +0000 | [diff] [blame] | 456 | reportIntegrityMetadataError(*m_resource, m_options.integrity); |
weinig@apple.com | b50adaa | 2017-05-09 22:53:13 +0000 | [diff] [blame] | 457 | return; |
| 458 | } |
| 459 | |
| 460 | auto response = m_resource->response(); |
| 461 | |
| 462 | if (options().filteringPolicy == ResponseFilteringPolicy::Disable) { |
| 463 | m_client->didReceiveResponse(identifier, response); |
commit-queue@webkit.org | 95b4cad | 2018-08-07 23:26:48 +0000 | [diff] [blame] | 464 | if (m_resource->resourceBuffer()) |
| 465 | m_client->didReceiveData(m_resource->resourceBuffer()->data(), m_resource->resourceBuffer()->size()); |
weinig@apple.com | b50adaa | 2017-05-09 22:53:13 +0000 | [diff] [blame] | 466 | } else { |
| 467 | ASSERT(response.type() == ResourceResponse::Type::Default); |
commit-queue@webkit.org | d1c8b43 | 2017-08-05 22:11:28 +0000 | [diff] [blame] | 468 | |
| 469 | m_client->didReceiveResponse(identifier, ResourceResponseBase::filter(response)); |
commit-queue@webkit.org | 95b4cad | 2018-08-07 23:26:48 +0000 | [diff] [blame] | 470 | if (m_resource->resourceBuffer()) |
| 471 | m_client->didReceiveData(m_resource->resourceBuffer()->data(), m_resource->resourceBuffer()->size()); |
weinig@apple.com | b50adaa | 2017-05-09 22:53:13 +0000 | [diff] [blame] | 472 | } |
| 473 | } |
| 474 | |
joepeck@webkit.org | ff39b7b | 2017-02-25 05:48:51 +0000 | [diff] [blame] | 475 | m_client->didFinishLoading(identifier); |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 476 | } |
| 477 | |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 478 | void DocumentThreadableLoader::didFail(unsigned long, const ResourceError& error) |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 479 | { |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 480 | ASSERT(m_client); |
commit-queue@webkit.org | 8a6ce4a | 2017-11-03 23:09:28 +0000 | [diff] [blame] | 481 | #if ENABLE(SERVICE_WORKER) |
commit-queue@webkit.org | d070d6d | 2017-12-08 22:45:21 +0000 | [diff] [blame] | 482 | if (m_bypassingPreflightForServiceWorkerRequest && error.isCancellation()) { |
commit-queue@webkit.org | 6974fbf | 2017-12-06 20:51:59 +0000 | [diff] [blame] | 483 | clearResource(); |
| 484 | |
commit-queue@webkit.org | 8a6ce4a | 2017-11-03 23:09:28 +0000 | [diff] [blame] | 485 | m_options.serviceWorkersMode = ServiceWorkersMode::None; |
commit-queue@webkit.org | 6974fbf | 2017-12-06 20:51:59 +0000 | [diff] [blame] | 486 | makeCrossOriginAccessRequestWithPreflight(WTFMove(m_bypassingPreflightForServiceWorkerRequest.value())); |
commit-queue@webkit.org | ee14415 | 2017-12-07 23:30:33 +0000 | [diff] [blame] | 487 | ASSERT(m_bypassingPreflightForServiceWorkerRequest->isNull()); |
cdumez@apple.com | 8b7a022 | 2018-12-20 04:41:11 +0000 | [diff] [blame] | 488 | m_bypassingPreflightForServiceWorkerRequest = WTF::nullopt; |
commit-queue@webkit.org | 8a6ce4a | 2017-11-03 23:09:28 +0000 | [diff] [blame] | 489 | return; |
| 490 | } |
| 491 | #endif |
youenn@apple.com | c37e622 | 2018-04-27 18:10:18 +0000 | [diff] [blame] | 492 | |
youenn@apple.com | 36b74c3 | 2018-04-25 17:57:56 +0000 | [diff] [blame] | 493 | if (m_shouldLogError == ShouldLogError::Yes) |
| 494 | logError(m_document, error, m_options.initiator); |
| 495 | |
| 496 | m_client->didFail(error); |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 497 | } |
| 498 | |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 499 | void DocumentThreadableLoader::preflightSuccess(ResourceRequest&& request) |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 500 | { |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 501 | ResourceRequest actualRequest(WTFMove(request)); |
cdumez@apple.com | 22964df | 2017-09-25 21:17:43 +0000 | [diff] [blame] | 502 | updateRequestForAccessControl(actualRequest, securityOrigin(), m_options.storedCredentialsPolicy); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 503 | |
cdumez@apple.com | 8b7a022 | 2018-12-20 04:41:11 +0000 | [diff] [blame] | 504 | m_preflightChecker = WTF::nullopt; |
japhet@chromium.org | 43f85fe | 2011-10-25 19:50:25 +0000 | [diff] [blame] | 505 | |
japhet@chromium.org | a330a3e | 2009-12-15 23:02:11 +0000 | [diff] [blame] | 506 | // It should be ok to skip the security check since we already asked about the preflight request. |
simon.fraser@apple.com | 90e9625 | 2018-07-09 23:54:18 +0000 | [diff] [blame] | 507 | loadRequest(WTFMove(actualRequest), SecurityCheckPolicy::SkipSecurityCheck); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 508 | } |
| 509 | |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 510 | void DocumentThreadableLoader::preflightFailure(unsigned long identifier, const ResourceError& error) |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 511 | { |
cdumez@apple.com | 8b7a022 | 2018-12-20 04:41:11 +0000 | [diff] [blame] | 512 | m_preflightChecker = WTF::nullopt; |
burg@cs.washington.edu | dbacfc1 | 2015-01-05 21:30:33 +0000 | [diff] [blame] | 513 | |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 514 | InspectorInstrumentation::didFailLoading(m_document.frame(), m_document.frame()->loader().documentLoader(), identifier, error); |
youenn@apple.com | 36b74c3 | 2018-04-25 17:57:56 +0000 | [diff] [blame] | 515 | |
| 516 | if (m_shouldLogError == ShouldLogError::Yes) |
| 517 | logError(m_document, error, m_options.initiator); |
| 518 | |
| 519 | m_client->didFail(error); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 520 | } |
| 521 | |
commit-queue@webkit.org | 9b57957 | 2016-08-01 07:02:35 +0000 | [diff] [blame] | 522 | void DocumentThreadableLoader::loadRequest(ResourceRequest&& request, SecurityCheckPolicy securityCheck) |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 523 | { |
beidson@apple.com | 2b846a4 | 2017-02-14 23:26:38 +0000 | [diff] [blame] | 524 | Ref<DocumentThreadableLoader> protectedThis(*this); |
| 525 | |
jchaffraix@webkit.org | 5ace159 | 2010-04-28 16:29:22 +0000 | [diff] [blame] | 526 | // Any credential should have been removed from the cross-site requests. |
darin@apple.com | 5ffbb5c | 2013-09-27 16:39:41 +0000 | [diff] [blame] | 527 | const URL& requestURL = request.url(); |
commit-queue@webkit.org | 877e149 | 2016-08-02 06:46:57 +0000 | [diff] [blame] | 528 | m_options.securityCheck = securityCheck; |
jchaffraix@webkit.org | 5ace159 | 2010-04-28 16:29:22 +0000 | [diff] [blame] | 529 | ASSERT(m_sameOriginRequest || requestURL.user().isEmpty()); |
| 530 | ASSERT(m_sameOriginRequest || requestURL.pass().isEmpty()); |
| 531 | |
commit-queue@webkit.org | f89b11d | 2016-08-02 07:20:23 +0000 | [diff] [blame] | 532 | if (!m_referrer.isNull()) |
| 533 | request.setHTTPReferrer(m_referrer); |
| 534 | |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 535 | if (m_async) { |
commit-queue@webkit.org | 7bf7536 | 2016-09-21 08:43:23 +0000 | [diff] [blame] | 536 | ResourceLoaderOptions options = m_options; |
commit-queue@webkit.org | ba1c71b | 2016-07-26 16:23:09 +0000 | [diff] [blame] | 537 | options.clientCredentialPolicy = m_sameOriginRequest ? ClientCredentialPolicy::MayAskClientForCredentials : ClientCredentialPolicy::CannotAskClientForCredentials; |
commit-queue@webkit.org | 7bf7536 | 2016-09-21 08:43:23 +0000 | [diff] [blame] | 538 | options.contentSecurityPolicyImposition = ContentSecurityPolicyImposition::SkipPolicyCheck; |
weinig@apple.com | b50adaa | 2017-05-09 22:53:13 +0000 | [diff] [blame] | 539 | |
| 540 | // If there is integrity metadata to validate, we must buffer. |
| 541 | if (!m_options.integrity.isEmpty()) |
simon.fraser@apple.com | 90e9625 | 2018-07-09 23:54:18 +0000 | [diff] [blame] | 542 | options.dataBufferingPolicy = DataBufferingPolicy::BufferData; |
levin@chromium.org | 1e06d8b | 2009-08-26 03:02:16 +0000 | [diff] [blame] | 543 | |
cdumez@apple.com | 22964df | 2017-09-25 21:17:43 +0000 | [diff] [blame] | 544 | request.setAllowCookies(m_options.storedCredentialsPolicy == StoredCredentialsPolicy::Use); |
commit-queue@webkit.org | 9b57957 | 2016-08-01 07:02:35 +0000 | [diff] [blame] | 545 | CachedResourceRequest newRequest(WTFMove(request), options); |
yoav@yoav.ws | 4ea6dc8 | 2016-05-02 08:21:50 +0000 | [diff] [blame] | 546 | if (RuntimeEnabledFeatures::sharedFeatures().resourceTimingEnabled()) |
| 547 | newRequest.setInitiator(m_options.initiator); |
akling@apple.com | 6be0e97 | 2017-01-18 19:35:49 +0000 | [diff] [blame] | 548 | newRequest.setOrigin(securityOrigin()); |
commit-queue@webkit.org | bfb64e2 | 2016-07-29 14:12:03 +0000 | [diff] [blame] | 549 | |
japhet@chromium.org | 43f85fe | 2011-10-25 19:50:25 +0000 | [diff] [blame] | 550 | ASSERT(!m_resource); |
beidson@apple.com | 2b846a4 | 2017-02-14 23:26:38 +0000 | [diff] [blame] | 551 | if (m_resource) { |
| 552 | CachedResourceHandle<CachedRawResource> resource = std::exchange(m_resource, nullptr); |
| 553 | resource->removeClient(*this); |
| 554 | } |
| 555 | |
cdumez@apple.com | d038ecf | 2017-08-15 21:15:09 +0000 | [diff] [blame] | 556 | auto cachedResource = m_document.cachedResourceLoader().requestRawResource(WTFMove(newRequest)); |
jfbastien@apple.com | bcea987 | 2017-12-04 23:34:57 +0000 | [diff] [blame] | 557 | m_resource = cachedResource.value_or(nullptr); |
yoav@yoav.ws | 1e8ae3a | 2016-05-26 05:33:58 +0000 | [diff] [blame] | 558 | if (m_resource) |
commit-queue@webkit.org | 0396ac0 | 2016-10-06 16:53:58 +0000 | [diff] [blame] | 559 | m_resource->addClient(*this); |
cdumez@apple.com | d038ecf | 2017-08-15 21:15:09 +0000 | [diff] [blame] | 560 | else |
| 561 | logErrorAndFail(cachedResource.error()); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 562 | return; |
| 563 | } |
youenn.fablet@crf.canon.fr | bba9793 | 2016-06-10 13:26:30 +0000 | [diff] [blame] | 564 | |
commit-queue@webkit.org | bfb64e2 | 2016-07-29 14:12:03 +0000 | [diff] [blame] | 565 | // If credentials mode is 'Omit', we should disable cookie sending. |
| 566 | ASSERT(m_options.credentials != FetchOptions::Credentials::Omit); |
| 567 | |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 568 | LoadTiming loadTiming; |
| 569 | loadTiming.markStartTimeAndFetchStart(); |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 570 | |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 571 | // FIXME: ThreadableLoaderOptions.sniffContent is not supported for synchronous requests. |
youenn.fablet@crf.canon.fr | 0aef67f | 2015-04-29 08:18:10 +0000 | [diff] [blame] | 572 | RefPtr<SharedBuffer> data; |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 573 | ResourceError error; |
| 574 | ResourceResponse response; |
| 575 | unsigned long identifier = std::numeric_limits<unsigned long>::max(); |
wilander@apple.com | bcbaaca | 2016-07-22 00:44:27 +0000 | [diff] [blame] | 576 | if (m_document.frame()) { |
| 577 | auto& frameLoader = m_document.frame()->loader(); |
| 578 | if (!frameLoader.mixedContentChecker().canRunInsecureContent(m_document.securityOrigin(), requestURL)) |
| 579 | return; |
youenn@apple.com | b9709cc | 2018-04-16 21:50:26 +0000 | [diff] [blame] | 580 | identifier = frameLoader.loadResourceSynchronously(request, m_options.clientCredentialPolicy, m_options, *m_originalHeaders, error, response, data); |
wilander@apple.com | bcbaaca | 2016-07-22 00:44:27 +0000 | [diff] [blame] | 581 | } |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 582 | |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 583 | loadTiming.setResponseEnd(MonotonicTime::now()); |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 584 | |
mmaxfield@apple.com | 46278cb | 2014-05-23 03:59:11 +0000 | [diff] [blame] | 585 | if (!error.isNull() && response.httpStatusCode() <= 0) { |
| 586 | if (requestURL.isLocalFile()) { |
| 587 | // We don't want XMLHttpRequest to raise an exception for file:// resources, see <rdar://problem/4962298>. |
| 588 | // FIXME: XMLHttpRequest quirks should be in XMLHttpRequest code, not in DocumentThreadableLoader.cpp. |
commit-queue@webkit.org | d1c8b43 | 2017-08-05 22:11:28 +0000 | [diff] [blame] | 589 | didReceiveResponse(identifier, response); |
joepeck@webkit.org | ff39b7b | 2017-02-25 05:48:51 +0000 | [diff] [blame] | 590 | didFinishLoading(identifier); |
mmaxfield@apple.com | 46278cb | 2014-05-23 03:59:11 +0000 | [diff] [blame] | 591 | return; |
| 592 | } |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 593 | logErrorAndFail(error); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 594 | return; |
| 595 | } |
| 596 | |
dbates@webkit.org | 2d7873d | 2018-05-11 05:34:20 +0000 | [diff] [blame] | 597 | if (!shouldPerformSecurityChecks()) { |
youenn@apple.com | b9709cc | 2018-04-16 21:50:26 +0000 | [diff] [blame] | 598 | // FIXME: FrameLoader::loadSynchronously() does not tell us whether a redirect happened or not, so we guess by comparing the |
| 599 | // request and response URLs. This isn't a perfect test though, since a server can serve a redirect to the same URL that was |
| 600 | // requested. Also comparing the request and response URLs as strings will fail if the requestURL still has its credentials. |
| 601 | bool didRedirect = requestURL != response.url(); |
| 602 | if (didRedirect) { |
| 603 | if (!isAllowedByContentSecurityPolicy(response.url(), ContentSecurityPolicy::RedirectResponseReceived::Yes)) { |
| 604 | reportContentSecurityPolicyError(requestURL); |
commit-queue@webkit.org | 0c8dff4 | 2016-09-06 11:06:52 +0000 | [diff] [blame] | 605 | return; |
| 606 | } |
youenn@apple.com | b9709cc | 2018-04-16 21:50:26 +0000 | [diff] [blame] | 607 | if (!isAllowedRedirect(response.url())) { |
| 608 | reportCrossOriginResourceSharingError(requestURL); |
| 609 | return; |
| 610 | } |
| 611 | } |
| 612 | |
| 613 | if (!m_sameOriginRequest) { |
| 614 | if (m_options.mode == FetchOptions::Mode::NoCors) |
| 615 | response.setTainting(ResourceResponse::Tainting::Opaque); |
| 616 | else { |
| 617 | ASSERT(m_options.mode == FetchOptions::Mode::Cors); |
| 618 | response.setTainting(ResourceResponse::Tainting::Cors); |
| 619 | String accessControlErrorDescription; |
| 620 | if (!passesAccessControlCheck(response, m_options.storedCredentialsPolicy, securityOrigin(), accessControlErrorDescription)) { |
| 621 | logErrorAndFail(ResourceError(errorDomainWebKitInternal, 0, response.url(), accessControlErrorDescription, ResourceError::Type::AccessControl)); |
| 622 | return; |
| 623 | } |
| 624 | } |
commit-queue@webkit.org | 0c8dff4 | 2016-09-06 11:06:52 +0000 | [diff] [blame] | 625 | } |
| 626 | } |
commit-queue@webkit.org | d1c8b43 | 2017-08-05 22:11:28 +0000 | [diff] [blame] | 627 | didReceiveResponse(identifier, response); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 628 | |
youenn.fablet@crf.canon.fr | 0aef67f | 2015-04-29 08:18:10 +0000 | [diff] [blame] | 629 | if (data) |
| 630 | didReceiveData(identifier, data->data(), data->size()); |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 631 | |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 632 | if (RuntimeEnabledFeatures::sharedFeatures().resourceTimingEnabled()) { |
commit-queue@webkit.org | d8ebc6a | 2017-05-02 01:16:26 +0000 | [diff] [blame] | 633 | auto resourceTiming = ResourceTiming::fromSynchronousLoad(requestURL, m_options.initiator, loadTiming, response.deprecatedNetworkLoadMetrics(), response, securityOrigin()); |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 634 | if (options().initiatorContext == InitiatorContext::Worker) |
| 635 | finishedTimingForWorkerLoad(resourceTiming); |
| 636 | else { |
cdumez@apple.com | 6ad592b | 2018-10-17 18:11:18 +0000 | [diff] [blame] | 637 | if (auto* window = document().domWindow()) |
| 638 | window->performance().addResourceTiming(WTFMove(resourceTiming)); |
bburg@apple.com | 2e0ba23 | 2017-07-26 18:40:50 +0000 | [diff] [blame] | 639 | } |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 640 | } |
joepeck@webkit.org | 301376e | 2017-02-16 19:18:32 +0000 | [diff] [blame] | 641 | |
joepeck@webkit.org | ff39b7b | 2017-02-25 05:48:51 +0000 | [diff] [blame] | 642 | didFinishLoading(identifier); |
eric@webkit.org | fba1b6b | 2009-08-14 19:25:37 +0000 | [diff] [blame] | 643 | } |
| 644 | |
commit-queue@webkit.org | 03af195 | 2016-09-22 08:28:37 +0000 | [diff] [blame] | 645 | bool DocumentThreadableLoader::isAllowedByContentSecurityPolicy(const URL& url, ContentSecurityPolicy::RedirectResponseReceived redirectResponseReceived) |
dbates@webkit.org | 25ec4da | 2016-02-09 01:26:56 +0000 | [diff] [blame] | 646 | { |
| 647 | switch (m_options.contentSecurityPolicyEnforcement) { |
| 648 | case ContentSecurityPolicyEnforcement::DoNotEnforce: |
| 649 | return true; |
dbates@webkit.org | 8c34a38 | 2016-02-13 00:18:40 +0000 | [diff] [blame] | 650 | case ContentSecurityPolicyEnforcement::EnforceChildSrcDirective: |
commit-queue@webkit.org | 03af195 | 2016-09-22 08:28:37 +0000 | [diff] [blame] | 651 | return contentSecurityPolicy().allowChildContextFromSource(url, redirectResponseReceived); |
dbates@webkit.org | 25ec4da | 2016-02-09 01:26:56 +0000 | [diff] [blame] | 652 | case ContentSecurityPolicyEnforcement::EnforceConnectSrcDirective: |
commit-queue@webkit.org | 03af195 | 2016-09-22 08:28:37 +0000 | [diff] [blame] | 653 | return contentSecurityPolicy().allowConnectToSource(url, redirectResponseReceived); |
dbates@webkit.org | 25ec4da | 2016-02-09 01:26:56 +0000 | [diff] [blame] | 654 | case ContentSecurityPolicyEnforcement::EnforceScriptSrcDirective: |
commit-queue@webkit.org | 03af195 | 2016-09-22 08:28:37 +0000 | [diff] [blame] | 655 | return contentSecurityPolicy().allowScriptFromSource(url, redirectResponseReceived); |
dbates@webkit.org | 25ec4da | 2016-02-09 01:26:56 +0000 | [diff] [blame] | 656 | } |
| 657 | ASSERT_NOT_REACHED(); |
| 658 | return false; |
| 659 | } |
| 660 | |
darin@apple.com | 5ffbb5c | 2013-09-27 16:39:41 +0000 | [diff] [blame] | 661 | bool DocumentThreadableLoader::isAllowedRedirect(const URL& url) |
eric@webkit.org | 9272179 | 2009-08-17 20:43:57 +0000 | [diff] [blame] | 662 | { |
commit-queue@webkit.org | 449ca6b | 2016-07-21 06:12:13 +0000 | [diff] [blame] | 663 | if (m_options.mode == FetchOptions::Mode::NoCors) |
eric@webkit.org | 9272179 | 2009-08-17 20:43:57 +0000 | [diff] [blame] | 664 | return true; |
| 665 | |
commit-queue@webkit.org | 6827a7a | 2016-06-30 06:28:58 +0000 | [diff] [blame] | 666 | return m_sameOriginRequest && securityOrigin().canRequest(url); |
mihaip@chromium.org | 7ef8e03 | 2011-05-26 19:53:00 +0000 | [diff] [blame] | 667 | } |
| 668 | |
commit-queue@webkit.org | 6827a7a | 2016-06-30 06:28:58 +0000 | [diff] [blame] | 669 | SecurityOrigin& DocumentThreadableLoader::securityOrigin() const |
mihaip@chromium.org | 7ef8e03 | 2011-05-26 19:53:00 +0000 | [diff] [blame] | 670 | { |
akling@apple.com | 6be0e97 | 2017-01-18 19:35:49 +0000 | [diff] [blame] | 671 | return m_origin ? *m_origin : m_document.securityOrigin(); |
eric@webkit.org | 9272179 | 2009-08-17 20:43:57 +0000 | [diff] [blame] | 672 | } |
| 673 | |
dbates@webkit.org | 25ec4da | 2016-02-09 01:26:56 +0000 | [diff] [blame] | 674 | const ContentSecurityPolicy& DocumentThreadableLoader::contentSecurityPolicy() const |
| 675 | { |
| 676 | if (m_contentSecurityPolicy) |
| 677 | return *m_contentSecurityPolicy.get(); |
| 678 | ASSERT(m_document.contentSecurityPolicy()); |
| 679 | return *m_document.contentSecurityPolicy(); |
| 680 | } |
| 681 | |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 682 | void DocumentThreadableLoader::reportRedirectionWithBadScheme(const URL& url) |
| 683 | { |
utatane.tea@gmail.com | 8407763 | 2018-06-23 08:39:34 +0000 | [diff] [blame] | 684 | logErrorAndFail(ResourceError(errorDomainWebKitInternal, 0, url, "Redirection to URL with a scheme that is not HTTP(S)."_s, ResourceError::Type::AccessControl)); |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 685 | } |
| 686 | |
| 687 | void DocumentThreadableLoader::reportContentSecurityPolicyError(const URL& url) |
| 688 | { |
utatane.tea@gmail.com | 8407763 | 2018-06-23 08:39:34 +0000 | [diff] [blame] | 689 | logErrorAndFail(ResourceError(errorDomainWebKitInternal, 0, url, "Blocked by Content Security Policy."_s, ResourceError::Type::AccessControl)); |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 690 | } |
| 691 | |
| 692 | void DocumentThreadableLoader::reportCrossOriginResourceSharingError(const URL& url) |
| 693 | { |
utatane.tea@gmail.com | 8407763 | 2018-06-23 08:39:34 +0000 | [diff] [blame] | 694 | logErrorAndFail(ResourceError(errorDomainWebKitInternal, 0, url, "Cross-origin redirection denied by Cross-Origin Resource Sharing policy."_s, ResourceError::Type::AccessControl)); |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 695 | } |
| 696 | |
commit-queue@webkit.org | fd264c2 | 2019-10-25 05:05:54 +0000 | [diff] [blame] | 697 | void DocumentThreadableLoader::reportIntegrityMetadataError(const CachedResource& resource, const String& expectedMetadata) |
weinig@apple.com | b50adaa | 2017-05-09 22:53:13 +0000 | [diff] [blame] | 698 | { |
commit-queue@webkit.org | fd264c2 | 2019-10-25 05:05:54 +0000 | [diff] [blame] | 699 | logErrorAndFail(ResourceError(errorDomainWebKitInternal, 0, resource.url(), makeString("Failed integrity metadata check. "_s, integrityMismatchDescription(resource, expectedMetadata)), ResourceError::Type::General)); |
weinig@apple.com | b50adaa | 2017-05-09 22:53:13 +0000 | [diff] [blame] | 700 | } |
| 701 | |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 702 | void DocumentThreadableLoader::logErrorAndFail(const ResourceError& error) |
| 703 | { |
youenn@apple.com | 36b74c3 | 2018-04-25 17:57:56 +0000 | [diff] [blame] | 704 | if (m_shouldLogError == ShouldLogError::Yes) { |
| 705 | if (error.isAccessControl() && !error.localizedDescription().isEmpty()) |
| 706 | m_document.addConsoleMessage(MessageSource::Security, MessageLevel::Error, error.localizedDescription()); |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 707 | logError(m_document, error, m_options.initiator); |
youenn@apple.com | 36b74c3 | 2018-04-25 17:57:56 +0000 | [diff] [blame] | 708 | } |
commit-queue@webkit.org | 4537669 | 2016-12-16 11:51:16 +0000 | [diff] [blame] | 709 | ASSERT(m_client); |
| 710 | m_client->didFail(error); |
| 711 | } |
| 712 | |
oliver@apple.com | ee5b1dd | 2009-01-22 00:22:45 +0000 | [diff] [blame] | 713 | } // namespace WebCore |