1 | /* |
2 | * Copyright (C) 2012, 2015, 2018 Apple Inc. All rights reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
15 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
17 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
23 | * THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #include "config.h" |
27 | #include "WebLoaderStrategy.h" |
28 | |
29 | #include "DataReference.h" |
30 | #include "HangDetectionDisabler.h" |
31 | #include "Logging.h" |
32 | #include "NetworkConnectionToWebProcessMessages.h" |
33 | #include "NetworkProcessConnection.h" |
34 | #include "NetworkResourceLoadParameters.h" |
35 | #include "SharedBufferDataReference.h" |
36 | #include "WebCompiledContentRuleList.h" |
37 | #include "WebCoreArgumentCoders.h" |
38 | #include "WebErrors.h" |
39 | #include "WebFrame.h" |
40 | #include "WebFrameLoaderClient.h" |
41 | #include "WebPage.h" |
42 | #include "WebPageProxyMessages.h" |
43 | #include "WebProcess.h" |
44 | #include "WebProcessPoolMessages.h" |
45 | #include "WebResourceLoader.h" |
46 | #include "WebServiceWorkerProvider.h" |
47 | #include "WebURLSchemeHandlerProxy.h" |
48 | #include "WebURLSchemeTaskProxy.h" |
49 | #include <WebCore/ApplicationCacheHost.h> |
50 | #include <WebCore/CachedResource.h> |
51 | #include <WebCore/ContentSecurityPolicy.h> |
52 | #include <WebCore/DiagnosticLoggingClient.h> |
53 | #include <WebCore/DiagnosticLoggingKeys.h> |
54 | #include <WebCore/Document.h> |
55 | #include <WebCore/DocumentLoader.h> |
56 | #include <WebCore/FetchOptions.h> |
57 | #include <WebCore/Frame.h> |
58 | #include <WebCore/FrameLoader.h> |
59 | #include <WebCore/NetscapePlugInStreamLoader.h> |
60 | #include <WebCore/NetworkLoadInformation.h> |
61 | #include <WebCore/PlatformStrategies.h> |
62 | #include <WebCore/ReferrerPolicy.h> |
63 | #include <WebCore/ResourceLoader.h> |
64 | #include <WebCore/RuntimeApplicationChecks.h> |
65 | #include <WebCore/RuntimeEnabledFeatures.h> |
66 | #include <WebCore/SecurityOrigin.h> |
67 | #include <WebCore/Settings.h> |
68 | #include <WebCore/SubresourceLoader.h> |
69 | #include <WebCore/UserContentProvider.h> |
70 | #include <pal/SessionID.h> |
71 | #include <wtf/CompletionHandler.h> |
72 | #include <wtf/text/CString.h> |
73 | |
74 | #if USE(QUICK_LOOK) |
75 | #include <WebCore/QuickLook.h> |
76 | #endif |
77 | |
78 | #define RELEASE_LOG_IF_ALLOWED(permissionChecker, fmt, ...) RELEASE_LOG_IF(permissionChecker.isAlwaysOnLoggingAllowed(), Network, "%p - WebLoaderStrategy::" fmt, this, ##__VA_ARGS__) |
79 | #define RELEASE_LOG_ERROR_IF_ALLOWED(permissionChecker, fmt, ...) RELEASE_LOG_ERROR_IF(permissionChecker.isAlwaysOnLoggingAllowed(), Network, "%p - WebLoaderStrategy::" fmt, this, ##__VA_ARGS__) |
80 | |
81 | namespace WebKit { |
82 | using namespace WebCore; |
83 | |
84 | WebLoaderStrategy::WebLoaderStrategy() |
85 | : m_internallyFailedLoadTimer(RunLoop::main(), this, &WebLoaderStrategy::internallyFailedLoadTimerFired) |
86 | { |
87 | } |
88 | |
89 | WebLoaderStrategy::~WebLoaderStrategy() |
90 | { |
91 | } |
92 | |
93 | void WebLoaderStrategy::loadResource(Frame& frame, CachedResource& resource, ResourceRequest&& request, const ResourceLoaderOptions& options, CompletionHandler<void(RefPtr<SubresourceLoader>&&)>&& completionHandler) |
94 | { |
95 | SubresourceLoader::create(frame, resource, WTFMove(request), options, [this, referrerPolicy = options.referrerPolicy, completionHandler = WTFMove(completionHandler), resource = CachedResourceHandle<CachedResource>(&resource), frame = makeRef(frame)] (RefPtr<SubresourceLoader>&& loader) mutable { |
96 | if (loader) |
97 | scheduleLoad(*loader, resource.get(), referrerPolicy == ReferrerPolicy::NoReferrerWhenDowngrade); |
98 | else |
99 | RELEASE_LOG_IF_ALLOWED(frame.get(), "loadResource: Unable to create SubresourceLoader (frame = %p" , &frame); |
100 | completionHandler(WTFMove(loader)); |
101 | }); |
102 | } |
103 | |
104 | void WebLoaderStrategy::schedulePluginStreamLoad(Frame& frame, NetscapePlugInStreamLoaderClient& client, ResourceRequest&& request, CompletionHandler<void(RefPtr<NetscapePlugInStreamLoader>&&)>&& completionHandler) |
105 | { |
106 | NetscapePlugInStreamLoader::create(frame, client, WTFMove(request), [this, completionHandler = WTFMove(completionHandler), frame = makeRef(frame)] (RefPtr<NetscapePlugInStreamLoader>&& loader) mutable { |
107 | if (loader) |
108 | scheduleLoad(*loader, 0, frame->document()->referrerPolicy() == ReferrerPolicy::NoReferrerWhenDowngrade); |
109 | completionHandler(WTFMove(loader)); |
110 | }); |
111 | } |
112 | |
113 | static Seconds maximumBufferingTime(CachedResource* resource) |
114 | { |
115 | if (!resource) |
116 | return 0_s; |
117 | |
118 | switch (resource->type()) { |
119 | case CachedResource::Type::Beacon: |
120 | case CachedResource::Type::Ping: |
121 | case CachedResource::Type::CSSStyleSheet: |
122 | case CachedResource::Type::Script: |
123 | #if ENABLE(SVG_FONTS) |
124 | case CachedResource::Type::SVGFontResource: |
125 | #endif |
126 | case CachedResource::Type::FontResource: |
127 | #if ENABLE(APPLICATION_MANIFEST) |
128 | case CachedResource::Type::ApplicationManifest: |
129 | #endif |
130 | return Seconds::infinity(); |
131 | case CachedResource::Type::ImageResource: |
132 | return 500_ms; |
133 | case CachedResource::Type::MediaResource: |
134 | return 50_ms; |
135 | case CachedResource::Type::MainResource: |
136 | case CachedResource::Type::Icon: |
137 | case CachedResource::Type::RawResource: |
138 | case CachedResource::Type::SVGDocumentResource: |
139 | case CachedResource::Type::LinkPrefetch: |
140 | #if ENABLE(VIDEO_TRACK) |
141 | case CachedResource::Type::TextTrackResource: |
142 | #endif |
143 | #if ENABLE(XSLT) |
144 | case CachedResource::Type::XSLStyleSheet: |
145 | #endif |
146 | return 0_s; |
147 | } |
148 | |
149 | ASSERT_NOT_REACHED(); |
150 | return 0_s; |
151 | } |
152 | |
153 | void WebLoaderStrategy::scheduleLoad(ResourceLoader& resourceLoader, CachedResource* resource, bool shouldClearReferrerOnHTTPSToHTTPRedirect) |
154 | { |
155 | ResourceLoadIdentifier identifier = resourceLoader.identifier(); |
156 | ASSERT(identifier); |
157 | |
158 | auto& frameLoaderClient = resourceLoader.frameLoader()->client(); |
159 | |
160 | WebResourceLoader::TrackingParameters trackingParameters; |
161 | trackingParameters.pageID = frameLoaderClient.pageID().valueOr(PageIdentifier { }); |
162 | trackingParameters.frameID = frameLoaderClient.frameID().valueOr(0); |
163 | trackingParameters.resourceID = identifier; |
164 | auto sessionID = frameLoaderClient.sessionID(); |
165 | |
166 | #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML) |
167 | // If the DocumentLoader schedules this as an archive resource load, |
168 | // then we should remember the ResourceLoader in our records but not schedule it in the NetworkProcess. |
169 | if (resourceLoader.documentLoader()->scheduleArchiveLoad(resourceLoader, resourceLoader.request())) { |
170 | LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be handled as an archive resource." , resourceLoader.url().string().utf8().data()); |
171 | RELEASE_LOG_IF_ALLOWED(resourceLoader, "scheduleLoad: URL will be handled as an archive resource (frame = %p, pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ")" , resourceLoader.frame(), trackingParameters.pageID.toUInt64(), trackingParameters.frameID, identifier); |
172 | m_webResourceLoaders.set(identifier, WebResourceLoader::create(resourceLoader, trackingParameters)); |
173 | return; |
174 | } |
175 | #endif |
176 | |
177 | if (resourceLoader.documentLoader()->applicationCacheHost().maybeLoadResource(resourceLoader, resourceLoader.request(), resourceLoader.request().url())) { |
178 | LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be loaded from application cache." , resourceLoader.url().string().utf8().data()); |
179 | RELEASE_LOG_IF_ALLOWED(resourceLoader, "scheduleLoad: URL will be loaded from application cache (frame = %p, pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ")" , resourceLoader.frame(), trackingParameters.pageID.toUInt64(), trackingParameters.frameID, identifier); |
180 | m_webResourceLoaders.set(identifier, WebResourceLoader::create(resourceLoader, trackingParameters)); |
181 | return; |
182 | } |
183 | |
184 | if (resourceLoader.request().url().protocolIsData()) { |
185 | LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be loaded as data." , resourceLoader.url().string().utf8().data()); |
186 | RELEASE_LOG_IF_ALLOWED(resourceLoader, "scheduleLoad: URL will be loaded as data (frame = %p, pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ")" , resourceLoader.frame(), trackingParameters.pageID.toUInt64(), trackingParameters.frameID, identifier); |
187 | startLocalLoad(resourceLoader); |
188 | return; |
189 | } |
190 | |
191 | #if USE(QUICK_LOOK) |
192 | if (isQuickLookPreviewURL(resourceLoader.request().url())) { |
193 | LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be handled as a QuickLook resource." , resourceLoader.url().string().utf8().data()); |
194 | RELEASE_LOG_IF_ALLOWED(resourceLoader, "scheduleLoad: URL will be handled as a QuickLook resource (frame = %p, pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ")" , resourceLoader.frame(), trackingParameters.pageID.toUInt64(), trackingParameters.frameID, identifier); |
195 | startLocalLoad(resourceLoader); |
196 | return; |
197 | } |
198 | #endif |
199 | |
200 | #if USE(SOUP) |
201 | // For apps that call g_resource_load in a web extension. |
202 | // https://blogs.gnome.org/alexl/2012/01/26/resources-in-glib/ |
203 | if (resourceLoader.request().url().protocolIs("resource" )) { |
204 | LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be handled as a GResource." , resourceLoader.url().string().utf8().data()); |
205 | RELEASE_LOG_IF_ALLOWED(resourceLoader, "scheduleLoad: URL will be handled as a GResource (frame = %p, pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ")" , resourceLoader.frame(), trackingParameters.pageID.toUInt64(), trackingParameters.frameID, identifier); |
206 | startLocalLoad(resourceLoader); |
207 | return; |
208 | } |
209 | #endif |
210 | |
211 | #if ENABLE(SERVICE_WORKER) |
212 | WebServiceWorkerProvider::singleton().handleFetch(resourceLoader, sessionID, shouldClearReferrerOnHTTPSToHTTPRedirect, [this, trackingParameters, identifier, sessionID, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime = maximumBufferingTime(resource), resourceLoader = makeRef(resourceLoader)] (ServiceWorkerClientFetch::Result result) mutable { |
213 | if (result != ServiceWorkerClientFetch::Result::Unhandled) { |
214 | LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be scheduled through ServiceWorker handle fetch algorithm" , resourceLoader->url().string().latin1().data()); |
215 | RELEASE_LOG_IF_ALLOWED(resourceLoader.get(), "scheduleLoad: URL will be scheduled through ServiceWorker handle fetch algorithm (frame = %p, pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ")" , resourceLoader->frame(), trackingParameters.pageID.toUInt64(), trackingParameters.frameID, identifier); |
216 | return; |
217 | } |
218 | if (resourceLoader->options().serviceWorkersMode == ServiceWorkersMode::Only) { |
219 | RELEASE_LOG_ERROR_IF_ALLOWED(resourceLoader.get(), "scheduleLoad: unable to schedule URL through ServiceWorker handle fetch algorithm (frame = %p, pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ")" , resourceLoader->frame(), trackingParameters.pageID.toUInt64(), trackingParameters.frameID, identifier); |
220 | callOnMainThread([resourceLoader = WTFMove(resourceLoader)] { |
221 | auto error = internalError(resourceLoader->request().url()); |
222 | error.setType(ResourceError::Type::Cancellation); |
223 | resourceLoader->didFail(error); |
224 | }); |
225 | return; |
226 | } |
227 | |
228 | if (!WebProcess::singleton().webLoaderStrategy().tryLoadingUsingURLSchemeHandler(resourceLoader)) |
229 | WebProcess::singleton().webLoaderStrategy().scheduleLoadFromNetworkProcess(resourceLoader.get(), resourceLoader->request(), trackingParameters, sessionID, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime); |
230 | else |
231 | RELEASE_LOG_IF_ALLOWED(resourceLoader.get(), "scheduleLoad: URL not handled by any handlers (frame = %p, pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ")" , resourceLoader->frame(), trackingParameters.pageID.toUInt64(), trackingParameters.frameID, identifier); |
232 | }); |
233 | #else |
234 | if (!tryLoadingUsingURLSchemeHandler(resourceLoader)) |
235 | scheduleLoadFromNetworkProcess(resourceLoader, resourceLoader.request(), trackingParameters, sessionID, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime(resource)); |
236 | else |
237 | RELEASE_LOG_IF_ALLOWED(resourceLoader, "scheduleLoad: URL not handled by any handlers (frame = %p, pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ")" , resourceLoader.frame(), trackingParameters.pageID.toUInt64(), trackingParameters.frameID, identifier); |
238 | #endif |
239 | } |
240 | |
241 | bool WebLoaderStrategy::tryLoadingUsingURLSchemeHandler(ResourceLoader& resourceLoader) |
242 | { |
243 | auto* webFrameLoaderClient = toWebFrameLoaderClient(resourceLoader.frameLoader()->client()); |
244 | auto* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : nullptr; |
245 | auto* webPage = webFrame ? webFrame->page() : nullptr; |
246 | if (webPage) { |
247 | if (auto* handler = webPage->urlSchemeHandlerForScheme(resourceLoader.request().url().protocol().toStringWithoutCopying())) { |
248 | LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, URL '%s' will be handled by a UIProcess URL scheme handler." , resourceLoader.url().string().utf8().data()); |
249 | RELEASE_LOG_IF_ALLOWED(resourceLoader, "scheduleLoad: URL will be handled by a UIProcess URL scheme handler (frame = %p, resourceID = %lu)" , resourceLoader.frame(), resourceLoader.identifier()); |
250 | |
251 | handler->startNewTask(resourceLoader); |
252 | return true; |
253 | } |
254 | } |
255 | return false; |
256 | } |
257 | |
258 | void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceLoader, const ResourceRequest& request, const WebResourceLoader::TrackingParameters& trackingParameters, PAL::SessionID sessionID, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime) |
259 | { |
260 | ResourceLoadIdentifier identifier = resourceLoader.identifier(); |
261 | ASSERT(identifier); |
262 | |
263 | LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be scheduled with the NetworkProcess with priority %d" , resourceLoader.url().string().latin1().data(), static_cast<int>(resourceLoader.request().priority())); |
264 | |
265 | ContentSniffingPolicy contentSniffingPolicy = resourceLoader.shouldSniffContent() ? ContentSniffingPolicy::SniffContent : ContentSniffingPolicy::DoNotSniffContent; |
266 | ContentEncodingSniffingPolicy contentEncodingSniffingPolicy = resourceLoader.shouldSniffContentEncoding() ? ContentEncodingSniffingPolicy::Sniff : ContentEncodingSniffingPolicy::DoNotSniff; |
267 | StoredCredentialsPolicy storedCredentialsPolicy = resourceLoader.shouldUseCredentialStorage() ? StoredCredentialsPolicy::Use : StoredCredentialsPolicy::DoNotUse; |
268 | |
269 | NetworkResourceLoadParameters loadParameters; |
270 | loadParameters.identifier = identifier; |
271 | loadParameters.webPageID = trackingParameters.pageID; |
272 | loadParameters.webFrameID = trackingParameters.frameID; |
273 | loadParameters.parentPID = presentingApplicationPID(); |
274 | loadParameters.sessionID = sessionID; |
275 | loadParameters.request = request; |
276 | loadParameters.contentSniffingPolicy = contentSniffingPolicy; |
277 | loadParameters.contentEncodingSniffingPolicy = contentEncodingSniffingPolicy; |
278 | loadParameters.storedCredentialsPolicy = storedCredentialsPolicy; |
279 | // If there is no WebFrame then this resource cannot be authenticated with the client. |
280 | loadParameters.clientCredentialPolicy = (loadParameters.webFrameID && loadParameters.webPageID && resourceLoader.isAllowedToAskUserForCredentials()) ? ClientCredentialPolicy::MayAskClientForCredentials : ClientCredentialPolicy::CannotAskClientForCredentials; |
281 | loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = shouldClearReferrerOnHTTPSToHTTPRedirect; |
282 | loadParameters.needsCertificateInfo = resourceLoader.shouldIncludeCertificateInfo(); |
283 | loadParameters.maximumBufferingTime = maximumBufferingTime; |
284 | loadParameters.options = resourceLoader.options(); |
285 | loadParameters.preflightPolicy = resourceLoader.options().preflightPolicy; |
286 | loadParameters.isHTTPSUpgradeEnabled = resourceLoader.frame() ? resourceLoader.frame()->settings().HTTPSUpgradeEnabled() : false; |
287 | |
288 | auto* document = resourceLoader.frame() ? resourceLoader.frame()->document() : nullptr; |
289 | if (resourceLoader.options().cspResponseHeaders) |
290 | loadParameters.cspResponseHeaders = resourceLoader.options().cspResponseHeaders; |
291 | else if (document && !document->shouldBypassMainWorldContentSecurityPolicy() && resourceLoader.options().contentSecurityPolicyImposition == ContentSecurityPolicyImposition::DoPolicyCheck) { |
292 | if (auto* contentSecurityPolicy = document->contentSecurityPolicy()) |
293 | loadParameters.cspResponseHeaders = contentSecurityPolicy->responseHeaders(); |
294 | } |
295 | |
296 | #if ENABLE(CONTENT_EXTENSIONS) |
297 | if (document) { |
298 | loadParameters.mainDocumentURL = document->topDocument().url(); |
299 | // FIXME: Instead of passing userContentControllerIdentifier, the NetworkProcess should be able to get it using webPageId. |
300 | auto* webFrameLoaderClient = toWebFrameLoaderClient(resourceLoader.frame()->loader().client()); |
301 | auto* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : nullptr; |
302 | auto* webPage = webFrame ? webFrame->page() : nullptr; |
303 | if (webPage) |
304 | loadParameters.userContentControllerIdentifier = webPage->userContentControllerIdentifier(); |
305 | } |
306 | #endif |
307 | |
308 | // FIXME: All loaders should provide their origin if navigation mode is cors/no-cors/same-origin. |
309 | // As a temporary approach, we use the document origin if available or the HTTP Origin header otherwise. |
310 | if (is<SubresourceLoader>(resourceLoader)) { |
311 | auto& loader = downcast<SubresourceLoader>(resourceLoader); |
312 | loadParameters.sourceOrigin = loader.origin(); |
313 | |
314 | if (auto* = loader.originalHeaders()) |
315 | loadParameters.originalRequestHeaders = *headers; |
316 | } |
317 | |
318 | if (!loadParameters.sourceOrigin && document) |
319 | loadParameters.sourceOrigin = &document->securityOrigin(); |
320 | if (!loadParameters.sourceOrigin) { |
321 | auto origin = request.httpOrigin(); |
322 | if (!origin.isNull()) |
323 | loadParameters.sourceOrigin = SecurityOrigin::createFromString(origin); |
324 | } |
325 | |
326 | if (loadParameters.options.mode != FetchOptions::Mode::Navigate) { |
327 | ASSERT(loadParameters.sourceOrigin); |
328 | if (!loadParameters.sourceOrigin) { |
329 | RELEASE_LOG_ERROR_IF_ALLOWED(resourceLoader, "scheduleLoad: no sourceOrigin (frame = %p, priority = %d, pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ")" , resourceLoader.frame(), static_cast<int>(resourceLoader.request().priority()), loadParameters.webPageID.toUInt64(), loadParameters.webFrameID, loadParameters.identifier); |
330 | scheduleInternallyFailedLoad(resourceLoader); |
331 | return; |
332 | } |
333 | } |
334 | |
335 | loadParameters.shouldRestrictHTTPResponseAccess = shouldPerformSecurityChecks(); |
336 | |
337 | loadParameters.isMainFrameNavigation = resourceLoader.frame() && resourceLoader.frame()->isMainFrame() && resourceLoader.options().mode == FetchOptions::Mode::Navigate; |
338 | |
339 | loadParameters.isMainResourceNavigationForAnyFrame = resourceLoader.frame() && resourceLoader.options().mode == FetchOptions::Mode::Navigate; |
340 | |
341 | loadParameters.shouldEnableCrossOriginResourcePolicy = RuntimeEnabledFeatures::sharedFeatures().crossOriginResourcePolicyEnabled() && !loadParameters.isMainFrameNavigation; |
342 | |
343 | if (resourceLoader.options().mode == FetchOptions::Mode::Navigate) { |
344 | Vector<RefPtr<SecurityOrigin>> frameAncestorOrigins; |
345 | for (auto* frame = resourceLoader.frame()->tree().parent(); frame; frame = frame->tree().parent()) |
346 | frameAncestorOrigins.append(makeRefPtr(frame->document()->securityOrigin())); |
347 | loadParameters.frameAncestorOrigins = WTFMove(frameAncestorOrigins); |
348 | } |
349 | |
350 | ASSERT((loadParameters.webPageID && loadParameters.webFrameID) || loadParameters.clientCredentialPolicy == ClientCredentialPolicy::CannotAskClientForCredentials); |
351 | |
352 | RELEASE_LOG_IF_ALLOWED(resourceLoader, "scheduleLoad: Resource is being scheduled with the NetworkProcess (frame = %p, priority = %d, pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ")" , resourceLoader.frame(), static_cast<int>(resourceLoader.request().priority()), loadParameters.webPageID.toUInt64(), loadParameters.webFrameID, loadParameters.identifier); |
353 | if (!WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::ScheduleResourceLoad(loadParameters), 0)) { |
354 | RELEASE_LOG_ERROR_IF_ALLOWED(resourceLoader, "scheduleLoad: Unable to schedule resource with the NetworkProcess (frame = %p, priority = %d, pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ")" , resourceLoader.frame(), static_cast<int>(resourceLoader.request().priority()), loadParameters.webPageID.toUInt64(), loadParameters.webFrameID, loadParameters.identifier); |
355 | // We probably failed to schedule this load with the NetworkProcess because it had crashed. |
356 | // This load will never succeed so we will schedule it to fail asynchronously. |
357 | scheduleInternallyFailedLoad(resourceLoader); |
358 | return; |
359 | } |
360 | |
361 | auto loader = WebResourceLoader::create(resourceLoader, trackingParameters); |
362 | if (resourceLoader.originalRequest().hasUpload()) { |
363 | if (m_loadersWithUploads.isEmpty()) |
364 | WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessPool::SetWebProcessHasUploads(Process::identifier()), 0); |
365 | m_loadersWithUploads.add(loader.ptr()); |
366 | } |
367 | |
368 | m_webResourceLoaders.set(identifier, WTFMove(loader)); |
369 | } |
370 | |
371 | void WebLoaderStrategy::scheduleInternallyFailedLoad(WebCore::ResourceLoader& resourceLoader) |
372 | { |
373 | m_internallyFailedResourceLoaders.add(&resourceLoader); |
374 | m_internallyFailedLoadTimer.startOneShot(0_s); |
375 | } |
376 | |
377 | void WebLoaderStrategy::internallyFailedLoadTimerFired() |
378 | { |
379 | for (auto& resourceLoader : copyToVector(m_internallyFailedResourceLoaders)) |
380 | resourceLoader->didFail(internalError(resourceLoader->url())); |
381 | } |
382 | |
383 | void WebLoaderStrategy::startLocalLoad(WebCore::ResourceLoader& resourceLoader) |
384 | { |
385 | resourceLoader.start(); |
386 | m_webResourceLoaders.set(resourceLoader.identifier(), WebResourceLoader::create(resourceLoader, { })); |
387 | } |
388 | |
389 | void WebLoaderStrategy::addURLSchemeTaskProxy(WebURLSchemeTaskProxy& task) |
390 | { |
391 | auto result = m_urlSchemeTasks.add(task.identifier(), &task); |
392 | ASSERT_UNUSED(result, result.isNewEntry); |
393 | } |
394 | |
395 | void WebLoaderStrategy::removeURLSchemeTaskProxy(WebURLSchemeTaskProxy& task) |
396 | { |
397 | m_urlSchemeTasks.remove(task.identifier()); |
398 | } |
399 | |
400 | void WebLoaderStrategy::remove(ResourceLoader* resourceLoader) |
401 | { |
402 | ASSERT(resourceLoader); |
403 | LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::remove, url '%s'" , resourceLoader->url().string().utf8().data()); |
404 | |
405 | if (auto task = m_urlSchemeTasks.take(resourceLoader->identifier())) { |
406 | ASSERT(!m_internallyFailedResourceLoaders.contains(resourceLoader)); |
407 | task->stopLoading(); |
408 | return; |
409 | } |
410 | |
411 | if (m_internallyFailedResourceLoaders.contains(resourceLoader)) { |
412 | m_internallyFailedResourceLoaders.remove(resourceLoader); |
413 | return; |
414 | } |
415 | |
416 | ResourceLoadIdentifier identifier = resourceLoader->identifier(); |
417 | if (!identifier) { |
418 | LOG_ERROR("WebLoaderStrategy removing a ResourceLoader that has no identifier." ); |
419 | return; |
420 | } |
421 | |
422 | #if ENABLE(SERVICE_WORKER) |
423 | if (WebServiceWorkerProvider::singleton().cancelFetch(makeObjectIdentifier<FetchIdentifierType>(identifier))) |
424 | return; |
425 | #endif |
426 | |
427 | RefPtr<WebResourceLoader> loader = m_webResourceLoaders.take(identifier); |
428 | // Loader may not be registered if we created it, but haven't scheduled yet (a bundle client can decide to cancel such request via willSendRequest). |
429 | if (!loader) |
430 | return; |
431 | |
432 | WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::RemoveLoadIdentifier(identifier), 0); |
433 | |
434 | if (m_loadersWithUploads.remove(loader.get()) && m_loadersWithUploads.isEmpty()) |
435 | WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessPool::ClearWebProcessHasUploads { Process::identifier() }, 0); |
436 | |
437 | // It's possible that this WebResourceLoader might be just about to message back to the NetworkProcess (e.g. ContinueWillSendRequest) |
438 | // but there's no point in doing so anymore. |
439 | loader->detachFromCoreLoader(); |
440 | } |
441 | |
442 | void WebLoaderStrategy::setDefersLoading(ResourceLoader&, bool) |
443 | { |
444 | } |
445 | |
446 | void WebLoaderStrategy::crossOriginRedirectReceived(ResourceLoader*, const URL&) |
447 | { |
448 | // We handle cross origin redirects entirely within the NetworkProcess. |
449 | // We override this call in the WebProcess to make it a no-op. |
450 | } |
451 | |
452 | void WebLoaderStrategy::servePendingRequests(ResourceLoadPriority) |
453 | { |
454 | // This overrides the base class version. |
455 | // We don't need to do anything as this is handled by the network process. |
456 | } |
457 | |
458 | void WebLoaderStrategy::suspendPendingRequests() |
459 | { |
460 | // Network process does keep requests in pending state. |
461 | } |
462 | |
463 | void WebLoaderStrategy::resumePendingRequests() |
464 | { |
465 | // Network process does keep requests in pending state. |
466 | } |
467 | |
468 | void WebLoaderStrategy::networkProcessCrashed() |
469 | { |
470 | RELEASE_LOG_ERROR(Network, "WebLoaderStrategy::networkProcessCrashed: failing all pending resource loaders" ); |
471 | |
472 | for (auto& loader : m_webResourceLoaders.values()) { |
473 | scheduleInternallyFailedLoad(*loader->resourceLoader()); |
474 | loader->detachFromCoreLoader(); |
475 | } |
476 | |
477 | m_webResourceLoaders.clear(); |
478 | |
479 | auto pingLoadCompletionHandlers = WTFMove(m_pingLoadCompletionHandlers); |
480 | for (auto& pingLoadCompletionHandler : pingLoadCompletionHandlers.values()) |
481 | pingLoadCompletionHandler(internalError(URL()), { }); |
482 | |
483 | auto preconnectCompletionHandlers = WTFMove(m_preconnectCompletionHandlers); |
484 | for (auto& preconnectCompletionHandler : preconnectCompletionHandlers.values()) |
485 | preconnectCompletionHandler(internalError(URL())); |
486 | } |
487 | |
488 | static bool shouldClearReferrerOnHTTPSToHTTPRedirect(Frame* frame) |
489 | { |
490 | if (frame) { |
491 | if (auto* document = frame->document()) |
492 | return document->referrerPolicy() == ReferrerPolicy::NoReferrerWhenDowngrade; |
493 | } |
494 | return true; |
495 | } |
496 | |
497 | Optional<WebLoaderStrategy::SyncLoadResult> WebLoaderStrategy::tryLoadingSynchronouslyUsingURLSchemeHandler(FrameLoader& frameLoader, ResourceLoadIdentifier identifier, const ResourceRequest& request) |
498 | { |
499 | auto* webFrameLoaderClient = toWebFrameLoaderClient(frameLoader.client()); |
500 | auto* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : nullptr; |
501 | auto* webPage = webFrame ? webFrame->page() : nullptr; |
502 | if (!webPage) |
503 | return WTF::nullopt; |
504 | |
505 | auto* handler = webPage->urlSchemeHandlerForScheme(request.url().protocol().toStringWithoutCopying()); |
506 | if (!handler) |
507 | return WTF::nullopt; |
508 | |
509 | LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, sync load to URL '%s' will be handled by a UIProcess URL scheme handler." , request.url().string().utf8().data()); |
510 | |
511 | SyncLoadResult result; |
512 | handler->loadSynchronously(identifier, request, result.response, result.error, result.data); |
513 | |
514 | return result; |
515 | } |
516 | |
517 | void WebLoaderStrategy::loadResourceSynchronously(FrameLoader& frameLoader, unsigned long resourceLoadIdentifier, const ResourceRequest& request, ClientCredentialPolicy clientCredentialPolicy, const FetchOptions& options, const HTTPHeaderMap& , ResourceError& error, ResourceResponse& response, Vector<char>& data) |
518 | { |
519 | WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frameLoader.client()); |
520 | WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : nullptr; |
521 | WebPage* webPage = webFrame ? webFrame->page() : nullptr; |
522 | |
523 | auto pageID = webPage ? webPage->pageID() : PageIdentifier { }; |
524 | auto frameID = webFrame ? webFrame->frameID() : 0; |
525 | auto sessionID = webPage ? webPage->sessionID() : PAL::SessionID::defaultSessionID(); |
526 | |
527 | auto* document = frameLoader.frame().document(); |
528 | if (!document) { |
529 | RELEASE_LOG_ERROR_IF_ALLOWED(sessionID, "loadResourceSynchronously: no document (pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %lu)" , pageID.toUInt64(), frameID, resourceLoadIdentifier); |
530 | error = internalError(request.url()); |
531 | return; |
532 | } |
533 | |
534 | if (auto syncLoadResult = tryLoadingSynchronouslyUsingURLSchemeHandler(frameLoader, resourceLoadIdentifier, request)) { |
535 | RELEASE_LOG_ERROR_IF_ALLOWED(sessionID, "loadResourceSynchronously: failed calling tryLoadingSynchronouslyUsingURLSchemeHandler (pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %lu, error = %d)" , pageID.toUInt64(), frameID, resourceLoadIdentifier, syncLoadResult->error.errorCode()); |
536 | error = WTFMove(syncLoadResult->error); |
537 | response = WTFMove(syncLoadResult->response); |
538 | data = WTFMove(syncLoadResult->data); |
539 | return; |
540 | } |
541 | |
542 | NetworkResourceLoadParameters loadParameters; |
543 | loadParameters.identifier = resourceLoadIdentifier; |
544 | loadParameters.webPageID = pageID; |
545 | loadParameters.webFrameID = frameID; |
546 | loadParameters.parentPID = presentingApplicationPID(); |
547 | loadParameters.sessionID = sessionID; |
548 | loadParameters.request = request; |
549 | loadParameters.contentSniffingPolicy = ContentSniffingPolicy::SniffContent; |
550 | loadParameters.contentEncodingSniffingPolicy = ContentEncodingSniffingPolicy::Sniff; |
551 | loadParameters.storedCredentialsPolicy = options.credentials == FetchOptions::Credentials::Omit ? StoredCredentialsPolicy::DoNotUse : StoredCredentialsPolicy::Use; |
552 | loadParameters.clientCredentialPolicy = clientCredentialPolicy; |
553 | loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = shouldClearReferrerOnHTTPSToHTTPRedirect(webFrame ? webFrame->coreFrame() : nullptr); |
554 | loadParameters.shouldRestrictHTTPResponseAccess = shouldPerformSecurityChecks(); |
555 | |
556 | loadParameters.options = options; |
557 | loadParameters.sourceOrigin = &document->securityOrigin(); |
558 | if (!document->shouldBypassMainWorldContentSecurityPolicy()) { |
559 | if (auto* contentSecurityPolicy = document->contentSecurityPolicy()) |
560 | loadParameters.cspResponseHeaders = contentSecurityPolicy->responseHeaders(); |
561 | } |
562 | loadParameters.originalRequestHeaders = originalRequestHeaders; |
563 | |
564 | data.shrink(0); |
565 | |
566 | HangDetectionDisabler hangDetectionDisabler; |
567 | |
568 | bool shouldNotifyOfUpload = request.hasUpload() && m_loadersWithUploads.isEmpty(); |
569 | if (shouldNotifyOfUpload) |
570 | WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessPool::SetWebProcessHasUploads { Process::identifier() }, 0); |
571 | |
572 | if (!WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad(loadParameters), Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::Reply(error, response, data), 0)) { |
573 | RELEASE_LOG_ERROR_IF_ALLOWED(sessionID, "loadResourceSynchronously: failed sending synchronous network process message (pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %lu)" , pageID.toUInt64(), frameID, resourceLoadIdentifier); |
574 | if (auto* page = webPage ? webPage->corePage() : nullptr) |
575 | page->diagnosticLoggingClient().logDiagnosticMessage(WebCore::DiagnosticLoggingKeys::internalErrorKey(), WebCore::DiagnosticLoggingKeys::synchronousMessageFailedKey(), WebCore::ShouldSample::No); |
576 | response = ResourceResponse(); |
577 | error = internalError(request.url()); |
578 | } |
579 | |
580 | if (shouldNotifyOfUpload) |
581 | WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessPool::ClearWebProcessHasUploads { Process::identifier() }, 0); |
582 | } |
583 | |
584 | void WebLoaderStrategy::pageLoadCompleted(PageIdentifier webPageID) |
585 | { |
586 | WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::PageLoadCompleted(webPageID), 0); |
587 | } |
588 | |
589 | static uint64_t generateLoadIdentifier() |
590 | { |
591 | static uint64_t identifier = 0; |
592 | return ++identifier; |
593 | } |
594 | |
595 | bool WebLoaderStrategy::usePingLoad() const |
596 | { |
597 | return !RuntimeEnabledFeatures::sharedFeatures().fetchAPIKeepAliveEnabled(); |
598 | } |
599 | |
600 | void WebLoaderStrategy::(Frame& frame, ResourceRequest& request, const HTTPHeaderMap& , const FetchOptions& options, ContentSecurityPolicyImposition policyCheck, PingLoadCompletionHandler&& completionHandler) |
601 | { |
602 | auto* document = frame.document(); |
603 | if (!document) { |
604 | if (completionHandler) |
605 | completionHandler(internalError(request.url()), { }); |
606 | return; |
607 | } |
608 | |
609 | NetworkResourceLoadParameters loadParameters; |
610 | loadParameters.identifier = generateLoadIdentifier(); |
611 | loadParameters.request = request; |
612 | loadParameters.sourceOrigin = &document->securityOrigin(); |
613 | loadParameters.parentPID = presentingApplicationPID(); |
614 | loadParameters.sessionID = frame.page() ? frame.page()->sessionID() : PAL::SessionID::defaultSessionID(); |
615 | loadParameters.storedCredentialsPolicy = options.credentials == FetchOptions::Credentials::Omit ? StoredCredentialsPolicy::DoNotUse : StoredCredentialsPolicy::Use; |
616 | loadParameters.options = options; |
617 | loadParameters.originalRequestHeaders = originalRequestHeaders; |
618 | loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = shouldClearReferrerOnHTTPSToHTTPRedirect(&frame); |
619 | loadParameters.shouldRestrictHTTPResponseAccess = shouldPerformSecurityChecks(); |
620 | if (policyCheck == ContentSecurityPolicyImposition::DoPolicyCheck && !document->shouldBypassMainWorldContentSecurityPolicy()) { |
621 | if (auto* contentSecurityPolicy = document->contentSecurityPolicy()) |
622 | loadParameters.cspResponseHeaders = contentSecurityPolicy->responseHeaders(); |
623 | } |
624 | |
625 | #if ENABLE(CONTENT_EXTENSIONS) |
626 | loadParameters.mainDocumentURL = document->topDocument().url(); |
627 | // FIXME: Instead of passing userContentControllerIdentifier, we should just pass webPageId to NetworkProcess. |
628 | WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame.loader().client()); |
629 | WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : nullptr; |
630 | WebPage* webPage = webFrame ? webFrame->page() : nullptr; |
631 | if (webPage) |
632 | loadParameters.userContentControllerIdentifier = webPage->userContentControllerIdentifier(); |
633 | #endif |
634 | |
635 | if (completionHandler) |
636 | m_pingLoadCompletionHandlers.add(loadParameters.identifier, WTFMove(completionHandler)); |
637 | |
638 | WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::LoadPing { loadParameters }, 0); |
639 | } |
640 | |
641 | void WebLoaderStrategy::didFinishPingLoad(uint64_t pingLoadIdentifier, ResourceError&& error, ResourceResponse&& response) |
642 | { |
643 | if (auto completionHandler = m_pingLoadCompletionHandlers.take(pingLoadIdentifier)) |
644 | completionHandler(WTFMove(error), WTFMove(response)); |
645 | } |
646 | |
647 | void WebLoaderStrategy::preconnectTo(FrameLoader& frameLoader, const URL& url, StoredCredentialsPolicy storedCredentialsPolicy, PreconnectCompletionHandler&& completionHandler) |
648 | { |
649 | uint64_t preconnectionIdentifier = generateLoadIdentifier(); |
650 | auto addResult = m_preconnectCompletionHandlers.add(preconnectionIdentifier, WTFMove(completionHandler)); |
651 | ASSERT_UNUSED(addResult, addResult.isNewEntry); |
652 | |
653 | auto* webFrameLoaderClient = toWebFrameLoaderClient(frameLoader.client()); |
654 | if (!webFrameLoaderClient) { |
655 | completionHandler(internalError(url)); |
656 | return; |
657 | } |
658 | auto* webFrame = webFrameLoaderClient->webFrame(); |
659 | if (!webFrame) { |
660 | completionHandler(internalError(url)); |
661 | return; |
662 | } |
663 | auto* webPage = webFrame->page(); |
664 | if (!webPage) { |
665 | completionHandler(internalError(url)); |
666 | return; |
667 | } |
668 | |
669 | NetworkResourceLoadParameters parameters; |
670 | parameters.request = ResourceRequest { url }; |
671 | parameters.webPageID = webPage->pageID(); |
672 | parameters.webFrameID = webFrame->frameID(); |
673 | parameters.parentPID = presentingApplicationPID(); |
674 | parameters.sessionID = webPage->sessionID(); |
675 | parameters.storedCredentialsPolicy = storedCredentialsPolicy; |
676 | parameters.shouldPreconnectOnly = PreconnectOnly::Yes; |
677 | parameters.shouldRestrictHTTPResponseAccess = shouldPerformSecurityChecks(); |
678 | // FIXME: Use the proper destination once all fetch options are passed. |
679 | parameters.options.destination = FetchOptions::Destination::EmptyString; |
680 | |
681 | WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::PreconnectTo(preconnectionIdentifier, WTFMove(parameters)), 0); |
682 | } |
683 | |
684 | void WebLoaderStrategy::didFinishPreconnection(uint64_t preconnectionIdentifier, ResourceError&& error) |
685 | { |
686 | if (auto completionHandler = m_preconnectCompletionHandlers.take(preconnectionIdentifier)) |
687 | completionHandler(WTFMove(error)); |
688 | } |
689 | |
690 | bool WebLoaderStrategy::isOnLine() const |
691 | { |
692 | return m_isOnLine; |
693 | } |
694 | |
695 | void WebLoaderStrategy::addOnlineStateChangeListener(Function<void(bool)>&& listener) |
696 | { |
697 | WebProcess::singleton().ensureNetworkProcessConnection(); |
698 | m_onlineStateChangeListeners.append(WTFMove(listener)); |
699 | } |
700 | |
701 | void WebLoaderStrategy::setOnLineState(bool isOnLine) |
702 | { |
703 | if (m_isOnLine == isOnLine) |
704 | return; |
705 | |
706 | m_isOnLine = isOnLine; |
707 | for (auto& listener : m_onlineStateChangeListeners) |
708 | listener(isOnLine); |
709 | } |
710 | |
711 | void WebLoaderStrategy::(bool enabled) |
712 | { |
713 | WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::SetCaptureExtraNetworkLoadMetricsEnabled(enabled), 0); |
714 | } |
715 | |
716 | ResourceResponse WebLoaderStrategy::responseFromResourceLoadIdentifier(uint64_t resourceLoadIdentifier) |
717 | { |
718 | ResourceResponse response; |
719 | WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkConnectionToWebProcess::GetNetworkLoadInformationResponse { resourceLoadIdentifier }, Messages::NetworkConnectionToWebProcess::GetNetworkLoadInformationResponse::Reply { response }, 0); |
720 | return response; |
721 | } |
722 | |
723 | Vector<NetworkTransactionInformation> WebLoaderStrategy::intermediateLoadInformationFromResourceLoadIdentifier(uint64_t resourceLoadIdentifier) |
724 | { |
725 | Vector<NetworkTransactionInformation> information; |
726 | WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkConnectionToWebProcess::GetNetworkLoadIntermediateInformation { resourceLoadIdentifier }, Messages::NetworkConnectionToWebProcess::GetNetworkLoadIntermediateInformation::Reply { information }, 0); |
727 | return information; |
728 | } |
729 | |
730 | NetworkLoadMetrics WebLoaderStrategy::networkMetricsFromResourceLoadIdentifier(uint64_t resourceLoadIdentifier) |
731 | { |
732 | NetworkLoadMetrics networkMetrics; |
733 | WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkConnectionToWebProcess::TakeNetworkLoadInformationMetrics { resourceLoadIdentifier }, Messages::NetworkConnectionToWebProcess::TakeNetworkLoadInformationMetrics::Reply { networkMetrics }, 0); |
734 | return networkMetrics; |
735 | } |
736 | |
737 | bool WebLoaderStrategy::shouldPerformSecurityChecks() const |
738 | { |
739 | return RuntimeEnabledFeatures::sharedFeatures().restrictedHTTPResponseAccess(); |
740 | } |
741 | |
742 | bool WebLoaderStrategy::havePerformedSecurityChecks(const ResourceResponse& response) const |
743 | { |
744 | if (!shouldPerformSecurityChecks()) |
745 | return false; |
746 | switch (response.source()) { |
747 | case ResourceResponse::Source::ApplicationCache: |
748 | case ResourceResponse::Source::MemoryCache: |
749 | case ResourceResponse::Source::MemoryCacheAfterValidation: |
750 | case ResourceResponse::Source::ServiceWorker: |
751 | return false; |
752 | case ResourceResponse::Source::DiskCache: |
753 | case ResourceResponse::Source::DiskCacheAfterValidation: |
754 | case ResourceResponse::Source::Network: |
755 | case ResourceResponse::Source::Unknown: |
756 | return true; |
757 | } |
758 | ASSERT_NOT_REACHED(); |
759 | return false; |
760 | } |
761 | |
762 | } // namespace WebKit |
763 | |
764 | #undef RELEASE_LOG_IF_ALLOWED |
765 | #undef RELEASE_LOG_ERROR_IF_ALLOWED |
766 | |