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