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