facdfd5d90d47030c0c679aa05781ccbb86d30bd
[WebKit-https.git] / Source / WebKit / NetworkProcess / NetworkProcess.cpp
1 /*
2  * Copyright (C) 2012-2019 Apple Inc. All rights reserved.
3  * Copyright (C) 2018 Sony Interactive Entertainment Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24  * THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "NetworkProcess.h"
29
30 #include "ArgumentCoders.h"
31 #include "Attachment.h"
32 #include "AuthenticationManager.h"
33 #include "AuxiliaryProcessMessages.h"
34 #include "DataReference.h"
35 #include "DownloadProxyMessages.h"
36 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
37 #include "LegacyCustomProtocolManager.h"
38 #endif
39 #include "Logging.h"
40 #include "NetworkConnectionToWebProcess.h"
41 #include "NetworkContentRuleListManagerMessages.h"
42 #include "NetworkProcessCreationParameters.h"
43 #include "NetworkProcessPlatformStrategies.h"
44 #include "NetworkProcessProxyMessages.h"
45 #include "NetworkProximityManager.h"
46 #include "NetworkResourceLoader.h"
47 #include "NetworkSession.h"
48 #include "NetworkSessionCreationParameters.h"
49 #include "PreconnectTask.h"
50 #include "RemoteNetworkingContext.h"
51 #include "ShouldGrandfatherStatistics.h"
52 #include "StatisticsData.h"
53 #include "StorageAccessStatus.h"
54 #include "WebCookieManager.h"
55 #include "WebPageProxyMessages.h"
56 #include "WebProcessPoolMessages.h"
57 #include "WebResourceLoadStatisticsStore.h"
58 #include "WebSWOriginStore.h"
59 #include "WebSWServerConnection.h"
60 #include "WebSWServerToContextConnection.h"
61 #include "WebsiteData.h"
62 #include "WebsiteDataFetchOption.h"
63 #include "WebsiteDataStore.h"
64 #include "WebsiteDataStoreParameters.h"
65 #include "WebsiteDataType.h"
66 #include <WebCore/DNS.h>
67 #include <WebCore/DeprecatedGlobalSettings.h>
68 #include <WebCore/DiagnosticLoggingClient.h>
69 #include <WebCore/LogInitialization.h>
70 #include <WebCore/MIMETypeRegistry.h>
71 #include <WebCore/NetworkStateNotifier.h>
72 #include <WebCore/NetworkStorageSession.h>
73 #include <WebCore/ResourceRequest.h>
74 #include <WebCore/RuntimeApplicationChecks.h>
75 #include <WebCore/RuntimeEnabledFeatures.h>
76 #include <WebCore/SchemeRegistry.h>
77 #include <WebCore/SecurityOriginData.h>
78 #include <wtf/Algorithms.h>
79 #include <wtf/CallbackAggregator.h>
80 #include <wtf/OptionSet.h>
81 #include <wtf/ProcessPrivilege.h>
82 #include <wtf/RunLoop.h>
83 #include <wtf/text/AtomicString.h>
84
85 #if ENABLE(SEC_ITEM_SHIM)
86 #include "SecItemShim.h"
87 #endif
88
89 #include "NetworkCache.h"
90 #include "NetworkCacheCoders.h"
91
92 #if PLATFORM(COCOA)
93 #include "NetworkSessionCocoa.h"
94 #endif
95
96 #if USE(SOUP)
97 #include <WebCore/DNSResolveQueueSoup.h>
98 #include <WebCore/SoupNetworkSession.h>
99 #endif
100
101 #if USE(CURL)
102 #include <WebCore/CurlContext.h>
103 #endif
104
105 #if ENABLE(SERVICE_WORKER)
106 #include "WebSWServerToContextConnectionMessages.h"
107 #endif
108
109 namespace WebKit {
110 using namespace WebCore;
111
112 static void callExitSoon(IPC::Connection*)
113 {
114     // If the connection has been closed and we haven't responded in the main thread for 10 seconds
115     // the process will exit forcibly.
116     auto watchdogDelay = 10_s;
117
118     WorkQueue::create("com.apple.WebKit.NetworkProcess.WatchDogQueue")->dispatchAfter(watchdogDelay, [] {
119         // We use _exit here since the watchdog callback is called from another thread and we don't want
120         // global destructors or atexit handlers to be called from this thread while the main thread is busy
121         // doing its thing.
122         RELEASE_LOG_ERROR(IPC, "Exiting process early due to unacknowledged closed-connection");
123         _exit(EXIT_FAILURE);
124     });
125 }
126
127 NetworkProcess::NetworkProcess(AuxiliaryProcessInitializationParameters&& parameters)
128     : m_downloadManager(*this)
129 #if ENABLE(CONTENT_EXTENSIONS)
130     , m_networkContentRuleListManager(*this)
131 #endif
132 #if PLATFORM(IOS_FAMILY)
133     , m_webSQLiteDatabaseTracker(*this)
134 #endif
135 {
136     NetworkProcessPlatformStrategies::initialize();
137
138     addSupplement<AuthenticationManager>();
139     addSupplement<WebCookieManager>();
140 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
141     addSupplement<LegacyCustomProtocolManager>();
142 #endif
143 #if PLATFORM(COCOA) || USE(SOUP)
144     LegacyCustomProtocolManager::networkProcessCreated(*this);
145 #endif
146 #if ENABLE(PROXIMITY_NETWORKING)
147     addSupplement<NetworkProximityManager>();
148 #endif
149
150 #if USE(SOUP)
151     DNSResolveQueueSoup::setGlobalDefaultNetworkStorageSessionAccessor([this]() -> NetworkStorageSession& {
152         return defaultStorageSession();
153     });
154 #endif
155
156     NetworkStateNotifier::singleton().addListener([weakThis = makeWeakPtr(*this)](bool isOnLine) {
157         if (!weakThis)
158             return;
159         for (auto& webProcessConnection : weakThis->m_webProcessConnections)
160             webProcessConnection->setOnLineState(isOnLine);
161     });
162
163     initialize(WTFMove(parameters));
164 }
165
166 NetworkProcess::~NetworkProcess()
167 {
168     for (auto& callbacks : m_cacheStorageParametersCallbacks.values()) {
169         for (auto& callback : callbacks)
170             callback(String { }, 0);
171     }
172 }
173
174 AuthenticationManager& NetworkProcess::authenticationManager()
175 {
176     return *supplement<AuthenticationManager>();
177 }
178
179 DownloadManager& NetworkProcess::downloadManager()
180 {
181     return m_downloadManager;
182 }
183
184 #if ENABLE(PROXIMITY_NETWORKING)
185 NetworkProximityManager& NetworkProcess::proximityManager()
186 {
187     return *supplement<NetworkProximityManager>();
188 }
189 #endif
190
191 void NetworkProcess::removeNetworkConnectionToWebProcess(NetworkConnectionToWebProcess& connection)
192 {
193     auto count = m_webProcessConnections.removeAllMatching([&] (const auto& c) {
194         return c.ptr() == &connection;
195     });
196     ASSERT_UNUSED(count, count == 1);
197 }
198
199 bool NetworkProcess::shouldTerminate()
200 {
201     // Network process keeps session cookies and credentials, so it should never terminate (as long as UI process connection is alive).
202     return false;
203 }
204
205 void NetworkProcess::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
206 {
207     if (messageReceiverMap().dispatchMessage(connection, decoder))
208         return;
209
210     if (decoder.messageReceiverName() == Messages::AuxiliaryProcess::messageReceiverName()) {
211         AuxiliaryProcess::didReceiveMessage(connection, decoder);
212         return;
213     }
214
215 #if ENABLE(CONTENT_EXTENSIONS)
216     if (decoder.messageReceiverName() == Messages::NetworkContentRuleListManager::messageReceiverName()) {
217         m_networkContentRuleListManager.didReceiveMessage(connection, decoder);
218         return;
219     }
220 #endif
221
222 #if ENABLE(SERVICE_WORKER)
223     if (decoder.messageReceiverName() == Messages::WebSWServerToContextConnection::messageReceiverName()) {
224         ASSERT(parentProcessHasServiceWorkerEntitlement());
225         if (!parentProcessHasServiceWorkerEntitlement())
226             return;
227         if (auto* webSWConnection = connectionToContextProcessFromIPCConnection(connection)) {
228             webSWConnection->didReceiveMessage(connection, decoder);
229             return;
230         }
231     }
232 #endif
233     didReceiveNetworkProcessMessage(connection, decoder);
234 }
235
236 void NetworkProcess::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder)
237 {
238     if (messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder))
239         return;
240
241     didReceiveSyncNetworkProcessMessage(connection, decoder, replyEncoder);
242 }
243
244 void NetworkProcess::didClose(IPC::Connection&)
245 {
246     ASSERT(RunLoop::isMain());
247
248     // Make sure we flush all cookies to disk before exiting.
249     platformSyncAllCookies([this] {
250         stopRunLoop();
251     });
252 }
253
254 void NetworkProcess::didCreateDownload()
255 {
256     disableTermination();
257 }
258
259 void NetworkProcess::didDestroyDownload()
260 {
261     enableTermination();
262 }
263
264 IPC::Connection* NetworkProcess::downloadProxyConnection()
265 {
266     return parentProcessConnection();
267 }
268
269 AuthenticationManager& NetworkProcess::downloadsAuthenticationManager()
270 {
271     return authenticationManager();
272 }
273
274 void NetworkProcess::lowMemoryHandler(Critical critical)
275 {
276     if (m_suppressMemoryPressureHandler)
277         return;
278
279     WTF::releaseFastMallocFreeMemory();
280 }
281
282 void NetworkProcess::initializeNetworkProcess(NetworkProcessCreationParameters&& parameters)
283 {
284 #if HAVE(SEC_KEY_PROXY)
285     WTF::setProcessPrivileges({ ProcessPrivilege::CanAccessRawCookies });
286 #else
287     WTF::setProcessPrivileges({ ProcessPrivilege::CanAccessRawCookies, ProcessPrivilege::CanAccessCredentials });
288 #endif
289     WebCore::NetworkStorageSession::permitProcessToUseCookieAPI(true);
290     platformInitializeNetworkProcess(parameters);
291
292     WTF::Thread::setCurrentThreadIsUserInitiated();
293     AtomicString::init();
294
295     m_suppressMemoryPressureHandler = parameters.shouldSuppressMemoryPressureHandler;
296     if (!m_suppressMemoryPressureHandler) {
297         auto& memoryPressureHandler = MemoryPressureHandler::singleton();
298         memoryPressureHandler.setLowMemoryHandler([this] (Critical critical, Synchronous) {
299             lowMemoryHandler(critical);
300         });
301         memoryPressureHandler.install();
302     }
303
304     m_diskCacheIsDisabledForTesting = parameters.shouldUseTestingNetworkSession;
305
306     setCacheModel(parameters.cacheModel);
307
308     setCanHandleHTTPSServerTrustEvaluation(parameters.canHandleHTTPSServerTrustEvaluation);
309
310     if (parameters.shouldUseTestingNetworkSession)
311         switchToNewTestingSession();
312
313     WebCore::RuntimeEnabledFeatures::sharedFeatures().setIsITPDatabaseEnabled(parameters.shouldEnableITPDatabase);
314
315     SandboxExtension::consumePermanently(parameters.defaultDataStoreParameters.networkSessionParameters.resourceLoadStatisticsDirectoryExtensionHandle);
316
317     auto sessionID = parameters.defaultDataStoreParameters.networkSessionParameters.sessionID;
318     setSession(sessionID, NetworkSession::create(*this, WTFMove(parameters.defaultDataStoreParameters.networkSessionParameters)));
319
320 #if ENABLE(INDEXED_DATABASE)
321     addIndexedDatabaseSession(sessionID, parameters.defaultDataStoreParameters.indexedDatabaseDirectory, parameters.defaultDataStoreParameters.indexedDatabaseDirectoryExtensionHandle);
322 #endif
323
324 #if ENABLE(SERVICE_WORKER)
325     if (parentProcessHasServiceWorkerEntitlement()) {
326         addServiceWorkerSession(PAL::SessionID::defaultSessionID(), parameters.serviceWorkerRegistrationDirectory, parameters.serviceWorkerRegistrationDirectoryExtensionHandle);
327
328         for (auto& scheme : parameters.urlSchemesServiceWorkersCanHandle)
329             registerURLSchemeServiceWorkersCanHandle(scheme);
330
331         m_shouldDisableServiceWorkerProcessTerminationDelay = parameters.shouldDisableServiceWorkerProcessTerminationDelay;
332     }
333 #endif
334
335     auto* defaultSession = networkSession(PAL::SessionID::defaultSessionID());
336     for (const auto& cookie : parameters.defaultDataStoreParameters.pendingCookies)
337         defaultSession->networkStorageSession().setCookie(cookie);
338
339     for (auto& supplement : m_supplements.values())
340         supplement->initialize(parameters);
341
342     for (auto& scheme : parameters.urlSchemesRegisteredAsSecure)
343         registerURLSchemeAsSecure(scheme);
344
345     for (auto& scheme : parameters.urlSchemesRegisteredAsBypassingContentSecurityPolicy)
346         registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
347
348     for (auto& scheme : parameters.urlSchemesRegisteredAsLocal)
349         registerURLSchemeAsLocal(scheme);
350
351     for (auto& scheme : parameters.urlSchemesRegisteredAsNoAccess)
352         registerURLSchemeAsNoAccess(scheme);
353
354     for (auto& scheme : parameters.urlSchemesRegisteredAsDisplayIsolated)
355         registerURLSchemeAsDisplayIsolated(scheme);
356
357     for (auto& scheme : parameters.urlSchemesRegisteredAsCORSEnabled)
358         registerURLSchemeAsCORSEnabled(scheme);
359
360     for (auto& scheme : parameters.urlSchemesRegisteredAsCanDisplayOnlyIfCanRequest)
361         registerURLSchemeAsCanDisplayOnlyIfCanRequest(scheme);
362
363     RELEASE_LOG(Process, "%p - NetworkProcess::initializeNetworkProcess: Presenting process = %d", this, WebCore::presentingApplicationPID());
364 }
365
366 void NetworkProcess::initializeConnection(IPC::Connection* connection)
367 {
368     AuxiliaryProcess::initializeConnection(connection);
369
370     // We give a chance for didClose() to get called on the main thread but forcefully call _exit() after a delay
371     // in case the main thread is unresponsive or didClose() takes too long.
372     connection->setDidCloseOnConnectionWorkQueueCallback(callExitSoon);
373
374     for (auto& supplement : m_supplements.values())
375         supplement->initializeConnection(connection);
376 }
377
378 void NetworkProcess::createNetworkConnectionToWebProcess(bool isServiceWorkerProcess, WebCore::SecurityOriginData&& securityOrigin)
379 {
380 #if USE(UNIX_DOMAIN_SOCKETS)
381     IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection();
382
383     auto connection = NetworkConnectionToWebProcess::create(*this, socketPair.server);
384     m_webProcessConnections.append(WTFMove(connection));
385
386     IPC::Attachment clientSocket(socketPair.client);
387     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientSocket), 0);
388 #elif OS(DARWIN)
389     // Create the listening port.
390     mach_port_t listeningPort = MACH_PORT_NULL;
391     auto kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort);
392     if (kr != KERN_SUCCESS) {
393         RELEASE_LOG_ERROR(Process, "NetworkProcess::createNetworkConnectionToWebProcess: Could not allocate mach port, error %x", kr);
394         CRASH();
395     }
396     if (!MACH_PORT_VALID(listeningPort)) {
397         RELEASE_LOG_ERROR(Process, "NetworkProcess::createNetworkConnectionToWebProcess: Could not allocate mach port, returned port was invalid");
398         CRASH();
399     }
400
401     // Create a listening connection.
402     auto connection = NetworkConnectionToWebProcess::create(*this, IPC::Connection::Identifier(listeningPort));
403     m_webProcessConnections.append(WTFMove(connection));
404
405     IPC::Attachment clientPort(listeningPort, MACH_MSG_TYPE_MAKE_SEND);
406     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientPort), 0);
407 #elif OS(WINDOWS)
408     IPC::Connection::Identifier serverIdentifier, clientIdentifier;
409     if (!IPC::Connection::createServerAndClientIdentifiers(serverIdentifier, clientIdentifier)) {
410         LOG_ERROR("Failed to create server and client identifiers");
411         CRASH();
412     }
413
414     auto connection = NetworkConnectionToWebProcess::create(*this, serverIdentifier);
415     m_webProcessConnections.append(WTFMove(connection));
416
417     IPC::Attachment clientSocket(clientIdentifier);
418     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientSocket), 0);
419 #else
420     notImplemented();
421 #endif
422
423     if (!m_webProcessConnections.isEmpty())
424         m_webProcessConnections.last()->setOnLineState(NetworkStateNotifier::singleton().onLine());
425     
426 #if ENABLE(SERVICE_WORKER)
427     if (isServiceWorkerProcess && !m_webProcessConnections.isEmpty()) {
428         ASSERT(parentProcessHasServiceWorkerEntitlement());
429         ASSERT(m_waitingForServerToContextProcessConnection);
430         auto contextConnection = WebSWServerToContextConnection::create(*this, securityOrigin, m_webProcessConnections.last()->connection());
431         auto addResult = m_serverToContextConnections.add(WTFMove(securityOrigin), contextConnection.copyRef());
432         ASSERT_UNUSED(addResult, addResult.isNewEntry);
433
434         m_waitingForServerToContextProcessConnection = false;
435
436         for (auto* server : SWServer::allServers())
437             server->serverToContextConnectionCreated(contextConnection);
438     }
439 #else
440     UNUSED_PARAM(isServiceWorkerProcess);
441     UNUSED_PARAM(securityOrigin);
442 #endif
443 }
444
445 void NetworkProcess::clearCachedCredentials()
446 {
447     defaultStorageSession().credentialStorage().clearCredentials();
448     if (auto* networkSession = this->networkSession(PAL::SessionID::defaultSessionID()))
449         networkSession->clearCredentials();
450     else
451         ASSERT_NOT_REACHED();
452 }
453
454 void NetworkProcess::addWebsiteDataStore(WebsiteDataStoreParameters&& parameters)
455 {
456 #if ENABLE(INDEXED_DATABASE)
457     addIndexedDatabaseSession(parameters.networkSessionParameters.sessionID, parameters.indexedDatabaseDirectory, parameters.indexedDatabaseDirectoryExtensionHandle);
458 #endif
459
460 #if ENABLE(SERVICE_WORKER)
461     if (parentProcessHasServiceWorkerEntitlement())
462         addServiceWorkerSession(parameters.networkSessionParameters.sessionID, parameters.serviceWorkerRegistrationDirectory, parameters.serviceWorkerRegistrationDirectoryExtensionHandle);
463 #endif
464
465     RemoteNetworkingContext::ensureWebsiteDataStoreSession(*this, WTFMove(parameters));
466 }
467
468 void NetworkProcess::switchToNewTestingSession()
469 {
470 #if PLATFORM(COCOA)
471     // Session name should be short enough for shared memory region name to be under the limit, otherwise sandbox rules won't work (see <rdar://problem/13642852>).
472     String sessionName = makeString("WebKit Test-", getCurrentProcessID());
473
474     auto session = adoptCF(WebCore::createPrivateStorageSession(sessionName.createCFString().get()));
475
476     RetainPtr<CFHTTPCookieStorageRef> cookieStorage;
477     if (WebCore::NetworkStorageSession::processMayUseCookieAPI()) {
478         ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies));
479         if (session)
480             cookieStorage = adoptCF(_CFURLStorageSessionCopyCookieStorage(kCFAllocatorDefault, session.get()));
481     }
482
483     m_defaultNetworkStorageSession = std::make_unique<WebCore::NetworkStorageSession>(PAL::SessionID::defaultSessionID(), WTFMove(session), WTFMove(cookieStorage));
484 #elif USE(SOUP)
485     m_defaultNetworkStorageSession = std::make_unique<WebCore::NetworkStorageSession>(PAL::SessionID::defaultSessionID(), std::make_unique<WebCore::SoupNetworkSession>());
486 #elif USE(CURL)
487     m_defaultNetworkStorageSession = std::make_unique<WebCore::NetworkStorageSession>(PAL::SessionID::defaultSessionID());
488 #endif
489 }
490
491 #if PLATFORM(COCOA)
492 void NetworkProcess::ensureSession(const PAL::SessionID& sessionID, const String& identifierBase, RetainPtr<CFHTTPCookieStorageRef>&& cookieStorage)
493 #else
494 void NetworkProcess::ensureSession(const PAL::SessionID& sessionID, const String& identifierBase)
495 #endif
496 {
497     ASSERT(sessionID != PAL::SessionID::defaultSessionID());
498
499     auto addResult = m_networkStorageSessions.add(sessionID, nullptr);
500     if (!addResult.isNewEntry)
501         return;
502
503 #if PLATFORM(COCOA)
504     RetainPtr<CFURLStorageSessionRef> storageSession;
505     RetainPtr<CFStringRef> cfIdentifier = String(identifierBase + ".PrivateBrowsing").createCFString();
506     if (sessionID.isEphemeral())
507         storageSession = adoptCF(createPrivateStorageSession(cfIdentifier.get()));
508     else
509         storageSession = WebCore::NetworkStorageSession::createCFStorageSessionForIdentifier(cfIdentifier.get());
510
511     if (NetworkStorageSession::processMayUseCookieAPI()) {
512         ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies));
513         if (!cookieStorage && storageSession)
514             cookieStorage = adoptCF(_CFURLStorageSessionCopyCookieStorage(kCFAllocatorDefault, storageSession.get()));
515     }
516
517     addResult.iterator->value = std::make_unique<NetworkStorageSession>(sessionID, WTFMove(storageSession), WTFMove(cookieStorage));
518 #elif USE(SOUP)
519     addResult.iterator->value = std::make_unique<NetworkStorageSession>(sessionID, std::make_unique<SoupNetworkSession>(sessionID));
520 #elif USE(CURL)
521     addResult.iterator->value = std::make_unique<NetworkStorageSession>(sessionID);
522 #endif
523 }
524
525 WebCore::NetworkStorageSession* NetworkProcess::storageSession(const PAL::SessionID& sessionID) const
526 {
527     if (sessionID == PAL::SessionID::defaultSessionID())
528         return &defaultStorageSession();
529     return m_networkStorageSessions.get(sessionID);
530 }
531
532 WebCore::NetworkStorageSession& NetworkProcess::defaultStorageSession() const
533 {
534     if (!m_defaultNetworkStorageSession)
535         m_defaultNetworkStorageSession = platformCreateDefaultStorageSession();
536     return *m_defaultNetworkStorageSession;
537 }
538
539 void NetworkProcess::forEachNetworkStorageSession(const Function<void(WebCore::NetworkStorageSession&)>& functor)
540 {
541     functor(defaultStorageSession());
542     for (auto& storageSession : m_networkStorageSessions.values())
543         functor(*storageSession);
544 }
545
546 NetworkSession* NetworkProcess::networkSession(const PAL::SessionID& sessionID) const
547 {
548     return m_networkSessions.get(sessionID);
549 }
550
551 void NetworkProcess::setSession(const PAL::SessionID& sessionID, Ref<NetworkSession>&& session)
552 {
553     m_networkSessions.set(sessionID, WTFMove(session));
554 }
555
556 void NetworkProcess::destroySession(const PAL::SessionID& sessionID)
557 {
558     ASSERT(sessionID != PAL::SessionID::defaultSessionID());
559
560     if (auto session = m_networkSessions.take(sessionID))
561         session->get().invalidateAndCancel();
562     m_networkStorageSessions.remove(sessionID);
563     m_sessionsControlledByAutomation.remove(sessionID);
564     CacheStorage::Engine::destroyEngine(*this, sessionID);
565
566 #if ENABLE(SERVICE_WORKER)
567     m_swServers.remove(sessionID);
568     m_swDatabasePaths.remove(sessionID);
569 #endif
570 }
571
572 #if ENABLE(RESOURCE_LOAD_STATISTICS)
573 void NetworkProcess::dumpResourceLoadStatistics(PAL::SessionID sessionID, CompletionHandler<void(String)>&& completionHandler)
574 {
575     if (auto* networkSession = this->networkSession(sessionID)) {
576         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
577             resourceLoadStatistics->dumpResourceLoadStatistics(WTFMove(completionHandler));
578         else
579             completionHandler({ });
580     } else {
581         ASSERT_NOT_REACHED();
582         completionHandler({ });
583     }
584 }
585
586 void NetworkProcess::updatePrevalentDomainsToBlockCookiesFor(PAL::SessionID sessionID, const Vector<RegistrableDomain>& domainsToBlock, CompletionHandler<void()>&& completionHandler)
587 {
588     if (auto* networkStorageSession = storageSession(sessionID))
589         networkStorageSession->setPrevalentDomainsToBlockCookiesFor(domainsToBlock);
590     completionHandler();
591 }
592
593 void NetworkProcess::isGrandfathered(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
594 {
595     if (auto* networkSession = this->networkSession(sessionID)) {
596         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
597             resourceLoadStatistics->isGrandfathered(domain, WTFMove(completionHandler));
598         else
599             completionHandler(false);
600     } else {
601         ASSERT_NOT_REACHED();
602         completionHandler(false);
603     }
604 }
605
606 void NetworkProcess::isPrevalentResource(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
607 {
608     if (auto* networkSession = this->networkSession(sessionID)) {
609         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
610             resourceLoadStatistics->isPrevalentResource(domain, WTFMove(completionHandler));
611         else
612             completionHandler(false);
613     } else {
614         ASSERT_NOT_REACHED();
615         completionHandler(false);
616     }
617 }
618
619 void NetworkProcess::isVeryPrevalentResource(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
620 {
621     if (auto* networkSession = this->networkSession(sessionID)) {
622         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
623             resourceLoadStatistics->isVeryPrevalentResource(domain, WTFMove(completionHandler));
624         else
625             completionHandler(false);
626     } else {
627         ASSERT_NOT_REACHED();
628         completionHandler(false);
629     }
630 }
631
632 void NetworkProcess::setAgeCapForClientSideCookies(PAL::SessionID sessionID, Optional<Seconds> seconds, CompletionHandler<void()>&& completionHandler)
633 {
634     if (auto* networkStorageSession = storageSession(sessionID))
635         networkStorageSession->setAgeCapForClientSideCookies(seconds);
636     completionHandler();
637 }
638
639 void NetworkProcess::setGrandfathered(PAL::SessionID sessionID, const RegistrableDomain& domain, bool isGrandfathered, CompletionHandler<void()>&& completionHandler)
640 {
641     if (auto* networkSession = this->networkSession(sessionID)) {
642         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
643             resourceLoadStatistics->setGrandfathered(domain, isGrandfathered, WTFMove(completionHandler));
644         else
645             completionHandler();
646     } else {
647         ASSERT_NOT_REACHED();
648         completionHandler();
649     }
650 }
651
652 void NetworkProcess::setPrevalentResource(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
653 {
654     if (auto* networkSession = this->networkSession(sessionID)) {
655         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
656             resourceLoadStatistics->setPrevalentResource(domain, WTFMove(completionHandler));
657         else
658             completionHandler();
659     } else {
660         ASSERT_NOT_REACHED();
661         completionHandler();
662     }
663 }
664
665 void NetworkProcess::setPrevalentResourceForDebugMode(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
666 {
667     if (auto* networkSession = this->networkSession(sessionID)) {
668         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
669             resourceLoadStatistics->setPrevalentResourceForDebugMode(domain, WTFMove(completionHandler));
670         else
671             completionHandler();
672     } else {
673         ASSERT_NOT_REACHED();
674         completionHandler();
675     }
676 }
677
678 void NetworkProcess::setVeryPrevalentResource(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
679 {
680     if (auto* networkSession = this->networkSession(sessionID)) {
681         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
682             resourceLoadStatistics->setVeryPrevalentResource(domain, WTFMove(completionHandler));
683         else
684             completionHandler();
685     } else {
686         ASSERT_NOT_REACHED();
687         completionHandler();
688     }
689 }
690
691 void NetworkProcess::clearPrevalentResource(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
692 {
693     if (auto* networkSession = this->networkSession(sessionID)) {
694         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
695             resourceLoadStatistics->clearPrevalentResource(domain, WTFMove(completionHandler));
696         else
697             completionHandler();
698     } else {
699         ASSERT_NOT_REACHED();
700         completionHandler();
701     }
702 }
703
704 void NetworkProcess::submitTelemetry(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
705 {
706     if (auto* networkSession = this->networkSession(sessionID)) {
707         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
708             resourceLoadStatistics->submitTelemetry(WTFMove(completionHandler));
709         else
710             completionHandler();
711     } else {
712         ASSERT_NOT_REACHED();
713         completionHandler();
714     }
715 }
716
717 void NetworkProcess::scheduleCookieBlockingUpdate(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
718 {
719     if (auto* networkSession = this->networkSession(sessionID)) {
720         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
721             resourceLoadStatistics->scheduleCookieBlockingUpdate(WTFMove(completionHandler));
722         else
723             completionHandler();
724     } else {
725         ASSERT_NOT_REACHED();
726         completionHandler();
727     }
728 }
729
730 void NetworkProcess::scheduleClearInMemoryAndPersistent(PAL::SessionID sessionID, Optional<WallTime> modifiedSince, ShouldGrandfatherStatistics shouldGrandfather, CompletionHandler<void()>&& completionHandler)
731 {
732     if (auto* networkSession = this->networkSession(sessionID)) {
733         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics()) {
734             if (modifiedSince)
735                 resourceLoadStatistics->scheduleClearInMemoryAndPersistent(modifiedSince.value(), shouldGrandfather, WTFMove(completionHandler));
736             else
737                 resourceLoadStatistics->scheduleClearInMemoryAndPersistent(shouldGrandfather, WTFMove(completionHandler));
738         } else
739             completionHandler();
740     } else {
741         ASSERT_NOT_REACHED();
742         completionHandler();
743     }
744 }
745
746 void NetworkProcess::resetParametersToDefaultValues(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
747 {
748     if (auto* networkSession = this->networkSession(sessionID)) {
749         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
750             resourceLoadStatistics->resetParametersToDefaultValues(WTFMove(completionHandler));
751         else
752             completionHandler();
753     } else {
754         ASSERT_NOT_REACHED();
755         completionHandler();
756     }
757 }
758
759 void NetworkProcess::scheduleStatisticsAndDataRecordsProcessing(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
760 {
761     if (auto* networkSession = this->networkSession(sessionID)) {
762         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
763             resourceLoadStatistics->scheduleStatisticsAndDataRecordsProcessing(WTFMove(completionHandler));
764         else
765             completionHandler();
766     } else {
767         ASSERT_NOT_REACHED();
768         completionHandler();
769     }
770 }
771
772 void NetworkProcess::setNotifyPagesWhenDataRecordsWereScanned(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
773 {
774     if (auto* networkSession = this->networkSession(sessionID)) {
775         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
776             resourceLoadStatistics->setNotifyPagesWhenDataRecordsWereScanned(value, WTFMove(completionHandler));
777         else
778             completionHandler();
779     } else {
780         ASSERT_NOT_REACHED();
781         completionHandler();
782     }
783 }
784
785 void NetworkProcess::setNotifyPagesWhenTelemetryWasCaptured(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
786 {
787     if (auto* networkSession = this->networkSession(sessionID)) {
788         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
789             resourceLoadStatistics->setNotifyPagesWhenTelemetryWasCaptured(value, WTFMove(completionHandler));
790         else
791             completionHandler();
792     } else {
793         ASSERT_NOT_REACHED();
794         completionHandler();
795     }
796 }
797
798 void NetworkProcess::setSubframeUnderTopFrameDomain(PAL::SessionID sessionID, const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void()>&& completionHandler)
799 {
800     if (auto* networkSession = this->networkSession(sessionID)) {
801         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
802             resourceLoadStatistics->setSubframeUnderTopFrameDomain(subFrameDomain, topFrameDomain, WTFMove(completionHandler));
803         else
804             completionHandler();
805     } else {
806         ASSERT_NOT_REACHED();
807         completionHandler();
808     }
809 }
810
811 void NetworkProcess::isRegisteredAsRedirectingTo(PAL::SessionID sessionID, const RegistrableDomain& domainRedirectedFrom, const RegistrableDomain& domainRedirectedTo, CompletionHandler<void(bool)>&& completionHandler)
812 {
813     if (auto* networkSession = this->networkSession(sessionID)) {
814         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
815             resourceLoadStatistics->isRegisteredAsRedirectingTo(domainRedirectedFrom, domainRedirectedTo, WTFMove(completionHandler));
816         else
817             completionHandler(false);
818     } else {
819         ASSERT_NOT_REACHED();
820         completionHandler(false);
821     }
822 }
823
824 void NetworkProcess::isRegisteredAsSubFrameUnder(PAL::SessionID sessionID, const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void(bool)>&& completionHandler)
825 {
826     if (auto* networkSession = this->networkSession(sessionID)) {
827         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
828             resourceLoadStatistics->isRegisteredAsSubFrameUnder(subFrameDomain, topFrameDomain, WTFMove(completionHandler));
829         else
830             completionHandler(false);
831     } else {
832         ASSERT_NOT_REACHED();
833         completionHandler(false);
834     }
835 }
836
837 void NetworkProcess::setSubresourceUnderTopFrameDomain(PAL::SessionID sessionID, const RegistrableDomain& subresourceDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void()>&& completionHandler)
838 {
839     if (auto* networkSession = this->networkSession(sessionID)) {
840         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
841             resourceLoadStatistics->setSubresourceUnderTopFrameDomain(subresourceDomain, topFrameDomain, WTFMove(completionHandler));
842         else
843             completionHandler();
844     } else {
845         ASSERT_NOT_REACHED();
846         completionHandler();
847     }
848 }
849
850 void NetworkProcess::setSubresourceUniqueRedirectTo(PAL::SessionID sessionID, const RegistrableDomain& subresourceDomain, const RegistrableDomain& domainRedirectedTo, CompletionHandler<void()>&& completionHandler)
851 {
852     if (auto* networkSession = this->networkSession(sessionID)) {
853         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
854             resourceLoadStatistics->setSubresourceUniqueRedirectTo(subresourceDomain, domainRedirectedTo, WTFMove(completionHandler));
855         else
856             completionHandler();
857     } else {
858         ASSERT_NOT_REACHED();
859         completionHandler();
860     }
861 }
862
863 void NetworkProcess::setSubresourceUniqueRedirectFrom(PAL::SessionID sessionID, const RegistrableDomain& subresourceDomain, const RegistrableDomain& domainRedirectedFrom, CompletionHandler<void()>&& completionHandler)
864 {
865     if (auto* networkSession = this->networkSession(sessionID)) {
866         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
867             resourceLoadStatistics->setSubresourceUniqueRedirectFrom(subresourceDomain, domainRedirectedFrom, WTFMove(completionHandler));
868         else
869             completionHandler();
870     } else {
871         ASSERT_NOT_REACHED();
872         completionHandler();
873     }
874 }
875
876 void NetworkProcess::isRegisteredAsSubresourceUnder(PAL::SessionID sessionID, const RegistrableDomain& subresourceDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void(bool)>&& completionHandler)
877 {
878     if (auto* networkSession = this->networkSession(sessionID)) {
879         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
880             resourceLoadStatistics->isRegisteredAsSubresourceUnder(subresourceDomain, topFrameDomain, WTFMove(completionHandler));
881         else
882             completionHandler(false);
883     } else {
884         ASSERT_NOT_REACHED();
885         completionHandler(false);
886     }
887 }
888
889 void NetworkProcess::setTopFrameUniqueRedirectTo(PAL::SessionID sessionID, const RegistrableDomain& topFrameDomain, const RegistrableDomain& domainRedirectedTo, CompletionHandler<void()>&& completionHandler)
890 {
891     if (auto* networkSession = this->networkSession(sessionID)) {
892         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
893             resourceLoadStatistics->setTopFrameUniqueRedirectTo(topFrameDomain, domainRedirectedTo, WTFMove(completionHandler));
894         else
895             completionHandler();
896     } else {
897         ASSERT_NOT_REACHED();
898         completionHandler();
899     }
900 }
901
902 void NetworkProcess::setTopFrameUniqueRedirectFrom(PAL::SessionID sessionID, const RegistrableDomain& topFrameDomain, const RegistrableDomain& domainRedirectedFrom, CompletionHandler<void()>&& completionHandler)
903 {
904     if (auto* networkSession = this->networkSession(sessionID)) {
905         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
906             resourceLoadStatistics->setTopFrameUniqueRedirectFrom(topFrameDomain, domainRedirectedFrom, WTFMove(completionHandler));
907         else
908             completionHandler();
909     } else {
910         ASSERT_NOT_REACHED();
911         completionHandler();
912     }
913 }
914     
915     
916 void NetworkProcess::setLastSeen(PAL::SessionID sessionID, const RegistrableDomain& domain, Seconds seconds, CompletionHandler<void()>&& completionHandler)
917 {
918     if (auto* networkSession = this->networkSession(sessionID)) {
919         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
920             resourceLoadStatistics->setLastSeen(domain, seconds, WTFMove(completionHandler));
921         else
922             completionHandler();
923     } else {
924         ASSERT_NOT_REACHED();
925         completionHandler();
926     }
927 }
928
929 void NetworkProcess::hasStorageAccessForFrame(PAL::SessionID sessionID, const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, uint64_t frameID, uint64_t pageID, CompletionHandler<void(bool)>&& completionHandler)
930 {
931     bool hasStorageAccess = false;
932     if (auto* networkStorageSession = storageSession(sessionID))
933         hasStorageAccess = networkStorageSession->hasStorageAccess(subFrameDomain, topFrameDomain, frameID, pageID);
934     else
935         ASSERT_NOT_REACHED();
936
937     completionHandler(hasStorageAccess);
938 }
939
940 void NetworkProcess::getAllStorageAccessEntries(PAL::SessionID sessionID, CompletionHandler<void(Vector<String> domains)>&& completionHandler)
941 {
942     if (auto* networkStorageSession = storageSession(sessionID))
943         completionHandler(networkStorageSession->getAllStorageAccessEntries());
944     else {
945         ASSERT_NOT_REACHED();
946         completionHandler({ });
947     }
948 }
949
950 void NetworkProcess::hasStorageAccess(PAL::SessionID sessionID, const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, Optional<uint64_t> frameID, uint64_t pageID, CompletionHandler<void(bool)>&& completionHandler)
951 {
952     if (auto* networkSession = this->networkSession(sessionID)) {
953         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
954             resourceLoadStatistics->hasStorageAccess(subFrameDomain, topFrameDomain, frameID, pageID, WTFMove(completionHandler));
955         else
956             completionHandler(false);
957     } else {
958         ASSERT_NOT_REACHED();
959         completionHandler(false);
960     }
961 }
962
963 void NetworkProcess::requestStorageAccess(PAL::SessionID sessionID, const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, Optional<uint64_t> frameID, uint64_t pageID, bool promptEnabled, CompletionHandler<void(StorageAccessStatus)>&& completionHandler)
964 {
965     if (auto* networkSession = this->networkSession(sessionID)) {
966         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
967             resourceLoadStatistics->requestStorageAccess(subFrameDomain, topFrameDomain, frameID.value(), pageID, promptEnabled, WTFMove(completionHandler));
968         else
969             completionHandler(StorageAccessStatus::CannotRequestAccess);
970     } else {
971         ASSERT_NOT_REACHED();
972         completionHandler(StorageAccessStatus::CannotRequestAccess);
973     }
974 }
975
976 void NetworkProcess::requestStorageAccessGranted(PAL::SessionID sessionID, const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, uint64_t frameID, uint64_t pageID, bool promptEnabled, CompletionHandler<void(bool)>&& completionHandler)
977 {
978     if (auto* networkSession = this->networkSession(sessionID)) {
979         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
980             resourceLoadStatistics->requestStorageAccessGranted(subFrameDomain, topFrameDomain, frameID, pageID, promptEnabled, WTFMove(completionHandler));
981         else
982             completionHandler(false);
983     } else {
984         ASSERT_NOT_REACHED();
985         completionHandler(false);
986     }
987 }
988
989 void NetworkProcess::grantStorageAccess(PAL::SessionID sessionID, const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, Optional<uint64_t> frameID, uint64_t pageID, bool userWasPrompted, CompletionHandler<void(bool)>&& completionHandler)
990 {
991     // FIXME: We should not accept an optional frame ID since we call frameID.value() unconditionally.
992     if (!frameID) {
993         completionHandler(false);
994         return;
995     }
996
997     if (auto* networkSession = this->networkSession(sessionID)) {
998         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
999             resourceLoadStatistics->grantStorageAccess(subFrameDomain, topFrameDomain, frameID.value(), pageID, userWasPrompted, WTFMove(completionHandler));
1000         else
1001             completionHandler(false);
1002     } else {
1003         ASSERT_NOT_REACHED();
1004         completionHandler(false);
1005     }
1006 }
1007
1008 void NetworkProcess::logFrameNavigation(PAL::SessionID sessionID, const RegistrableDomain& targetDomain, const RegistrableDomain& topFrameDomain, const RegistrableDomain& sourceDomain, bool isRedirect, bool isMainFrame)
1009 {
1010     if (auto* networkSession = this->networkSession(sessionID)) {
1011         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1012             resourceLoadStatistics->logFrameNavigation(targetDomain, topFrameDomain, sourceDomain, isRedirect, isMainFrame);
1013     } else
1014         ASSERT_NOT_REACHED();
1015 }
1016
1017 void NetworkProcess::logUserInteraction(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
1018 {
1019     if (auto* networkSession = this->networkSession(sessionID)) {
1020         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1021             resourceLoadStatistics->logUserInteraction(domain, WTFMove(completionHandler));
1022         else
1023             completionHandler();
1024     } else {
1025         ASSERT_NOT_REACHED();
1026         completionHandler();
1027     }
1028 }
1029
1030 void NetworkProcess::hadUserInteraction(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
1031 {
1032     if (auto* networkSession = this->networkSession(sessionID)) {
1033         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1034             resourceLoadStatistics->hasHadUserInteraction(domain, WTFMove(completionHandler));
1035         else
1036             completionHandler(false);
1037     } else {
1038         ASSERT_NOT_REACHED();
1039         completionHandler(false);
1040     }
1041 }
1042
1043 void NetworkProcess::clearUserInteraction(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
1044 {
1045     if (auto* networkSession = this->networkSession(sessionID)) {
1046         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1047             resourceLoadStatistics->clearUserInteraction(domain, WTFMove(completionHandler));
1048         else
1049             completionHandler();
1050     } else {
1051         ASSERT_NOT_REACHED();
1052         completionHandler();
1053     }
1054 }
1055
1056 void NetworkProcess::removeAllStorageAccess(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
1057 {
1058     if (auto* networkStorageSession = storageSession(sessionID))
1059         networkStorageSession->removeAllStorageAccess();
1060     else
1061         ASSERT_NOT_REACHED();
1062     completionHandler();
1063 }
1064
1065 void NetworkProcess::removePrevalentDomains(PAL::SessionID sessionID, const Vector<RegistrableDomain>& domains)
1066 {
1067     if (auto* networkStorageSession = storageSession(sessionID))
1068         networkStorageSession->removePrevalentDomains(domains);
1069 }
1070
1071 void NetworkProcess::setCacheMaxAgeCapForPrevalentResources(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
1072 {
1073     if (auto* networkStorageSession = storageSession(sessionID))
1074         networkStorageSession->setCacheMaxAgeCapForPrevalentResources(Seconds { seconds });
1075     else
1076         ASSERT_NOT_REACHED();
1077     completionHandler();
1078 }
1079
1080 void NetworkProcess::setGrandfatheringTime(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
1081 {
1082     if (auto* networkSession = this->networkSession(sessionID)) {
1083         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1084             resourceLoadStatistics->setGrandfatheringTime(seconds, WTFMove(completionHandler));
1085         else
1086             completionHandler();
1087     } else {
1088         ASSERT_NOT_REACHED();
1089         completionHandler();
1090     }
1091 }
1092
1093 void NetworkProcess::setMaxStatisticsEntries(PAL::SessionID sessionID, uint64_t maximumEntryCount, CompletionHandler<void()>&& completionHandler)
1094 {
1095     if (auto* networkSession = this->networkSession(sessionID)) {
1096         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1097             resourceLoadStatistics->setMaxStatisticsEntries(maximumEntryCount, WTFMove(completionHandler));
1098         else
1099             completionHandler();
1100     } else {
1101         ASSERT_NOT_REACHED();
1102         completionHandler();
1103     }
1104 }
1105
1106 void NetworkProcess::setMinimumTimeBetweenDataRecordsRemoval(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
1107 {
1108     if (auto* networkSession = this->networkSession(sessionID)) {
1109         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1110             resourceLoadStatistics->setMinimumTimeBetweenDataRecordsRemoval(seconds, WTFMove(completionHandler));
1111         else
1112             completionHandler();
1113     } else {
1114         ASSERT_NOT_REACHED();
1115         completionHandler();
1116     }
1117 }
1118
1119 void NetworkProcess::setPruneEntriesDownTo(PAL::SessionID sessionID, uint64_t pruneTargetCount, CompletionHandler<void()>&& completionHandler)
1120 {
1121     if (auto* networkSession = this->networkSession(sessionID)) {
1122         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1123             resourceLoadStatistics->setPruneEntriesDownTo(pruneTargetCount, WTFMove(completionHandler));
1124         else
1125             completionHandler();
1126     } else {
1127         ASSERT_NOT_REACHED();
1128         completionHandler();
1129     }
1130 }
1131
1132 void NetworkProcess::setTimeToLiveUserInteraction(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
1133 {
1134     if (auto* networkSession = this->networkSession(sessionID)) {
1135         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1136             resourceLoadStatistics->setTimeToLiveUserInteraction(seconds, WTFMove(completionHandler));
1137         else
1138             completionHandler();
1139     } else {
1140         ASSERT_NOT_REACHED();
1141         completionHandler();
1142     }
1143 }
1144
1145 void NetworkProcess::setShouldClassifyResourcesBeforeDataRecordsRemoval(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
1146 {
1147     if (auto* networkSession = this->networkSession(sessionID)) {
1148         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1149             resourceLoadStatistics->setShouldClassifyResourcesBeforeDataRecordsRemoval(value, WTFMove(completionHandler));
1150         else
1151             completionHandler();
1152     } else {
1153         ASSERT_NOT_REACHED();
1154         completionHandler();
1155     }
1156 }
1157
1158 void NetworkProcess::setResourceLoadStatisticsEnabled(bool enabled)
1159 {
1160     for (auto& networkSession : m_networkSessions.values())
1161         networkSession.get().setResourceLoadStatisticsEnabled(enabled);
1162 }
1163
1164 void NetworkProcess::setResourceLoadStatisticsDebugMode(PAL::SessionID sessionID, bool debugMode, CompletionHandler<void()>&& completionHandler)
1165 {
1166     if (auto* networkSession = this->networkSession(sessionID)) {
1167         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1168             resourceLoadStatistics->setResourceLoadStatisticsDebugMode(debugMode, WTFMove(completionHandler));
1169         else
1170             completionHandler();
1171     } else {
1172         ASSERT_NOT_REACHED();
1173         completionHandler();
1174     }
1175 }
1176
1177 void NetworkProcess::resetCacheMaxAgeCapForPrevalentResources(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
1178 {
1179     if (auto* networkStorageSession = storageSession(sessionID))
1180         networkStorageSession->resetCacheMaxAgeCapForPrevalentResources();
1181     else
1182         ASSERT_NOT_REACHED();
1183     completionHandler();
1184 }
1185
1186 void NetworkProcess::committedCrossSiteLoadWithLinkDecoration(PAL::SessionID sessionID, const RegistrableDomain& fromDomain, const RegistrableDomain& toDomain, uint64_t pageID)
1187 {
1188     if (auto* networkStorageSession = storageSession(sessionID))
1189         networkStorageSession->committedCrossSiteLoadWithLinkDecoration(fromDomain, toDomain, pageID);
1190     else
1191         ASSERT_NOT_REACHED();
1192 }
1193
1194 void NetworkProcess::resetCrossSiteLoadsWithLinkDecorationForTesting(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
1195 {
1196     if (auto* networkStorageSession = storageSession(sessionID))
1197         networkStorageSession->resetCrossSiteLoadsWithLinkDecorationForTesting();
1198     else
1199         ASSERT_NOT_REACHED();
1200     completionHandler();
1201 }
1202 #endif // ENABLE(RESOURCE_LOAD_STATISTICS)
1203
1204 bool NetworkProcess::sessionIsControlledByAutomation(PAL::SessionID sessionID) const
1205 {
1206     return m_sessionsControlledByAutomation.contains(sessionID);
1207 }
1208
1209 void NetworkProcess::setSessionIsControlledByAutomation(PAL::SessionID sessionID, bool controlled)
1210 {
1211     if (controlled)
1212         m_sessionsControlledByAutomation.add(sessionID);
1213     else
1214         m_sessionsControlledByAutomation.remove(sessionID);
1215 }
1216
1217 static void fetchDiskCacheEntries(NetworkCache::Cache* cache, PAL::SessionID sessionID, OptionSet<WebsiteDataFetchOption> fetchOptions, CompletionHandler<void(Vector<WebsiteData::Entry>)>&& completionHandler)
1218 {
1219     if (!cache) {
1220         RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler)] () mutable {
1221             completionHandler({ });
1222         });
1223         return;
1224     }
1225     
1226     HashMap<SecurityOriginData, uint64_t> originsAndSizes;
1227     cache->traverse([fetchOptions, completionHandler = WTFMove(completionHandler), originsAndSizes = WTFMove(originsAndSizes)](auto* traversalEntry) mutable {
1228         if (!traversalEntry) {
1229             Vector<WebsiteData::Entry> entries;
1230
1231             for (auto& originAndSize : originsAndSizes)
1232                 entries.append(WebsiteData::Entry { originAndSize.key, WebsiteDataType::DiskCache, originAndSize.value });
1233
1234             RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), entries = WTFMove(entries)] () mutable {
1235                 completionHandler(entries);
1236             });
1237
1238             return;
1239         }
1240
1241         auto url = traversalEntry->entry.response().url();
1242         auto result = originsAndSizes.add({url.protocol().toString(), url.host().toString(), url.port()}, 0);
1243
1244         if (fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes))
1245             result.iterator->value += traversalEntry->entry.sourceStorageRecord().header.size() + traversalEntry->recordInfo.bodySize;
1246     });
1247 }
1248
1249 void NetworkProcess::fetchWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, uint64_t callbackID)
1250 {
1251     struct CallbackAggregator final : public ThreadSafeRefCounted<CallbackAggregator> {
1252         explicit CallbackAggregator(Function<void (WebsiteData)>&& completionHandler)
1253             : m_completionHandler(WTFMove(completionHandler))
1254         {
1255         }
1256
1257         ~CallbackAggregator()
1258         {
1259             RunLoop::main().dispatch([completionHandler = WTFMove(m_completionHandler), websiteData = WTFMove(m_websiteData)] () mutable {
1260                 completionHandler(websiteData);
1261             });
1262         }
1263
1264         CompletionHandler<void(WebsiteData)> m_completionHandler;
1265         WebsiteData m_websiteData;
1266     };
1267
1268     auto callbackAggregator = adoptRef(*new CallbackAggregator([this, callbackID] (WebsiteData websiteData) {
1269         parentProcessConnection()->send(Messages::NetworkProcessProxy::DidFetchWebsiteData(callbackID, websiteData), 0);
1270     }));
1271
1272     if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
1273         if (auto* networkStorageSession = storageSession(sessionID))
1274             networkStorageSession->getHostnamesWithCookies(callbackAggregator->m_websiteData.hostNamesWithCookies);
1275     }
1276
1277     if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
1278         if (storageSession(sessionID))
1279             callbackAggregator->m_websiteData.originsWithCredentials = storageSession(sessionID)->credentialStorage().originsWithCredentials();
1280     }
1281
1282     if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) {
1283         CacheStorage::Engine::fetchEntries(*this, sessionID, fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes), [callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
1284             callbackAggregator->m_websiteData.entries.appendVector(entries);
1285         });
1286     }
1287
1288 #if PLATFORM(COCOA)
1289     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
1290         if (auto* networkStorageSession = storageSession(sessionID))
1291             getHostNamesWithHSTSCache(*networkStorageSession, callbackAggregator->m_websiteData.hostNamesWithHSTSCache);
1292     }
1293 #endif
1294
1295 #if ENABLE(INDEXED_DATABASE)
1296     auto path = m_idbDatabasePaths.get(sessionID);
1297     if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases)) {
1298         // FIXME: Pick the right database store based on the session ID.
1299         postStorageTask(CrossThreadTask([this, callbackAggregator = callbackAggregator.copyRef(), path = WTFMove(path)]() mutable {
1300             RunLoop::main().dispatch([callbackAggregator = WTFMove(callbackAggregator), securityOrigins = indexedDatabaseOrigins(path)] {
1301                 for (const auto& securityOrigin : securityOrigins)
1302                     callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::IndexedDBDatabases, 0 });
1303             });
1304         }));
1305     }
1306 #endif
1307
1308 #if ENABLE(SERVICE_WORKER)
1309     path = m_swDatabasePaths.get(sessionID);
1310     if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations)) {
1311         swServerForSession(sessionID).getOriginsWithRegistrations([callbackAggregator = callbackAggregator.copyRef()](const HashSet<SecurityOriginData>& securityOrigins) mutable {
1312             for (auto& origin : securityOrigins)
1313                 callbackAggregator->m_websiteData.entries.append({ origin, WebsiteDataType::ServiceWorkerRegistrations, 0 });
1314         });
1315     }
1316 #endif
1317
1318     if (websiteDataTypes.contains(WebsiteDataType::DiskCache)) {
1319         fetchDiskCacheEntries(cache(), sessionID, fetchOptions, [callbackAggregator = WTFMove(callbackAggregator)](auto entries) mutable {
1320             callbackAggregator->m_websiteData.entries.appendVector(entries);
1321         });
1322     }
1323 }
1324
1325 void NetworkProcess::deleteWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, WallTime modifiedSince, uint64_t callbackID)
1326 {
1327 #if PLATFORM(COCOA)
1328     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
1329         if (auto* networkStorageSession = storageSession(sessionID))
1330             clearHSTSCache(*networkStorageSession, modifiedSince);
1331     }
1332 #endif
1333
1334     if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
1335         if (auto* networkStorageSession = storageSession(sessionID))
1336             networkStorageSession->deleteAllCookiesModifiedSince(modifiedSince);
1337     }
1338
1339     if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
1340         if (auto* session = storageSession(sessionID))
1341             session->credentialStorage().clearCredentials();
1342     }
1343
1344     auto clearTasksHandler = WTF::CallbackAggregator::create([this, callbackID] {
1345         parentProcessConnection()->send(Messages::NetworkProcessProxy::DidDeleteWebsiteData(callbackID), 0);
1346     });
1347
1348     if (websiteDataTypes.contains(WebsiteDataType::DOMCache))
1349         CacheStorage::Engine::clearAllCaches(*this, sessionID, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1350
1351 #if ENABLE(INDEXED_DATABASE)
1352     if (websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases) && !sessionID.isEphemeral())
1353         idbServer(sessionID).closeAndDeleteDatabasesModifiedSince(modifiedSince, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1354 #endif
1355
1356 #if ENABLE(SERVICE_WORKER)
1357     if (websiteDataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations) && !sessionID.isEphemeral())
1358         swServerForSession(sessionID).clearAll([clearTasksHandler = clearTasksHandler.copyRef()] { });
1359 #endif
1360
1361 #if ENABLE(RESOURCE_LOAD_STATISTICS)
1362     if (websiteDataTypes.contains(WebsiteDataType::ResourceLoadStatistics)) {
1363         if (auto* networkSession = this->networkSession(sessionID)) {
1364             if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics()) {
1365                 auto deletedTypesRaw = websiteDataTypes.toRaw();
1366                 auto monitoredTypesRaw = WebResourceLoadStatisticsStore::monitoredDataTypes().toRaw();
1367                 
1368                 // If we are deleting all of the data types that the resource load statistics store monitors
1369                 // we do not need to re-grandfather old data.
1370                 auto shouldGrandfather = ((monitoredTypesRaw & deletedTypesRaw) == monitoredTypesRaw) ? ShouldGrandfatherStatistics::No : ShouldGrandfatherStatistics::Yes;
1371                 
1372                 resourceLoadStatistics->scheduleClearInMemoryAndPersistent(modifiedSince, shouldGrandfather, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1373             }
1374         }
1375     }
1376 #endif
1377
1378     if (websiteDataTypes.contains(WebsiteDataType::DiskCache) && !sessionID.isEphemeral())
1379         clearDiskCache(modifiedSince, [clearTasksHandler = WTFMove(clearTasksHandler)] { });
1380 }
1381
1382 static void clearDiskCacheEntries(NetworkCache::Cache* cache, const Vector<SecurityOriginData>& origins, CompletionHandler<void()>&& completionHandler)
1383 {
1384     if (!cache) {
1385         RunLoop::main().dispatch(WTFMove(completionHandler));
1386         return;
1387     }
1388
1389     HashSet<RefPtr<SecurityOrigin>> originsToDelete;
1390     for (auto& origin : origins)
1391         originsToDelete.add(origin.securityOrigin());
1392
1393     Vector<NetworkCache::Key> cacheKeysToDelete;
1394     cache->traverse([cache, completionHandler = WTFMove(completionHandler), originsToDelete = WTFMove(originsToDelete), cacheKeysToDelete = WTFMove(cacheKeysToDelete)](auto* traversalEntry) mutable {
1395         if (traversalEntry) {
1396             if (originsToDelete.contains(SecurityOrigin::create(traversalEntry->entry.response().url())))
1397                 cacheKeysToDelete.append(traversalEntry->entry.key());
1398             return;
1399         }
1400
1401         cache->remove(cacheKeysToDelete, WTFMove(completionHandler));
1402         return;
1403     });
1404 }
1405
1406 void NetworkProcess::deleteWebsiteDataForOrigins(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, const Vector<SecurityOriginData>& originDatas, const Vector<String>& cookieHostNames, const Vector<String>& HSTSCacheHostNames, uint64_t callbackID)
1407 {
1408     if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
1409         if (auto* networkStorageSession = storageSession(sessionID))
1410             networkStorageSession->deleteCookiesForHostnames(cookieHostNames);
1411     }
1412
1413 #if PLATFORM(COCOA)
1414     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
1415         if (auto* networkStorageSession = storageSession(sessionID))
1416             deleteHSTSCacheForHostNames(*networkStorageSession, HSTSCacheHostNames);
1417     }
1418 #endif
1419
1420     auto clearTasksHandler = WTF::CallbackAggregator::create([this, callbackID] {
1421         parentProcessConnection()->send(Messages::NetworkProcessProxy::DidDeleteWebsiteDataForOrigins(callbackID), 0);
1422     });
1423
1424     if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) {
1425         for (auto& originData : originDatas)
1426             CacheStorage::Engine::clearCachesForOrigin(*this, sessionID, SecurityOriginData { originData }, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1427     }
1428
1429 #if ENABLE(INDEXED_DATABASE)
1430     if (websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases) && !sessionID.isEphemeral())
1431         idbServer(sessionID).closeAndDeleteDatabasesForOrigins(originDatas, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1432 #endif
1433
1434 #if ENABLE(SERVICE_WORKER)
1435     if (websiteDataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations) && !sessionID.isEphemeral()) {
1436         auto& server = swServerForSession(sessionID);
1437         for (auto& originData : originDatas)
1438             server.clear(originData, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1439     }
1440 #endif
1441
1442     if (websiteDataTypes.contains(WebsiteDataType::DiskCache) && !sessionID.isEphemeral())
1443         clearDiskCacheEntries(cache(), originDatas, [clearTasksHandler = WTFMove(clearTasksHandler)] { });
1444 }
1445
1446 #if ENABLE(RESOURCE_LOAD_STATISTICS)
1447 static Vector<String> filterForRegistrableDomains(const Vector<RegistrableDomain>& registrableDomains, const HashSet<String>& foundValues)
1448 {
1449     Vector<String> result;
1450     for (const auto& domain : registrableDomains) {
1451         if (foundValues.contains(domain.string()))
1452             result.append(domain.string());
1453     }
1454     
1455     return result;
1456 }
1457
1458 static Vector<WebsiteData::Entry> filterForRegistrableDomains(const Vector<RegistrableDomain>& registrableDomains, const Vector<WebsiteData::Entry>& foundValues)
1459 {
1460     Vector<WebsiteData::Entry> result;
1461     for (const auto& value : foundValues) {
1462         if (registrableDomains.contains(RegistrableDomain::uncheckedCreateFromHost(value.origin.host)))
1463             result.append(value);
1464     }
1465     
1466     return result;
1467 }
1468
1469 void NetworkProcess::deleteWebsiteDataForRegistrableDomainsInAllPersistentDataStores(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, Vector<RegistrableDomain>&& domains, bool shouldNotifyPage, CompletionHandler<void(const HashSet<RegistrableDomain>&)>&& completionHandler)
1470 {
1471     OptionSet<WebsiteDataFetchOption> fetchOptions = WebsiteDataFetchOption::DoNotCreateProcesses;
1472
1473     struct CallbackAggregator final : public ThreadSafeRefCounted<CallbackAggregator> {
1474         explicit CallbackAggregator(CompletionHandler<void(const HashSet<RegistrableDomain>&)>&& completionHandler)
1475             : m_completionHandler(WTFMove(completionHandler))
1476         {
1477         }
1478         
1479         ~CallbackAggregator()
1480         {
1481             RunLoop::main().dispatch([completionHandler = WTFMove(m_completionHandler), websiteData = WTFMove(m_websiteData)] () mutable {
1482                 HashSet<RegistrableDomain> domains;
1483                 for (const auto& hostnameWithCookies : websiteData.hostNamesWithCookies)
1484                     domains.add(RegistrableDomain::uncheckedCreateFromHost(hostnameWithCookies));
1485
1486                 for (const auto& hostnameWithHSTS : websiteData.hostNamesWithHSTSCache)
1487                     domains.add(RegistrableDomain::uncheckedCreateFromHost(hostnameWithHSTS));
1488
1489                 for (const auto& entry : websiteData.entries)
1490                     domains.add(RegistrableDomain::uncheckedCreateFromHost(entry.origin.host));
1491
1492                 completionHandler(domains);
1493             });
1494         }
1495         
1496         CompletionHandler<void(const HashSet<RegistrableDomain>&)> m_completionHandler;
1497         WebsiteData m_websiteData;
1498     };
1499     
1500     auto callbackAggregator = adoptRef(*new CallbackAggregator([this, completionHandler = WTFMove(completionHandler), shouldNotifyPage] (const HashSet<RegistrableDomain>& domainsWithData) mutable {
1501         if (shouldNotifyPage)
1502             parentProcessConnection()->send(Messages::NetworkProcessProxy::NotifyWebsiteDataDeletionForRegistrableDomainsFinished(), 0);
1503         
1504         RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), domainsWithData = crossThreadCopy(domainsWithData)] () mutable {
1505             completionHandler(domainsWithData);
1506         });
1507     }));
1508
1509     auto& websiteDataStore = callbackAggregator->m_websiteData;
1510
1511     Vector<String> hostnamesWithCookiesToDelete;
1512     if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
1513         if (auto* networkStorageSession = storageSession(sessionID)) {
1514             networkStorageSession->getHostnamesWithCookies(websiteDataStore.hostNamesWithCookies);
1515             hostnamesWithCookiesToDelete = filterForRegistrableDomains(domains, websiteDataStore.hostNamesWithCookies);
1516             networkStorageSession->deleteCookiesForHostnames(hostnamesWithCookiesToDelete);
1517         }
1518     }
1519
1520     Vector<String> hostnamesWithHSTSToDelete;
1521 #if PLATFORM(COCOA)
1522     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
1523         if (auto* networkStorageSession = storageSession(sessionID)) {
1524             getHostNamesWithHSTSCache(*networkStorageSession, websiteDataStore.hostNamesWithHSTSCache);
1525             hostnamesWithHSTSToDelete = filterForRegistrableDomains(domains, websiteDataStore.hostNamesWithHSTSCache);
1526             deleteHSTSCacheForHostNames(*networkStorageSession, hostnamesWithHSTSToDelete);
1527         }
1528     }
1529 #endif
1530
1531     /*
1532     // FIXME: No API to delete credentials by origin
1533     if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
1534         if (storageSession(sessionID))
1535             websiteDataStore.originsWithCredentials = storageSession(sessionID)->credentialStorage().originsWithCredentials();
1536     }
1537     */
1538     
1539     if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) {
1540         CacheStorage::Engine::fetchEntries(*this, sessionID, fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes), [this, domains, sessionID, callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
1541             
1542             auto entriesToDelete = filterForRegistrableDomains(domains, entries);
1543
1544             callbackAggregator->m_websiteData.entries.appendVector(entriesToDelete);
1545             
1546             for (auto& entry : entriesToDelete)
1547                 CacheStorage::Engine::clearCachesForOrigin(*this, sessionID, SecurityOriginData { entry.origin }, [callbackAggregator = callbackAggregator.copyRef()] { });
1548         });
1549     }
1550     
1551 #if ENABLE(INDEXED_DATABASE)
1552     auto path = m_idbDatabasePaths.get(sessionID);
1553     if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases)) {
1554         // FIXME: Pick the right database store based on the session ID.
1555         postStorageTask(CrossThreadTask([this, sessionID, callbackAggregator = callbackAggregator.copyRef(), path = WTFMove(path), domains]() mutable {
1556             RunLoop::main().dispatch([this, sessionID, domains = crossThreadCopy(domains), callbackAggregator = callbackAggregator.copyRef(), securityOrigins = indexedDatabaseOrigins(path)] {
1557                 Vector<SecurityOriginData> entriesToDelete;
1558                 for (const auto& securityOrigin : securityOrigins) {
1559                     if (!domains.contains(RegistrableDomain::uncheckedCreateFromHost(securityOrigin.host)))
1560                         continue;
1561
1562                     entriesToDelete.append(securityOrigin);
1563                     callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::IndexedDBDatabases, 0 });
1564                 }
1565
1566                 idbServer(sessionID).closeAndDeleteDatabasesForOrigins(entriesToDelete, [callbackAggregator = callbackAggregator.copyRef()] { });
1567             });
1568         }));
1569     }
1570 #endif
1571     
1572 #if ENABLE(SERVICE_WORKER)
1573     path = m_swDatabasePaths.get(sessionID);
1574     if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations)) {
1575         swServerForSession(sessionID).getOriginsWithRegistrations([this, sessionID, domains, callbackAggregator = callbackAggregator.copyRef()](const HashSet<SecurityOriginData>& securityOrigins) mutable {
1576             for (auto& securityOrigin : securityOrigins) {
1577                 if (!domains.contains(RegistrableDomain::uncheckedCreateFromHost(securityOrigin.host)))
1578                     continue;
1579                 callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::ServiceWorkerRegistrations, 0 });
1580                 swServerForSession(sessionID).clear(securityOrigin, [callbackAggregator = callbackAggregator.copyRef()] { });
1581             }
1582         });
1583     }
1584 #endif
1585     
1586     if (websiteDataTypes.contains(WebsiteDataType::DiskCache)) {
1587         fetchDiskCacheEntries(cache(), sessionID, fetchOptions, [this, domains, callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
1588
1589             Vector<SecurityOriginData> entriesToDelete;
1590             for (auto& entry : entries) {
1591                 if (!domains.contains(RegistrableDomain::uncheckedCreateFromHost(entry.origin.host)))
1592                     continue;
1593                 entriesToDelete.append(entry.origin);
1594                 callbackAggregator->m_websiteData.entries.append(entry);
1595             }
1596             clearDiskCacheEntries(cache(), entriesToDelete, [callbackAggregator = callbackAggregator.copyRef()] { });
1597         });
1598     }
1599 }
1600
1601 void NetworkProcess::registrableDomainsWithWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, bool shouldNotifyPage, CompletionHandler<void(HashSet<RegistrableDomain>&&)>&& completionHandler)
1602 {
1603     OptionSet<WebsiteDataFetchOption> fetchOptions = WebsiteDataFetchOption::DoNotCreateProcesses;
1604     
1605     struct CallbackAggregator final : public ThreadSafeRefCounted<CallbackAggregator> {
1606         explicit CallbackAggregator(CompletionHandler<void(HashSet<RegistrableDomain>&&)>&& completionHandler)
1607             : m_completionHandler(WTFMove(completionHandler))
1608         {
1609         }
1610         
1611         ~CallbackAggregator()
1612         {
1613             RunLoop::main().dispatch([completionHandler = WTFMove(m_completionHandler), websiteData = WTFMove(m_websiteData)] () mutable {
1614                 HashSet<RegistrableDomain> domains;
1615                 for (const auto& hostnameWithCookies : websiteData.hostNamesWithCookies)
1616                     domains.add(RegistrableDomain::uncheckedCreateFromHost(hostnameWithCookies));
1617
1618                 for (const auto& hostnameWithHSTS : websiteData.hostNamesWithHSTSCache)
1619                     domains.add(RegistrableDomain::uncheckedCreateFromHost(hostnameWithHSTS));
1620
1621                 for (const auto& entry : websiteData.entries)
1622                     domains.add(RegistrableDomain::uncheckedCreateFromHost(entry.origin.host));
1623
1624                 completionHandler(WTFMove(domains));
1625             });
1626         }
1627         
1628         CompletionHandler<void(HashSet<RegistrableDomain>&&)> m_completionHandler;
1629         WebsiteData m_websiteData;
1630     };
1631     
1632     auto callbackAggregator = adoptRef(*new CallbackAggregator([this, completionHandler = WTFMove(completionHandler), shouldNotifyPage] (HashSet<RegistrableDomain>&& domainsWithData) mutable {
1633         if (shouldNotifyPage)
1634             parentProcessConnection()->send(Messages::NetworkProcessProxy::NotifyWebsiteDataScanForRegistrableDomainsFinished(), 0);
1635
1636         RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), domainsWithData = crossThreadCopy(domainsWithData)] () mutable {
1637             completionHandler(WTFMove(domainsWithData));
1638         });
1639     }));
1640     
1641     auto& websiteDataStore = callbackAggregator->m_websiteData;
1642     
1643     Vector<String> hostnamesWithCookiesToDelete;
1644     if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
1645         if (auto* networkStorageSession = storageSession(sessionID))
1646             networkStorageSession->getHostnamesWithCookies(websiteDataStore.hostNamesWithCookies);
1647     }
1648     
1649     Vector<String> hostnamesWithHSTSToDelete;
1650 #if PLATFORM(COCOA)
1651     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
1652         if (auto* networkStorageSession = storageSession(sessionID))
1653             getHostNamesWithHSTSCache(*networkStorageSession, websiteDataStore.hostNamesWithHSTSCache);
1654     }
1655 #endif
1656
1657     if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
1658         if (auto* networkStorageSession = storageSession(sessionID))
1659             websiteDataStore.originsWithCredentials = networkStorageSession->credentialStorage().originsWithCredentials();
1660     }
1661     
1662     if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) {
1663         CacheStorage::Engine::fetchEntries(*this, sessionID, fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes), [callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
1664             callbackAggregator->m_websiteData.entries.appendVector(entries);
1665         });
1666     }
1667     
1668 #if ENABLE(INDEXED_DATABASE)
1669     auto path = m_idbDatabasePaths.get(sessionID);
1670     if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases)) {
1671         // FIXME: Pick the right database store based on the session ID.
1672         postStorageTask(CrossThreadTask([this, callbackAggregator = callbackAggregator.copyRef(), path = WTFMove(path)]() mutable {
1673             RunLoop::main().dispatch([callbackAggregator = callbackAggregator.copyRef(), securityOrigins = indexedDatabaseOrigins(path)] {
1674                 for (const auto& securityOrigin : securityOrigins)
1675                     callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::IndexedDBDatabases, 0 });
1676             });
1677         }));
1678     }
1679 #endif
1680     
1681 #if ENABLE(SERVICE_WORKER)
1682     path = m_swDatabasePaths.get(sessionID);
1683     if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations)) {
1684         swServerForSession(sessionID).getOriginsWithRegistrations([callbackAggregator = callbackAggregator.copyRef()](const HashSet<SecurityOriginData>& securityOrigins) mutable {
1685             for (auto& securityOrigin : securityOrigins)
1686                 callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::ServiceWorkerRegistrations, 0 });
1687         });
1688     }
1689 #endif
1690     
1691     if (websiteDataTypes.contains(WebsiteDataType::DiskCache)) {
1692         fetchDiskCacheEntries(cache(), sessionID, fetchOptions, [callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
1693             callbackAggregator->m_websiteData.entries.appendVector(entries);
1694         });
1695     }
1696 }
1697 #endif // ENABLE(RESOURCE_LOAD_STATISTICS)
1698
1699 CacheStorage::Engine* NetworkProcess::findCacheEngine(const PAL::SessionID& sessionID)
1700 {
1701     return m_cacheEngines.get(sessionID);
1702 }
1703
1704 CacheStorage::Engine& NetworkProcess::ensureCacheEngine(const PAL::SessionID& sessionID, Function<Ref<CacheStorage::Engine>()>&& functor)
1705 {
1706     return m_cacheEngines.ensure(sessionID, WTFMove(functor)).iterator->value;
1707 }
1708
1709 void NetworkProcess::removeCacheEngine(const PAL::SessionID& sessionID)
1710 {
1711     m_cacheEngines.remove(sessionID);
1712 }
1713
1714 void NetworkProcess::downloadRequest(PAL::SessionID sessionID, DownloadID downloadID, const ResourceRequest& request, const String& suggestedFilename)
1715 {
1716     downloadManager().startDownload(sessionID, downloadID, request, suggestedFilename);
1717 }
1718
1719 void NetworkProcess::resumeDownload(PAL::SessionID sessionID, DownloadID downloadID, const IPC::DataReference& resumeData, const String& path, WebKit::SandboxExtension::Handle&& sandboxExtensionHandle)
1720 {
1721     downloadManager().resumeDownload(sessionID, downloadID, resumeData, path, WTFMove(sandboxExtensionHandle));
1722 }
1723
1724 void NetworkProcess::cancelDownload(DownloadID downloadID)
1725 {
1726     downloadManager().cancelDownload(downloadID);
1727 }
1728
1729 #if PLATFORM(COCOA)
1730 void NetworkProcess::publishDownloadProgress(DownloadID downloadID, const URL& url, SandboxExtension::Handle&& sandboxExtensionHandle)
1731 {
1732     downloadManager().publishDownloadProgress(downloadID, url, WTFMove(sandboxExtensionHandle));
1733 }
1734 #endif
1735
1736 void NetworkProcess::continueWillSendRequest(DownloadID downloadID, WebCore::ResourceRequest&& request)
1737 {
1738     downloadManager().continueWillSendRequest(downloadID, WTFMove(request));
1739 }
1740
1741 void NetworkProcess::pendingDownloadCanceled(DownloadID downloadID)
1742 {
1743     downloadProxyConnection()->send(Messages::DownloadProxy::DidCancel({ }), downloadID.downloadID());
1744 }
1745
1746 void NetworkProcess::findPendingDownloadLocation(NetworkDataTask& networkDataTask, ResponseCompletionHandler&& completionHandler, const ResourceResponse& response)
1747 {
1748     uint64_t destinationID = networkDataTask.pendingDownloadID().downloadID();
1749     downloadProxyConnection()->send(Messages::DownloadProxy::DidReceiveResponse(response), destinationID);
1750
1751     downloadManager().willDecidePendingDownloadDestination(networkDataTask, WTFMove(completionHandler));
1752
1753     // As per https://html.spec.whatwg.org/#as-a-download (step 2), the filename from the Content-Disposition header
1754     // should override the suggested filename from the download attribute.
1755     String suggestedFilename = response.isAttachmentWithFilename() ? response.suggestedFilename() : networkDataTask.suggestedFilename();
1756     suggestedFilename = MIMETypeRegistry::appendFileExtensionIfNecessary(suggestedFilename, response.mimeType());
1757
1758     downloadProxyConnection()->send(Messages::DownloadProxy::DecideDestinationWithSuggestedFilenameAsync(networkDataTask.pendingDownloadID(), suggestedFilename), destinationID);
1759 }
1760
1761 void NetworkProcess::continueDecidePendingDownloadDestination(DownloadID downloadID, String destination, SandboxExtension::Handle&& sandboxExtensionHandle, bool allowOverwrite)
1762 {
1763     if (destination.isEmpty())
1764         downloadManager().cancelDownload(downloadID);
1765     else
1766         downloadManager().continueDecidePendingDownloadDestination(downloadID, destination, WTFMove(sandboxExtensionHandle), allowOverwrite);
1767 }
1768
1769 void NetworkProcess::setCacheModel(CacheModel cacheModel)
1770 {
1771     if (m_hasSetCacheModel && (cacheModel == m_cacheModel))
1772         return;
1773
1774     m_hasSetCacheModel = true;
1775     m_cacheModel = cacheModel;
1776
1777     unsigned urlCacheMemoryCapacity = 0;
1778     uint64_t urlCacheDiskCapacity = 0;
1779     uint64_t diskFreeSize = 0;
1780     if (FileSystem::getVolumeFreeSpace(m_diskCacheDirectory, diskFreeSize)) {
1781         // As a fudge factor, use 1000 instead of 1024, in case the reported byte
1782         // count doesn't align exactly to a megabyte boundary.
1783         diskFreeSize /= KB * 1000;
1784         calculateURLCacheSizes(cacheModel, diskFreeSize, urlCacheMemoryCapacity, urlCacheDiskCapacity);
1785     }
1786
1787     if (m_cache)
1788         m_cache->setCapacity(urlCacheDiskCapacity);
1789 }
1790
1791 void NetworkProcess::setCanHandleHTTPSServerTrustEvaluation(bool value)
1792 {
1793     m_canHandleHTTPSServerTrustEvaluation = value;
1794 }
1795
1796 void NetworkProcess::getNetworkProcessStatistics(uint64_t callbackID)
1797 {
1798     StatisticsData data;
1799
1800     data.statisticsNumbers.set("DownloadsActiveCount", downloadManager().activeDownloadCount());
1801     data.statisticsNumbers.set("OutstandingAuthenticationChallengesCount", authenticationManager().outstandingAuthenticationChallengeCount());
1802
1803     parentProcessConnection()->send(Messages::WebProcessPool::DidGetStatistics(data, callbackID), 0);
1804 }
1805
1806 void NetworkProcess::setAllowsAnySSLCertificateForWebSocket(bool allows, CompletionHandler<void()>&& completionHandler)
1807 {
1808     DeprecatedGlobalSettings::setAllowsAnySSLCertificate(allows);
1809     completionHandler();
1810 }
1811
1812 void NetworkProcess::logDiagnosticMessage(uint64_t webPageID, const String& message, const String& description, ShouldSample shouldSample)
1813 {
1814     if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
1815         return;
1816
1817     parentProcessConnection()->send(Messages::NetworkProcessProxy::LogDiagnosticMessage(webPageID, message, description, ShouldSample::No), 0);
1818 }
1819
1820 void NetworkProcess::logDiagnosticMessageWithResult(uint64_t webPageID, const String& message, const String& description, DiagnosticLoggingResultType result, ShouldSample shouldSample)
1821 {
1822     if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
1823         return;
1824
1825     parentProcessConnection()->send(Messages::NetworkProcessProxy::LogDiagnosticMessageWithResult(webPageID, message, description, result, ShouldSample::No), 0);
1826 }
1827
1828 void NetworkProcess::logDiagnosticMessageWithValue(uint64_t webPageID, const String& message, const String& description, double value, unsigned significantFigures, ShouldSample shouldSample)
1829 {
1830     if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
1831         return;
1832
1833     parentProcessConnection()->send(Messages::NetworkProcessProxy::LogDiagnosticMessageWithValue(webPageID, message, description, value, significantFigures, ShouldSample::No), 0);
1834 }
1835
1836 void NetworkProcess::terminate()
1837 {
1838     platformTerminate();
1839     AuxiliaryProcess::terminate();
1840 }
1841
1842 void NetworkProcess::processDidTransitionToForeground()
1843 {
1844     platformProcessDidTransitionToForeground();
1845 }
1846
1847 void NetworkProcess::processDidTransitionToBackground()
1848 {
1849     platformProcessDidTransitionToBackground();
1850 }
1851
1852 // FIXME: We can remove this one by adapting RefCounter.
1853 class TaskCounter : public RefCounted<TaskCounter> {
1854 public:
1855     explicit TaskCounter(Function<void()>&& callback) : m_callback(WTFMove(callback)) { }
1856     ~TaskCounter() { m_callback(); };
1857
1858 private:
1859     Function<void()> m_callback;
1860 };
1861
1862 void NetworkProcess::actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend shouldAcknowledgeWhenReadyToSuspend)
1863 {
1864     lowMemoryHandler(Critical::Yes);
1865
1866     RefPtr<TaskCounter> delayedTaskCounter;
1867     if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) {
1868         delayedTaskCounter = adoptRef(new TaskCounter([this] {
1869             RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::notifyProcessReadyToSuspend() Sending ProcessReadyToSuspend IPC message", this);
1870             if (parentProcessConnection())
1871                 parentProcessConnection()->send(Messages::NetworkProcessProxy::ProcessReadyToSuspend(), 0);
1872         }));
1873     }
1874
1875     platformPrepareToSuspend([delayedTaskCounter] { });
1876     platformSyncAllCookies([delayedTaskCounter] { });
1877
1878     for (auto& connection : m_webProcessConnections)
1879         connection->cleanupForSuspension([delayedTaskCounter] { });
1880 }
1881
1882 void NetworkProcess::processWillSuspendImminently(CompletionHandler<void(bool)>&& completionHandler)
1883 {
1884     actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::No);
1885     completionHandler(true);
1886 }
1887
1888 void NetworkProcess::prepareToSuspend()
1889 {
1890     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::prepareToSuspend()", this);
1891     actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::Yes);
1892 }
1893
1894 void NetworkProcess::cancelPrepareToSuspend()
1895 {
1896     // Although it is tempting to send a NetworkProcessProxy::DidCancelProcessSuspension message from here
1897     // we do not because prepareToSuspend() already replied with a NetworkProcessProxy::ProcessReadyToSuspend
1898     // message. And NetworkProcessProxy expects to receive either a NetworkProcessProxy::ProcessReadyToSuspend-
1899     // or NetworkProcessProxy::DidCancelProcessSuspension- message, but not both.
1900     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::cancelPrepareToSuspend()", this);
1901     platformProcessDidResume();
1902     for (auto& connection : m_webProcessConnections)
1903         connection->endSuspension();
1904 }
1905
1906 void NetworkProcess::processDidResume()
1907 {
1908     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::processDidResume()", this);
1909     platformProcessDidResume();
1910     for (auto& connection : m_webProcessConnections)
1911         connection->endSuspension();
1912 }
1913
1914 void NetworkProcess::prefetchDNS(const String& hostname)
1915 {
1916     WebCore::prefetchDNS(hostname);
1917 }
1918
1919 void NetworkProcess::cacheStorageParameters(PAL::SessionID sessionID, CacheStorageParametersCallback&& callback)
1920 {
1921     m_cacheStorageParametersCallbacks.ensure(sessionID, [&] {
1922         parentProcessConnection()->send(Messages::NetworkProcessProxy::RetrieveCacheStorageParameters { sessionID }, 0);
1923         return Vector<CacheStorageParametersCallback> { };
1924     }).iterator->value.append(WTFMove(callback));
1925 }
1926
1927 void NetworkProcess::setCacheStorageParameters(PAL::SessionID sessionID, uint64_t quota, String&& cacheStorageDirectory, SandboxExtension::Handle&& handle)
1928 {
1929     auto iterator = m_cacheStorageParametersCallbacks.find(sessionID);
1930     if (iterator == m_cacheStorageParametersCallbacks.end())
1931         return;
1932
1933     SandboxExtension::consumePermanently(handle);
1934     auto callbacks = WTFMove(iterator->value);
1935     m_cacheStorageParametersCallbacks.remove(iterator);
1936     for (auto& callback : callbacks)
1937         callback(String { cacheStorageDirectory }, quota);
1938 }
1939
1940 void NetworkProcess::preconnectTo(const URL& url, WebCore::StoredCredentialsPolicy storedCredentialsPolicy)
1941 {
1942 #if ENABLE(SERVER_PRECONNECT)
1943     NetworkLoadParameters parameters;
1944     parameters.request = ResourceRequest { url };
1945     parameters.sessionID = PAL::SessionID::defaultSessionID();
1946     parameters.storedCredentialsPolicy = storedCredentialsPolicy;
1947     parameters.shouldPreconnectOnly = PreconnectOnly::Yes;
1948
1949     new PreconnectTask(*this, WTFMove(parameters));
1950 #else
1951     UNUSED_PARAM(url);
1952     UNUSED_PARAM(storedCredentialsPolicy);
1953 #endif
1954 }
1955
1956 void NetworkProcess::registerURLSchemeAsSecure(const String& scheme) const
1957 {
1958     SchemeRegistry::registerURLSchemeAsSecure(scheme);
1959 }
1960
1961 void NetworkProcess::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme) const
1962 {
1963     SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
1964 }
1965
1966 void NetworkProcess::registerURLSchemeAsLocal(const String& scheme) const
1967 {
1968     SchemeRegistry::registerURLSchemeAsLocal(scheme);
1969 }
1970
1971 void NetworkProcess::registerURLSchemeAsNoAccess(const String& scheme) const
1972 {
1973     SchemeRegistry::registerURLSchemeAsNoAccess(scheme);
1974 }
1975
1976 void NetworkProcess::registerURLSchemeAsDisplayIsolated(const String& scheme) const
1977 {
1978     SchemeRegistry::registerURLSchemeAsDisplayIsolated(scheme);
1979 }
1980
1981 void NetworkProcess::registerURLSchemeAsCORSEnabled(const String& scheme) const
1982 {
1983     SchemeRegistry::registerURLSchemeAsCORSEnabled(scheme);
1984 }
1985
1986 void NetworkProcess::registerURLSchemeAsCanDisplayOnlyIfCanRequest(const String& scheme) const
1987 {
1988     SchemeRegistry::registerAsCanDisplayOnlyIfCanRequest(scheme);
1989 }
1990
1991 void NetworkProcess::didSyncAllCookies()
1992 {
1993     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidSyncAllCookies(), 0);
1994 }
1995
1996 #if ENABLE(INDEXED_DATABASE)
1997 IDBServer::IDBServer& NetworkProcess::idbServer(PAL::SessionID sessionID)
1998 {
1999     auto addResult = m_idbServers.add(sessionID, nullptr);
2000     if (!addResult.isNewEntry) {
2001         ASSERT(addResult.iterator->value);
2002         return *addResult.iterator->value;
2003     }
2004     
2005     auto path = m_idbDatabasePaths.get(sessionID);
2006     // There should already be a registered path for this PAL::SessionID.
2007     // If there's not, then where did this PAL::SessionID come from?
2008     ASSERT(!path.isEmpty());
2009     
2010     addResult.iterator->value = IDBServer::IDBServer::create(path, *this, [this](bool isHoldingLockedFiles) {
2011         notifyHoldingLockedFiles(isHoldingLockedFiles);
2012     });
2013     addResult.iterator->value->setPerOriginQuota(m_idbPerOriginQuota);
2014     return *addResult.iterator->value;
2015 }
2016
2017 void NetworkProcess::ensurePathExists(const String& path)
2018 {
2019     ASSERT(!RunLoop::isMain());
2020     
2021     if (!FileSystem::makeAllDirectories(path))
2022         LOG_ERROR("Failed to make all directories for path '%s'", path.utf8().data());
2023 }
2024
2025 void NetworkProcess::postStorageTask(CrossThreadTask&& task)
2026 {
2027     ASSERT(RunLoop::isMain());
2028     
2029     LockHolder locker(m_storageTaskMutex);
2030     
2031     m_storageTasks.append(WTFMove(task));
2032     
2033     m_storageTaskQueue->dispatch([this] {
2034         performNextStorageTask();
2035     });
2036 }
2037
2038 void NetworkProcess::performNextStorageTask()
2039 {
2040     ASSERT(!RunLoop::isMain());
2041     
2042     CrossThreadTask task;
2043     {
2044         LockHolder locker(m_storageTaskMutex);
2045         ASSERT(!m_storageTasks.isEmpty());
2046         task = m_storageTasks.takeFirst();
2047     }
2048     
2049     task.performTask();
2050 }
2051
2052 void NetworkProcess::accessToTemporaryFileComplete(const String& path)
2053 {
2054     // We've either hard linked the temporary blob file to the database directory, copied it there,
2055     // or the transaction is being aborted.
2056     // In any of those cases, we can delete the temporary blob file now.
2057     FileSystem::deleteFile(path);
2058 }
2059
2060 HashSet<WebCore::SecurityOriginData> NetworkProcess::indexedDatabaseOrigins(const String& path)
2061 {
2062     if (path.isEmpty())
2063         return { };
2064     
2065     HashSet<WebCore::SecurityOriginData> securityOrigins;
2066     for (auto& topOriginPath : FileSystem::listDirectory(path, "*")) {
2067         auto databaseIdentifier = FileSystem::pathGetFileName(topOriginPath);
2068         if (auto securityOrigin = SecurityOriginData::fromDatabaseIdentifier(databaseIdentifier))
2069             securityOrigins.add(WTFMove(*securityOrigin));
2070         
2071         for (auto& originPath : FileSystem::listDirectory(topOriginPath, "*")) {
2072             databaseIdentifier = FileSystem::pathGetFileName(originPath);
2073             if (auto securityOrigin = SecurityOriginData::fromDatabaseIdentifier(databaseIdentifier))
2074                 securityOrigins.add(WTFMove(*securityOrigin));
2075         }
2076     }
2077
2078     return securityOrigins;
2079 }
2080
2081 void NetworkProcess::addIndexedDatabaseSession(PAL::SessionID sessionID, String& indexedDatabaseDirectory, SandboxExtension::Handle& handle)
2082 {
2083     // *********
2084     // IMPORTANT: Do not change the directory structure for indexed databases on disk without first consulting a reviewer from Apple (<rdar://problem/17454712>)
2085     // *********
2086     auto addResult = m_idbDatabasePaths.add(sessionID, indexedDatabaseDirectory);
2087     if (addResult.isNewEntry) {
2088         SandboxExtension::consumePermanently(handle);
2089         if (!indexedDatabaseDirectory.isEmpty())
2090             postStorageTask(createCrossThreadTask(*this, &NetworkProcess::ensurePathExists, indexedDatabaseDirectory));
2091     }
2092 }
2093
2094 void NetworkProcess::setIDBPerOriginQuota(uint64_t quota)
2095 {
2096     m_idbPerOriginQuota = quota;
2097     
2098     for (auto& server : m_idbServers.values())
2099         server->setPerOriginQuota(quota);
2100 }
2101 #endif // ENABLE(INDEXED_DATABASE)
2102
2103 #if ENABLE(SANDBOX_EXTENSIONS)
2104 void NetworkProcess::getSandboxExtensionsForBlobFiles(const Vector<String>& filenames, CompletionHandler<void(SandboxExtension::HandleArray&&)>&& completionHandler)
2105 {
2106     parentProcessConnection()->sendWithAsyncReply(Messages::NetworkProcessProxy::GetSandboxExtensionsForBlobFiles(filenames), WTFMove(completionHandler));
2107 }
2108 #endif // ENABLE(SANDBOX_EXTENSIONS)
2109
2110 #if ENABLE(SERVICE_WORKER)
2111 WebSWServerToContextConnection* NetworkProcess::connectionToContextProcessFromIPCConnection(IPC::Connection& connection)
2112 {
2113     for (auto& serverToContextConnection : m_serverToContextConnections.values()) {
2114         if (serverToContextConnection->ipcConnection() == &connection)
2115             return serverToContextConnection.get();
2116     }
2117     return nullptr;
2118 }
2119
2120 void NetworkProcess::connectionToContextProcessWasClosed(Ref<WebSWServerToContextConnection>&& serverToContextConnection)
2121 {
2122     auto& securityOrigin = serverToContextConnection->securityOrigin();
2123     
2124     serverToContextConnection->connectionClosed();
2125     m_serverToContextConnections.remove(securityOrigin);
2126     
2127     for (auto& swServer : m_swServers.values())
2128         swServer->markAllWorkersForOriginAsTerminated(securityOrigin);
2129     
2130     if (needsServerToContextConnectionForOrigin(securityOrigin)) {
2131         RELEASE_LOG(ServiceWorker, "Connection to service worker process was closed but is still needed, relaunching it");
2132         createServerToContextConnection(securityOrigin, WTF::nullopt);
2133     }
2134 }
2135
2136 bool NetworkProcess::needsServerToContextConnectionForOrigin(const SecurityOriginData& securityOrigin) const
2137 {
2138     return WTF::anyOf(m_swServers.values(), [&](auto& swServer) {
2139         return swServer->needsServerToContextConnectionForOrigin(securityOrigin);
2140     });
2141 }
2142
2143 SWServer& NetworkProcess::swServerForSession(PAL::SessionID sessionID)
2144 {
2145     ASSERT(sessionID.isValid());
2146     
2147     auto result = m_swServers.ensure(sessionID, [&] {
2148         auto path = m_swDatabasePaths.get(sessionID);
2149         // There should already be a registered path for this PAL::SessionID.
2150         // If there's not, then where did this PAL::SessionID come from?
2151         ASSERT(sessionID.isEphemeral() || !path.isEmpty());
2152         
2153         auto value = std::make_unique<SWServer>(makeUniqueRef<WebSWOriginStore>(), WTFMove(path), sessionID);
2154         if (m_shouldDisableServiceWorkerProcessTerminationDelay)
2155             value->disableServiceWorkerProcessTerminationDelay();
2156         return value;
2157     });
2158
2159     return *result.iterator->value;
2160 }
2161
2162 WebSWOriginStore& NetworkProcess::swOriginStoreForSession(PAL::SessionID sessionID)
2163 {
2164     return static_cast<WebSWOriginStore&>(swServerForSession(sessionID).originStore());
2165 }
2166
2167 WebSWOriginStore* NetworkProcess::existingSWOriginStoreForSession(PAL::SessionID sessionID) const
2168 {
2169     auto* swServer = m_swServers.get(sessionID);
2170     if (!swServer)
2171         return nullptr;
2172     return &static_cast<WebSWOriginStore&>(swServer->originStore());
2173 }
2174
2175 WebSWServerToContextConnection* NetworkProcess::serverToContextConnectionForOrigin(const SecurityOriginData& securityOrigin)
2176 {
2177     return m_serverToContextConnections.get(securityOrigin);
2178 }
2179
2180 void NetworkProcess::createServerToContextConnection(const SecurityOriginData& securityOrigin, Optional<PAL::SessionID> sessionID)
2181 {
2182     if (m_waitingForServerToContextProcessConnection)
2183         return;
2184     
2185     m_waitingForServerToContextProcessConnection = true;
2186     if (sessionID)
2187         parentProcessConnection()->send(Messages::NetworkProcessProxy::EstablishWorkerContextConnectionToNetworkProcessForExplicitSession(securityOrigin, *sessionID), 0);
2188     else
2189         parentProcessConnection()->send(Messages::NetworkProcessProxy::EstablishWorkerContextConnectionToNetworkProcess(securityOrigin), 0);
2190 }
2191
2192 void NetworkProcess::didFailFetch(SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier fetchIdentifier, const ResourceError& error)
2193 {
2194     if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
2195         connection->didFailFetch(fetchIdentifier, error);
2196 }
2197
2198 void NetworkProcess::didNotHandleFetch(SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier fetchIdentifier)
2199 {
2200     if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
2201         connection->didNotHandleFetch(fetchIdentifier);
2202 }
2203
2204 void NetworkProcess::didReceiveFetchRedirectResponse(SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier fetchIdentifier, const WebCore::ResourceResponse& response)
2205 {
2206     if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
2207         connection->didReceiveFetchRedirectResponse(fetchIdentifier, response);
2208 }
2209
2210 void NetworkProcess::didReceiveFetchResponse(SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier fetchIdentifier, const WebCore::ResourceResponse& response, bool needsContinueDidReceiveResponseMessage)
2211 {
2212     if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
2213         connection->didReceiveFetchResponse(fetchIdentifier, response, needsContinueDidReceiveResponseMessage);
2214 }
2215
2216 void NetworkProcess::didReceiveFetchData(SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier fetchIdentifier, const IPC::DataReference& data, int64_t encodedDataLength)
2217 {
2218     if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
2219         connection->didReceiveFetchData(fetchIdentifier, data, encodedDataLength);
2220 }
2221
2222 void NetworkProcess::didReceiveFetchFormData(SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier fetchIdentifier, const IPC::FormDataReference& formData)
2223 {
2224     if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
2225         connection->didReceiveFetchFormData(fetchIdentifier, formData);
2226 }
2227
2228 void NetworkProcess::didFinishFetch(SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier fetchIdentifier)
2229 {
2230     if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
2231         connection->didFinishFetch(fetchIdentifier);
2232 }
2233
2234 void NetworkProcess::postMessageToServiceWorkerClient(const ServiceWorkerClientIdentifier& destinationIdentifier, MessageWithMessagePorts&& message, ServiceWorkerIdentifier sourceIdentifier, const String& sourceOrigin)
2235 {
2236     if (auto* connection = m_swServerConnections.get(destinationIdentifier.serverConnectionIdentifier))
2237         connection->postMessageToServiceWorkerClient(destinationIdentifier.contextIdentifier, WTFMove(message), sourceIdentifier, sourceOrigin);
2238 }
2239
2240 void NetworkProcess::postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destination, WebCore::MessageWithMessagePorts&& message, const WebCore::ServiceWorkerOrClientIdentifier& source, SWServerConnectionIdentifier connectionIdentifier)
2241 {
2242     if (auto* connection = m_swServerConnections.get(connectionIdentifier))
2243         connection->postMessageToServiceWorker(destination, WTFMove(message), source);
2244 }
2245
2246 void NetworkProcess::registerSWServerConnection(WebSWServerConnection& connection)
2247 {
2248     ASSERT(parentProcessHasServiceWorkerEntitlement());
2249     ASSERT(!m_swServerConnections.contains(connection.identifier()));
2250     m_swServerConnections.add(connection.identifier(), &connection);
2251     swOriginStoreForSession(connection.sessionID()).registerSWServerConnection(connection);
2252 }
2253
2254 void NetworkProcess::unregisterSWServerConnection(WebSWServerConnection& connection)
2255 {
2256     ASSERT(m_swServerConnections.get(connection.identifier()) == &connection);
2257     m_swServerConnections.remove(connection.identifier());
2258     if (auto* store = existingSWOriginStoreForSession(connection.sessionID()))
2259         store->unregisterSWServerConnection(connection);
2260 }
2261
2262 void NetworkProcess::swContextConnectionMayNoLongerBeNeeded(WebSWServerToContextConnection& serverToContextConnection)
2263 {
2264     auto& securityOrigin = serverToContextConnection.securityOrigin();
2265     if (needsServerToContextConnectionForOrigin(securityOrigin))
2266         return;
2267     
2268     RELEASE_LOG(ServiceWorker, "Service worker process is no longer needed, terminating it");
2269     serverToContextConnection.terminate();
2270     
2271     for (auto& swServer : m_swServers.values())
2272         swServer->markAllWorkersForOriginAsTerminated(securityOrigin);
2273     
2274     serverToContextConnection.connectionClosed();
2275     m_serverToContextConnections.remove(securityOrigin);
2276 }
2277
2278 void NetworkProcess::disableServiceWorkerProcessTerminationDelay()
2279 {
2280     if (m_shouldDisableServiceWorkerProcessTerminationDelay)
2281         return;
2282     
2283     m_shouldDisableServiceWorkerProcessTerminationDelay = true;
2284     for (auto& swServer : m_swServers.values())
2285         swServer->disableServiceWorkerProcessTerminationDelay();
2286 }
2287
2288 void NetworkProcess::addServiceWorkerSession(PAL::SessionID sessionID, String& serviceWorkerRegistrationDirectory, const SandboxExtension::Handle& handle)
2289 {
2290     auto addResult = m_swDatabasePaths.add(sessionID, serviceWorkerRegistrationDirectory);
2291     if (addResult.isNewEntry) {
2292         SandboxExtension::consumePermanently(handle);
2293         if (!serviceWorkerRegistrationDirectory.isEmpty())
2294             postStorageTask(createCrossThreadTask(*this, &NetworkProcess::ensurePathExists, serviceWorkerRegistrationDirectory));
2295     }
2296 }
2297 #endif // ENABLE(SERVICE_WORKER)
2298
2299 void NetworkProcess::requestCacheStorageSpace(PAL::SessionID sessionID, const ClientOrigin& origin, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t>)>&& callback)
2300 {
2301     parentProcessConnection()->sendWithAsyncReply(Messages::NetworkProcessProxy::RequestCacheStorageSpace { sessionID, origin, quota, currentSize, spaceRequired }, WTFMove(callback), 0);
2302 }
2303
2304 #if !PLATFORM(COCOA)
2305 void NetworkProcess::initializeProcess(const AuxiliaryProcessInitializationParameters&)
2306 {
2307 }
2308
2309 void NetworkProcess::initializeProcessName(const AuxiliaryProcessInitializationParameters&)
2310 {
2311 }
2312
2313 void NetworkProcess::initializeSandbox(const AuxiliaryProcessInitializationParameters&, SandboxInitializationParameters&)
2314 {
2315 }
2316
2317 void NetworkProcess::syncAllCookies()
2318 {
2319 }
2320
2321 void NetworkProcess::platformSyncAllCookies(CompletionHandler<void()>&& completionHandler)
2322 {
2323     completionHandler();
2324 }
2325
2326 #endif
2327
2328 void NetworkProcess::storeAdClickAttribution(PAL::SessionID sessionID, WebCore::AdClickAttribution&& adClickAttribution)
2329 {
2330     if (auto session = networkSession(sessionID))
2331         session->storeAdClickAttribution(WTFMove(adClickAttribution));
2332 }
2333
2334 void NetworkProcess::dumpAdClickAttribution(PAL::SessionID sessionID, CompletionHandler<void(String)>&& completionHandler)
2335 {
2336     if (auto session = networkSession(sessionID))
2337         return session->dumpAdClickAttribution(WTFMove(completionHandler));
2338
2339     completionHandler({ });
2340 }
2341
2342 void NetworkProcess::clearAdClickAttribution(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
2343 {
2344     if (auto session = networkSession(sessionID))
2345         return session->clearAdClickAttribution(WTFMove(completionHandler));
2346     
2347     completionHandler();
2348 }
2349
2350 void NetworkProcess::notifyHoldingLockedFiles(bool isIDBDatabaseHoldingLockedFiles)
2351 {
2352     parentProcessConnection()->send(Messages::NetworkProcessProxy::SetIsIDBDatabaseHoldingLockedFiles(isIDBDatabaseHoldingLockedFiles), 0);
2353 }
2354
2355 } // namespace WebKit