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