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