2 * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "WebLoaderStrategy.h"
29 #include "DataReference.h"
30 #include "HangDetectionDisabler.h"
32 #include "NetworkConnectionToWebProcessMessages.h"
33 #include "NetworkProcessConnection.h"
34 #include "NetworkResourceLoadParameters.h"
35 #include "SessionTracker.h"
36 #include "WebCompiledContentRuleList.h"
37 #include "WebCoreArgumentCoders.h"
38 #include "WebErrors.h"
40 #include "WebFrameLoaderClient.h"
41 #include "WebFrameNetworkingContext.h"
43 #include "WebPageProxyMessages.h"
44 #include "WebProcess.h"
45 #include "WebResourceLoader.h"
46 #include "WebURLSchemeHandlerProxy.h"
47 #include "WebURLSchemeTaskProxy.h"
48 #include <WebCore/ApplicationCacheHost.h>
49 #include <WebCore/CachedResource.h>
50 #include <WebCore/ContentSecurityPolicy.h>
51 #include <WebCore/DiagnosticLoggingClient.h>
52 #include <WebCore/DiagnosticLoggingKeys.h>
53 #include <WebCore/Document.h>
54 #include <WebCore/DocumentLoader.h>
55 #include <WebCore/FetchOptions.h>
56 #include <WebCore/Frame.h>
57 #include <WebCore/FrameLoader.h>
58 #include <WebCore/NetscapePlugInStreamLoader.h>
59 #include <WebCore/PlatformStrategies.h>
60 #include <WebCore/ReferrerPolicy.h>
61 #include <WebCore/ResourceLoader.h>
62 #include <WebCore/SecurityOrigin.h>
63 #include <WebCore/Settings.h>
64 #include <WebCore/SubresourceLoader.h>
65 #include <WebCore/UserContentProvider.h>
66 #include <pal/SessionID.h>
67 #include <wtf/text/CString.h>
70 #include <WebCore/QuickLook.h>
73 using namespace WebCore;
75 #define RELEASE_LOG_IF_ALLOWED(permissionChecker, fmt, ...) RELEASE_LOG_IF(permissionChecker.isAlwaysOnLoggingAllowed(), Network, "%p - WebLoaderStrategy::" fmt, this, ##__VA_ARGS__)
76 #define RELEASE_LOG_ERROR_IF_ALLOWED(permissionChecker, fmt, ...) RELEASE_LOG_ERROR_IF(permissionChecker.isAlwaysOnLoggingAllowed(), Network, "%p - WebLoaderStrategy::" fmt, this, ##__VA_ARGS__)
80 WebLoaderStrategy::WebLoaderStrategy()
81 : m_internallyFailedLoadTimer(RunLoop::main(), this, &WebLoaderStrategy::internallyFailedLoadTimerFired)
85 WebLoaderStrategy::~WebLoaderStrategy()
89 RefPtr<SubresourceLoader> WebLoaderStrategy::loadResource(Frame& frame, CachedResource& resource, const ResourceRequest& request, const ResourceLoaderOptions& options)
91 RefPtr<SubresourceLoader> loader = SubresourceLoader::create(frame, resource, request, options);
93 scheduleLoad(*loader, &resource, frame.document()->referrerPolicy() == ReferrerPolicy::NoReferrerWhenDowngrade);
95 RELEASE_LOG_IF_ALLOWED(frame, "loadResource: Unable to create SubresourceLoader (frame = %p", &frame);
99 RefPtr<NetscapePlugInStreamLoader> WebLoaderStrategy::schedulePluginStreamLoad(Frame& frame, NetscapePlugInStreamLoaderClient& client, const ResourceRequest& request)
101 RefPtr<NetscapePlugInStreamLoader> loader = NetscapePlugInStreamLoader::create(frame, client, request);
103 scheduleLoad(*loader, 0, frame.document()->referrerPolicy() == ReferrerPolicy::NoReferrerWhenDowngrade);
107 static Seconds maximumBufferingTime(CachedResource* resource)
112 switch (resource->type()) {
113 case CachedResource::Beacon:
114 case CachedResource::CSSStyleSheet:
115 case CachedResource::Script:
116 #if ENABLE(SVG_FONTS)
117 case CachedResource::SVGFontResource:
119 case CachedResource::FontResource:
120 return Seconds::infinity();
121 case CachedResource::ImageResource:
123 case CachedResource::MediaResource:
125 case CachedResource::MainResource:
126 case CachedResource::Icon:
127 case CachedResource::RawResource:
128 case CachedResource::SVGDocumentResource:
129 #if ENABLE(LINK_PREFETCH)
130 case CachedResource::LinkPrefetch:
131 case CachedResource::LinkSubresource:
133 #if ENABLE(VIDEO_TRACK)
134 case CachedResource::TextTrackResource:
137 case CachedResource::XSLStyleSheet:
142 ASSERT_NOT_REACHED();
146 void WebLoaderStrategy::scheduleLoad(ResourceLoader& resourceLoader, CachedResource* resource, bool shouldClearReferrerOnHTTPSToHTTPRedirect)
148 ResourceLoadIdentifier identifier = resourceLoader.identifier();
151 // FIXME: Some entities in WebCore use WebCore's "EmptyFrameLoaderClient" instead of having a proper WebFrameLoaderClient.
152 // EmptyFrameLoaderClient shouldn't exist and everything should be using a WebFrameLoaderClient,
153 // but in the meantime we have to make sure not to mis-cast.
154 WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(resourceLoader.frameLoader()->client());
155 WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : nullptr;
156 WebPage* webPage = webFrame ? webFrame->page() : nullptr;
158 WebResourceLoader::TrackingParameters trackingParameters;
159 trackingParameters.pageID = webPage ? webPage->pageID() : 0;
160 trackingParameters.frameID = webFrame ? webFrame->frameID() : 0;
161 trackingParameters.resourceID = identifier;
163 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
164 // If the DocumentLoader schedules this as an archive resource load,
165 // then we should remember the ResourceLoader in our records but not schedule it in the NetworkProcess.
166 if (resourceLoader.documentLoader()->scheduleArchiveLoad(resourceLoader, resourceLoader.request())) {
167 LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be handled as an archive resource.", resourceLoader.url().string().utf8().data());
168 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, trackingParameters.frameID, identifier);
169 m_webResourceLoaders.set(identifier, WebResourceLoader::create(resourceLoader, trackingParameters));
174 if (resourceLoader.documentLoader()->applicationCacheHost().maybeLoadResource(resourceLoader, resourceLoader.request(), resourceLoader.request().url())) {
175 LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be loaded from application cache.", resourceLoader.url().string().utf8().data());
176 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, trackingParameters.frameID, identifier);
177 m_webResourceLoaders.set(identifier, WebResourceLoader::create(resourceLoader, trackingParameters));
181 if (resourceLoader.request().url().protocolIsData()) {
182 LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be loaded as data.", resourceLoader.url().string().utf8().data());
183 RELEASE_LOG_IF_ALLOWED(resourceLoader, "scheduleLoad: URL will be loaded as data (frame = %p, pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ")", resourceLoader.frame(), trackingParameters.pageID, trackingParameters.frameID, identifier);
184 startLocalLoad(resourceLoader);
189 if (isQuickLookPreviewURL(resourceLoader.request().url())) {
190 LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be handled as a QuickLook resource.", resourceLoader.url().string().utf8().data());
191 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, trackingParameters.frameID, identifier);
192 startLocalLoad(resourceLoader);
198 // For apps that call g_resource_load in a web extension.
199 // https://blogs.gnome.org/alexl/2012/01/26/resources-in-glib/
200 if (resourceLoader.request().url().protocolIs("resource")) {
201 LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be handled as a GResource.", resourceLoader.url().string().utf8().data());
202 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, trackingParameters.frameID, identifier);
203 startLocalLoad(resourceLoader);
209 if (auto* handler = webPage->urlSchemeHandlerForScheme(resourceLoader.request().url().protocol().toStringWithoutCopying())) {
210 LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, URL '%s' will be handled by a UIProcess URL scheme handler.", resourceLoader.url().string().utf8().data());
211 RELEASE_LOG_IF_ALLOWED(resourceLoader, "scheduleLoad: URL will be handled by a UIProcess URL scheme handler (frame = %p, resourceID = %" PRIu64 ")", resourceLoader.frame(), identifier);
213 handler->startNewTask(resourceLoader);
218 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()));
220 ContentSniffingPolicy contentSniffingPolicy = resourceLoader.shouldSniffContent() ? SniffContent : DoNotSniffContent;
221 StoredCredentials allowStoredCredentials = resourceLoader.shouldUseCredentialStorage() ? AllowStoredCredentials : DoNotAllowStoredCredentials;
223 NetworkResourceLoadParameters loadParameters;
224 loadParameters.identifier = identifier;
225 loadParameters.webPageID = webPage ? webPage->pageID() : 0;
226 loadParameters.webFrameID = webFrame ? webFrame->frameID() : 0;
227 loadParameters.sessionID = webPage ? webPage->sessionID() : PAL::SessionID::defaultSessionID();
228 loadParameters.request = resourceLoader.request();
229 loadParameters.contentSniffingPolicy = contentSniffingPolicy;
230 loadParameters.allowStoredCredentials = allowStoredCredentials;
231 // If there is no WebFrame then this resource cannot be authenticated with the client.
232 loadParameters.clientCredentialPolicy = (webFrame && webPage && resourceLoader.isAllowedToAskUserForCredentials()) ? ClientCredentialPolicy::MayAskClientForCredentials : ClientCredentialPolicy::CannotAskClientForCredentials;
233 loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = shouldClearReferrerOnHTTPSToHTTPRedirect;
234 loadParameters.defersLoading = resourceLoader.defersLoading();
235 loadParameters.needsCertificateInfo = resourceLoader.shouldIncludeCertificateInfo();
236 loadParameters.maximumBufferingTime = maximumBufferingTime(resource);
237 loadParameters.derivedCachedDataTypesToRetrieve = resourceLoader.options().derivedCachedDataTypesToRetrieve;
239 ASSERT((loadParameters.webPageID && loadParameters.webFrameID) || loadParameters.clientCredentialPolicy == ClientCredentialPolicy::CannotAskClientForCredentials);
241 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, loadParameters.webFrameID, loadParameters.identifier);
242 if (!WebProcess::singleton().networkConnection().connection().send(Messages::NetworkConnectionToWebProcess::ScheduleResourceLoad(loadParameters), 0)) {
243 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, loadParameters.webFrameID, loadParameters.identifier);
244 // We probably failed to schedule this load with the NetworkProcess because it had crashed.
245 // This load will never succeed so we will schedule it to fail asynchronously.
246 scheduleInternallyFailedLoad(resourceLoader);
250 m_webResourceLoaders.set(identifier, WebResourceLoader::create(resourceLoader, trackingParameters));
253 void WebLoaderStrategy::scheduleInternallyFailedLoad(WebCore::ResourceLoader& resourceLoader)
255 m_internallyFailedResourceLoaders.add(&resourceLoader);
256 m_internallyFailedLoadTimer.startOneShot(0_s);
259 void WebLoaderStrategy::internallyFailedLoadTimerFired()
261 Vector<RefPtr<ResourceLoader>> internallyFailedResourceLoaders;
262 copyToVector(m_internallyFailedResourceLoaders, internallyFailedResourceLoaders);
264 for (size_t i = 0; i < internallyFailedResourceLoaders.size(); ++i)
265 internallyFailedResourceLoaders[i]->didFail(internalError(internallyFailedResourceLoaders[i]->url()));
268 void WebLoaderStrategy::startLocalLoad(WebCore::ResourceLoader& resourceLoader)
270 resourceLoader.start();
271 m_webResourceLoaders.set(resourceLoader.identifier(), WebResourceLoader::create(resourceLoader, { }));
274 void WebLoaderStrategy::addURLSchemeTaskProxy(WebURLSchemeTaskProxy& task)
276 auto result = m_urlSchemeTasks.add(task.identifier(), &task);
277 ASSERT_UNUSED(result, result.isNewEntry);
280 void WebLoaderStrategy::removeURLSchemeTaskProxy(WebURLSchemeTaskProxy& task)
282 m_urlSchemeTasks.remove(task.identifier());
285 void WebLoaderStrategy::remove(ResourceLoader* resourceLoader)
287 ASSERT(resourceLoader);
288 LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::remove, url '%s'", resourceLoader->url().string().utf8().data());
290 if (auto task = m_urlSchemeTasks.take(resourceLoader->identifier())) {
291 ASSERT(!m_internallyFailedResourceLoaders.contains(resourceLoader));
296 if (m_internallyFailedResourceLoaders.contains(resourceLoader)) {
297 m_internallyFailedResourceLoaders.remove(resourceLoader);
301 ResourceLoadIdentifier identifier = resourceLoader->identifier();
303 LOG_ERROR("WebLoaderStrategy removing a ResourceLoader that has no identifier.");
307 RefPtr<WebResourceLoader> loader = m_webResourceLoaders.take(identifier);
308 // 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).
312 WebProcess::singleton().networkConnection().connection().send(Messages::NetworkConnectionToWebProcess::RemoveLoadIdentifier(identifier), 0);
314 // It's possible that this WebResourceLoader might be just about to message back to the NetworkProcess (e.g. ContinueWillSendRequest)
315 // but there's no point in doing so anymore.
316 loader->detachFromCoreLoader();
319 void WebLoaderStrategy::setDefersLoading(ResourceLoader* resourceLoader, bool defers)
321 ResourceLoadIdentifier identifier = resourceLoader->identifier();
322 WebProcess::singleton().networkConnection().connection().send(Messages::NetworkConnectionToWebProcess::SetDefersLoading(identifier, defers), 0);
325 void WebLoaderStrategy::crossOriginRedirectReceived(ResourceLoader*, const URL&)
327 // We handle cross origin redirects entirely within the NetworkProcess.
328 // We override this call in the WebProcess to make it a no-op.
331 void WebLoaderStrategy::servePendingRequests(ResourceLoadPriority)
333 // This overrides the base class version.
334 // We don't need to do anything as this is handled by the network process.
337 void WebLoaderStrategy::suspendPendingRequests()
339 // Network process does keep requests in pending state.
342 void WebLoaderStrategy::resumePendingRequests()
344 // Network process does keep requests in pending state.
347 void WebLoaderStrategy::networkProcessCrashed()
349 RELEASE_LOG_ERROR(Network, "WebLoaderStrategy::networkProcessCrashed: failing all pending resource loaders");
351 for (auto& loader : m_webResourceLoaders)
352 scheduleInternallyFailedLoad(*loader.value->resourceLoader());
354 m_webResourceLoaders.clear();
356 auto pingLoadCompletionHandlers = WTFMove(m_pingLoadCompletionHandlers);
357 for (auto& pingLoadCompletionHandler : pingLoadCompletionHandlers.values())
358 pingLoadCompletionHandler(internalError(URL()));
361 void WebLoaderStrategy::loadResourceSynchronously(NetworkingContext* context, unsigned long resourceLoadIdentifier, const ResourceRequest& request, StoredCredentials storedCredentials, ClientCredentialPolicy clientCredentialPolicy, ResourceError& error, ResourceResponse& response, Vector<char>& data)
363 WebFrameNetworkingContext* webContext = static_cast<WebFrameNetworkingContext*>(context);
364 // FIXME: Some entities in WebCore use WebCore's "EmptyFrameLoaderClient" instead of having a proper WebFrameLoaderClient.
365 // EmptyFrameLoaderClient shouldn't exist and everything should be using a WebFrameLoaderClient,
366 // but in the meantime we have to make sure not to mis-cast.
367 WebFrameLoaderClient* webFrameLoaderClient = webContext->webFrameLoaderClient();
368 WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
369 WebPage* webPage = webFrame ? webFrame->page() : 0;
371 NetworkResourceLoadParameters loadParameters;
372 loadParameters.identifier = resourceLoadIdentifier;
373 loadParameters.webPageID = webPage ? webPage->pageID() : 0;
374 loadParameters.webFrameID = webFrame ? webFrame->frameID() : 0;
375 loadParameters.sessionID = webPage ? webPage->sessionID() : PAL::SessionID::defaultSessionID();
376 loadParameters.request = request;
377 loadParameters.contentSniffingPolicy = SniffContent;
378 loadParameters.allowStoredCredentials = storedCredentials;
379 loadParameters.clientCredentialPolicy = clientCredentialPolicy;
380 loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = context->shouldClearReferrerOnHTTPSToHTTPRedirect();
384 HangDetectionDisabler hangDetectionDisabler;
386 if (!WebProcess::singleton().networkConnection().connection().sendSync(Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad(loadParameters), Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::Reply(error, response, data), 0)) {
387 RELEASE_LOG_ERROR_IF_ALLOWED(loadParameters.sessionID, "loadResourceSynchronously: failed sending synchronous network process message (pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ")", loadParameters.webPageID, loadParameters.webFrameID, loadParameters.identifier);
388 if (auto* page = webPage->corePage())
389 page->diagnosticLoggingClient().logDiagnosticMessage(WebCore::DiagnosticLoggingKeys::internalErrorKey(), WebCore::DiagnosticLoggingKeys::synchronousMessageFailedKey(), WebCore::ShouldSample::No);
390 response = ResourceResponse();
391 error = internalError(request.url());
395 static uint64_t generatePingLoadIdentifier()
397 static uint64_t identifier = 0;
401 void WebLoaderStrategy::startPingLoad(Frame& frame, ResourceRequest& request, const HTTPHeaderMap& originalRequestHeaders, const FetchOptions& options, PingLoadCompletionHandler&& completionHandler)
403 // It's possible that call to createPingHandle might be made during initial empty Document creation before a NetworkingContext exists.
404 // It is not clear that we should send ping loads during that process anyways.
405 auto* networkingContext = frame.loader().networkingContext();
406 if (!networkingContext) {
407 if (completionHandler)
408 completionHandler(internalError(request.url()));
412 WebFrameNetworkingContext* webContext = static_cast<WebFrameNetworkingContext*>(networkingContext);
413 WebFrameLoaderClient* webFrameLoaderClient = webContext->webFrameLoaderClient();
414 WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : nullptr;
415 WebPage* webPage = webFrame ? webFrame->page() : nullptr;
417 auto* document = frame.document();
419 if (completionHandler)
420 completionHandler(internalError(request.url()));
424 NetworkResourceLoadParameters loadParameters;
425 loadParameters.identifier = generatePingLoadIdentifier();
426 loadParameters.request = request;
427 loadParameters.sourceOrigin = &document->securityOrigin();
428 loadParameters.sessionID = webPage ? webPage->sessionID() : PAL::SessionID::defaultSessionID();
429 loadParameters.allowStoredCredentials = options.credentials == FetchOptions::Credentials::Omit ? DoNotAllowStoredCredentials : AllowStoredCredentials;
430 loadParameters.mode = options.mode;
431 loadParameters.shouldFollowRedirects = options.redirect == FetchOptions::Redirect::Follow;
432 loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = networkingContext->shouldClearReferrerOnHTTPSToHTTPRedirect();
433 if (!document->shouldBypassMainWorldContentSecurityPolicy()) {
434 if (auto * contentSecurityPolicy = document->contentSecurityPolicy())
435 loadParameters.cspResponseHeaders = contentSecurityPolicy->responseHeaders();
438 #if ENABLE(CONTENT_EXTENSIONS)
439 loadParameters.mainDocumentURL = document->topDocument().url();
441 if (auto* documentLoader = frame.loader().documentLoader()) {
442 if (auto* page = frame.page()) {
443 page->userContentProvider().forEachContentExtension([&loadParameters](const String& identifier, ContentExtensions::ContentExtension& contentExtension) {
444 loadParameters.contentRuleLists.append(std::make_pair(identifier, static_cast<const WebCompiledContentRuleList&>(contentExtension.compiledExtension()).data()));
450 if (completionHandler)
451 m_pingLoadCompletionHandlers.add(loadParameters.identifier, WTFMove(completionHandler));
453 WebProcess::singleton().networkConnection().connection().send(Messages::NetworkConnectionToWebProcess::LoadPing(WTFMove(loadParameters), originalRequestHeaders), 0);
456 void WebLoaderStrategy::didFinishPingLoad(uint64_t pingLoadIdentifier, ResourceError&& error)
458 if (auto completionHandler = m_pingLoadCompletionHandlers.take(pingLoadIdentifier))
459 completionHandler(WTFMove(error));
462 void WebLoaderStrategy::storeDerivedDataToCache(const SHA1::Digest& bodyHash, const String& type, const String& partition, WebCore::SharedBuffer& data)
464 NetworkCache::DataKey key { partition, type, bodyHash };
465 IPC::SharedBufferDataReference dataReference { &data };
466 WebProcess::singleton().networkConnection().connection().send(Messages::NetworkConnectionToWebProcess::StoreDerivedDataToCache(key, dataReference), 0);
469 void WebLoaderStrategy::setCaptureExtraNetworkLoadMetricsEnabled(bool enabled)
471 WebProcess::singleton().networkConnection().connection().send(Messages::NetworkConnectionToWebProcess::SetCaptureExtraNetworkLoadMetricsEnabled(enabled), 0);
474 } // namespace WebKit