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