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