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