2a98b304a13c6c69c4a4075fce05811e1176fa1e
[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 "ChildProcessMessages.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 "NetworkBlobRegistry.h"
41 #include "NetworkConnectionToWebProcess.h"
42 #include "NetworkContentRuleListManagerMessages.h"
43 #include "NetworkProcessCreationParameters.h"
44 #include "NetworkProcessPlatformStrategies.h"
45 #include "NetworkProcessProxyMessages.h"
46 #include "NetworkProximityManager.h"
47 #include "NetworkResourceLoader.h"
48 #include "NetworkSession.h"
49 #include "NetworkSessionCreationParameters.h"
50 #include "PreconnectTask.h"
51 #include "RemoteNetworkingContext.h"
52 #include "StatisticsData.h"
53 #include "WebCookieManager.h"
54 #include "WebPageProxyMessages.h"
55 #include "WebProcessPoolMessages.h"
56 #include "WebResourceLoadStatisticsStore.h"
57 #include "WebSWOriginStore.h"
58 #include "WebSWServerConnection.h"
59 #include "WebSWServerToContextConnection.h"
60 #include "WebsiteData.h"
61 #include "WebsiteDataFetchOption.h"
62 #include "WebsiteDataStore.h"
63 #include "WebsiteDataStoreParameters.h"
64 #include "WebsiteDataType.h"
65 #include <WebCore/DNS.h>
66 #include <WebCore/DeprecatedGlobalSettings.h>
67 #include <WebCore/DiagnosticLoggingClient.h>
68 #include <WebCore/LogInitialization.h>
69 #include <WebCore/MIMETypeRegistry.h>
70 #include <WebCore/NetworkStateNotifier.h>
71 #include <WebCore/NetworkStorageSession.h>
72 #include <WebCore/ResourceRequest.h>
73 #include <WebCore/RuntimeApplicationChecks.h>
74 #include <WebCore/SchemeRegistry.h>
75 #include <WebCore/SecurityOriginData.h>
76 #include <wtf/Algorithms.h>
77 #include <wtf/CallbackAggregator.h>
78 #include <wtf/OptionSet.h>
79 #include <wtf/ProcessPrivilege.h>
80 #include <wtf/RunLoop.h>
81 #include <wtf/text/AtomicString.h>
82
83 #if ENABLE(SEC_ITEM_SHIM)
84 #include "SecItemShim.h"
85 #endif
86
87 #include "NetworkCache.h"
88 #include "NetworkCacheCoders.h"
89
90 #if PLATFORM(COCOA)
91 #include "NetworkSessionCocoa.h"
92 #endif
93
94 #if ENABLE(SERVICE_WORKER)
95 #include "WebSWServerToContextConnectionMessages.h"
96 #endif
97
98 namespace WebKit {
99 using namespace WebCore;
100
101 static void callExitSoon(IPC::Connection*)
102 {
103     // If the connection has been closed and we haven't responded in the main thread for 10 seconds
104     // the process will exit forcibly.
105     auto watchdogDelay = 10_s;
106
107     WorkQueue::create("com.apple.WebKit.ChildProcess.WatchDogQueue")->dispatchAfter(watchdogDelay, [] {
108         // We use _exit here since the watchdog callback is called from another thread and we don't want
109         // global destructors or atexit handlers to be called from this thread while the main thread is busy
110         // doing its thing.
111         RELEASE_LOG_ERROR(IPC, "Exiting process early due to unacknowledged closed-connection");
112         _exit(EXIT_FAILURE);
113     });
114 }
115
116 NetworkProcess& NetworkProcess::singleton()
117 {
118     static NeverDestroyed<Ref<NetworkProcess>> networkProcess(adoptRef(*new NetworkProcess));
119     return networkProcess.get();
120 }
121
122 NetworkProcess::NetworkProcess()
123     : m_hasSetCacheModel(false)
124     , m_cacheModel(CacheModel::DocumentViewer)
125     , m_diskCacheIsDisabledForTesting(false)
126     , m_canHandleHTTPSServerTrustEvaluation(true)
127     , m_downloadManager(*this)
128 #if PLATFORM(COCOA)
129     , m_clearCacheDispatchGroup(0)
130 #endif
131 #if ENABLE(CONTENT_EXTENSIONS)
132     , m_networkContentRuleListManager(*this)
133 #endif
134     , m_storageTaskQueue(WorkQueue::create("com.apple.WebKit.StorageTask"))
135 #if ENABLE(INDEXED_DATABASE)
136     , m_idbPerOriginQuota(IDBServer::defaultPerOriginQuota)
137 #endif
138 {
139     NetworkProcessPlatformStrategies::initialize();
140
141     addSupplement<AuthenticationManager>();
142     addSupplement<WebCookieManager>();
143 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
144     addSupplement<LegacyCustomProtocolManager>();
145 #if PLATFORM(COCOA)
146     LegacyCustomProtocolManager::networkProcessCreated(*this);
147 #endif
148 #endif
149 #if ENABLE(PROXIMITY_NETWORKING)
150     addSupplement<NetworkProximityManager>();
151 #endif
152
153     NetworkStateNotifier::singleton().addListener([this](bool isOnLine) {
154         auto webProcessConnections = m_webProcessConnections;
155         for (auto& webProcessConnection : webProcessConnections)
156             webProcessConnection->setOnLineState(isOnLine);
157     });
158 }
159
160 NetworkProcess::~NetworkProcess()
161 {
162     for (auto& callbacks : m_cacheStorageParametersCallbacks.values()) {
163         for (auto& callback : callbacks)
164             callback(String { }, 0);
165     }
166 }
167
168 AuthenticationManager& NetworkProcess::authenticationManager()
169 {
170     return *supplement<AuthenticationManager>();
171 }
172
173 DownloadManager& NetworkProcess::downloadManager()
174 {
175     return m_downloadManager;
176 }
177
178 #if ENABLE(PROXIMITY_NETWORKING)
179 NetworkProximityManager& NetworkProcess::proximityManager()
180 {
181     return *supplement<NetworkProximityManager>();
182 }
183 #endif
184
185 void NetworkProcess::removeNetworkConnectionToWebProcess(NetworkConnectionToWebProcess* connection)
186 {
187     size_t vectorIndex = m_webProcessConnections.find(connection);
188     ASSERT(vectorIndex != notFound);
189
190     m_webProcessConnections.remove(vectorIndex);
191 }
192
193 bool NetworkProcess::shouldTerminate()
194 {
195     // Network process keeps session cookies and credentials, so it should never terminate (as long as UI process connection is alive).
196     return false;
197 }
198
199 void NetworkProcess::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
200 {
201     if (messageReceiverMap().dispatchMessage(connection, decoder))
202         return;
203
204     if (decoder.messageReceiverName() == Messages::ChildProcess::messageReceiverName()) {
205         ChildProcess::didReceiveMessage(connection, decoder);
206         return;
207     }
208
209 #if ENABLE(CONTENT_EXTENSIONS)
210     if (decoder.messageReceiverName() == Messages::NetworkContentRuleListManager::messageReceiverName()) {
211         m_networkContentRuleListManager.didReceiveMessage(connection, decoder);
212         return;
213     }
214 #endif
215
216 #if ENABLE(SERVICE_WORKER)
217     if (decoder.messageReceiverName() == Messages::WebSWServerToContextConnection::messageReceiverName()) {
218         ASSERT(parentProcessHasServiceWorkerEntitlement());
219         if (!parentProcessHasServiceWorkerEntitlement())
220             return;
221         if (auto* webSWConnection = connectionToContextProcessFromIPCConnection(connection)) {
222             webSWConnection->didReceiveMessage(connection, decoder);
223             return;
224         }
225     }
226 #endif
227     didReceiveNetworkProcessMessage(connection, decoder);
228 }
229
230 void NetworkProcess::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder)
231 {
232     if (messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder))
233         return;
234
235     didReceiveSyncNetworkProcessMessage(connection, decoder, replyEncoder);
236 }
237
238 void NetworkProcess::didClose(IPC::Connection&)
239 {
240     ASSERT(RunLoop::isMain());
241
242     // Make sure we flush all cookies to disk before exiting.
243     platformSyncAllCookies([this] {
244         stopRunLoop();
245     });
246 }
247
248 void NetworkProcess::didCreateDownload()
249 {
250     disableTermination();
251 }
252
253 void NetworkProcess::didDestroyDownload()
254 {
255     enableTermination();
256 }
257
258 IPC::Connection* NetworkProcess::downloadProxyConnection()
259 {
260     return parentProcessConnection();
261 }
262
263 AuthenticationManager& NetworkProcess::downloadsAuthenticationManager()
264 {
265     return authenticationManager();
266 }
267
268 void NetworkProcess::lowMemoryHandler(Critical critical)
269 {
270     if (m_suppressMemoryPressureHandler)
271         return;
272
273     WTF::releaseFastMallocFreeMemory();
274 }
275
276 void NetworkProcess::initializeNetworkProcess(NetworkProcessCreationParameters&& parameters)
277 {
278 #if HAVE(SEC_KEY_PROXY)
279     WTF::setProcessPrivileges({ ProcessPrivilege::CanAccessRawCookies });
280 #else
281     WTF::setProcessPrivileges({ ProcessPrivilege::CanAccessRawCookies, ProcessPrivilege::CanAccessCredentials });
282 #endif
283     WebCore::NetworkStorageSession::permitProcessToUseCookieAPI(true);
284     platformInitializeNetworkProcess(parameters);
285
286     WTF::Thread::setCurrentThreadIsUserInitiated();
287     AtomicString::init();
288
289     m_suppressMemoryPressureHandler = parameters.shouldSuppressMemoryPressureHandler;
290     if (!m_suppressMemoryPressureHandler) {
291         auto& memoryPressureHandler = MemoryPressureHandler::singleton();
292         memoryPressureHandler.setLowMemoryHandler([this] (Critical critical, Synchronous) {
293             lowMemoryHandler(critical);
294         });
295         memoryPressureHandler.install();
296     }
297
298     m_diskCacheIsDisabledForTesting = parameters.shouldUseTestingNetworkSession;
299
300     setCacheModel(parameters.cacheModel);
301
302     setCanHandleHTTPSServerTrustEvaluation(parameters.canHandleHTTPSServerTrustEvaluation);
303
304     if (parameters.shouldUseTestingNetworkSession)
305         NetworkStorageSession::switchToNewTestingSession();
306
307     SandboxExtension::consumePermanently(parameters.defaultDataStoreParameters.networkSessionParameters.resourceLoadStatisticsDirectoryExtensionHandle);
308
309     auto sessionID = parameters.defaultDataStoreParameters.networkSessionParameters.sessionID;
310     setSession(sessionID, NetworkSession::create(*this, WTFMove(parameters.defaultDataStoreParameters.networkSessionParameters)));
311
312 #if ENABLE(INDEXED_DATABASE)
313     addIndexedDatabaseSession(sessionID, parameters.defaultDataStoreParameters.indexedDatabaseDirectory, parameters.defaultDataStoreParameters.indexedDatabaseDirectoryExtensionHandle);
314 #endif
315
316 #if ENABLE(SERVICE_WORKER)
317     if (parentProcessHasServiceWorkerEntitlement()) {
318         addServiceWorkerSession(PAL::SessionID::defaultSessionID(), parameters.serviceWorkerRegistrationDirectory, parameters.serviceWorkerRegistrationDirectoryExtensionHandle);
319
320         for (auto& scheme : parameters.urlSchemesServiceWorkersCanHandle)
321             registerURLSchemeServiceWorkersCanHandle(scheme);
322
323         m_shouldDisableServiceWorkerProcessTerminationDelay = parameters.shouldDisableServiceWorkerProcessTerminationDelay;
324     }
325 #endif
326
327     auto* defaultSession = networkSession(PAL::SessionID::defaultSessionID());
328     for (const auto& cookie : parameters.defaultDataStoreParameters.pendingCookies)
329         defaultSession->networkStorageSession().setCookie(cookie);
330
331     for (auto& supplement : m_supplements.values())
332         supplement->initialize(parameters);
333
334     for (auto& scheme : parameters.urlSchemesRegisteredAsSecure)
335         registerURLSchemeAsSecure(scheme);
336
337     for (auto& scheme : parameters.urlSchemesRegisteredAsBypassingContentSecurityPolicy)
338         registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
339
340     for (auto& scheme : parameters.urlSchemesRegisteredAsLocal)
341         registerURLSchemeAsLocal(scheme);
342
343     for (auto& scheme : parameters.urlSchemesRegisteredAsNoAccess)
344         registerURLSchemeAsNoAccess(scheme);
345
346     for (auto& scheme : parameters.urlSchemesRegisteredAsDisplayIsolated)
347         registerURLSchemeAsDisplayIsolated(scheme);
348
349     for (auto& scheme : parameters.urlSchemesRegisteredAsCORSEnabled)
350         registerURLSchemeAsCORSEnabled(scheme);
351
352     for (auto& scheme : parameters.urlSchemesRegisteredAsCanDisplayOnlyIfCanRequest)
353         registerURLSchemeAsCanDisplayOnlyIfCanRequest(scheme);
354
355     RELEASE_LOG(Process, "%p - NetworkProcess::initializeNetworkProcess: Presenting process = %d", this, WebCore::presentingApplicationPID());
356 }
357
358 void NetworkProcess::initializeConnection(IPC::Connection* connection)
359 {
360     ChildProcess::initializeConnection(connection);
361
362     // We give a chance for didClose() to get called on the main thread but forcefully call _exit() after a delay
363     // in case the main thread is unresponsive or didClose() takes too long.
364     connection->setDidCloseOnConnectionWorkQueueCallback(callExitSoon);
365
366     for (auto& supplement : m_supplements.values())
367         supplement->initializeConnection(connection);
368 }
369
370 void NetworkProcess::createNetworkConnectionToWebProcess(bool isServiceWorkerProcess, WebCore::SecurityOriginData&& securityOrigin)
371 {
372 #if USE(UNIX_DOMAIN_SOCKETS)
373     IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection();
374
375     auto connection = NetworkConnectionToWebProcess::create(*this, socketPair.server);
376     m_webProcessConnections.append(WTFMove(connection));
377
378     IPC::Attachment clientSocket(socketPair.client);
379     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientSocket), 0);
380 #elif OS(DARWIN)
381     // Create the listening port.
382     mach_port_t listeningPort = MACH_PORT_NULL;
383     auto kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort);
384     if (kr != KERN_SUCCESS) {
385         RELEASE_LOG_ERROR(Process, "NetworkProcess::createNetworkConnectionToWebProcess: Could not allocate mach port, error %x", kr);
386         CRASH();
387     }
388     if (!MACH_PORT_VALID(listeningPort)) {
389         RELEASE_LOG_ERROR(Process, "NetworkProcess::createNetworkConnectionToWebProcess: Could not allocate mach port, returned port was invalid");
390         CRASH();
391     }
392
393     // Create a listening connection.
394     auto connection = NetworkConnectionToWebProcess::create(*this, IPC::Connection::Identifier(listeningPort));
395     m_webProcessConnections.append(WTFMove(connection));
396
397     IPC::Attachment clientPort(listeningPort, MACH_MSG_TYPE_MAKE_SEND);
398     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientPort), 0);
399 #elif OS(WINDOWS)
400     IPC::Connection::Identifier serverIdentifier, clientIdentifier;
401     if (!IPC::Connection::createServerAndClientIdentifiers(serverIdentifier, clientIdentifier)) {
402         LOG_ERROR("Failed to create server and client identifiers");
403         CRASH();
404     }
405
406     auto connection = NetworkConnectionToWebProcess::create(*this, serverIdentifier);
407     m_webProcessConnections.append(WTFMove(connection));
408
409     IPC::Attachment clientSocket(clientIdentifier);
410     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientSocket), 0);
411 #else
412     notImplemented();
413 #endif
414
415     if (!m_webProcessConnections.isEmpty())
416         m_webProcessConnections.last()->setOnLineState(NetworkStateNotifier::singleton().onLine());
417     
418 #if ENABLE(SERVICE_WORKER)
419     if (isServiceWorkerProcess && !m_webProcessConnections.isEmpty()) {
420         ASSERT(parentProcessHasServiceWorkerEntitlement());
421         ASSERT(m_waitingForServerToContextProcessConnection);
422         auto contextConnection = WebSWServerToContextConnection::create(*this, securityOrigin, m_webProcessConnections.last()->connection());
423         auto addResult = m_serverToContextConnections.add(WTFMove(securityOrigin), contextConnection.copyRef());
424         ASSERT_UNUSED(addResult, addResult.isNewEntry);
425
426         m_waitingForServerToContextProcessConnection = false;
427
428         for (auto* server : SWServer::allServers())
429             server->serverToContextConnectionCreated(contextConnection);
430     }
431 #else
432     UNUSED_PARAM(isServiceWorkerProcess);
433     UNUSED_PARAM(securityOrigin);
434 #endif
435 }
436
437 void NetworkProcess::clearCachedCredentials()
438 {
439     NetworkStorageSession::defaultStorageSession().credentialStorage().clearCredentials();
440     if (auto* networkSession = this->networkSession(PAL::SessionID::defaultSessionID()))
441         networkSession->clearCredentials();
442     else
443         ASSERT_NOT_REACHED();
444 }
445
446 void NetworkProcess::addWebsiteDataStore(WebsiteDataStoreParameters&& parameters)
447 {
448 #if ENABLE(INDEXED_DATABASE)
449     addIndexedDatabaseSession(parameters.networkSessionParameters.sessionID, parameters.indexedDatabaseDirectory, parameters.indexedDatabaseDirectoryExtensionHandle);
450 #endif
451
452 #if ENABLE(SERVICE_WORKER)
453     if (parentProcessHasServiceWorkerEntitlement())
454         addServiceWorkerSession(parameters.networkSessionParameters.sessionID, parameters.serviceWorkerRegistrationDirectory, parameters.serviceWorkerRegistrationDirectoryExtensionHandle);
455 #endif
456
457     RemoteNetworkingContext::ensureWebsiteDataStoreSession(*this, WTFMove(parameters));
458 }
459
460 NetworkSession* NetworkProcess::networkSession(const PAL::SessionID& sessionID) const
461 {
462     return m_networkSessions.get(sessionID);
463 }
464
465 void NetworkProcess::setSession(const PAL::SessionID& sessionID, Ref<NetworkSession>&& session)
466 {
467     m_networkSessions.set(sessionID, WTFMove(session));
468 }
469
470 void NetworkProcess::destroySession(const PAL::SessionID& sessionID)
471 {
472     if (auto session = m_networkSessions.take(sessionID))
473         session->get().invalidateAndCancel();
474     NetworkStorageSession::destroySession(sessionID);
475     m_sessionsControlledByAutomation.remove(sessionID);
476     CacheStorage::Engine::destroyEngine(*this, sessionID);
477
478 #if ENABLE(SERVICE_WORKER)
479     m_swServers.remove(sessionID);
480     m_swDatabasePaths.remove(sessionID);
481 #endif
482 }
483
484 void NetworkProcess::writeBlobToFilePath(const URL& url, const String& path, SandboxExtension::Handle&& handleForWriting, CompletionHandler<void(bool)>&& completionHandler)
485 {
486     auto extension = SandboxExtension::create(WTFMove(handleForWriting));
487     if (!extension) {
488         completionHandler(false);
489         return;
490     }
491
492     extension->consume();
493     NetworkBlobRegistry::singleton().writeBlobToFilePath(url, path, [extension = WTFMove(extension), completionHandler = WTFMove(completionHandler)] (bool success) mutable {
494         extension->revoke();
495         completionHandler(success);
496     });
497 }
498
499 #if ENABLE(RESOURCE_LOAD_STATISTICS)
500 void NetworkProcess::dumpResourceLoadStatistics(PAL::SessionID sessionID, uint64_t contextId)
501 {
502     if (auto* networkSession = this->networkSession(sessionID)) {
503         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics()) {
504             resourceLoadStatistics->dumpResourceLoadStatistics([this, contextId](const String& dumpedStatistics) {
505                 parentProcessConnection()->send(Messages::NetworkProcessProxy::DidDumpResourceLoadStatistics(dumpedStatistics, contextId), 0);
506             });
507         }
508     } else
509         ASSERT_NOT_REACHED();
510 }
511
512 void NetworkProcess::updatePrevalentDomainsToBlockCookiesFor(PAL::SessionID sessionID, const Vector<String>& domainsToBlock, uint64_t contextId)
513 {
514     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
515         networkStorageSession->setPrevalentDomainsToBlockCookiesFor(domainsToBlock);
516     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidUpdateBlockCookies(contextId), 0);
517 }
518
519 void NetworkProcess::isGrandfathered(PAL::SessionID sessionID, const String& targetPrimaryDomain, CompletionHandler<void(bool)>&& completionHandler)
520 {
521     if (auto* networkSession = this->networkSession(sessionID)) {
522         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
523             resourceLoadStatistics->isGrandfathered(targetPrimaryDomain, WTFMove(completionHandler));
524     } else
525         ASSERT_NOT_REACHED();
526 }
527
528 void NetworkProcess::isPrevalentResource(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void(bool)>&& completionHandler)
529 {
530     if (auto* networkSession = this->networkSession(sessionID)) {
531         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
532             resourceLoadStatistics->isPrevalentResource(resourceDomain, WTFMove(completionHandler));
533     } else
534         ASSERT_NOT_REACHED();
535 }
536
537 void NetworkProcess::isVeryPrevalentResource(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void(bool)>&& completionHandler)
538 {
539     if (auto* networkSession = this->networkSession(sessionID)) {
540         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
541             resourceLoadStatistics->isVeryPrevalentResource(resourceDomain, WTFMove(completionHandler));
542     } else
543         ASSERT_NOT_REACHED();
544 }
545
546 void NetworkProcess::setAgeCapForClientSideCookies(PAL::SessionID sessionID, Optional<Seconds> seconds, uint64_t contextId)
547 {
548     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
549         networkStorageSession->setAgeCapForClientSideCookies(seconds);
550     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidSetAgeCapForClientSideCookies(contextId), 0);
551 }
552
553 void NetworkProcess::setGrandfathered(PAL::SessionID sessionID, const String& resourceDomain, bool isGrandfathered, CompletionHandler<void()>&& completionHandler)
554 {
555     if (auto* networkSession = this->networkSession(sessionID)) {
556         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
557             resourceLoadStatistics->setGrandfathered(resourceDomain, isGrandfathered, WTFMove(completionHandler));
558     } else
559         ASSERT_NOT_REACHED();
560 }
561
562 void NetworkProcess::setPrevalentResource(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void()>&& completionHandler)
563 {
564     if (auto* networkSession = this->networkSession(sessionID)) {
565         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
566             resourceLoadStatistics->setPrevalentResource(resourceDomain, WTFMove(completionHandler));
567     } else
568         ASSERT_NOT_REACHED();
569 }
570
571 void NetworkProcess::setPrevalentResourceForDebugMode(PAL::SessionID sessionID, String resourceDomain, CompletionHandler<void()>&& completionHandler)
572 {
573     if (auto* networkSession = this->networkSession(sessionID)) {
574         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
575             resourceLoadStatistics->setPrevalentResourceForDebugMode(resourceDomain, WTFMove(completionHandler));
576     } else
577         ASSERT_NOT_REACHED();
578 }
579
580 void NetworkProcess::setVeryPrevalentResource(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void()>&& completionHandler)
581 {
582     if (auto* networkSession = this->networkSession(sessionID)) {
583         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
584             resourceLoadStatistics->setVeryPrevalentResource(resourceDomain, WTFMove(completionHandler));
585     } else
586         ASSERT_NOT_REACHED();
587 }
588
589 void NetworkProcess::clearPrevalentResource(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void()>&& completionHandler)
590 {
591     if (auto* networkSession = this->networkSession(sessionID)) {
592         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
593             resourceLoadStatistics->clearPrevalentResource(resourceDomain, WTFMove(completionHandler));
594     } else
595         ASSERT_NOT_REACHED();
596 }
597
598 void NetworkProcess::submitTelemetry(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
599 {
600     if (auto* networkSession = this->networkSession(sessionID)) {
601         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
602             resourceLoadStatistics->submitTelemetry(WTFMove(completionHandler));
603     } else
604         ASSERT_NOT_REACHED();
605 }
606
607 void NetworkProcess::scheduleCookieBlockingUpdate(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
608 {
609     if (auto* networkSession = this->networkSession(sessionID)) {
610         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
611             resourceLoadStatistics->scheduleCookieBlockingUpdate(WTFMove(completionHandler));
612     } else
613         ASSERT_NOT_REACHED();
614 }
615
616 void NetworkProcess::scheduleClearInMemoryAndPersistent(PAL::SessionID sessionID, Optional<WallTime> modifiedSince, bool shouldGrandfather, CompletionHandler<void()>&& completionHandler)
617 {
618     if (auto* networkSession = this->networkSession(sessionID)) {
619         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics()) {
620             auto grandfather = shouldGrandfather ? ShouldGrandfather::Yes : ShouldGrandfather::No;
621             if (modifiedSince)
622                 resourceLoadStatistics->scheduleClearInMemoryAndPersistent(modifiedSince.value(), grandfather, WTFMove(completionHandler));
623             else
624                 resourceLoadStatistics->scheduleClearInMemoryAndPersistent(grandfather, WTFMove(completionHandler));
625         }
626     } else
627         ASSERT_NOT_REACHED();
628 }
629
630 void NetworkProcess::resetParametersToDefaultValues(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
631 {
632     if (auto* networkSession = this->networkSession(sessionID)) {
633         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
634             resourceLoadStatistics->resetParametersToDefaultValues(WTFMove(completionHandler));
635     } else
636         ASSERT_NOT_REACHED();
637 }
638
639 void NetworkProcess::scheduleStatisticsAndDataRecordsProcessing(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
640 {
641     if (auto* networkSession = this->networkSession(sessionID)) {
642         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
643             resourceLoadStatistics->scheduleStatisticsAndDataRecordsProcessing(WTFMove(completionHandler));
644     } else
645         ASSERT_NOT_REACHED();
646 }
647
648 void NetworkProcess::setNotifyPagesWhenDataRecordsWereScanned(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
649 {
650     if (auto* networkSession = this->networkSession(sessionID)) {
651         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
652             resourceLoadStatistics->setNotifyPagesWhenDataRecordsWereScanned(value, WTFMove(completionHandler));
653     } else
654         ASSERT_NOT_REACHED();
655 }
656
657 void NetworkProcess::setNotifyPagesWhenTelemetryWasCaptured(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
658 {
659     if (auto* networkSession = this->networkSession(sessionID)) {
660         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
661             resourceLoadStatistics->setNotifyPagesWhenTelemetryWasCaptured(value, WTFMove(completionHandler));
662     } else
663         ASSERT_NOT_REACHED();
664 }
665
666 void NetworkProcess::setSubframeUnderTopFrameOrigin(PAL::SessionID sessionID, String subframe, String topFrame, CompletionHandler<void()>&& completionHandler)
667 {
668     if (auto* networkSession = this->networkSession(sessionID)) {
669         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
670             resourceLoadStatistics->setSubframeUnderTopFrameOrigin(subframe, topFrame, WTFMove(completionHandler));
671     } else
672         ASSERT_NOT_REACHED();
673 }
674
675 void NetworkProcess::isRegisteredAsRedirectingTo(PAL::SessionID sessionID, const String& redirectedFrom, const String& redirectedTo, CompletionHandler<void(bool)>&& completionHandler)
676 {
677     if (auto* networkSession = this->networkSession(sessionID)) {
678         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
679             resourceLoadStatistics->isRegisteredAsRedirectingTo(redirectedFrom, redirectedTo, WTFMove(completionHandler));
680     } else
681         ASSERT_NOT_REACHED();
682 }
683
684 void NetworkProcess::isRegisteredAsSubFrameUnder(PAL::SessionID sessionID, const String& subframe, const String& topFrame, CompletionHandler<void(bool)>&& completionHandler)
685 {
686     if (auto* networkSession = this->networkSession(sessionID)) {
687         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
688             resourceLoadStatistics->isRegisteredAsSubFrameUnder(subframe, topFrame, WTFMove(completionHandler));
689     } else
690         ASSERT_NOT_REACHED();
691 }
692
693 void NetworkProcess::setSubresourceUnderTopFrameOrigin(PAL::SessionID sessionID, String subresource, String topFrame, CompletionHandler<void()>&& completionHandler)
694 {
695     if (auto* networkSession = this->networkSession(sessionID)) {
696         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
697             resourceLoadStatistics->setSubresourceUnderTopFrameOrigin(subresource, topFrame, WTFMove(completionHandler));
698     } else
699         ASSERT_NOT_REACHED();
700 }
701
702 void NetworkProcess::setSubresourceUniqueRedirectTo(PAL::SessionID sessionID, String subresource, String hostNameRedirectedTo, CompletionHandler<void()>&& completionHandler)
703 {
704     if (auto* networkSession = this->networkSession(sessionID)) {
705         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
706             resourceLoadStatistics->setSubresourceUniqueRedirectTo(subresource, hostNameRedirectedTo, WTFMove(completionHandler));
707     } else
708         ASSERT_NOT_REACHED();
709 }
710
711 void NetworkProcess::setSubresourceUniqueRedirectFrom(PAL::SessionID sessionID, String subresource, String hostNameRedirectedFrom, CompletionHandler<void()>&& completionHandler)
712 {
713     if (auto* networkSession = this->networkSession(sessionID)) {
714         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
715             resourceLoadStatistics->setSubresourceUniqueRedirectFrom(subresource, hostNameRedirectedFrom, WTFMove(completionHandler));
716     } else
717         ASSERT_NOT_REACHED();
718 }
719
720 void NetworkProcess::isRegisteredAsSubresourceUnder(PAL::SessionID sessionID, const String& subresource, const String& topFrame, CompletionHandler<void(bool)>&& completionHandler)
721 {
722     if (auto* networkSession = this->networkSession(sessionID)) {
723         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
724             resourceLoadStatistics->isRegisteredAsSubresourceUnder(subresource, topFrame, WTFMove(completionHandler));
725     } else
726         ASSERT_NOT_REACHED();
727 }
728
729 void NetworkProcess::setTopFrameUniqueRedirectTo(PAL::SessionID sessionID, String topFrameHostName, String hostNameRedirectedTo, CompletionHandler<void()>&& completionHandler)
730 {
731     if (auto* networkSession = this->networkSession(sessionID)) {
732         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
733             resourceLoadStatistics->setTopFrameUniqueRedirectTo(topFrameHostName, hostNameRedirectedTo, WTFMove(completionHandler));
734     } else
735         ASSERT_NOT_REACHED();
736 }
737
738 void NetworkProcess::setTopFrameUniqueRedirectFrom(PAL::SessionID sessionID, String topFrameHostName, String hostNameRedirectedFrom, CompletionHandler<void()>&& completionHandler)
739 {
740     if (auto* networkSession = this->networkSession(sessionID)) {
741         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
742             resourceLoadStatistics->setTopFrameUniqueRedirectFrom(topFrameHostName, hostNameRedirectedFrom, WTFMove(completionHandler));
743     } else
744         ASSERT_NOT_REACHED();
745 }
746     
747     
748 void NetworkProcess::setLastSeen(PAL::SessionID sessionID, const String& resourceDomain, Seconds seconds, CompletionHandler<void()>&& completionHandler)
749 {
750     if (auto* networkSession = this->networkSession(sessionID)) {
751         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
752             resourceLoadStatistics->setLastSeen(resourceDomain, seconds, WTFMove(completionHandler));
753     } else
754         ASSERT_NOT_REACHED();
755 }
756
757 void NetworkProcess::hasStorageAccessForFrame(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, uint64_t contextId)
758 {
759     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
760         parentProcessConnection()->send(Messages::NetworkProcessProxy::StorageAccessOperationResult(networkStorageSession->hasStorageAccess(resourceDomain, firstPartyDomain, frameID, pageID), contextId), 0);
761     else
762         ASSERT_NOT_REACHED();
763 }
764
765 void NetworkProcess::getAllStorageAccessEntries(PAL::SessionID sessionID, uint64_t contextId)
766 {
767     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
768         parentProcessConnection()->send(Messages::NetworkProcessProxy::AllStorageAccessEntriesResult(networkStorageSession->getAllStorageAccessEntries(), contextId), 0);
769     else
770         ASSERT_NOT_REACHED();
771 }
772
773 void NetworkProcess::hasStorageAccess(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, Optional<uint64_t> frameID, uint64_t pageID, CompletionHandler<void(bool)>&& completionHandler)
774 {
775     if (auto* networkSession = this->networkSession(sessionID)) {
776         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
777             resourceLoadStatistics->hasStorageAccess(resourceDomain, firstPartyDomain, frameID, pageID, WTFMove(completionHandler));
778     } else
779         ASSERT_NOT_REACHED();
780 }
781
782 void NetworkProcess::requestStorageAccess(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, Optional<uint64_t> frameID, uint64_t pageID, bool promptEnabled, uint64_t contextId)
783 {
784     if (auto* networkSession = this->networkSession(sessionID)) {
785         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics()) {
786             resourceLoadStatistics->requestStorageAccess(resourceDomain, firstPartyDomain, frameID, pageID, promptEnabled, [this, contextId](StorageAccessStatus promptAccepted) {
787                 parentProcessConnection()->send(Messages::NetworkProcessProxy::StorageAccessRequestResult(static_cast<unsigned>(promptAccepted), contextId), 0);
788             });
789         }
790     } else
791         ASSERT_NOT_REACHED();
792 }
793
794 void NetworkProcess::grantStorageAccess(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, Optional<uint64_t> frameID, uint64_t pageID, bool userWasPrompted, uint64_t contextId)
795 {
796     bool isStorageGranted = false;
797     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID)) {
798         networkStorageSession->grantStorageAccess(resourceDomain, firstPartyDomain, frameID, pageID);
799         ASSERT(networkStorageSession->hasStorageAccess(resourceDomain, firstPartyDomain, frameID, pageID));
800         isStorageGranted = true;
801     } else
802         ASSERT_NOT_REACHED();
803
804     parentProcessConnection()->send(Messages::NetworkProcessProxy::StorageAccessOperationResult(isStorageGranted, contextId), 0);
805 }
806
807 void NetworkProcess::logFrameNavigation(PAL::SessionID sessionID, const String& targetPrimaryDomain, const String& mainFramePrimaryDomain, const String& sourcePrimaryDomain, const String& targetHost, const String& mainFrameHost, bool isRedirect, bool isMainFrame)
808 {
809     if (auto* networkSession = this->networkSession(sessionID)) {
810         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
811             resourceLoadStatistics->logFrameNavigation(targetPrimaryDomain, mainFramePrimaryDomain, sourcePrimaryDomain, targetHost, mainFrameHost, isRedirect, isMainFrame);
812     } else
813         ASSERT_NOT_REACHED();
814 }
815
816 void NetworkProcess::logUserInteraction(PAL::SessionID sessionID, const String& targetPrimaryDomain, CompletionHandler<void()>&& completionHandler)
817 {
818     if (auto* networkSession = this->networkSession(sessionID)) {
819         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
820             resourceLoadStatistics->logUserInteraction(targetPrimaryDomain, WTFMove(completionHandler));
821     } else
822         ASSERT_NOT_REACHED();
823 }
824
825 void NetworkProcess::hadUserInteraction(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void(bool)>&& completionHandler)
826 {
827     if (auto* networkSession = this->networkSession(sessionID)) {
828         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics()) {
829             resourceLoadStatistics->hasHadUserInteraction(resourceDomain, WTFMove(completionHandler));
830         }
831     } else
832         ASSERT_NOT_REACHED();
833 }
834
835 void NetworkProcess::clearUserInteraction(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void()>&& completionHandler)
836 {
837     if (auto* networkSession = this->networkSession(sessionID)) {
838         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
839             resourceLoadStatistics->clearUserInteraction(resourceDomain, WTFMove(completionHandler));
840     } else
841         ASSERT_NOT_REACHED();
842 }
843
844 void NetworkProcess::removeAllStorageAccess(PAL::SessionID sessionID, uint64_t contextId)
845 {
846     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
847         networkStorageSession->removeAllStorageAccess();
848     else
849         ASSERT_NOT_REACHED();
850     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidRemoveAllStorageAccess(contextId), 0);
851 }
852
853 void NetworkProcess::removePrevalentDomains(PAL::SessionID sessionID, const Vector<String>& domains)
854 {
855     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
856         networkStorageSession->removePrevalentDomains(domains);
857 }
858
859 void NetworkProcess::setCacheMaxAgeCapForPrevalentResources(PAL::SessionID sessionID, Seconds seconds, uint64_t contextId)
860 {
861     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
862         networkStorageSession->setCacheMaxAgeCapForPrevalentResources(Seconds { seconds });
863     else
864         ASSERT_NOT_REACHED();
865     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidSetCacheMaxAgeCapForPrevalentResources(contextId), 0);
866 }
867
868 void NetworkProcess::setGrandfatheringTime(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
869 {
870     if (auto* networkSession = this->networkSession(sessionID)) {
871         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
872             resourceLoadStatistics->setGrandfatheringTime(seconds, WTFMove(completionHandler));
873     } else
874         ASSERT_NOT_REACHED();
875 }
876
877 void NetworkProcess::setMaxStatisticsEntries(PAL::SessionID sessionID, uint64_t maximumEntryCount, CompletionHandler<void()>&& completionHandler)
878 {
879     if (auto* networkSession = this->networkSession(sessionID)) {
880         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
881             resourceLoadStatistics->setMaxStatisticsEntries(maximumEntryCount, WTFMove(completionHandler));
882     } else
883         ASSERT_NOT_REACHED();
884 }
885
886 void NetworkProcess::setMinimumTimeBetweenDataRecordsRemoval(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
887 {
888     if (auto* networkSession = this->networkSession(sessionID)) {
889         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
890             resourceLoadStatistics->setMinimumTimeBetweenDataRecordsRemoval(seconds, WTFMove(completionHandler));
891     } else
892         ASSERT_NOT_REACHED();
893 }
894
895 void NetworkProcess::setPruneEntriesDownTo(PAL::SessionID sessionID, uint64_t pruneTargetCount, CompletionHandler<void()>&& completionHandler)
896 {
897     if (auto* networkSession = this->networkSession(sessionID)) {
898         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
899             resourceLoadStatistics->setPruneEntriesDownTo(pruneTargetCount, WTFMove(completionHandler));
900     } else
901         ASSERT_NOT_REACHED();
902 }
903
904 void NetworkProcess::setTimeToLiveUserInteraction(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
905 {
906     if (auto* networkSession = this->networkSession(sessionID)) {
907         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
908             resourceLoadStatistics->setTimeToLiveUserInteraction(seconds, WTFMove(completionHandler));
909     } else
910         ASSERT_NOT_REACHED();
911 }
912
913 void NetworkProcess::setShouldClassifyResourcesBeforeDataRecordsRemoval(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
914 {
915     if (auto* networkSession = this->networkSession(sessionID)) {
916         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
917             resourceLoadStatistics->setShouldClassifyResourcesBeforeDataRecordsRemoval(value, WTFMove(completionHandler));
918     } else
919         ASSERT_NOT_REACHED();
920 }
921
922 void NetworkProcess::setResourceLoadStatisticsEnabled(bool enabled)
923 {
924     for (auto& networkSession : m_networkSessions.values())
925         networkSession.get().setResourceLoadStatisticsEnabled(enabled);
926 }
927
928 void NetworkProcess::setResourceLoadStatisticsDebugMode(PAL::SessionID sessionID, bool debugMode, CompletionHandler<void()>&& completionHandler)
929 {
930     if (auto* networkSession = this->networkSession(sessionID)) {
931         if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
932             resourceLoadStatistics->setResourceLoadStatisticsDebugMode(debugMode, WTFMove(completionHandler));
933     } else
934         ASSERT_NOT_REACHED();
935 }
936
937 void NetworkProcess::resetCacheMaxAgeCapForPrevalentResources(PAL::SessionID sessionID, uint64_t contextId)
938 {
939     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
940         networkStorageSession->resetCacheMaxAgeCapForPrevalentResources();
941     else
942         ASSERT_NOT_REACHED();
943     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidUpdateRuntimeSettings(contextId), 0);
944 }
945 #endif // ENABLE(RESOURCE_LOAD_STATISTICS)
946
947 bool NetworkProcess::sessionIsControlledByAutomation(PAL::SessionID sessionID) const
948 {
949     return m_sessionsControlledByAutomation.contains(sessionID);
950 }
951
952 void NetworkProcess::setSessionIsControlledByAutomation(PAL::SessionID sessionID, bool controlled)
953 {
954     if (controlled)
955         m_sessionsControlledByAutomation.add(sessionID);
956     else
957         m_sessionsControlledByAutomation.remove(sessionID);
958 }
959
960 static void fetchDiskCacheEntries(NetworkCache::Cache* cache, PAL::SessionID sessionID, OptionSet<WebsiteDataFetchOption> fetchOptions, CompletionHandler<void(Vector<WebsiteData::Entry>)>&& completionHandler)
961 {
962     if (!cache) {
963         RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler)] () mutable {
964             completionHandler({ });
965         });
966         return;
967     }
968     
969     HashMap<SecurityOriginData, uint64_t> originsAndSizes;
970     cache->traverse([fetchOptions, completionHandler = WTFMove(completionHandler), originsAndSizes = WTFMove(originsAndSizes)](auto* traversalEntry) mutable {
971         if (!traversalEntry) {
972             Vector<WebsiteData::Entry> entries;
973
974             for (auto& originAndSize : originsAndSizes)
975                 entries.append(WebsiteData::Entry { originAndSize.key, WebsiteDataType::DiskCache, originAndSize.value });
976
977             RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), entries = WTFMove(entries)] () mutable {
978                 completionHandler(entries);
979             });
980
981             return;
982         }
983
984         auto url = traversalEntry->entry.response().url();
985         auto result = originsAndSizes.add({url.protocol().toString(), url.host().toString(), url.port()}, 0);
986
987         if (fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes))
988             result.iterator->value += traversalEntry->entry.sourceStorageRecord().header.size() + traversalEntry->recordInfo.bodySize;
989     });
990 }
991
992 void NetworkProcess::fetchWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, uint64_t callbackID)
993 {
994     struct CallbackAggregator final : public RefCounted<CallbackAggregator> {
995         explicit CallbackAggregator(Function<void (WebsiteData)>&& completionHandler)
996             : m_completionHandler(WTFMove(completionHandler))
997         {
998         }
999
1000         ~CallbackAggregator()
1001         {
1002             RunLoop::main().dispatch([completionHandler = WTFMove(m_completionHandler), websiteData = WTFMove(m_websiteData)] () mutable {
1003                 completionHandler(websiteData);
1004             });
1005         }
1006
1007         CompletionHandler<void(WebsiteData)> m_completionHandler;
1008         WebsiteData m_websiteData;
1009     };
1010
1011     auto callbackAggregator = adoptRef(*new CallbackAggregator([this, callbackID] (WebsiteData websiteData) {
1012         parentProcessConnection()->send(Messages::NetworkProcessProxy::DidFetchWebsiteData(callbackID, websiteData), 0);
1013     }));
1014
1015     if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
1016         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
1017             networkStorageSession->getHostnamesWithCookies(callbackAggregator->m_websiteData.hostNamesWithCookies);
1018     }
1019
1020     if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
1021         if (NetworkStorageSession::storageSession(sessionID))
1022             callbackAggregator->m_websiteData.originsWithCredentials = NetworkStorageSession::storageSession(sessionID)->credentialStorage().originsWithCredentials();
1023     }
1024
1025     if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) {
1026         CacheStorage::Engine::fetchEntries(*this, sessionID, fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes), [callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
1027             callbackAggregator->m_websiteData.entries.appendVector(entries);
1028         });
1029     }
1030
1031 #if PLATFORM(COCOA)
1032     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
1033         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
1034             getHostNamesWithHSTSCache(*networkStorageSession, callbackAggregator->m_websiteData.hostNamesWithHSTSCache);
1035     }
1036 #endif
1037
1038 #if ENABLE(INDEXED_DATABASE)
1039     auto path = m_idbDatabasePaths.get(sessionID);
1040     if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases)) {
1041         // FIXME: Pick the right database store based on the session ID.
1042         postStorageTask(CrossThreadTask([this, callbackAggregator = callbackAggregator.copyRef(), path = WTFMove(path)]() mutable {
1043             RunLoop::main().dispatch([callbackAggregator = WTFMove(callbackAggregator), securityOrigins = indexedDatabaseOrigins(path)] {
1044                 for (const auto& securityOrigin : securityOrigins)
1045                     callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::IndexedDBDatabases, 0 });
1046             });
1047         }));
1048     }
1049 #endif
1050
1051 #if ENABLE(SERVICE_WORKER)
1052     path = m_swDatabasePaths.get(sessionID);
1053     if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations)) {
1054         swServerForSession(sessionID).getOriginsWithRegistrations([callbackAggregator = callbackAggregator.copyRef()](const HashSet<SecurityOriginData>& securityOrigins) mutable {
1055             for (auto& origin : securityOrigins)
1056                 callbackAggregator->m_websiteData.entries.append({ origin, WebsiteDataType::ServiceWorkerRegistrations, 0 });
1057         });
1058     }
1059 #endif
1060
1061     if (websiteDataTypes.contains(WebsiteDataType::DiskCache)) {
1062         fetchDiskCacheEntries(cache(), sessionID, fetchOptions, [callbackAggregator = WTFMove(callbackAggregator)](auto entries) mutable {
1063             callbackAggregator->m_websiteData.entries.appendVector(entries);
1064         });
1065     }
1066 }
1067
1068 void NetworkProcess::deleteWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, WallTime modifiedSince, uint64_t callbackID)
1069 {
1070 #if PLATFORM(COCOA)
1071     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
1072         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
1073             clearHSTSCache(*networkStorageSession, modifiedSince);
1074     }
1075 #endif
1076
1077     if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
1078         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
1079             networkStorageSession->deleteAllCookiesModifiedSince(modifiedSince);
1080     }
1081
1082     if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
1083         if (NetworkStorageSession::storageSession(sessionID))
1084             NetworkStorageSession::storageSession(sessionID)->credentialStorage().clearCredentials();
1085     }
1086
1087     auto clearTasksHandler = WTF::CallbackAggregator::create([this, callbackID] {
1088         parentProcessConnection()->send(Messages::NetworkProcessProxy::DidDeleteWebsiteData(callbackID), 0);
1089     });
1090
1091     if (websiteDataTypes.contains(WebsiteDataType::DOMCache))
1092         CacheStorage::Engine::clearAllCaches(*this, sessionID, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1093
1094 #if ENABLE(INDEXED_DATABASE)
1095     if (websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases) && !sessionID.isEphemeral())
1096         idbServer(sessionID).closeAndDeleteDatabasesModifiedSince(modifiedSince, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1097 #endif
1098
1099 #if ENABLE(SERVICE_WORKER)
1100     if (websiteDataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations) && !sessionID.isEphemeral())
1101         swServerForSession(sessionID).clearAll([clearTasksHandler = clearTasksHandler.copyRef()] { });
1102 #endif
1103
1104     if (websiteDataTypes.contains(WebsiteDataType::DiskCache) && !sessionID.isEphemeral())
1105         clearDiskCache(modifiedSince, [clearTasksHandler = WTFMove(clearTasksHandler)] { });
1106
1107 #if ENABLE(RESOURCE_LOAD_STATISTICS)
1108     if (websiteDataTypes.contains(WebsiteDataType::ResourceLoadStatistics)) {
1109         if (auto* networkSession = this->networkSession(sessionID)) {
1110             if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics()) {
1111                 auto deletedTypesRaw = websiteDataTypes.toRaw();
1112                 auto monitoredTypesRaw = WebResourceLoadStatisticsStore::monitoredDataTypes().toRaw();
1113
1114                 // If we are deleting all of the data types that the resource load statistics store monitors
1115                 // we do not need to re-grandfather old data.
1116                 auto shouldGrandfather = ((monitoredTypesRaw & deletedTypesRaw) == monitoredTypesRaw) ? ShouldGrandfather::No : ShouldGrandfather::Yes;
1117
1118                 resourceLoadStatistics->scheduleClearInMemoryAndPersistent(modifiedSince, shouldGrandfather, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1119             }
1120         }
1121     }
1122 #endif
1123 }
1124
1125 static void clearDiskCacheEntries(NetworkCache::Cache* cache, const Vector<SecurityOriginData>& origins, CompletionHandler<void()>&& completionHandler)
1126 {
1127     if (!cache) {
1128         RunLoop::main().dispatch(WTFMove(completionHandler));
1129         return;
1130     }
1131
1132     HashSet<RefPtr<SecurityOrigin>> originsToDelete;
1133     for (auto& origin : origins)
1134         originsToDelete.add(origin.securityOrigin());
1135
1136     Vector<NetworkCache::Key> cacheKeysToDelete;
1137     cache->traverse([cache, completionHandler = WTFMove(completionHandler), originsToDelete = WTFMove(originsToDelete), cacheKeysToDelete = WTFMove(cacheKeysToDelete)](auto* traversalEntry) mutable {
1138         if (traversalEntry) {
1139             if (originsToDelete.contains(SecurityOrigin::create(traversalEntry->entry.response().url())))
1140                 cacheKeysToDelete.append(traversalEntry->entry.key());
1141             return;
1142         }
1143
1144         cache->remove(cacheKeysToDelete, WTFMove(completionHandler));
1145         return;
1146     });
1147 }
1148
1149 void NetworkProcess::deleteWebsiteDataForOrigins(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, const Vector<SecurityOriginData>& originDatas, const Vector<String>& cookieHostNames, const Vector<String>& HSTSCacheHostNames, uint64_t callbackID)
1150 {
1151     if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
1152         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
1153             networkStorageSession->deleteCookiesForHostnames(cookieHostNames);
1154     }
1155
1156 #if PLATFORM(COCOA)
1157     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
1158         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
1159             deleteHSTSCacheForHostNames(*networkStorageSession, HSTSCacheHostNames);
1160     }
1161 #endif
1162
1163     auto clearTasksHandler = WTF::CallbackAggregator::create([this, callbackID] {
1164         parentProcessConnection()->send(Messages::NetworkProcessProxy::DidDeleteWebsiteDataForOrigins(callbackID), 0);
1165     });
1166
1167     if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) {
1168         for (auto& originData : originDatas)
1169             CacheStorage::Engine::clearCachesForOrigin(*this, sessionID, SecurityOriginData { originData }, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1170     }
1171
1172 #if ENABLE(INDEXED_DATABASE)
1173     if (websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases) && !sessionID.isEphemeral())
1174         idbServer(sessionID).closeAndDeleteDatabasesForOrigins(originDatas, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1175 #endif
1176
1177 #if ENABLE(SERVICE_WORKER)
1178     if (websiteDataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations) && !sessionID.isEphemeral()) {
1179         auto& server = swServerForSession(sessionID);
1180         for (auto& originData : originDatas)
1181             server.clear(originData, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1182     }
1183 #endif
1184
1185     if (websiteDataTypes.contains(WebsiteDataType::DiskCache) && !sessionID.isEphemeral())
1186         clearDiskCacheEntries(cache(), originDatas, [clearTasksHandler = WTFMove(clearTasksHandler)] { });
1187 }
1188
1189 #if ENABLE(RESOURCE_LOAD_STATISTICS)
1190 static Vector<String> filterForTopLevelDomains(const Vector<String>& topLevelDomains, const HashSet<String>& foundValues)
1191 {
1192     Vector<String> result;
1193     for (const auto& hostname : topLevelDomains) {
1194         if (foundValues.contains(hostname))
1195             result.append(hostname);
1196     }
1197     
1198     return result;
1199 }
1200
1201 static Vector<WebsiteData::Entry> filterForTopLevelDomains(const Vector<String>& topLevelDomains, const Vector<WebsiteData::Entry>& foundValues)
1202 {
1203     Vector<WebsiteData::Entry> result;
1204     for (const auto& value : foundValues) {
1205         if (topLevelDomains.contains(value.origin.host))
1206             result.append(value);
1207     }
1208     
1209     return result;
1210 }
1211
1212 void NetworkProcess::deleteWebsiteDataForTopPrivatelyControlledDomainsInAllPersistentDataStores(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, Vector<String>&& topPrivatelyControlledDomains, bool shouldNotifyPage, CompletionHandler<void(const HashSet<String>&)>&& completionHandler)
1213 {
1214     OptionSet<WebsiteDataFetchOption> fetchOptions = WebsiteDataFetchOption::DoNotCreateProcesses;
1215
1216     struct CallbackAggregator final : public RefCounted<CallbackAggregator> {
1217         explicit CallbackAggregator(CompletionHandler<void(const HashSet<String>&)>&& completionHandler)
1218             : m_completionHandler(WTFMove(completionHandler))
1219         {
1220         }
1221         
1222         ~CallbackAggregator()
1223         {
1224             RunLoop::main().dispatch([completionHandler = WTFMove(m_completionHandler), websiteData = WTFMove(m_websiteData)] () mutable {
1225                 HashSet<String> origins;
1226                 for (const auto& hostnameWithCookies : websiteData.hostNamesWithCookies)
1227                     origins.add(hostnameWithCookies);
1228
1229                 for (const auto& hostnameWithHSTS : websiteData.hostNamesWithHSTSCache)
1230                     origins.add(hostnameWithHSTS);
1231
1232                 for (const auto& entry : websiteData.entries)
1233                     origins.add(entry.origin.host);
1234
1235                 completionHandler(origins);
1236             });
1237         }
1238         
1239         CompletionHandler<void(const HashSet<String>&)> m_completionHandler;
1240         WebsiteData m_websiteData;
1241     };
1242     
1243     auto callbackAggregator = adoptRef(*new CallbackAggregator([this, completionHandler = WTFMove(completionHandler), shouldNotifyPage] (const HashSet<String>& originsWithData) mutable {
1244         if (shouldNotifyPage)
1245             parentProcessConnection()->send(Messages::NetworkProcessProxy::NotifyWebsiteDataDeletionForTopPrivatelyOwnedDomainsFinished(), 0);
1246         
1247         RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), originsWithData = crossThreadCopy(originsWithData)] () mutable {
1248             completionHandler(originsWithData);
1249         });
1250     }));
1251
1252     auto& websiteDataStore = callbackAggregator->m_websiteData;
1253
1254     Vector<String> hostnamesWithCookiesToDelete;
1255     if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
1256         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID)) {
1257             networkStorageSession->getHostnamesWithCookies(websiteDataStore.hostNamesWithCookies);
1258             hostnamesWithCookiesToDelete = filterForTopLevelDomains(topPrivatelyControlledDomains, websiteDataStore.hostNamesWithCookies);
1259             networkStorageSession->deleteCookiesForHostnames(hostnamesWithCookiesToDelete);
1260         }
1261     }
1262
1263     Vector<String> hostnamesWithHSTSToDelete;
1264 #if PLATFORM(COCOA)
1265     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
1266         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID)) {
1267             getHostNamesWithHSTSCache(*networkStorageSession, websiteDataStore.hostNamesWithHSTSCache);
1268             hostnamesWithHSTSToDelete = filterForTopLevelDomains(topPrivatelyControlledDomains, websiteDataStore.hostNamesWithHSTSCache);
1269             deleteHSTSCacheForHostNames(*networkStorageSession, hostnamesWithHSTSToDelete);
1270         }
1271     }
1272 #endif
1273
1274     /*
1275     // FIXME: No API to delete credentials by origin
1276     if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
1277         if (NetworkStorageSession::storageSession(sessionID))
1278             websiteDataStore.originsWithCredentials = NetworkStorageSession::storageSession(sessionID)->credentialStorage().originsWithCredentials();
1279     }
1280     */
1281     
1282     if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) {
1283         CacheStorage::Engine::fetchEntries(*this, sessionID, fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes), [this, topPrivatelyControlledDomains, sessionID, callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
1284             
1285             auto entriesToDelete = filterForTopLevelDomains(topPrivatelyControlledDomains, entries);
1286
1287             callbackAggregator->m_websiteData.entries.appendVector(entriesToDelete);
1288             
1289             for (auto& entry : entriesToDelete)
1290                 CacheStorage::Engine::clearCachesForOrigin(*this, sessionID, SecurityOriginData { entry.origin }, [callbackAggregator = callbackAggregator.copyRef()] { });
1291         });
1292     }
1293     
1294 #if ENABLE(INDEXED_DATABASE)
1295     auto path = m_idbDatabasePaths.get(sessionID);
1296     if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases)) {
1297         // FIXME: Pick the right database store based on the session ID.
1298         postStorageTask(CrossThreadTask([this, sessionID, callbackAggregator = callbackAggregator.copyRef(), path = WTFMove(path), topPrivatelyControlledDomains]() mutable {
1299             RunLoop::main().dispatch([this, sessionID, topPrivatelyControlledDomains = crossThreadCopy(topPrivatelyControlledDomains), callbackAggregator = callbackAggregator.copyRef(), securityOrigins = indexedDatabaseOrigins(path)] {
1300                 Vector<SecurityOriginData> entriesToDelete;
1301                 for (const auto& securityOrigin : securityOrigins) {
1302                     if (!topPrivatelyControlledDomains.contains(securityOrigin.host))
1303                         continue;
1304
1305                     entriesToDelete.append(securityOrigin);
1306                     callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::IndexedDBDatabases, 0 });
1307                 }
1308
1309                 idbServer(sessionID).closeAndDeleteDatabasesForOrigins(entriesToDelete, [callbackAggregator = callbackAggregator.copyRef()] { });
1310             });
1311         }));
1312     }
1313 #endif
1314     
1315 #if ENABLE(SERVICE_WORKER)
1316     path = m_swDatabasePaths.get(sessionID);
1317     if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations)) {
1318         swServerForSession(sessionID).getOriginsWithRegistrations([this, sessionID, topPrivatelyControlledDomains, callbackAggregator = callbackAggregator.copyRef()](const HashSet<SecurityOriginData>& securityOrigins) mutable {
1319             for (auto& securityOrigin : securityOrigins) {
1320                 if (!topPrivatelyControlledDomains.contains(securityOrigin.host))
1321                     continue;
1322                 callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::ServiceWorkerRegistrations, 0 });
1323                 swServerForSession(sessionID).clear(securityOrigin, [callbackAggregator = callbackAggregator.copyRef()] { });
1324             }
1325         });
1326     }
1327 #endif
1328     
1329     if (websiteDataTypes.contains(WebsiteDataType::DiskCache)) {
1330         fetchDiskCacheEntries(cache(), sessionID, fetchOptions, [this, topPrivatelyControlledDomains, callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
1331
1332             Vector<SecurityOriginData> entriesToDelete;
1333             for (auto& entry : entries) {
1334                 if (!topPrivatelyControlledDomains.contains(entry.origin.host))
1335                     continue;
1336                 entriesToDelete.append(entry.origin);
1337                 callbackAggregator->m_websiteData.entries.append(entry);
1338             }
1339             clearDiskCacheEntries(cache(), entriesToDelete, [callbackAggregator = callbackAggregator.copyRef()] { });
1340         });
1341     }
1342 }
1343
1344 void NetworkProcess::topPrivatelyControlledDomainsWithWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, bool shouldNotifyPage, CompletionHandler<void(HashSet<String>&&)>&& completionHandler)
1345 {
1346     OptionSet<WebsiteDataFetchOption> fetchOptions = WebsiteDataFetchOption::DoNotCreateProcesses;
1347     
1348     struct CallbackAggregator final : public RefCounted<CallbackAggregator> {
1349         explicit CallbackAggregator(CompletionHandler<void(HashSet<String>&&)>&& completionHandler)
1350             : m_completionHandler(WTFMove(completionHandler))
1351         {
1352         }
1353         
1354         ~CallbackAggregator()
1355         {
1356             RunLoop::main().dispatch([completionHandler = WTFMove(m_completionHandler), websiteData = WTFMove(m_websiteData)] () mutable {
1357                 HashSet<String> origins;
1358                 for (const auto& hostnameWithCookies : websiteData.hostNamesWithCookies)
1359                     origins.add(hostnameWithCookies);
1360                 
1361                 for (const auto& hostnameWithHSTS : websiteData.hostNamesWithHSTSCache)
1362                     origins.add(hostnameWithHSTS);
1363                 
1364                 for (const auto& entry : websiteData.entries)
1365                     origins.add(entry.origin.host);
1366                 
1367                 completionHandler(WTFMove(origins));
1368             });
1369         }
1370         
1371         CompletionHandler<void(HashSet<String>&&)> m_completionHandler;
1372         WebsiteData m_websiteData;
1373     };
1374     
1375     auto callbackAggregator = adoptRef(*new CallbackAggregator([this, completionHandler = WTFMove(completionHandler), shouldNotifyPage] (HashSet<String>&& originsWithData) mutable {
1376         if (shouldNotifyPage)
1377             parentProcessConnection()->send(Messages::NetworkProcessProxy::NotifyWebsiteDataScanForTopPrivatelyControlledDomainsFinished(), 0);
1378
1379         RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), originsWithData = crossThreadCopy(originsWithData)] () mutable {
1380             completionHandler(WTFMove(originsWithData));
1381         });
1382     }));
1383     
1384     auto& websiteDataStore = callbackAggregator->m_websiteData;
1385     
1386     Vector<String> hostnamesWithCookiesToDelete;
1387     if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
1388         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
1389             networkStorageSession->getHostnamesWithCookies(websiteDataStore.hostNamesWithCookies);
1390     }
1391     
1392     Vector<String> hostnamesWithHSTSToDelete;
1393 #if PLATFORM(COCOA)
1394     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
1395         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
1396             getHostNamesWithHSTSCache(*networkStorageSession, websiteDataStore.hostNamesWithHSTSCache);
1397     }
1398 #endif
1399
1400     if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
1401         if (NetworkStorageSession::storageSession(sessionID))
1402             websiteDataStore.originsWithCredentials = NetworkStorageSession::storageSession(sessionID)->credentialStorage().originsWithCredentials();
1403     }
1404     
1405     if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) {
1406         CacheStorage::Engine::fetchEntries(*this, sessionID, fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes), [callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
1407             callbackAggregator->m_websiteData.entries.appendVector(entries);
1408         });
1409     }
1410     
1411 #if ENABLE(INDEXED_DATABASE)
1412     auto path = m_idbDatabasePaths.get(sessionID);
1413     if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases)) {
1414         // FIXME: Pick the right database store based on the session ID.
1415         postStorageTask(CrossThreadTask([this, callbackAggregator = callbackAggregator.copyRef(), path = WTFMove(path)]() mutable {
1416             RunLoop::main().dispatch([callbackAggregator = callbackAggregator.copyRef(), securityOrigins = indexedDatabaseOrigins(path)] {
1417                 for (const auto& securityOrigin : securityOrigins)
1418                     callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::IndexedDBDatabases, 0 });
1419             });
1420         }));
1421     }
1422 #endif
1423     
1424 #if ENABLE(SERVICE_WORKER)
1425     path = m_swDatabasePaths.get(sessionID);
1426     if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations)) {
1427         swServerForSession(sessionID).getOriginsWithRegistrations([callbackAggregator = callbackAggregator.copyRef()](const HashSet<SecurityOriginData>& securityOrigins) mutable {
1428             for (auto& securityOrigin : securityOrigins)
1429                 callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::ServiceWorkerRegistrations, 0 });
1430         });
1431     }
1432 #endif
1433     
1434     if (websiteDataTypes.contains(WebsiteDataType::DiskCache)) {
1435         fetchDiskCacheEntries(cache(), sessionID, fetchOptions, [callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
1436             callbackAggregator->m_websiteData.entries.appendVector(entries);
1437         });
1438     }
1439 }
1440 #endif // ENABLE(RESOURCE_LOAD_STATISTICS)
1441
1442 CacheStorage::Engine* NetworkProcess::findCacheEngine(const PAL::SessionID& sessionID)
1443 {
1444     return m_cacheEngines.get(sessionID);
1445 }
1446
1447 CacheStorage::Engine& NetworkProcess::ensureCacheEngine(const PAL::SessionID& sessionID, Function<Ref<CacheStorage::Engine>()>&& functor)
1448 {
1449     return m_cacheEngines.ensure(sessionID, WTFMove(functor)).iterator->value;
1450 }
1451
1452 void NetworkProcess::removeCacheEngine(const PAL::SessionID& sessionID)
1453 {
1454     m_cacheEngines.remove(sessionID);
1455 }
1456
1457 void NetworkProcess::downloadRequest(PAL::SessionID sessionID, DownloadID downloadID, const ResourceRequest& request, const String& suggestedFilename)
1458 {
1459     downloadManager().startDownload(nullptr, sessionID, downloadID, request, suggestedFilename);
1460 }
1461
1462 void NetworkProcess::resumeDownload(PAL::SessionID sessionID, DownloadID downloadID, const IPC::DataReference& resumeData, const String& path, WebKit::SandboxExtension::Handle&& sandboxExtensionHandle)
1463 {
1464     downloadManager().resumeDownload(sessionID, downloadID, resumeData, path, WTFMove(sandboxExtensionHandle));
1465 }
1466
1467 void NetworkProcess::cancelDownload(DownloadID downloadID)
1468 {
1469     downloadManager().cancelDownload(downloadID);
1470 }
1471
1472 #if PLATFORM(COCOA)
1473 void NetworkProcess::publishDownloadProgress(DownloadID downloadID, const URL& url, SandboxExtension::Handle&& sandboxExtensionHandle)
1474 {
1475     downloadManager().publishDownloadProgress(downloadID, url, WTFMove(sandboxExtensionHandle));
1476 }
1477 #endif
1478
1479 void NetworkProcess::continueWillSendRequest(DownloadID downloadID, WebCore::ResourceRequest&& request)
1480 {
1481     downloadManager().continueWillSendRequest(downloadID, WTFMove(request));
1482 }
1483
1484 void NetworkProcess::pendingDownloadCanceled(DownloadID downloadID)
1485 {
1486     downloadProxyConnection()->send(Messages::DownloadProxy::DidCancel({ }), downloadID.downloadID());
1487 }
1488
1489 void NetworkProcess::findPendingDownloadLocation(NetworkDataTask& networkDataTask, ResponseCompletionHandler&& completionHandler, const ResourceResponse& response)
1490 {
1491     uint64_t destinationID = networkDataTask.pendingDownloadID().downloadID();
1492     downloadProxyConnection()->send(Messages::DownloadProxy::DidReceiveResponse(response), destinationID);
1493
1494     downloadManager().willDecidePendingDownloadDestination(networkDataTask, WTFMove(completionHandler));
1495
1496     // As per https://html.spec.whatwg.org/#as-a-download (step 2), the filename from the Content-Disposition header
1497     // should override the suggested filename from the download attribute.
1498     String suggestedFilename = response.isAttachmentWithFilename() ? response.suggestedFilename() : networkDataTask.suggestedFilename();
1499     suggestedFilename = MIMETypeRegistry::appendFileExtensionIfNecessary(suggestedFilename, response.mimeType());
1500
1501     downloadProxyConnection()->send(Messages::DownloadProxy::DecideDestinationWithSuggestedFilenameAsync(networkDataTask.pendingDownloadID(), suggestedFilename), destinationID);
1502 }
1503
1504 void NetworkProcess::continueDecidePendingDownloadDestination(DownloadID downloadID, String destination, SandboxExtension::Handle&& sandboxExtensionHandle, bool allowOverwrite)
1505 {
1506     if (destination.isEmpty())
1507         downloadManager().cancelDownload(downloadID);
1508     else
1509         downloadManager().continueDecidePendingDownloadDestination(downloadID, destination, WTFMove(sandboxExtensionHandle), allowOverwrite);
1510 }
1511
1512 void NetworkProcess::setCacheModel(CacheModel cacheModel)
1513 {
1514     if (m_hasSetCacheModel && (cacheModel == m_cacheModel))
1515         return;
1516
1517     m_hasSetCacheModel = true;
1518     m_cacheModel = cacheModel;
1519
1520     unsigned urlCacheMemoryCapacity = 0;
1521     uint64_t urlCacheDiskCapacity = 0;
1522     uint64_t diskFreeSize = 0;
1523     if (WebCore::FileSystem::getVolumeFreeSpace(m_diskCacheDirectory, diskFreeSize)) {
1524         // As a fudge factor, use 1000 instead of 1024, in case the reported byte
1525         // count doesn't align exactly to a megabyte boundary.
1526         diskFreeSize /= KB * 1000;
1527         calculateURLCacheSizes(cacheModel, diskFreeSize, urlCacheMemoryCapacity, urlCacheDiskCapacity);
1528     }
1529
1530     if (m_cache)
1531         m_cache->setCapacity(urlCacheDiskCapacity);
1532 }
1533
1534 void NetworkProcess::setCanHandleHTTPSServerTrustEvaluation(bool value)
1535 {
1536     m_canHandleHTTPSServerTrustEvaluation = value;
1537 }
1538
1539 void NetworkProcess::getNetworkProcessStatistics(uint64_t callbackID)
1540 {
1541     StatisticsData data;
1542
1543     data.statisticsNumbers.set("DownloadsActiveCount", downloadManager().activeDownloadCount());
1544     data.statisticsNumbers.set("OutstandingAuthenticationChallengesCount", authenticationManager().outstandingAuthenticationChallengeCount());
1545
1546     parentProcessConnection()->send(Messages::WebProcessPool::DidGetStatistics(data, callbackID), 0);
1547 }
1548
1549 void NetworkProcess::setAllowsAnySSLCertificateForWebSocket(bool allows)
1550 {
1551     DeprecatedGlobalSettings::setAllowsAnySSLCertificate(allows);
1552 }
1553
1554 void NetworkProcess::logDiagnosticMessage(uint64_t webPageID, const String& message, const String& description, ShouldSample shouldSample)
1555 {
1556     if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
1557         return;
1558
1559     parentProcessConnection()->send(Messages::NetworkProcessProxy::LogDiagnosticMessage(webPageID, message, description, ShouldSample::No), 0);
1560 }
1561
1562 void NetworkProcess::logDiagnosticMessageWithResult(uint64_t webPageID, const String& message, const String& description, DiagnosticLoggingResultType result, ShouldSample shouldSample)
1563 {
1564     if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
1565         return;
1566
1567     parentProcessConnection()->send(Messages::NetworkProcessProxy::LogDiagnosticMessageWithResult(webPageID, message, description, result, ShouldSample::No), 0);
1568 }
1569
1570 void NetworkProcess::logDiagnosticMessageWithValue(uint64_t webPageID, const String& message, const String& description, double value, unsigned significantFigures, ShouldSample shouldSample)
1571 {
1572     if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
1573         return;
1574
1575     parentProcessConnection()->send(Messages::NetworkProcessProxy::LogDiagnosticMessageWithValue(webPageID, message, description, value, significantFigures, ShouldSample::No), 0);
1576 }
1577
1578 void NetworkProcess::terminate()
1579 {
1580     platformTerminate();
1581     ChildProcess::terminate();
1582 }
1583
1584 void NetworkProcess::processDidTransitionToForeground()
1585 {
1586     platformProcessDidTransitionToForeground();
1587 }
1588
1589 void NetworkProcess::processDidTransitionToBackground()
1590 {
1591     platformProcessDidTransitionToBackground();
1592 }
1593
1594 // FIXME: We can remove this one by adapting RefCounter.
1595 class TaskCounter : public RefCounted<TaskCounter> {
1596 public:
1597     explicit TaskCounter(Function<void()>&& callback) : m_callback(WTFMove(callback)) { }
1598     ~TaskCounter() { m_callback(); };
1599
1600 private:
1601     Function<void()> m_callback;
1602 };
1603
1604 void NetworkProcess::actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend shouldAcknowledgeWhenReadyToSuspend)
1605 {
1606     lowMemoryHandler(Critical::Yes);
1607
1608     RefPtr<TaskCounter> delayedTaskCounter;
1609     if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) {
1610         delayedTaskCounter = adoptRef(new TaskCounter([this] {
1611             RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::notifyProcessReadyToSuspend() Sending ProcessReadyToSuspend IPC message", this);
1612             if (parentProcessConnection())
1613                 parentProcessConnection()->send(Messages::NetworkProcessProxy::ProcessReadyToSuspend(), 0);
1614         }));
1615     }
1616
1617     platformPrepareToSuspend([delayedTaskCounter] { });
1618     platformSyncAllCookies([delayedTaskCounter] { });
1619
1620     for (auto& connection : m_webProcessConnections)
1621         connection->cleanupForSuspension([delayedTaskCounter] { });
1622 }
1623
1624 void NetworkProcess::processWillSuspendImminently(bool& handled)
1625 {
1626     actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::No);
1627     handled = true;
1628 }
1629
1630 void NetworkProcess::prepareToSuspend()
1631 {
1632     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::prepareToSuspend()", this);
1633     actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::Yes);
1634 }
1635
1636 void NetworkProcess::cancelPrepareToSuspend()
1637 {
1638     // Although it is tempting to send a NetworkProcessProxy::DidCancelProcessSuspension message from here
1639     // we do not because prepareToSuspend() already replied with a NetworkProcessProxy::ProcessReadyToSuspend
1640     // message. And NetworkProcessProxy expects to receive either a NetworkProcessProxy::ProcessReadyToSuspend-
1641     // or NetworkProcessProxy::DidCancelProcessSuspension- message, but not both.
1642     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::cancelPrepareToSuspend()", this);
1643     platformProcessDidResume();
1644     for (auto& connection : m_webProcessConnections)
1645         connection->endSuspension();
1646 }
1647
1648 void NetworkProcess::processDidResume()
1649 {
1650     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::processDidResume()", this);
1651     platformProcessDidResume();
1652     for (auto& connection : m_webProcessConnections)
1653         connection->endSuspension();
1654 }
1655
1656 void NetworkProcess::prefetchDNS(const String& hostname)
1657 {
1658     WebCore::prefetchDNS(hostname);
1659 }
1660
1661 void NetworkProcess::cacheStorageParameters(PAL::SessionID sessionID, CacheStorageParametersCallback&& callback)
1662 {
1663     m_cacheStorageParametersCallbacks.ensure(sessionID, [&] {
1664         parentProcessConnection()->send(Messages::NetworkProcessProxy::RetrieveCacheStorageParameters { sessionID }, 0);
1665         return Vector<CacheStorageParametersCallback> { };
1666     }).iterator->value.append(WTFMove(callback));
1667 }
1668
1669 void NetworkProcess::setCacheStorageParameters(PAL::SessionID sessionID, uint64_t quota, String&& cacheStorageDirectory, SandboxExtension::Handle&& handle)
1670 {
1671     auto iterator = m_cacheStorageParametersCallbacks.find(sessionID);
1672     if (iterator == m_cacheStorageParametersCallbacks.end())
1673         return;
1674
1675     SandboxExtension::consumePermanently(handle);
1676     auto callbacks = WTFMove(iterator->value);
1677     m_cacheStorageParametersCallbacks.remove(iterator);
1678     for (auto& callback : callbacks)
1679         callback(String { cacheStorageDirectory }, quota);
1680 }
1681
1682 void NetworkProcess::preconnectTo(const URL& url, WebCore::StoredCredentialsPolicy storedCredentialsPolicy)
1683 {
1684 #if ENABLE(SERVER_PRECONNECT)
1685     NetworkLoadParameters parameters;
1686     parameters.request = ResourceRequest { url };
1687     parameters.sessionID = PAL::SessionID::defaultSessionID();
1688     parameters.storedCredentialsPolicy = storedCredentialsPolicy;
1689     parameters.shouldPreconnectOnly = PreconnectOnly::Yes;
1690
1691     new PreconnectTask(*this, WTFMove(parameters));
1692 #else
1693     UNUSED_PARAM(url);
1694     UNUSED_PARAM(storedCredentialsPolicy);
1695 #endif
1696 }
1697
1698 void NetworkProcess::registerURLSchemeAsSecure(const String& scheme) const
1699 {
1700     SchemeRegistry::registerURLSchemeAsSecure(scheme);
1701 }
1702
1703 void NetworkProcess::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme) const
1704 {
1705     SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
1706 }
1707
1708 void NetworkProcess::registerURLSchemeAsLocal(const String& scheme) const
1709 {
1710     SchemeRegistry::registerURLSchemeAsLocal(scheme);
1711 }
1712
1713 void NetworkProcess::registerURLSchemeAsNoAccess(const String& scheme) const
1714 {
1715     SchemeRegistry::registerURLSchemeAsNoAccess(scheme);
1716 }
1717
1718 void NetworkProcess::registerURLSchemeAsDisplayIsolated(const String& scheme) const
1719 {
1720     SchemeRegistry::registerURLSchemeAsDisplayIsolated(scheme);
1721 }
1722
1723 void NetworkProcess::registerURLSchemeAsCORSEnabled(const String& scheme) const
1724 {
1725     SchemeRegistry::registerURLSchemeAsCORSEnabled(scheme);
1726 }
1727
1728 void NetworkProcess::registerURLSchemeAsCanDisplayOnlyIfCanRequest(const String& scheme) const
1729 {
1730     SchemeRegistry::registerAsCanDisplayOnlyIfCanRequest(scheme);
1731 }
1732
1733 void NetworkProcess::didSyncAllCookies()
1734 {
1735     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidSyncAllCookies(), 0);
1736 }
1737
1738 #if ENABLE(INDEXED_DATABASE)
1739 IDBServer::IDBServer& NetworkProcess::idbServer(PAL::SessionID sessionID)
1740 {
1741     auto addResult = m_idbServers.add(sessionID, nullptr);
1742     if (!addResult.isNewEntry) {
1743         ASSERT(addResult.iterator->value);
1744         return *addResult.iterator->value;
1745     }
1746     
1747     auto path = m_idbDatabasePaths.get(sessionID);
1748     // There should already be a registered path for this PAL::SessionID.
1749     // If there's not, then where did this PAL::SessionID come from?
1750     ASSERT(!path.isEmpty());
1751     
1752     addResult.iterator->value = IDBServer::IDBServer::create(path, *this);
1753     addResult.iterator->value->setPerOriginQuota(m_idbPerOriginQuota);
1754     return *addResult.iterator->value;
1755 }
1756
1757 void NetworkProcess::ensurePathExists(const String& path)
1758 {
1759     ASSERT(!RunLoop::isMain());
1760     
1761     if (!FileSystem::makeAllDirectories(path))
1762         LOG_ERROR("Failed to make all directories for path '%s'", path.utf8().data());
1763 }
1764
1765 void NetworkProcess::postStorageTask(CrossThreadTask&& task)
1766 {
1767     ASSERT(RunLoop::isMain());
1768     
1769     LockHolder locker(m_storageTaskMutex);
1770     
1771     m_storageTasks.append(WTFMove(task));
1772     
1773     m_storageTaskQueue->dispatch([this] {
1774         performNextStorageTask();
1775     });
1776 }
1777
1778 void NetworkProcess::performNextStorageTask()
1779 {
1780     ASSERT(!RunLoop::isMain());
1781     
1782     CrossThreadTask task;
1783     {
1784         LockHolder locker(m_storageTaskMutex);
1785         ASSERT(!m_storageTasks.isEmpty());
1786         task = m_storageTasks.takeFirst();
1787     }
1788     
1789     task.performTask();
1790 }
1791
1792 void NetworkProcess::accessToTemporaryFileComplete(const String& path)
1793 {
1794     // We've either hard linked the temporary blob file to the database directory, copied it there,
1795     // or the transaction is being aborted.
1796     // In any of those cases, we can delete the temporary blob file now.
1797     FileSystem::deleteFile(path);
1798 }
1799
1800 HashSet<WebCore::SecurityOriginData> NetworkProcess::indexedDatabaseOrigins(const String& path)
1801 {
1802     if (path.isEmpty())
1803         return { };
1804     
1805     HashSet<WebCore::SecurityOriginData> securityOrigins;
1806     for (auto& topOriginPath : FileSystem::listDirectory(path, "*")) {
1807         auto databaseIdentifier = FileSystem::pathGetFileName(topOriginPath);
1808         if (auto securityOrigin = SecurityOriginData::fromDatabaseIdentifier(databaseIdentifier))
1809             securityOrigins.add(WTFMove(*securityOrigin));
1810         
1811         for (auto& originPath : FileSystem::listDirectory(topOriginPath, "*")) {
1812             databaseIdentifier = FileSystem::pathGetFileName(originPath);
1813             if (auto securityOrigin = SecurityOriginData::fromDatabaseIdentifier(databaseIdentifier))
1814                 securityOrigins.add(WTFMove(*securityOrigin));
1815         }
1816     }
1817
1818     return securityOrigins;
1819 }
1820
1821 void NetworkProcess::addIndexedDatabaseSession(PAL::SessionID sessionID, String& indexedDatabaseDirectory, SandboxExtension::Handle& handle)
1822 {
1823     // *********
1824     // IMPORTANT: Do not change the directory structure for indexed databases on disk without first consulting a reviewer from Apple (<rdar://problem/17454712>)
1825     // *********
1826     auto addResult = m_idbDatabasePaths.add(sessionID, indexedDatabaseDirectory);
1827     if (addResult.isNewEntry) {
1828         SandboxExtension::consumePermanently(handle);
1829         if (!indexedDatabaseDirectory.isEmpty())
1830             postStorageTask(createCrossThreadTask(*this, &NetworkProcess::ensurePathExists, indexedDatabaseDirectory));
1831     }
1832 }
1833
1834 void NetworkProcess::setIDBPerOriginQuota(uint64_t quota)
1835 {
1836     m_idbPerOriginQuota = quota;
1837     
1838     for (auto& server : m_idbServers.values())
1839         server->setPerOriginQuota(quota);
1840 }
1841 #endif // ENABLE(INDEXED_DATABASE)
1842
1843 #if ENABLE(SANDBOX_EXTENSIONS)
1844 void NetworkProcess::getSandboxExtensionsForBlobFiles(const Vector<String>& filenames, CompletionHandler<void(SandboxExtension::HandleArray&&)>&& completionHandler)
1845 {
1846     parentProcessConnection()->sendWithAsyncReply(Messages::NetworkProcessProxy::GetSandboxExtensionsForBlobFiles(filenames), WTFMove(completionHandler));
1847 }
1848 #endif // ENABLE(SANDBOX_EXTENSIONS)
1849
1850 #if ENABLE(SERVICE_WORKER)
1851 WebSWServerToContextConnection* NetworkProcess::connectionToContextProcessFromIPCConnection(IPC::Connection& connection)
1852 {
1853     for (auto& serverToContextConnection : m_serverToContextConnections.values()) {
1854         if (serverToContextConnection->ipcConnection() == &connection)
1855             return serverToContextConnection.get();
1856     }
1857     return nullptr;
1858 }
1859
1860 void NetworkProcess::connectionToContextProcessWasClosed(Ref<WebSWServerToContextConnection>&& serverToContextConnection)
1861 {
1862     auto& securityOrigin = serverToContextConnection->securityOrigin();
1863     
1864     serverToContextConnection->connectionClosed();
1865     m_serverToContextConnections.remove(securityOrigin);
1866     
1867     for (auto& swServer : m_swServers.values())
1868         swServer->markAllWorkersForOriginAsTerminated(securityOrigin);
1869     
1870     if (needsServerToContextConnectionForOrigin(securityOrigin)) {
1871         RELEASE_LOG(ServiceWorker, "Connection to service worker process was closed but is still needed, relaunching it");
1872         createServerToContextConnection(securityOrigin, WTF::nullopt);
1873     }
1874 }
1875
1876 bool NetworkProcess::needsServerToContextConnectionForOrigin(const SecurityOriginData& securityOrigin) const
1877 {
1878     return WTF::anyOf(m_swServers.values(), [&](auto& swServer) {
1879         return swServer->needsServerToContextConnectionForOrigin(securityOrigin);
1880     });
1881 }
1882
1883 SWServer& NetworkProcess::swServerForSession(PAL::SessionID sessionID)
1884 {
1885     ASSERT(sessionID.isValid());
1886     
1887     auto result = m_swServers.ensure(sessionID, [&] {
1888         auto path = m_swDatabasePaths.get(sessionID);
1889         // There should already be a registered path for this PAL::SessionID.
1890         // If there's not, then where did this PAL::SessionID come from?
1891         ASSERT(sessionID.isEphemeral() || !path.isEmpty());
1892         
1893         auto value = std::make_unique<SWServer>(makeUniqueRef<WebSWOriginStore>(), WTFMove(path), sessionID);
1894         if (m_shouldDisableServiceWorkerProcessTerminationDelay)
1895             value->disableServiceWorkerProcessTerminationDelay();
1896         return value;
1897     });
1898
1899     return *result.iterator->value;
1900 }
1901
1902 WebSWOriginStore& NetworkProcess::swOriginStoreForSession(PAL::SessionID sessionID)
1903 {
1904     return static_cast<WebSWOriginStore&>(swServerForSession(sessionID).originStore());
1905 }
1906
1907 WebSWOriginStore* NetworkProcess::existingSWOriginStoreForSession(PAL::SessionID sessionID) const
1908 {
1909     auto* swServer = m_swServers.get(sessionID);
1910     if (!swServer)
1911         return nullptr;
1912     return &static_cast<WebSWOriginStore&>(swServer->originStore());
1913 }
1914
1915 WebSWServerToContextConnection* NetworkProcess::serverToContextConnectionForOrigin(const SecurityOriginData& securityOrigin)
1916 {
1917     return m_serverToContextConnections.get(securityOrigin);
1918 }
1919
1920 void NetworkProcess::createServerToContextConnection(const SecurityOriginData& securityOrigin, Optional<PAL::SessionID> sessionID)
1921 {
1922     if (m_waitingForServerToContextProcessConnection)
1923         return;
1924     
1925     m_waitingForServerToContextProcessConnection = true;
1926     if (sessionID)
1927         parentProcessConnection()->send(Messages::NetworkProcessProxy::EstablishWorkerContextConnectionToNetworkProcessForExplicitSession(securityOrigin, *sessionID), 0);
1928     else
1929         parentProcessConnection()->send(Messages::NetworkProcessProxy::EstablishWorkerContextConnectionToNetworkProcess(securityOrigin), 0);
1930 }
1931
1932 void NetworkProcess::didFailFetch(SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier fetchIdentifier, const ResourceError& error)
1933 {
1934     if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
1935         connection->didFailFetch(fetchIdentifier, error);
1936 }
1937
1938 void NetworkProcess::didNotHandleFetch(SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier fetchIdentifier)
1939 {
1940     if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
1941         connection->didNotHandleFetch(fetchIdentifier);
1942 }
1943
1944 void NetworkProcess::didReceiveFetchResponse(SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier fetchIdentifier, const WebCore::ResourceResponse& response)
1945 {
1946     if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
1947         connection->didReceiveFetchResponse(fetchIdentifier, response);
1948 }
1949
1950 void NetworkProcess::didReceiveFetchData(SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier fetchIdentifier, const IPC::DataReference& data, int64_t encodedDataLength)
1951 {
1952     if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
1953         connection->didReceiveFetchData(fetchIdentifier, data, encodedDataLength);
1954 }
1955
1956 void NetworkProcess::didReceiveFetchFormData(SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier fetchIdentifier, const IPC::FormDataReference& formData)
1957 {
1958     if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
1959         connection->didReceiveFetchFormData(fetchIdentifier, formData);
1960 }
1961
1962 void NetworkProcess::didFinishFetch(SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier fetchIdentifier)
1963 {
1964     if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
1965         connection->didFinishFetch(fetchIdentifier);
1966 }
1967
1968 void NetworkProcess::postMessageToServiceWorkerClient(const ServiceWorkerClientIdentifier& destinationIdentifier, MessageWithMessagePorts&& message, ServiceWorkerIdentifier sourceIdentifier, const String& sourceOrigin)
1969 {
1970     if (auto* connection = m_swServerConnections.get(destinationIdentifier.serverConnectionIdentifier))
1971         connection->postMessageToServiceWorkerClient(destinationIdentifier.contextIdentifier, WTFMove(message), sourceIdentifier, sourceOrigin);
1972 }
1973
1974 void NetworkProcess::postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destination, WebCore::MessageWithMessagePorts&& message, const WebCore::ServiceWorkerOrClientIdentifier& source, SWServerConnectionIdentifier connectionIdentifier)
1975 {
1976     if (auto* connection = m_swServerConnections.get(connectionIdentifier))
1977         connection->postMessageToServiceWorker(destination, WTFMove(message), source);
1978 }
1979
1980 void NetworkProcess::registerSWServerConnection(WebSWServerConnection& connection)
1981 {
1982     ASSERT(parentProcessHasServiceWorkerEntitlement());
1983     ASSERT(!m_swServerConnections.contains(connection.identifier()));
1984     m_swServerConnections.add(connection.identifier(), &connection);
1985     swOriginStoreForSession(connection.sessionID()).registerSWServerConnection(connection);
1986 }
1987
1988 void NetworkProcess::unregisterSWServerConnection(WebSWServerConnection& connection)
1989 {
1990     ASSERT(m_swServerConnections.get(connection.identifier()) == &connection);
1991     m_swServerConnections.remove(connection.identifier());
1992     if (auto* store = existingSWOriginStoreForSession(connection.sessionID()))
1993         store->unregisterSWServerConnection(connection);
1994 }
1995
1996 void NetworkProcess::swContextConnectionMayNoLongerBeNeeded(WebSWServerToContextConnection& serverToContextConnection)
1997 {
1998     auto& securityOrigin = serverToContextConnection.securityOrigin();
1999     if (needsServerToContextConnectionForOrigin(securityOrigin))
2000         return;
2001     
2002     RELEASE_LOG(ServiceWorker, "Service worker process is no longer needed, terminating it");
2003     serverToContextConnection.terminate();
2004     
2005     for (auto& swServer : m_swServers.values())
2006         swServer->markAllWorkersForOriginAsTerminated(securityOrigin);
2007     
2008     serverToContextConnection.connectionClosed();
2009     m_serverToContextConnections.remove(securityOrigin);
2010 }
2011
2012 void NetworkProcess::disableServiceWorkerProcessTerminationDelay()
2013 {
2014     if (m_shouldDisableServiceWorkerProcessTerminationDelay)
2015         return;
2016     
2017     m_shouldDisableServiceWorkerProcessTerminationDelay = true;
2018     for (auto& swServer : m_swServers.values())
2019         swServer->disableServiceWorkerProcessTerminationDelay();
2020 }
2021
2022 void NetworkProcess::addServiceWorkerSession(PAL::SessionID sessionID, String& serviceWorkerRegistrationDirectory, const SandboxExtension::Handle& handle)
2023 {
2024     auto addResult = m_swDatabasePaths.add(sessionID, serviceWorkerRegistrationDirectory);
2025     if (addResult.isNewEntry) {
2026         SandboxExtension::consumePermanently(handle);
2027         if (!serviceWorkerRegistrationDirectory.isEmpty())
2028             postStorageTask(createCrossThreadTask(*this, &NetworkProcess::ensurePathExists, serviceWorkerRegistrationDirectory));
2029     }
2030 }
2031 #endif // ENABLE(SERVICE_WORKER)
2032
2033 void NetworkProcess::requestCacheStorageSpace(PAL::SessionID sessionID, const ClientOrigin& origin, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t>)>&& callback)
2034 {
2035     parentProcessConnection()->sendWithAsyncReply(Messages::NetworkProcessProxy::RequestCacheStorageSpace { sessionID, origin, quota, currentSize, spaceRequired }, WTFMove(callback), 0);
2036 }
2037
2038 #if !PLATFORM(COCOA)
2039 void NetworkProcess::initializeProcess(const ChildProcessInitializationParameters&)
2040 {
2041 }
2042
2043 void NetworkProcess::initializeProcessName(const ChildProcessInitializationParameters&)
2044 {
2045 }
2046
2047 void NetworkProcess::initializeSandbox(const ChildProcessInitializationParameters&, SandboxInitializationParameters&)
2048 {
2049 }
2050
2051 void NetworkProcess::syncAllCookies()
2052 {
2053 }
2054
2055 void NetworkProcess::platformSyncAllCookies(CompletionHandler<void()>&& completionHandler)
2056 {
2057     completionHandler();
2058 }
2059
2060 #endif
2061
2062 } // namespace WebKit