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