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