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