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