Link prefetch not useful for top-level navigation
[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)
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     lowMemoryHandler(Critical::Yes);
1926
1927     RefPtr<TaskCounter> delayedTaskCounter;
1928     if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) {
1929         delayedTaskCounter = adoptRef(new TaskCounter([this] {
1930             RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::notifyProcessReadyToSuspend() Sending ProcessReadyToSuspend IPC message", this);
1931             if (parentProcessConnection())
1932                 parentProcessConnection()->send(Messages::NetworkProcessProxy::ProcessReadyToSuspend(), 0);
1933         }));
1934     }
1935
1936     platformPrepareToSuspend([delayedTaskCounter] { });
1937     platformSyncAllCookies([delayedTaskCounter] { });
1938
1939     for (auto& connection : m_webProcessConnections)
1940         connection->cleanupForSuspension([delayedTaskCounter] { });
1941
1942 #if ENABLE(SERVICE_WORKER)
1943     for (auto& server : m_swServers.values())
1944         server->startSuspension([delayedTaskCounter] { });
1945 #endif
1946 }
1947
1948 void NetworkProcess::processWillSuspendImminently(CompletionHandler<void(bool)>&& completionHandler)
1949 {
1950 #if PLATFORM(IOS_FAMILY) && ENABLE(INDEXED_DATABASE)
1951     for (auto& server : m_idbServers.values())
1952         server->tryStop(IDBServer::ShouldForceStop::Yes);
1953 #endif
1954     actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::No);
1955     completionHandler(true);
1956 }
1957
1958 void NetworkProcess::prepareToSuspend()
1959 {
1960     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::prepareToSuspend()", this);
1961
1962 #if PLATFORM(IOS_FAMILY) && ENABLE(INDEXED_DATABASE)
1963     for (auto& server : m_idbServers.values())
1964         server->tryStop(IDBServer::ShouldForceStop::No);
1965 #endif
1966     actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::Yes);
1967 }
1968
1969 void NetworkProcess::cancelPrepareToSuspend()
1970 {
1971     // Although it is tempting to send a NetworkProcessProxy::DidCancelProcessSuspension message from here
1972     // we do not because prepareToSuspend() already replied with a NetworkProcessProxy::ProcessReadyToSuspend
1973     // message. And NetworkProcessProxy expects to receive either a NetworkProcessProxy::ProcessReadyToSuspend-
1974     // or NetworkProcessProxy::DidCancelProcessSuspension- message, but not both.
1975     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::cancelPrepareToSuspend()", this);
1976     resume();
1977 }
1978
1979 void NetworkProcess::applicationDidEnterBackground()
1980 {
1981     m_downloadManager.applicationDidEnterBackground();
1982 }
1983
1984 void NetworkProcess::applicationWillEnterForeground()
1985 {
1986     m_downloadManager.applicationWillEnterForeground();
1987 }
1988
1989 void NetworkProcess::processDidResume()
1990 {
1991     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::processDidResume()", this);
1992     resume();
1993 }
1994
1995 void NetworkProcess::resume()
1996 {
1997     platformProcessDidResume();
1998     for (auto& connection : m_webProcessConnections)
1999         connection->endSuspension();
2000
2001 #if ENABLE(SERVICE_WORKER)
2002     for (auto& server : m_swServers.values())
2003         server->endSuspension();
2004 #endif
2005 #if PLATFORM(IOS_FAMILY) && ENABLE(INDEXED_DATABASE)
2006     for (auto& server : m_idbServers.values())
2007         server->resume();
2008 #endif
2009 }
2010
2011 void NetworkProcess::prefetchDNS(const String& hostname)
2012 {
2013     WebCore::prefetchDNS(hostname);
2014 }
2015
2016 void NetworkProcess::cacheStorageRootPath(PAL::SessionID sessionID, CacheStorageRootPathCallback&& callback)
2017 {
2018     m_cacheStorageParametersCallbacks.ensure(sessionID, [&] {
2019         parentProcessConnection()->send(Messages::NetworkProcessProxy::RetrieveCacheStorageParameters { sessionID }, 0);
2020         return Vector<CacheStorageRootPathCallback> { };
2021     }).iterator->value.append(WTFMove(callback));
2022 }
2023
2024 void NetworkProcess::setCacheStorageParameters(PAL::SessionID sessionID, String&& cacheStorageDirectory, SandboxExtension::Handle&& handle)
2025 {
2026     auto iterator = m_cacheStorageParametersCallbacks.find(sessionID);
2027     if (iterator == m_cacheStorageParametersCallbacks.end())
2028         return;
2029
2030     SandboxExtension::consumePermanently(handle);
2031     auto callbacks = WTFMove(iterator->value);
2032     m_cacheStorageParametersCallbacks.remove(iterator);
2033     for (auto& callback : callbacks)
2034         callback(String { cacheStorageDirectory });
2035 }
2036
2037 void NetworkProcess::preconnectTo(const URL& url, WebCore::StoredCredentialsPolicy storedCredentialsPolicy)
2038 {
2039 #if ENABLE(SERVER_PRECONNECT)
2040     NetworkLoadParameters parameters;
2041     parameters.request = ResourceRequest { url };
2042     parameters.sessionID = PAL::SessionID::defaultSessionID();
2043     parameters.storedCredentialsPolicy = storedCredentialsPolicy;
2044     parameters.shouldPreconnectOnly = PreconnectOnly::Yes;
2045
2046     new PreconnectTask(*this, WTFMove(parameters));
2047 #else
2048     UNUSED_PARAM(url);
2049     UNUSED_PARAM(storedCredentialsPolicy);
2050 #endif
2051 }
2052
2053 void NetworkProcess::registerURLSchemeAsSecure(const String& scheme) const
2054 {
2055     SchemeRegistry::registerURLSchemeAsSecure(scheme);
2056 }
2057
2058 void NetworkProcess::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme) const
2059 {
2060     SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
2061 }
2062
2063 void NetworkProcess::registerURLSchemeAsLocal(const String& scheme) const
2064 {
2065     SchemeRegistry::registerURLSchemeAsLocal(scheme);
2066 }
2067
2068 void NetworkProcess::registerURLSchemeAsNoAccess(const String& scheme) const
2069 {
2070     SchemeRegistry::registerURLSchemeAsNoAccess(scheme);
2071 }
2072
2073 void NetworkProcess::registerURLSchemeAsDisplayIsolated(const String& scheme) const
2074 {
2075     SchemeRegistry::registerURLSchemeAsDisplayIsolated(scheme);
2076 }
2077
2078 void NetworkProcess::registerURLSchemeAsCORSEnabled(const String& scheme) const
2079 {
2080     SchemeRegistry::registerURLSchemeAsCORSEnabled(scheme);
2081 }
2082
2083 void NetworkProcess::registerURLSchemeAsCanDisplayOnlyIfCanRequest(const String& scheme) const
2084 {
2085     SchemeRegistry::registerAsCanDisplayOnlyIfCanRequest(scheme);
2086 }
2087
2088 void NetworkProcess::didSyncAllCookies()
2089 {
2090     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidSyncAllCookies(), 0);
2091 }
2092
2093 #if ENABLE(INDEXED_DATABASE)
2094 Ref<IDBServer::IDBServer> NetworkProcess::createIDBServer(PAL::SessionID sessionID)
2095 {
2096     String path;
2097     if (!sessionID.isEphemeral()) {
2098         ASSERT(m_idbDatabasePaths.contains(sessionID));
2099         path = m_idbDatabasePaths.get(sessionID);
2100     }
2101
2102     auto server = IDBServer::IDBServer::create(sessionID, path, *this, [this, weakThis = makeWeakPtr(this)](PAL::SessionID sessionID, const auto& origin) -> StorageQuotaManager* {
2103         if (!weakThis)
2104             return nullptr;
2105         return &this->storageQuotaManager(sessionID, origin);
2106     });
2107     server->setPerOriginQuota(m_idbPerOriginQuota);
2108     return server;
2109 }
2110
2111 IDBServer::IDBServer& NetworkProcess::idbServer(PAL::SessionID sessionID)
2112 {
2113     return *m_idbServers.ensure(sessionID, [this, sessionID] {
2114         return this->createIDBServer(sessionID);
2115     }).iterator->value;
2116 }
2117
2118 void NetworkProcess::ensurePathExists(const String& path)
2119 {
2120     ASSERT(!RunLoop::isMain());
2121     
2122     if (!FileSystem::makeAllDirectories(path))
2123         LOG_ERROR("Failed to make all directories for path '%s'", path.utf8().data());
2124 }
2125
2126 void NetworkProcess::postStorageTask(CrossThreadTask&& task)
2127 {
2128     ASSERT(RunLoop::isMain());
2129     
2130     LockHolder locker(m_storageTaskMutex);
2131     
2132     m_storageTasks.append(WTFMove(task));
2133     
2134     m_storageTaskQueue->dispatch([this] {
2135         performNextStorageTask();
2136     });
2137 }
2138
2139 void NetworkProcess::performNextStorageTask()
2140 {
2141     ASSERT(!RunLoop::isMain());
2142     
2143     CrossThreadTask task;
2144     {
2145         LockHolder locker(m_storageTaskMutex);
2146         ASSERT(!m_storageTasks.isEmpty());
2147         task = m_storageTasks.takeFirst();
2148     }
2149     
2150     task.performTask();
2151 }
2152
2153 void NetworkProcess::accessToTemporaryFileComplete(const String& path)
2154 {
2155     // We've either hard linked the temporary blob file to the database directory, copied it there,
2156     // or the transaction is being aborted.
2157     // In any of those cases, we can delete the temporary blob file now.
2158     FileSystem::deleteFile(path);
2159 }
2160
2161 void NetworkProcess::collectIndexedDatabaseOriginsForVersion(const String& path, HashSet<WebCore::SecurityOriginData>& securityOrigins)
2162 {
2163     if (path.isEmpty())
2164         return;
2165
2166     for (auto& topOriginPath : FileSystem::listDirectory(path, "*")) {
2167         auto databaseIdentifier = FileSystem::pathGetFileName(topOriginPath);
2168         if (auto securityOrigin = SecurityOriginData::fromDatabaseIdentifier(databaseIdentifier)) {
2169             securityOrigins.add(WTFMove(*securityOrigin));
2170         
2171             for (auto& originPath : FileSystem::listDirectory(topOriginPath, "*")) {
2172                 databaseIdentifier = FileSystem::pathGetFileName(originPath);
2173                 if (auto securityOrigin = SecurityOriginData::fromDatabaseIdentifier(databaseIdentifier))
2174                     securityOrigins.add(WTFMove(*securityOrigin));
2175             }
2176         }
2177     }
2178 }
2179
2180 HashSet<WebCore::SecurityOriginData> NetworkProcess::indexedDatabaseOrigins(const String& path)
2181 {
2182     if (path.isEmpty())
2183         return { };
2184     
2185     HashSet<WebCore::SecurityOriginData> securityOrigins;
2186     collectIndexedDatabaseOriginsForVersion(FileSystem::pathByAppendingComponent(path, "v0"), securityOrigins);
2187     collectIndexedDatabaseOriginsForVersion(FileSystem::pathByAppendingComponent(path, "v1"), securityOrigins);
2188
2189     return securityOrigins;
2190 }
2191
2192 void NetworkProcess::addIndexedDatabaseSession(PAL::SessionID sessionID, String& indexedDatabaseDirectory, SandboxExtension::Handle& handle)
2193 {
2194     // *********
2195     // IMPORTANT: Do not change the directory structure for indexed databases on disk without first consulting a reviewer from Apple (<rdar://problem/17454712>)
2196     // *********
2197     auto addResult = m_idbDatabasePaths.add(sessionID, indexedDatabaseDirectory);
2198     if (addResult.isNewEntry) {
2199         SandboxExtension::consumePermanently(handle);
2200         if (!indexedDatabaseDirectory.isEmpty())
2201             postStorageTask(createCrossThreadTask(*this, &NetworkProcess::ensurePathExists, indexedDatabaseDirectory));
2202     }
2203 }
2204
2205 void NetworkProcess::setIDBPerOriginQuota(uint64_t quota)
2206 {
2207     m_idbPerOriginQuota = quota;
2208     
2209     for (auto& server : m_idbServers.values())
2210         server->setPerOriginQuota(quota);
2211 }
2212 #endif // ENABLE(INDEXED_DATABASE)
2213
2214 void NetworkProcess::updateQuotaBasedOnSpaceUsageForTesting(PAL::SessionID sessionID, const ClientOrigin& origin)
2215 {
2216     auto& manager = storageQuotaManager(sessionID, origin);
2217     manager.resetQuota(m_storageQuotaManagers.find(sessionID)->value.defaultQuota(origin));
2218     manager.updateQuotaBasedOnSpaceUsage();
2219 }
2220
2221 #if ENABLE(SANDBOX_EXTENSIONS)
2222 void NetworkProcess::getSandboxExtensionsForBlobFiles(const Vector<String>& filenames, CompletionHandler<void(SandboxExtension::HandleArray&&)>&& completionHandler)
2223 {
2224     parentProcessConnection()->sendWithAsyncReply(Messages::NetworkProcessProxy::GetSandboxExtensionsForBlobFiles(filenames), WTFMove(completionHandler));
2225 }
2226 #endif // ENABLE(SANDBOX_EXTENSIONS)
2227
2228 #if ENABLE(SERVICE_WORKER)
2229 WebSWServerToContextConnection* NetworkProcess::connectionToContextProcessFromIPCConnection(IPC::Connection& connection)
2230 {
2231     for (auto& serverToContextConnection : m_serverToContextConnections.values()) {
2232         if (serverToContextConnection->ipcConnection() == &connection)
2233             return serverToContextConnection.get();
2234     }
2235     return nullptr;
2236 }
2237
2238 void NetworkProcess::connectionToContextProcessWasClosed(Ref<WebSWServerToContextConnection>&& serverToContextConnection)
2239 {
2240     auto& registrableDomain = serverToContextConnection->registrableDomain();
2241     
2242     serverToContextConnection->connectionClosed();
2243     m_serverToContextConnections.remove(registrableDomain);
2244     
2245     for (auto& swServer : m_swServers.values())
2246         swServer->markAllWorkersForRegistrableDomainAsTerminated(registrableDomain);
2247     
2248     if (needsServerToContextConnectionForRegistrableDomain(registrableDomain)) {
2249         RELEASE_LOG(ServiceWorker, "Connection to service worker process was closed but is still needed, relaunching it");
2250         createServerToContextConnection(registrableDomain, WTF::nullopt);
2251     }
2252 }
2253
2254 bool NetworkProcess::needsServerToContextConnectionForRegistrableDomain(const RegistrableDomain& registrableDomain) const
2255 {
2256     return WTF::anyOf(m_swServers.values(), [&](auto& swServer) {
2257         return swServer->needsServerToContextConnectionForRegistrableDomain(registrableDomain);
2258     });
2259 }
2260
2261 SWServer& NetworkProcess::swServerForSession(PAL::SessionID sessionID)
2262 {
2263     ASSERT(sessionID.isValid());
2264     
2265     auto result = m_swServers.ensure(sessionID, [&] {
2266         auto path = m_swDatabasePaths.get(sessionID);
2267         // There should already be a registered path for this PAL::SessionID.
2268         // If there's not, then where did this PAL::SessionID come from?
2269         ASSERT(sessionID.isEphemeral() || !path.isEmpty());
2270         
2271         auto value = std::make_unique<SWServer>(makeUniqueRef<WebSWOriginStore>(), WTFMove(path), sessionID);
2272         if (m_shouldDisableServiceWorkerProcessTerminationDelay)
2273             value->disableServiceWorkerProcessTerminationDelay();
2274         return value;
2275     });
2276
2277     return *result.iterator->value;
2278 }
2279
2280 WebSWOriginStore& NetworkProcess::swOriginStoreForSession(PAL::SessionID sessionID)
2281 {
2282     return static_cast<WebSWOriginStore&>(swServerForSession(sessionID).originStore());
2283 }
2284
2285 WebSWOriginStore* NetworkProcess::existingSWOriginStoreForSession(PAL::SessionID sessionID) const
2286 {
2287     auto* swServer = m_swServers.get(sessionID);
2288     if (!swServer)
2289         return nullptr;
2290     return &static_cast<WebSWOriginStore&>(swServer->originStore());
2291 }
2292
2293 WebSWServerToContextConnection* NetworkProcess::serverToContextConnectionForRegistrableDomain(const RegistrableDomain& registrableDomain)
2294 {
2295     return m_serverToContextConnections.get(registrableDomain);
2296 }
2297
2298 void NetworkProcess::createServerToContextConnection(const RegistrableDomain& registrableDomain, Optional<PAL::SessionID> sessionID)
2299 {
2300     if (m_waitingForServerToContextProcessConnection)
2301         return;
2302     
2303     m_waitingForServerToContextProcessConnection = true;
2304     if (sessionID)
2305         parentProcessConnection()->send(Messages::NetworkProcessProxy::EstablishWorkerContextConnectionToNetworkProcessForExplicitSession(registrableDomain, *sessionID), 0);
2306     else
2307         parentProcessConnection()->send(Messages::NetworkProcessProxy::EstablishWorkerContextConnectionToNetworkProcess(registrableDomain), 0);
2308 }
2309
2310 void NetworkProcess::postMessageToServiceWorkerClient(const ServiceWorkerClientIdentifier& destinationIdentifier, MessageWithMessagePorts&& message, ServiceWorkerIdentifier sourceIdentifier, const String& sourceOrigin)
2311 {
2312     if (auto* connection = m_swServerConnections.get(destinationIdentifier.serverConnectionIdentifier))
2313         connection->postMessageToServiceWorkerClient(destinationIdentifier.contextIdentifier, WTFMove(message), sourceIdentifier, sourceOrigin);
2314 }
2315
2316 void NetworkProcess::postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destination, WebCore::MessageWithMessagePorts&& message, const WebCore::ServiceWorkerOrClientIdentifier& source, SWServerConnectionIdentifier connectionIdentifier)
2317 {
2318     if (auto* connection = m_swServerConnections.get(connectionIdentifier))
2319         connection->postMessageToServiceWorker(destination, WTFMove(message), source);
2320 }
2321
2322 void NetworkProcess::registerSWServerConnection(WebSWServerConnection& connection)
2323 {
2324     ASSERT(parentProcessHasServiceWorkerEntitlement());
2325     ASSERT(!m_swServerConnections.contains(connection.identifier()));
2326     m_swServerConnections.add(connection.identifier(), &connection);
2327     swOriginStoreForSession(connection.sessionID()).registerSWServerConnection(connection);
2328 }
2329
2330 void NetworkProcess::unregisterSWServerConnection(WebSWServerConnection& connection)
2331 {
2332     ASSERT(m_swServerConnections.get(connection.identifier()) == &connection);
2333     m_swServerConnections.remove(connection.identifier());
2334     if (auto* store = existingSWOriginStoreForSession(connection.sessionID()))
2335         store->unregisterSWServerConnection(connection);
2336 }
2337
2338 void NetworkProcess::swContextConnectionMayNoLongerBeNeeded(WebSWServerToContextConnection& serverToContextConnection)
2339 {
2340     auto& registrableDomain = serverToContextConnection.registrableDomain();
2341     if (needsServerToContextConnectionForRegistrableDomain(registrableDomain))
2342         return;
2343     
2344     RELEASE_LOG(ServiceWorker, "Service worker process is no longer needed, terminating it");
2345     serverToContextConnection.terminate();
2346     
2347     for (auto& swServer : m_swServers.values())
2348         swServer->markAllWorkersForRegistrableDomainAsTerminated(registrableDomain);
2349     
2350     serverToContextConnection.connectionClosed();
2351     m_serverToContextConnections.remove(registrableDomain);
2352 }
2353
2354 void NetworkProcess::disableServiceWorkerProcessTerminationDelay()
2355 {
2356     if (m_shouldDisableServiceWorkerProcessTerminationDelay)
2357         return;
2358     
2359     m_shouldDisableServiceWorkerProcessTerminationDelay = true;
2360     for (auto& swServer : m_swServers.values())
2361         swServer->disableServiceWorkerProcessTerminationDelay();
2362 }
2363
2364 void NetworkProcess::addServiceWorkerSession(PAL::SessionID sessionID, String& serviceWorkerRegistrationDirectory, const SandboxExtension::Handle& handle)
2365 {
2366     auto addResult = m_swDatabasePaths.add(sessionID, serviceWorkerRegistrationDirectory);
2367     if (addResult.isNewEntry) {
2368         SandboxExtension::consumePermanently(handle);
2369         if (!serviceWorkerRegistrationDirectory.isEmpty())
2370             postStorageTask(createCrossThreadTask(*this, &NetworkProcess::ensurePathExists, serviceWorkerRegistrationDirectory));
2371     }
2372 }
2373 #endif // ENABLE(SERVICE_WORKER)
2374
2375 void NetworkProcess::requestStorageSpace(PAL::SessionID sessionID, const ClientOrigin& origin, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t>)>&& callback)
2376 {
2377     parentProcessConnection()->sendWithAsyncReply(Messages::NetworkProcessProxy::RequestStorageSpace { sessionID, origin, quota, currentSize, spaceRequired }, WTFMove(callback), 0);
2378 }
2379
2380 class QuotaUserInitializer final : public WebCore::StorageQuotaUser {
2381 public:
2382     explicit QuotaUserInitializer(StorageQuotaManager& manager)
2383         : m_manager(makeWeakPtr(manager))
2384     {
2385         manager.addUser(*this);
2386     }
2387
2388     ~QuotaUserInitializer()
2389     {
2390         if (m_manager)
2391             m_manager->removeUser(*this);
2392         if (m_callback)
2393             m_callback();
2394     }
2395
2396 private:
2397     // StorageQuotaUser API.
2398     uint64_t spaceUsed() const final
2399     {
2400         ASSERT_NOT_REACHED();
2401         return 0;
2402     }
2403
2404     void whenInitialized(CompletionHandler<void()>&& callback) final
2405     {
2406         m_callback = WTFMove(callback);
2407     }
2408
2409     WeakPtr<StorageQuotaManager> m_manager;
2410     CompletionHandler<void()> m_callback;
2411 };
2412
2413 void NetworkProcess::initializeQuotaUsers(StorageQuotaManager& manager, PAL::SessionID sessionID, const ClientOrigin& origin)
2414 {
2415     RunLoop::main().dispatch([this, weakThis = makeWeakPtr(this), sessionID, origin, user = std::make_unique<QuotaUserInitializer>(manager)]() mutable {
2416         if (!weakThis)
2417             return;
2418         this->idbServer(sessionID).initializeQuotaUser(origin);
2419         CacheStorage::Engine::initializeQuotaUser(*this, sessionID, origin, [user = WTFMove(user)] { });
2420     });
2421 }
2422
2423 StorageQuotaManager& NetworkProcess::storageQuotaManager(PAL::SessionID sessionID, const ClientOrigin& origin)
2424 {
2425     auto& storageQuotaManagers = m_storageQuotaManagers.ensure(sessionID, [] {
2426         return StorageQuotaManagers { };
2427     }).iterator->value;
2428     return *storageQuotaManagers.managersPerOrigin().ensure(origin, [this, &storageQuotaManagers, sessionID, &origin] {
2429         auto manager = std::make_unique<StorageQuotaManager>(storageQuotaManagers.defaultQuota(origin), [this, sessionID, origin](uint64_t quota, uint64_t currentSpace, uint64_t spaceIncrease, auto callback) {
2430             this->requestStorageSpace(sessionID, origin, quota, currentSpace, spaceIncrease, WTFMove(callback));
2431         });
2432         initializeQuotaUsers(*manager, sessionID, origin);
2433         return manager;
2434     }).iterator->value;
2435 }
2436
2437 #if !PLATFORM(COCOA)
2438 void NetworkProcess::removeCredential(WebCore::Credential&&, WebCore::ProtectionSpace&&, CompletionHandler<void()>&& completionHandler)
2439 {
2440     completionHandler();
2441 }
2442
2443 void NetworkProcess::originsWithPersistentCredentials(CompletionHandler<void(Vector<WebCore::SecurityOriginData>)>&& completionHandler)
2444 {
2445     completionHandler(Vector<WebCore::SecurityOriginData>());
2446 }
2447
2448 void NetworkProcess::removeCredentialsWithOrigins(const Vector<WebCore::SecurityOriginData>&, CompletionHandler<void()>&& completionHandler)
2449 {
2450     completionHandler();
2451 }
2452
2453 void NetworkProcess::initializeProcess(const AuxiliaryProcessInitializationParameters&)
2454 {
2455 }
2456
2457 void NetworkProcess::initializeProcessName(const AuxiliaryProcessInitializationParameters&)
2458 {
2459 }
2460
2461 void NetworkProcess::initializeSandbox(const AuxiliaryProcessInitializationParameters&, SandboxInitializationParameters&)
2462 {
2463 }
2464
2465 void NetworkProcess::syncAllCookies()
2466 {
2467 }
2468
2469 void NetworkProcess::platformSyncAllCookies(CompletionHandler<void()>&& completionHandler)
2470 {
2471     completionHandler();
2472 }
2473
2474 #endif
2475
2476 void NetworkProcess::storeAdClickAttribution(PAL::SessionID sessionID, WebCore::AdClickAttribution&& adClickAttribution)
2477 {
2478     if (auto* session = networkSession(sessionID))
2479         session->storeAdClickAttribution(WTFMove(adClickAttribution));
2480 }
2481
2482 void NetworkProcess::dumpAdClickAttribution(PAL::SessionID sessionID, CompletionHandler<void(String)>&& completionHandler)
2483 {
2484     if (auto* session = networkSession(sessionID))
2485         return session->dumpAdClickAttribution(WTFMove(completionHandler));
2486
2487     completionHandler({ });
2488 }
2489
2490 void NetworkProcess::clearAdClickAttribution(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
2491 {
2492     if (auto* session = networkSession(sessionID))
2493         session->clearAdClickAttribution();
2494     
2495     completionHandler();
2496 }
2497
2498 void NetworkProcess::setAdClickAttributionOverrideTimerForTesting(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
2499 {
2500     if (auto* session = networkSession(sessionID))
2501         session->setAdClickAttributionOverrideTimerForTesting(value);
2502     
2503     completionHandler();
2504 }
2505
2506 void NetworkProcess::setAdClickAttributionConversionURLForTesting(PAL::SessionID sessionID, URL&& url, CompletionHandler<void()>&& completionHandler)
2507 {
2508     if (auto* session = networkSession(sessionID))
2509         session->setAdClickAttributionConversionURLForTesting(WTFMove(url));
2510     
2511     completionHandler();
2512 }
2513
2514 void NetworkProcess::markAdClickAttributionsAsExpiredForTesting(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
2515 {
2516     if (auto* session = networkSession(sessionID))
2517         session->markAdClickAttributionsAsExpiredForTesting();
2518
2519     completionHandler();
2520 }
2521
2522 void NetworkProcess::addKeptAliveLoad(Ref<NetworkResourceLoader>&& loader)
2523 {
2524     if (auto session = m_networkSessions.get(loader->sessionID()))
2525         session->addKeptAliveLoad(WTFMove(loader));
2526 }
2527
2528 void NetworkProcess::removeKeptAliveLoad(NetworkResourceLoader& loader)
2529 {
2530     if (auto session = m_networkSessions.get(loader.sessionID()))
2531         session->removeKeptAliveLoad(loader);
2532 }
2533
2534 } // namespace WebKit