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