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