2 * Copyright (C) 2012-2019 Apple Inc. All rights reserved.
3 * Copyright (C) 2018 Sony Interactive Entertainment Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
28 #include "NetworkProcess.h"
30 #include "ArgumentCoders.h"
31 #include "Attachment.h"
32 #include "AuthenticationManager.h"
33 #include "AuxiliaryProcessMessages.h"
34 #include "DataReference.h"
36 #include "DownloadProxyMessages.h"
37 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
38 #include "LegacyCustomProtocolManager.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 "StorageManager.h"
57 #include "StorageManagerMessages.h"
58 #include "WebCookieManager.h"
59 #include "WebPageProxyMessages.h"
60 #include "WebProcessPoolMessages.h"
61 #include "WebResourceLoadStatisticsStore.h"
62 #include "WebSWOriginStore.h"
63 #include "WebSWServerConnection.h"
64 #include "WebSWServerToContextConnection.h"
65 #include "WebsiteDataFetchOption.h"
66 #include "WebsiteDataStore.h"
67 #include "WebsiteDataStoreParameters.h"
68 #include "WebsiteDataType.h"
69 #include <WebCore/CookieJar.h>
70 #include <WebCore/DNS.h>
71 #include <WebCore/DeprecatedGlobalSettings.h>
72 #include <WebCore/DiagnosticLoggingClient.h>
73 #include <WebCore/LogInitialization.h>
74 #include <WebCore/MIMETypeRegistry.h>
75 #include <WebCore/NetworkStateNotifier.h>
76 #include <WebCore/NetworkStorageSession.h>
77 #include <WebCore/ResourceRequest.h>
78 #include <WebCore/RuntimeApplicationChecks.h>
79 #include <WebCore/RuntimeEnabledFeatures.h>
80 #include <WebCore/SchemeRegistry.h>
81 #include <WebCore/SecurityOriginData.h>
82 #include <WebCore/StorageQuotaManager.h>
83 #include <wtf/Algorithms.h>
84 #include <wtf/CallbackAggregator.h>
85 #include <wtf/OptionSet.h>
86 #include <wtf/ProcessPrivilege.h>
87 #include <wtf/RunLoop.h>
88 #include <wtf/text/AtomString.h>
90 #if ENABLE(SEC_ITEM_SHIM)
91 #include "SecItemShim.h"
94 #include "NetworkCache.h"
95 #include "NetworkCacheCoders.h"
98 #include "NetworkSessionCocoa.h"
102 #include <WebCore/DNSResolveQueueSoup.h>
103 #include <WebCore/SoupNetworkSession.h>
107 #include <WebCore/CurlContext.h>
110 #if ENABLE(SERVICE_WORKER)
111 #include "WebSWServerToContextConnectionMessages.h"
115 using namespace WebCore;
117 static void callExitSoon(IPC::Connection*)
119 // If the connection has been closed and we haven't responded in the main thread for 10 seconds
120 // the process will exit forcibly.
121 auto watchdogDelay = 10_s;
123 WorkQueue::create("com.apple.WebKit.NetworkProcess.WatchDogQueue")->dispatchAfter(watchdogDelay, [] {
124 // We use _exit here since the watchdog callback is called from another thread and we don't want
125 // global destructors or atexit handlers to be called from this thread while the main thread is busy
127 RELEASE_LOG_ERROR(IPC, "Exiting process early due to unacknowledged closed-connection");
132 NetworkProcess::NetworkProcess(AuxiliaryProcessInitializationParameters&& parameters)
133 : m_downloadManager(*this)
134 #if ENABLE(CONTENT_EXTENSIONS)
135 , m_networkContentRuleListManager(*this)
137 #if PLATFORM(IOS_FAMILY)
138 , m_webSQLiteDatabaseTracker([this](bool isHoldingLockedFiles) { parentProcessConnection()->send(Messages::NetworkProcessProxy::SetIsHoldingLockedFiles(isHoldingLockedFiles), 0); })
141 NetworkProcessPlatformStrategies::initialize();
143 addSupplement<AuthenticationManager>();
144 addSupplement<WebCookieManager>();
145 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
146 addSupplement<LegacyCustomProtocolManager>();
148 #if PLATFORM(COCOA) || USE(SOUP)
149 LegacyCustomProtocolManager::networkProcessCreated(*this);
153 DNSResolveQueueSoup::setGlobalDefaultNetworkStorageSessionAccessor([this]() -> NetworkStorageSession& {
154 return defaultStorageSession();
158 NetworkStateNotifier::singleton().addListener([weakThis = makeWeakPtr(*this)](bool isOnLine) {
161 for (auto& webProcessConnection : weakThis->m_webProcessConnections)
162 webProcessConnection->setOnLineState(isOnLine);
165 initialize(WTFMove(parameters));
168 NetworkProcess::~NetworkProcess()
170 for (auto& callbacks : m_cacheStorageParametersCallbacks.values()) {
171 for (auto& callback : callbacks)
172 callback(String { });
176 AuthenticationManager& NetworkProcess::authenticationManager()
178 return *supplement<AuthenticationManager>();
181 DownloadManager& NetworkProcess::downloadManager()
183 return m_downloadManager;
186 void NetworkProcess::removeNetworkConnectionToWebProcess(NetworkConnectionToWebProcess& connection)
188 auto count = m_webProcessConnections.removeAllMatching([&] (const auto& c) {
189 return c.ptr() == &connection;
191 ASSERT_UNUSED(count, count == 1);
194 bool NetworkProcess::shouldTerminate()
196 // Network process keeps session cookies and credentials, so it should never terminate (as long as UI process connection is alive).
200 void NetworkProcess::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
202 if (messageReceiverMap().dispatchMessage(connection, decoder))
205 if (decoder.messageReceiverName() == Messages::AuxiliaryProcess::messageReceiverName()) {
206 AuxiliaryProcess::didReceiveMessage(connection, decoder);
210 #if ENABLE(CONTENT_EXTENSIONS)
211 if (decoder.messageReceiverName() == Messages::NetworkContentRuleListManager::messageReceiverName()) {
212 m_networkContentRuleListManager.didReceiveMessage(connection, decoder);
217 #if ENABLE(SERVICE_WORKER)
218 if (decoder.messageReceiverName() == Messages::WebSWServerToContextConnection::messageReceiverName()) {
219 ASSERT(parentProcessHasServiceWorkerEntitlement());
220 if (!parentProcessHasServiceWorkerEntitlement())
222 if (auto* webSWConnection = connectionToContextProcessFromIPCConnection(connection)) {
223 webSWConnection->didReceiveMessage(connection, decoder);
228 didReceiveNetworkProcessMessage(connection, decoder);
231 void NetworkProcess::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder)
233 if (messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder))
236 didReceiveSyncNetworkProcessMessage(connection, decoder, replyEncoder);
239 void NetworkProcess::didClose(IPC::Connection&)
241 ASSERT(RunLoop::isMain());
243 // Make sure we flush all cookies to disk before exiting.
244 platformSyncAllCookies([this] {
249 void NetworkProcess::didCreateDownload()
251 disableTermination();
254 void NetworkProcess::didDestroyDownload()
259 IPC::Connection* NetworkProcess::downloadProxyConnection()
261 return parentProcessConnection();
264 AuthenticationManager& NetworkProcess::downloadsAuthenticationManager()
266 return authenticationManager();
269 void NetworkProcess::lowMemoryHandler(Critical critical)
271 if (m_suppressMemoryPressureHandler)
274 WTF::releaseFastMallocFreeMemory();
276 for (auto& networkSession : m_networkSessions.values())
277 networkSession.get().clearPrefetchCache();
280 void NetworkProcess::initializeNetworkProcess(NetworkProcessCreationParameters&& parameters)
282 #if HAVE(SEC_KEY_PROXY)
283 WTF::setProcessPrivileges({ ProcessPrivilege::CanAccessRawCookies });
285 WTF::setProcessPrivileges({ ProcessPrivilege::CanAccessRawCookies, ProcessPrivilege::CanAccessCredentials });
287 WebCore::NetworkStorageSession::permitProcessToUseCookieAPI(true);
288 platformInitializeNetworkProcess(parameters);
290 WTF::Thread::setCurrentThreadIsUserInitiated();
293 m_suppressMemoryPressureHandler = parameters.shouldSuppressMemoryPressureHandler;
294 if (!m_suppressMemoryPressureHandler) {
295 auto& memoryPressureHandler = MemoryPressureHandler::singleton();
296 memoryPressureHandler.setLowMemoryHandler([this] (Critical critical, Synchronous) {
297 lowMemoryHandler(critical);
299 memoryPressureHandler.install();
302 m_diskCacheIsDisabledForTesting = parameters.shouldUseTestingNetworkSession;
304 setCacheModel(parameters.cacheModel);
306 setCanHandleHTTPSServerTrustEvaluation(parameters.canHandleHTTPSServerTrustEvaluation);
308 if (parameters.shouldUseTestingNetworkSession)
309 switchToNewTestingSession();
311 WebCore::RuntimeEnabledFeatures::sharedFeatures().setIsITPDatabaseEnabled(parameters.shouldEnableITPDatabase);
313 WebCore::RuntimeEnabledFeatures::sharedFeatures().setAdClickAttributionDebugModeEnabled(parameters.enableAdClickAttributionDebugMode);
315 SandboxExtension::consumePermanently(parameters.defaultDataStoreParameters.networkSessionParameters.resourceLoadStatisticsDirectoryExtensionHandle);
317 auto sessionID = parameters.defaultDataStoreParameters.networkSessionParameters.sessionID;
318 setSession(sessionID, NetworkSession::create(*this, WTFMove(parameters.defaultDataStoreParameters.networkSessionParameters)));
320 #if ENABLE(INDEXED_DATABASE)
321 addIndexedDatabaseSession(sessionID, parameters.defaultDataStoreParameters.indexedDatabaseDirectory, parameters.defaultDataStoreParameters.indexedDatabaseDirectoryExtensionHandle);
324 #if ENABLE(SERVICE_WORKER)
325 if (parentProcessHasServiceWorkerEntitlement()) {
326 addServiceWorkerSession(PAL::SessionID::defaultSessionID(), parameters.serviceWorkerRegistrationDirectory, parameters.serviceWorkerRegistrationDirectoryExtensionHandle);
328 for (auto& scheme : parameters.urlSchemesServiceWorkersCanHandle)
329 registerURLSchemeServiceWorkersCanHandle(scheme);
331 m_shouldDisableServiceWorkerProcessTerminationDelay = parameters.shouldDisableServiceWorkerProcessTerminationDelay;
334 initializeStorageQuota(parameters.defaultDataStoreParameters);
336 auto* defaultSession = networkSession(PAL::SessionID::defaultSessionID());
337 auto* defaultStorageSession = defaultSession->networkStorageSession();
338 for (const auto& cookie : parameters.defaultDataStoreParameters.pendingCookies)
339 defaultStorageSession->setCookie(cookie);
341 for (auto& supplement : m_supplements.values())
342 supplement->initialize(parameters);
344 for (auto& scheme : parameters.urlSchemesRegisteredAsSecure)
345 registerURLSchemeAsSecure(scheme);
347 for (auto& scheme : parameters.urlSchemesRegisteredAsBypassingContentSecurityPolicy)
348 registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
350 for (auto& scheme : parameters.urlSchemesRegisteredAsLocal)
351 registerURLSchemeAsLocal(scheme);
353 for (auto& scheme : parameters.urlSchemesRegisteredAsNoAccess)
354 registerURLSchemeAsNoAccess(scheme);
356 for (auto& scheme : parameters.urlSchemesRegisteredAsDisplayIsolated)
357 registerURLSchemeAsDisplayIsolated(scheme);
359 for (auto& scheme : parameters.urlSchemesRegisteredAsCORSEnabled)
360 registerURLSchemeAsCORSEnabled(scheme);
362 for (auto& scheme : parameters.urlSchemesRegisteredAsCanDisplayOnlyIfCanRequest)
363 registerURLSchemeAsCanDisplayOnlyIfCanRequest(scheme);
365 m_downloadMonitorSpeedMultiplier = parameters.downloadMonitorSpeedMultiplier;
367 RELEASE_LOG(Process, "%p - NetworkProcess::initializeNetworkProcess: Presenting process = %d", this, WebCore::presentingApplicationPID());
370 void NetworkProcess::initializeConnection(IPC::Connection* connection)
372 AuxiliaryProcess::initializeConnection(connection);
374 // We give a chance for didClose() to get called on the main thread but forcefully call _exit() after a delay
375 // in case the main thread is unresponsive or didClose() takes too long.
376 connection->setDidCloseOnConnectionWorkQueueCallback(callExitSoon);
378 for (auto& supplement : m_supplements.values())
379 supplement->initializeConnection(connection);
382 void NetworkProcess::createNetworkConnectionToWebProcess(bool isServiceWorkerProcess, WebCore::RegistrableDomain&& registrableDomain)
384 #if USE(UNIX_DOMAIN_SOCKETS)
385 IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection();
387 auto connection = NetworkConnectionToWebProcess::create(*this, socketPair.server);
388 m_webProcessConnections.append(WTFMove(connection));
390 IPC::Attachment clientSocket(socketPair.client);
391 parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientSocket), 0);
393 // Create the listening port.
394 mach_port_t listeningPort = MACH_PORT_NULL;
395 auto kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort);
396 if (kr != KERN_SUCCESS) {
397 RELEASE_LOG_ERROR(Process, "NetworkProcess::createNetworkConnectionToWebProcess: Could not allocate mach port, error %x", kr);
400 if (!MACH_PORT_VALID(listeningPort)) {
401 RELEASE_LOG_ERROR(Process, "NetworkProcess::createNetworkConnectionToWebProcess: Could not allocate mach port, returned port was invalid");
405 // Create a listening connection.
406 auto connection = NetworkConnectionToWebProcess::create(*this, IPC::Connection::Identifier(listeningPort));
407 m_webProcessConnections.append(WTFMove(connection));
409 IPC::Attachment clientPort(listeningPort, MACH_MSG_TYPE_MAKE_SEND);
410 parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientPort), 0);
412 IPC::Connection::Identifier serverIdentifier, clientIdentifier;
413 if (!IPC::Connection::createServerAndClientIdentifiers(serverIdentifier, clientIdentifier)) {
414 LOG_ERROR("Failed to create server and client identifiers");
418 auto connection = NetworkConnectionToWebProcess::create(*this, serverIdentifier);
419 m_webProcessConnections.append(WTFMove(connection));
421 IPC::Attachment clientSocket(clientIdentifier);
422 parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientSocket), 0);
427 if (!m_webProcessConnections.isEmpty())
428 m_webProcessConnections.last()->setOnLineState(NetworkStateNotifier::singleton().onLine());
430 #if ENABLE(SERVICE_WORKER)
431 if (isServiceWorkerProcess && !m_webProcessConnections.isEmpty()) {
432 ASSERT(parentProcessHasServiceWorkerEntitlement());
433 ASSERT(m_waitingForServerToContextProcessConnection);
434 auto contextConnection = WebSWServerToContextConnection::create(*this, registrableDomain, m_webProcessConnections.last()->connection());
435 auto addResult = m_serverToContextConnections.add(WTFMove(registrableDomain), contextConnection.copyRef());
436 ASSERT_UNUSED(addResult, addResult.isNewEntry);
438 m_waitingForServerToContextProcessConnection = false;
440 for (auto* server : SWServer::allServers())
441 server->serverToContextConnectionCreated(contextConnection);
444 UNUSED_PARAM(isServiceWorkerProcess);
445 UNUSED_PARAM(registrableDomain);
449 void NetworkProcess::clearCachedCredentials()
451 defaultStorageSession().credentialStorage().clearCredentials();
452 if (auto* networkSession = this->networkSession(PAL::SessionID::defaultSessionID()))
453 networkSession->clearCredentials();
455 ASSERT_NOT_REACHED();
458 void NetworkProcess::clearPermanentCredentialsForProtectionSpace(const ProtectionSpace& protectionSpace, CompletionHandler<void()>&& completionHandler)
460 WebCore::CredentialStorage::clearPermanentCredentialsForProtectionSpace(protectionSpace);
464 void NetworkProcess::addWebsiteDataStore(WebsiteDataStoreParameters&& parameters)
466 #if ENABLE(INDEXED_DATABASE)
467 addIndexedDatabaseSession(parameters.networkSessionParameters.sessionID, parameters.indexedDatabaseDirectory, parameters.indexedDatabaseDirectoryExtensionHandle);
470 #if ENABLE(SERVICE_WORKER)
471 if (parentProcessHasServiceWorkerEntitlement())
472 addServiceWorkerSession(parameters.networkSessionParameters.sessionID, parameters.serviceWorkerRegistrationDirectory, parameters.serviceWorkerRegistrationDirectoryExtensionHandle);
475 initializeStorageQuota(parameters);
477 RemoteNetworkingContext::ensureWebsiteDataStoreSession(*this, WTFMove(parameters));
480 void NetworkProcess::initializeStorageQuota(const WebsiteDataStoreParameters& parameters)
482 auto& managers = m_storageQuotaManagers.ensure(parameters.networkSessionParameters.sessionID, [] {
483 return StorageQuotaManagers { };
485 managers.setDefaultQuotas(parameters.perOriginStorageQuota, parameters.perThirdPartyOriginStorageQuota);
488 void NetworkProcess::switchToNewTestingSession()
491 // 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>).
492 String sessionName = makeString("WebKit Test-", getCurrentProcessID());
494 auto session = adoptCF(WebCore::createPrivateStorageSession(sessionName.createCFString().get()));
496 RetainPtr<CFHTTPCookieStorageRef> cookieStorage;
497 if (WebCore::NetworkStorageSession::processMayUseCookieAPI()) {
498 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies));
500 cookieStorage = adoptCF(_CFURLStorageSessionCopyCookieStorage(kCFAllocatorDefault, session.get()));
503 m_defaultNetworkStorageSession = std::make_unique<WebCore::NetworkStorageSession>(PAL::SessionID::defaultSessionID(), WTFMove(session), WTFMove(cookieStorage));
505 m_defaultNetworkStorageSession = std::make_unique<WebCore::NetworkStorageSession>(PAL::SessionID::defaultSessionID(), std::make_unique<WebCore::SoupNetworkSession>());
507 m_defaultNetworkStorageSession = std::make_unique<WebCore::NetworkStorageSession>(PAL::SessionID::defaultSessionID());
512 void NetworkProcess::ensureSession(const PAL::SessionID& sessionID, const String& identifierBase, RetainPtr<CFHTTPCookieStorageRef>&& cookieStorage)
514 void NetworkProcess::ensureSession(const PAL::SessionID& sessionID, const String& identifierBase)
517 ASSERT(sessionID != PAL::SessionID::defaultSessionID());
519 auto addResult = m_networkStorageSessions.add(sessionID, nullptr);
520 if (!addResult.isNewEntry)
524 RetainPtr<CFURLStorageSessionRef> storageSession;
525 RetainPtr<CFStringRef> cfIdentifier = String(identifierBase + ".PrivateBrowsing").createCFString();
526 if (sessionID.isEphemeral())
527 storageSession = adoptCF(createPrivateStorageSession(cfIdentifier.get()));
529 storageSession = WebCore::NetworkStorageSession::createCFStorageSessionForIdentifier(cfIdentifier.get());
531 if (NetworkStorageSession::processMayUseCookieAPI()) {
532 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies));
533 if (!cookieStorage && storageSession)
534 cookieStorage = adoptCF(_CFURLStorageSessionCopyCookieStorage(kCFAllocatorDefault, storageSession.get()));
537 addResult.iterator->value = std::make_unique<NetworkStorageSession>(sessionID, WTFMove(storageSession), WTFMove(cookieStorage));
539 addResult.iterator->value = std::make_unique<NetworkStorageSession>(sessionID, std::make_unique<SoupNetworkSession>(sessionID));
541 addResult.iterator->value = std::make_unique<NetworkStorageSession>(sessionID);
545 WebCore::NetworkStorageSession* NetworkProcess::storageSession(const PAL::SessionID& sessionID) const
547 if (sessionID == PAL::SessionID::defaultSessionID())
548 return &defaultStorageSession();
549 return m_networkStorageSessions.get(sessionID);
552 WebCore::NetworkStorageSession& NetworkProcess::defaultStorageSession() const
554 if (!m_defaultNetworkStorageSession)
555 m_defaultNetworkStorageSession = platformCreateDefaultStorageSession();
556 return *m_defaultNetworkStorageSession;
559 void NetworkProcess::forEachNetworkStorageSession(const Function<void(WebCore::NetworkStorageSession&)>& functor)
561 functor(defaultStorageSession());
562 for (auto& storageSession : m_networkStorageSessions.values())
563 functor(*storageSession);
566 NetworkSession* NetworkProcess::networkSession(const PAL::SessionID& sessionID) const
568 ASSERT(RunLoop::isMain());
569 ASSERT(sessionID.isValid());
570 return sessionID.isValid() ? m_networkSessions.get(sessionID) : nullptr;
573 NetworkSession* NetworkProcess::networkSessionByConnection(IPC::Connection& connection) const
575 auto sessionID = m_sessionByConnection.get(connection.uniqueID());
576 return sessionID.isValid() ? networkSession(sessionID) : nullptr;
579 void NetworkProcess::setSession(const PAL::SessionID& sessionID, Ref<NetworkSession>&& session)
581 ASSERT(RunLoop::isMain());
582 ASSERT(sessionID.isValid());
583 if (!sessionID.isValid())
586 m_networkSessions.set(sessionID, WTFMove(session));
589 void NetworkProcess::destroySession(const PAL::SessionID& sessionID)
591 ASSERT(RunLoop::isMain());
592 ASSERT(sessionID.isValid());
593 if (!sessionID.isValid())
596 ASSERT(sessionID != PAL::SessionID::defaultSessionID());
598 if (auto session = m_networkSessions.take(sessionID))
599 session->get().invalidateAndCancel();
600 m_networkStorageSessions.remove(sessionID);
601 m_sessionsControlledByAutomation.remove(sessionID);
602 CacheStorage::Engine::destroyEngine(*this, sessionID);
604 #if ENABLE(SERVICE_WORKER)
605 m_swServers.remove(sessionID);
606 m_swDatabasePaths.remove(sessionID);
609 m_storageQuotaManagers.remove(sessionID);
612 #if ENABLE(RESOURCE_LOAD_STATISTICS)
613 void NetworkProcess::dumpResourceLoadStatistics(PAL::SessionID sessionID, CompletionHandler<void(String)>&& completionHandler)
615 if (auto* networkSession = this->networkSession(sessionID)) {
616 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
617 resourceLoadStatistics->dumpResourceLoadStatistics(WTFMove(completionHandler));
619 completionHandler({ });
621 ASSERT_NOT_REACHED();
622 completionHandler({ });
626 void NetworkProcess::updatePrevalentDomainsToBlockCookiesFor(PAL::SessionID sessionID, const Vector<RegistrableDomain>& domainsToBlock, CompletionHandler<void()>&& completionHandler)
628 if (auto* networkStorageSession = storageSession(sessionID))
629 networkStorageSession->setPrevalentDomainsToBlockCookiesFor(domainsToBlock);
633 void NetworkProcess::isGrandfathered(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
635 if (auto* networkSession = this->networkSession(sessionID)) {
636 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
637 resourceLoadStatistics->isGrandfathered(domain, WTFMove(completionHandler));
639 completionHandler(false);
641 ASSERT_NOT_REACHED();
642 completionHandler(false);
646 void NetworkProcess::isPrevalentResource(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
648 if (auto* networkSession = this->networkSession(sessionID)) {
649 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
650 resourceLoadStatistics->isPrevalentResource(domain, WTFMove(completionHandler));
652 completionHandler(false);
654 ASSERT_NOT_REACHED();
655 completionHandler(false);
659 void NetworkProcess::isVeryPrevalentResource(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
661 if (auto* networkSession = this->networkSession(sessionID)) {
662 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
663 resourceLoadStatistics->isVeryPrevalentResource(domain, WTFMove(completionHandler));
665 completionHandler(false);
667 ASSERT_NOT_REACHED();
668 completionHandler(false);
672 void NetworkProcess::setAgeCapForClientSideCookies(PAL::SessionID sessionID, Optional<Seconds> seconds, CompletionHandler<void()>&& completionHandler)
674 if (auto* networkStorageSession = storageSession(sessionID))
675 networkStorageSession->setAgeCapForClientSideCookies(seconds);
679 void NetworkProcess::setGrandfathered(PAL::SessionID sessionID, const RegistrableDomain& domain, bool isGrandfathered, CompletionHandler<void()>&& completionHandler)
681 if (auto* networkSession = this->networkSession(sessionID)) {
682 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
683 resourceLoadStatistics->setGrandfathered(domain, isGrandfathered, WTFMove(completionHandler));
687 ASSERT_NOT_REACHED();
692 void NetworkProcess::setPrevalentResource(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
694 if (auto* networkSession = this->networkSession(sessionID)) {
695 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
696 resourceLoadStatistics->setPrevalentResource(domain, WTFMove(completionHandler));
700 ASSERT_NOT_REACHED();
705 void NetworkProcess::setPrevalentResourceForDebugMode(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
707 if (auto* networkSession = this->networkSession(sessionID)) {
708 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
709 resourceLoadStatistics->setPrevalentResourceForDebugMode(domain, WTFMove(completionHandler));
713 ASSERT_NOT_REACHED();
718 void NetworkProcess::setVeryPrevalentResource(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
720 if (auto* networkSession = this->networkSession(sessionID)) {
721 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
722 resourceLoadStatistics->setVeryPrevalentResource(domain, WTFMove(completionHandler));
726 ASSERT_NOT_REACHED();
731 void NetworkProcess::clearPrevalentResource(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
733 if (auto* networkSession = this->networkSession(sessionID)) {
734 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
735 resourceLoadStatistics->clearPrevalentResource(domain, WTFMove(completionHandler));
739 ASSERT_NOT_REACHED();
744 void NetworkProcess::submitTelemetry(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
746 if (auto* networkSession = this->networkSession(sessionID)) {
747 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
748 resourceLoadStatistics->submitTelemetry(WTFMove(completionHandler));
752 ASSERT_NOT_REACHED();
757 void NetworkProcess::scheduleCookieBlockingUpdate(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
759 if (auto* networkSession = this->networkSession(sessionID)) {
760 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
761 resourceLoadStatistics->scheduleCookieBlockingUpdate(WTFMove(completionHandler));
765 ASSERT_NOT_REACHED();
770 void NetworkProcess::scheduleClearInMemoryAndPersistent(PAL::SessionID sessionID, Optional<WallTime> modifiedSince, ShouldGrandfatherStatistics shouldGrandfather, CompletionHandler<void()>&& completionHandler)
772 if (auto* networkSession = this->networkSession(sessionID)) {
773 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics()) {
775 resourceLoadStatistics->scheduleClearInMemoryAndPersistent(modifiedSince.value(), shouldGrandfather, WTFMove(completionHandler));
777 resourceLoadStatistics->scheduleClearInMemoryAndPersistent(shouldGrandfather, WTFMove(completionHandler));
781 ASSERT_NOT_REACHED();
786 void NetworkProcess::resetParametersToDefaultValues(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
788 if (auto* networkSession = this->networkSession(sessionID)) {
789 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
790 resourceLoadStatistics->resetParametersToDefaultValues(WTFMove(completionHandler));
794 ASSERT_NOT_REACHED();
799 void NetworkProcess::scheduleStatisticsAndDataRecordsProcessing(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
801 if (auto* networkSession = this->networkSession(sessionID)) {
802 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
803 resourceLoadStatistics->scheduleStatisticsAndDataRecordsProcessing(WTFMove(completionHandler));
807 ASSERT_NOT_REACHED();
812 void NetworkProcess::setNotifyPagesWhenDataRecordsWereScanned(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
814 if (auto* networkSession = this->networkSession(sessionID)) {
815 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
816 resourceLoadStatistics->setNotifyPagesWhenDataRecordsWereScanned(value, WTFMove(completionHandler));
820 ASSERT_NOT_REACHED();
825 void NetworkProcess::setIsRunningResourceLoadStatisticsTest(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
827 if (auto* networkSession = this->networkSession(sessionID)) {
828 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
829 resourceLoadStatistics->setIsRunningTest(value, WTFMove(completionHandler));
833 ASSERT_NOT_REACHED();
838 void NetworkProcess::setNotifyPagesWhenTelemetryWasCaptured(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
840 if (auto* networkSession = this->networkSession(sessionID)) {
841 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
842 resourceLoadStatistics->setNotifyPagesWhenTelemetryWasCaptured(value, WTFMove(completionHandler));
846 ASSERT_NOT_REACHED();
851 void NetworkProcess::setSubframeUnderTopFrameDomain(PAL::SessionID sessionID, const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void()>&& completionHandler)
853 if (auto* networkSession = this->networkSession(sessionID)) {
854 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
855 resourceLoadStatistics->setSubframeUnderTopFrameDomain(subFrameDomain, topFrameDomain, WTFMove(completionHandler));
859 ASSERT_NOT_REACHED();
864 void NetworkProcess::isRegisteredAsRedirectingTo(PAL::SessionID sessionID, const RegistrableDomain& domainRedirectedFrom, const RegistrableDomain& domainRedirectedTo, CompletionHandler<void(bool)>&& completionHandler)
866 if (auto* networkSession = this->networkSession(sessionID)) {
867 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
868 resourceLoadStatistics->isRegisteredAsRedirectingTo(domainRedirectedFrom, domainRedirectedTo, WTFMove(completionHandler));
870 completionHandler(false);
872 ASSERT_NOT_REACHED();
873 completionHandler(false);
877 void NetworkProcess::isRegisteredAsSubFrameUnder(PAL::SessionID sessionID, const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void(bool)>&& completionHandler)
879 if (auto* networkSession = this->networkSession(sessionID)) {
880 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
881 resourceLoadStatistics->isRegisteredAsSubFrameUnder(subFrameDomain, topFrameDomain, WTFMove(completionHandler));
883 completionHandler(false);
885 ASSERT_NOT_REACHED();
886 completionHandler(false);
890 void NetworkProcess::setSubresourceUnderTopFrameDomain(PAL::SessionID sessionID, const RegistrableDomain& subresourceDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void()>&& completionHandler)
892 if (auto* networkSession = this->networkSession(sessionID)) {
893 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
894 resourceLoadStatistics->setSubresourceUnderTopFrameDomain(subresourceDomain, topFrameDomain, WTFMove(completionHandler));
898 ASSERT_NOT_REACHED();
903 void NetworkProcess::setSubresourceUniqueRedirectTo(PAL::SessionID sessionID, const RegistrableDomain& subresourceDomain, const RegistrableDomain& domainRedirectedTo, CompletionHandler<void()>&& completionHandler)
905 if (auto* networkSession = this->networkSession(sessionID)) {
906 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
907 resourceLoadStatistics->setSubresourceUniqueRedirectTo(subresourceDomain, domainRedirectedTo, WTFMove(completionHandler));
911 ASSERT_NOT_REACHED();
916 void NetworkProcess::setSubresourceUniqueRedirectFrom(PAL::SessionID sessionID, const RegistrableDomain& subresourceDomain, const RegistrableDomain& domainRedirectedFrom, CompletionHandler<void()>&& completionHandler)
918 if (auto* networkSession = this->networkSession(sessionID)) {
919 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
920 resourceLoadStatistics->setSubresourceUniqueRedirectFrom(subresourceDomain, domainRedirectedFrom, WTFMove(completionHandler));
924 ASSERT_NOT_REACHED();
929 void NetworkProcess::isRegisteredAsSubresourceUnder(PAL::SessionID sessionID, const RegistrableDomain& subresourceDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void(bool)>&& completionHandler)
931 if (auto* networkSession = this->networkSession(sessionID)) {
932 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
933 resourceLoadStatistics->isRegisteredAsSubresourceUnder(subresourceDomain, topFrameDomain, WTFMove(completionHandler));
935 completionHandler(false);
937 ASSERT_NOT_REACHED();
938 completionHandler(false);
942 void NetworkProcess::setTopFrameUniqueRedirectTo(PAL::SessionID sessionID, const RegistrableDomain& topFrameDomain, const RegistrableDomain& domainRedirectedTo, CompletionHandler<void()>&& completionHandler)
944 if (auto* networkSession = this->networkSession(sessionID)) {
945 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
946 resourceLoadStatistics->setTopFrameUniqueRedirectTo(topFrameDomain, domainRedirectedTo, WTFMove(completionHandler));
950 ASSERT_NOT_REACHED();
955 void NetworkProcess::setTopFrameUniqueRedirectFrom(PAL::SessionID sessionID, const RegistrableDomain& topFrameDomain, const RegistrableDomain& domainRedirectedFrom, CompletionHandler<void()>&& completionHandler)
957 if (auto* networkSession = this->networkSession(sessionID)) {
958 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
959 resourceLoadStatistics->setTopFrameUniqueRedirectFrom(topFrameDomain, domainRedirectedFrom, WTFMove(completionHandler));
963 ASSERT_NOT_REACHED();
969 void NetworkProcess::setLastSeen(PAL::SessionID sessionID, const RegistrableDomain& domain, Seconds seconds, CompletionHandler<void()>&& completionHandler)
971 if (auto* networkSession = this->networkSession(sessionID)) {
972 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
973 resourceLoadStatistics->setLastSeen(domain, seconds, WTFMove(completionHandler));
977 ASSERT_NOT_REACHED();
982 void NetworkProcess::getAllStorageAccessEntries(PAL::SessionID sessionID, CompletionHandler<void(Vector<String> domains)>&& completionHandler)
984 if (auto* networkStorageSession = storageSession(sessionID))
985 completionHandler(networkStorageSession->getAllStorageAccessEntries());
987 ASSERT_NOT_REACHED();
988 completionHandler({ });
992 void NetworkProcess::logFrameNavigation(PAL::SessionID sessionID, const RegistrableDomain& targetDomain, const RegistrableDomain& topFrameDomain, const RegistrableDomain& sourceDomain, bool isRedirect, bool isMainFrame)
994 if (auto* networkSession = this->networkSession(sessionID)) {
995 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
996 resourceLoadStatistics->logFrameNavigation(targetDomain, topFrameDomain, sourceDomain, isRedirect, isMainFrame);
998 ASSERT_NOT_REACHED();
1001 void NetworkProcess::logUserInteraction(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
1003 if (auto* networkSession = this->networkSession(sessionID)) {
1004 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1005 resourceLoadStatistics->logUserInteraction(domain, WTFMove(completionHandler));
1007 completionHandler();
1009 ASSERT_NOT_REACHED();
1010 completionHandler();
1014 void NetworkProcess::hadUserInteraction(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
1016 if (auto* networkSession = this->networkSession(sessionID)) {
1017 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1018 resourceLoadStatistics->hasHadUserInteraction(domain, WTFMove(completionHandler));
1020 completionHandler(false);
1022 ASSERT_NOT_REACHED();
1023 completionHandler(false);
1027 void NetworkProcess::clearUserInteraction(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
1029 if (auto* networkSession = this->networkSession(sessionID)) {
1030 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1031 resourceLoadStatistics->clearUserInteraction(domain, WTFMove(completionHandler));
1033 completionHandler();
1035 ASSERT_NOT_REACHED();
1036 completionHandler();
1040 void NetworkProcess::hasLocalStorage(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
1042 if (auto* session = networkSession(sessionID)) {
1043 session->storageManager().getLocalStorageOrigins([domain, completionHandler = WTFMove(completionHandler)](auto&& origins) mutable {
1044 completionHandler(WTF::anyOf(origins, [&domain](auto& origin) {
1045 return domain.matches(origin);
1050 completionHandler(false);
1053 void NetworkProcess::removePrevalentDomains(PAL::SessionID sessionID, const Vector<RegistrableDomain>& domains)
1055 if (auto* networkStorageSession = storageSession(sessionID))
1056 networkStorageSession->removePrevalentDomains(domains);
1059 void NetworkProcess::setCacheMaxAgeCapForPrevalentResources(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
1061 if (auto* networkStorageSession = storageSession(sessionID))
1062 networkStorageSession->setCacheMaxAgeCapForPrevalentResources(Seconds { seconds });
1064 ASSERT_NOT_REACHED();
1065 completionHandler();
1068 void NetworkProcess::setGrandfatheringTime(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
1070 if (auto* networkSession = this->networkSession(sessionID)) {
1071 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1072 resourceLoadStatistics->setGrandfatheringTime(seconds, WTFMove(completionHandler));
1074 completionHandler();
1076 ASSERT_NOT_REACHED();
1077 completionHandler();
1081 void NetworkProcess::setMaxStatisticsEntries(PAL::SessionID sessionID, uint64_t maximumEntryCount, CompletionHandler<void()>&& completionHandler)
1083 if (auto* networkSession = this->networkSession(sessionID)) {
1084 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1085 resourceLoadStatistics->setMaxStatisticsEntries(maximumEntryCount, WTFMove(completionHandler));
1087 completionHandler();
1089 ASSERT_NOT_REACHED();
1090 completionHandler();
1094 void NetworkProcess::setMinimumTimeBetweenDataRecordsRemoval(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
1096 if (auto* networkSession = this->networkSession(sessionID)) {
1097 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1098 resourceLoadStatistics->setMinimumTimeBetweenDataRecordsRemoval(seconds, WTFMove(completionHandler));
1100 completionHandler();
1102 ASSERT_NOT_REACHED();
1103 completionHandler();
1107 void NetworkProcess::setPruneEntriesDownTo(PAL::SessionID sessionID, uint64_t pruneTargetCount, CompletionHandler<void()>&& completionHandler)
1109 if (auto* networkSession = this->networkSession(sessionID)) {
1110 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1111 resourceLoadStatistics->setPruneEntriesDownTo(pruneTargetCount, WTFMove(completionHandler));
1113 completionHandler();
1115 ASSERT_NOT_REACHED();
1116 completionHandler();
1120 void NetworkProcess::setTimeToLiveUserInteraction(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
1122 if (auto* networkSession = this->networkSession(sessionID)) {
1123 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1124 resourceLoadStatistics->setTimeToLiveUserInteraction(seconds, WTFMove(completionHandler));
1126 completionHandler();
1128 ASSERT_NOT_REACHED();
1129 completionHandler();
1133 void NetworkProcess::setShouldClassifyResourcesBeforeDataRecordsRemoval(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
1135 if (auto* networkSession = this->networkSession(sessionID)) {
1136 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1137 resourceLoadStatistics->setShouldClassifyResourcesBeforeDataRecordsRemoval(value, WTFMove(completionHandler));
1139 completionHandler();
1141 ASSERT_NOT_REACHED();
1142 completionHandler();
1146 void NetworkProcess::setResourceLoadStatisticsEnabled(bool enabled)
1148 for (auto& networkSession : m_networkSessions.values())
1149 networkSession.get().setResourceLoadStatisticsEnabled(enabled);
1152 void NetworkProcess::setResourceLoadStatisticsDebugMode(PAL::SessionID sessionID, bool debugMode, CompletionHandler<void()>&& completionHandler)
1154 if (auto* networkSession = this->networkSession(sessionID)) {
1155 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1156 resourceLoadStatistics->setResourceLoadStatisticsDebugMode(debugMode, WTFMove(completionHandler));
1158 completionHandler();
1160 ASSERT_NOT_REACHED();
1161 completionHandler();
1165 void NetworkProcess::resetCacheMaxAgeCapForPrevalentResources(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
1167 if (auto* networkStorageSession = storageSession(sessionID))
1168 networkStorageSession->resetCacheMaxAgeCapForPrevalentResources();
1170 ASSERT_NOT_REACHED();
1171 completionHandler();
1174 void NetworkProcess::didCommitCrossSiteLoadWithDataTransfer(PAL::SessionID sessionID, const RegistrableDomain& fromDomain, const RegistrableDomain& toDomain, OptionSet<WebCore::CrossSiteNavigationDataTransfer::Flag> navigationDataTransfer, WebCore::PageIdentifier pageID)
1176 ASSERT(!navigationDataTransfer.isEmpty());
1178 if (auto* networkStorageSession = storageSession(sessionID)) {
1179 if (!networkStorageSession->shouldBlockThirdPartyCookies(fromDomain))
1182 if (navigationDataTransfer.contains(CrossSiteNavigationDataTransfer::Flag::DestinationLinkDecoration))
1183 networkStorageSession->didCommitCrossSiteLoadWithDataTransferFromPrevalentResource(toDomain, pageID);
1185 if (navigationDataTransfer.contains(CrossSiteNavigationDataTransfer::Flag::ReferrerLinkDecoration))
1186 parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCommitCrossSiteLoadWithDataTransferFromPrevalentResource(pageID), 0);
1188 ASSERT_NOT_REACHED();
1190 if (navigationDataTransfer.contains(CrossSiteNavigationDataTransfer::Flag::DestinationLinkDecoration)) {
1191 if (auto* networkSession = this->networkSession(sessionID)) {
1192 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1193 resourceLoadStatistics->logCrossSiteLoadWithLinkDecoration(fromDomain, toDomain, [] { });
1195 ASSERT_NOT_REACHED();
1199 void NetworkProcess::setCrossSiteLoadWithLinkDecorationForTesting(PAL::SessionID sessionID, const RegistrableDomain& fromDomain, const RegistrableDomain& toDomain, CompletionHandler<void()>&& completionHandler)
1201 if (auto* networkSession = this->networkSession(sessionID)) {
1202 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
1203 resourceLoadStatistics->logCrossSiteLoadWithLinkDecoration(fromDomain, toDomain, WTFMove(completionHandler));
1205 completionHandler();
1207 ASSERT_NOT_REACHED();
1208 completionHandler();
1212 void NetworkProcess::resetCrossSiteLoadsWithLinkDecorationForTesting(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
1214 if (auto* networkStorageSession = storageSession(sessionID))
1215 networkStorageSession->resetCrossSiteLoadsWithLinkDecorationForTesting();
1217 ASSERT_NOT_REACHED();
1218 completionHandler();
1220 #endif // ENABLE(RESOURCE_LOAD_STATISTICS)
1222 bool NetworkProcess::sessionIsControlledByAutomation(PAL::SessionID sessionID) const
1224 return m_sessionsControlledByAutomation.contains(sessionID);
1227 void NetworkProcess::setSessionIsControlledByAutomation(PAL::SessionID sessionID, bool controlled)
1230 m_sessionsControlledByAutomation.add(sessionID);
1232 m_sessionsControlledByAutomation.remove(sessionID);
1235 static void fetchDiskCacheEntries(NetworkCache::Cache* cache, PAL::SessionID sessionID, OptionSet<WebsiteDataFetchOption> fetchOptions, CompletionHandler<void(Vector<WebsiteData::Entry>)>&& completionHandler)
1238 RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler)] () mutable {
1239 completionHandler({ });
1244 HashMap<SecurityOriginData, uint64_t> originsAndSizes;
1245 cache->traverse([fetchOptions, completionHandler = WTFMove(completionHandler), originsAndSizes = WTFMove(originsAndSizes)](auto* traversalEntry) mutable {
1246 if (!traversalEntry) {
1247 Vector<WebsiteData::Entry> entries;
1249 for (auto& originAndSize : originsAndSizes)
1250 entries.append(WebsiteData::Entry { originAndSize.key, WebsiteDataType::DiskCache, originAndSize.value });
1252 RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), entries = WTFMove(entries)] () mutable {
1253 completionHandler(entries);
1259 auto url = traversalEntry->entry.response().url();
1260 auto result = originsAndSizes.add({url.protocol().toString(), url.host().toString(), url.port()}, 0);
1262 if (fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes))
1263 result.iterator->value += traversalEntry->entry.sourceStorageRecord().header.size() + traversalEntry->recordInfo.bodySize;
1267 void NetworkProcess::fetchWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, uint64_t callbackID)
1269 ASSERT(sessionID.isValid());
1270 if (!sessionID.isValid())
1273 struct CallbackAggregator final : public ThreadSafeRefCounted<CallbackAggregator> {
1274 explicit CallbackAggregator(Function<void (WebsiteData)>&& completionHandler)
1275 : m_completionHandler(WTFMove(completionHandler))
1279 ~CallbackAggregator()
1281 RunLoop::main().dispatch([completionHandler = WTFMove(m_completionHandler), websiteData = WTFMove(m_websiteData)] () mutable {
1282 completionHandler(websiteData);
1286 CompletionHandler<void(WebsiteData)> m_completionHandler;
1287 WebsiteData m_websiteData;
1290 auto callbackAggregator = adoptRef(*new CallbackAggregator([this, callbackID] (WebsiteData websiteData) {
1291 parentProcessConnection()->send(Messages::NetworkProcessProxy::DidFetchWebsiteData(callbackID, websiteData), 0);
1294 if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
1295 if (auto* networkStorageSession = storageSession(sessionID))
1296 networkStorageSession->getHostnamesWithCookies(callbackAggregator->m_websiteData.hostNamesWithCookies);
1299 if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
1300 if (storageSession(sessionID)) {
1301 auto securityOrigins = storageSession(sessionID)->credentialStorage().originsWithCredentials();
1302 for (auto& securityOrigin : securityOrigins)
1303 callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::Credentials, 0 });
1305 auto securityOrigins = WebCore::CredentialStorage::originsWithSessionCredentials();
1306 for (auto& securityOrigin : securityOrigins)
1307 callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::Credentials, 0 });
1310 if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) {
1311 CacheStorage::Engine::fetchEntries(*this, sessionID, fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes), [callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
1312 callbackAggregator->m_websiteData.entries.appendVector(entries);
1316 auto* session = networkSession(sessionID);
1317 if (websiteDataTypes.contains(WebsiteDataType::SessionStorage) && session) {
1318 session->storageManager().getSessionStorageOrigins([callbackAggregator = callbackAggregator.copyRef()](auto&& origins) {
1319 while (!origins.isEmpty())
1320 callbackAggregator->m_websiteData.entries.append(WebsiteData::Entry { origins.takeAny(), WebsiteDataType::SessionStorage, 0 });
1324 if (websiteDataTypes.contains(WebsiteDataType::LocalStorage) && session) {
1325 session->storageManager().getLocalStorageOrigins([callbackAggregator = callbackAggregator.copyRef()](auto&& origins) {
1326 while (!origins.isEmpty())
1327 callbackAggregator->m_websiteData.entries.append(WebsiteData::Entry { origins.takeAny(), WebsiteDataType::LocalStorage, 0 });
1332 if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
1333 if (auto* networkStorageSession = storageSession(sessionID))
1334 getHostNamesWithHSTSCache(*networkStorageSession, callbackAggregator->m_websiteData.hostNamesWithHSTSCache);
1338 #if ENABLE(INDEXED_DATABASE)
1339 auto path = m_idbDatabasePaths.get(sessionID);
1340 if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases)) {
1341 // FIXME: Pick the right database store based on the session ID.
1342 postStorageTask(CrossThreadTask([this, callbackAggregator = callbackAggregator.copyRef(), path = WTFMove(path)]() mutable {
1343 RunLoop::main().dispatch([callbackAggregator = WTFMove(callbackAggregator), securityOrigins = indexedDatabaseOrigins(path)] {
1344 for (const auto& securityOrigin : securityOrigins)
1345 callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::IndexedDBDatabases, 0 });
1351 #if ENABLE(SERVICE_WORKER)
1352 path = m_swDatabasePaths.get(sessionID);
1353 if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations)) {
1354 swServerForSession(sessionID).getOriginsWithRegistrations([callbackAggregator = callbackAggregator.copyRef()](const HashSet<SecurityOriginData>& securityOrigins) mutable {
1355 for (auto& origin : securityOrigins)
1356 callbackAggregator->m_websiteData.entries.append({ origin, WebsiteDataType::ServiceWorkerRegistrations, 0 });
1361 if (websiteDataTypes.contains(WebsiteDataType::DiskCache)) {
1362 fetchDiskCacheEntries(cache(), sessionID, fetchOptions, [callbackAggregator = WTFMove(callbackAggregator)](auto entries) mutable {
1363 callbackAggregator->m_websiteData.entries.appendVector(entries);
1368 void NetworkProcess::deleteWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, WallTime modifiedSince, uint64_t callbackID)
1370 ASSERT(sessionID.isValid());
1371 if (!sessionID.isValid())
1375 if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
1376 if (auto* networkStorageSession = storageSession(sessionID))
1377 clearHSTSCache(*networkStorageSession, modifiedSince);
1381 if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
1382 if (auto* networkStorageSession = storageSession(sessionID))
1383 networkStorageSession->deleteAllCookiesModifiedSince(modifiedSince);
1386 if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
1387 if (auto* session = storageSession(sessionID))
1388 session->credentialStorage().clearCredentials();
1389 WebCore::CredentialStorage::clearSessionCredentials();
1392 auto clearTasksHandler = WTF::CallbackAggregator::create([this, callbackID] {
1393 parentProcessConnection()->send(Messages::NetworkProcessProxy::DidDeleteWebsiteData(callbackID), 0);
1396 if (websiteDataTypes.contains(WebsiteDataType::DOMCache))
1397 CacheStorage::Engine::clearAllCaches(*this, sessionID, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1399 auto* session = networkSession(sessionID);
1400 if (websiteDataTypes.contains(WebsiteDataType::SessionStorage) && session)
1401 session->storageManager().deleteSessionStorageOrigins([clearTasksHandler = clearTasksHandler.copyRef()] { });
1403 if (websiteDataTypes.contains(WebsiteDataType::LocalStorage) && session)
1404 session->storageManager().deleteLocalStorageOriginsModifiedSince(modifiedSince, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1406 #if ENABLE(INDEXED_DATABASE)
1407 if (websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases) && !sessionID.isEphemeral())
1408 idbServer(sessionID).closeAndDeleteDatabasesModifiedSince(modifiedSince, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1411 #if ENABLE(SERVICE_WORKER)
1412 if (websiteDataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations) && !sessionID.isEphemeral())
1413 swServerForSession(sessionID).clearAll([clearTasksHandler = clearTasksHandler.copyRef()] { });
1416 #if ENABLE(RESOURCE_LOAD_STATISTICS)
1417 if (websiteDataTypes.contains(WebsiteDataType::ResourceLoadStatistics)) {
1418 if (auto* networkSession = this->networkSession(sessionID)) {
1419 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics()) {
1420 auto deletedTypesRaw = websiteDataTypes.toRaw();
1421 auto monitoredTypesRaw = WebResourceLoadStatisticsStore::monitoredDataTypes().toRaw();
1423 // If we are deleting all of the data types that the resource load statistics store monitors
1424 // we do not need to re-grandfather old data.
1425 auto shouldGrandfather = ((monitoredTypesRaw & deletedTypesRaw) == monitoredTypesRaw) ? ShouldGrandfatherStatistics::No : ShouldGrandfatherStatistics::Yes;
1427 resourceLoadStatistics->scheduleClearInMemoryAndPersistent(modifiedSince, shouldGrandfather, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1433 if (websiteDataTypes.contains(WebsiteDataType::DiskCache) && !sessionID.isEphemeral())
1434 clearDiskCache(modifiedSince, [clearTasksHandler = WTFMove(clearTasksHandler)] { });
1436 if (websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases) || websiteDataTypes.contains(WebsiteDataType::DOMCache))
1437 clearStorageQuota(sessionID);
1439 if (websiteDataTypes.contains(WebsiteDataType::AdClickAttributions)) {
1440 if (auto* networkSession = this->networkSession(sessionID))
1441 networkSession->clearAdClickAttribution();
1445 static void clearDiskCacheEntries(NetworkCache::Cache* cache, const Vector<SecurityOriginData>& origins, CompletionHandler<void()>&& completionHandler)
1448 RunLoop::main().dispatch(WTFMove(completionHandler));
1452 HashSet<RefPtr<SecurityOrigin>> originsToDelete;
1453 for (auto& origin : origins)
1454 originsToDelete.add(origin.securityOrigin());
1456 Vector<NetworkCache::Key> cacheKeysToDelete;
1457 cache->traverse([cache, completionHandler = WTFMove(completionHandler), originsToDelete = WTFMove(originsToDelete), cacheKeysToDelete = WTFMove(cacheKeysToDelete)](auto* traversalEntry) mutable {
1458 if (traversalEntry) {
1459 if (originsToDelete.contains(SecurityOrigin::create(traversalEntry->entry.response().url())))
1460 cacheKeysToDelete.append(traversalEntry->entry.key());
1464 cache->remove(cacheKeysToDelete, WTFMove(completionHandler));
1469 void NetworkProcess::deleteWebsiteDataForOrigins(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, const Vector<SecurityOriginData>& originDatas, const Vector<String>& cookieHostNames, const Vector<String>& HSTSCacheHostNames, uint64_t callbackID)
1471 if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
1472 if (auto* networkStorageSession = storageSession(sessionID))
1473 networkStorageSession->deleteCookiesForHostnames(cookieHostNames);
1477 if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
1478 if (auto* networkStorageSession = storageSession(sessionID))
1479 deleteHSTSCacheForHostNames(*networkStorageSession, HSTSCacheHostNames);
1483 if (websiteDataTypes.contains(WebsiteDataType::AdClickAttributions)) {
1484 if (auto* networkSession = this->networkSession(sessionID)) {
1485 for (auto& originData : originDatas)
1486 networkSession->clearAdClickAttributionForRegistrableDomain(RegistrableDomain::uncheckedCreateFromHost(originData.host));
1490 auto clearTasksHandler = WTF::CallbackAggregator::create([this, callbackID] {
1491 parentProcessConnection()->send(Messages::NetworkProcessProxy::DidDeleteWebsiteDataForOrigins(callbackID), 0);
1494 if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) {
1495 for (auto& originData : originDatas)
1496 CacheStorage::Engine::clearCachesForOrigin(*this, sessionID, SecurityOriginData { originData }, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1499 auto* session = networkSession(sessionID);
1500 if (websiteDataTypes.contains(WebsiteDataType::SessionStorage) && session)
1501 session->storageManager().deleteSessionStorageEntriesForOrigins(originDatas, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1503 if (websiteDataTypes.contains(WebsiteDataType::LocalStorage) && session)
1504 session->storageManager().deleteLocalStorageEntriesForOrigins(originDatas, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1506 #if ENABLE(INDEXED_DATABASE)
1507 if (websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases) && !sessionID.isEphemeral())
1508 idbServer(sessionID).closeAndDeleteDatabasesForOrigins(originDatas, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1511 #if ENABLE(SERVICE_WORKER)
1512 if (websiteDataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations) && !sessionID.isEphemeral()) {
1513 auto& server = swServerForSession(sessionID);
1514 for (auto& originData : originDatas)
1515 server.clear(originData, [clearTasksHandler = clearTasksHandler.copyRef()] { });
1519 if (websiteDataTypes.contains(WebsiteDataType::DiskCache) && !sessionID.isEphemeral())
1520 clearDiskCacheEntries(cache(), originDatas, [clearTasksHandler = WTFMove(clearTasksHandler)] { });
1522 if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
1523 if (auto* session = storageSession(sessionID)) {
1524 for (auto& originData : originDatas)
1525 session->credentialStorage().removeCredentialsWithOrigin(originData);
1527 WebCore::CredentialStorage::removeSessionCredentialsWithOrigins(originDatas);
1530 // FIXME: Implement storage quota clearing for these origins.
1533 void NetworkProcess::clearStorageQuota(PAL::SessionID sessionID)
1535 auto iterator = m_storageQuotaManagers.find(sessionID);
1536 if (iterator == m_storageQuotaManagers.end())
1539 auto& managers = iterator->value;
1540 for (auto& manager : managers.managersPerOrigin())
1541 manager.value->resetQuota(managers.defaultQuota(manager.key));
1544 #if ENABLE(RESOURCE_LOAD_STATISTICS)
1545 static Vector<String> filterForRegistrableDomains(const Vector<RegistrableDomain>& registrableDomains, const HashSet<String>& foundValues)
1547 Vector<String> result;
1548 for (const auto& value : foundValues) {
1549 if (registrableDomains.contains(RegistrableDomain::uncheckedCreateFromHost(value)))
1550 result.append(value);
1556 static Vector<WebsiteData::Entry> filterForRegistrableDomains(const Vector<RegistrableDomain>& registrableDomains, const Vector<WebsiteData::Entry>& foundValues)
1558 Vector<WebsiteData::Entry> result;
1559 for (const auto& value : foundValues) {
1560 if (registrableDomains.contains(RegistrableDomain::uncheckedCreateFromHost(value.origin.host)))
1561 result.append(value);
1567 static Vector<WebCore::SecurityOriginData> filterForRegistrableDomains(const HashSet<WebCore::SecurityOriginData>& origins, const Vector<RegistrableDomain>& domainsToDelete, HashSet<RegistrableDomain>& domainsDeleted)
1569 Vector<SecurityOriginData> originsDeleted;
1570 for (const auto& origin : origins) {
1571 auto domain = RegistrableDomain::uncheckedCreateFromHost(origin.host);
1572 if (!domainsToDelete.contains(domain))
1574 originsDeleted.append(origin);
1575 domainsDeleted.add(domain);
1578 return originsDeleted;
1581 void NetworkProcess::deleteWebsiteDataForRegistrableDomains(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, HashMap<RegistrableDomain, WebsiteDataToRemove>&& domains, bool shouldNotifyPage, CompletionHandler<void(const HashSet<RegistrableDomain>&)>&& completionHandler)
1583 ASSERT(sessionID.isValid());
1584 if (!sessionID.isValid())
1587 OptionSet<WebsiteDataFetchOption> fetchOptions = WebsiteDataFetchOption::DoNotCreateProcesses;
1589 struct CallbackAggregator final : public ThreadSafeRefCounted<CallbackAggregator> {
1590 explicit CallbackAggregator(CompletionHandler<void(const HashSet<RegistrableDomain>&)>&& completionHandler)
1591 : m_completionHandler(WTFMove(completionHandler))
1595 ~CallbackAggregator()
1597 RunLoop::main().dispatch([completionHandler = WTFMove(m_completionHandler), domains = WTFMove(m_domains)] () mutable {
1598 completionHandler(domains);
1602 CompletionHandler<void(const HashSet<RegistrableDomain>&)> m_completionHandler;
1603 HashSet<RegistrableDomain> m_domains;
1606 auto callbackAggregator = adoptRef(*new CallbackAggregator([this, completionHandler = WTFMove(completionHandler), shouldNotifyPage] (const HashSet<RegistrableDomain>& domainsWithData) mutable {
1607 if (shouldNotifyPage)
1608 parentProcessConnection()->send(Messages::NetworkProcessProxy::NotifyWebsiteDataDeletionForRegistrableDomainsFinished(), 0);
1610 RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), domainsWithData = crossThreadCopy(domainsWithData)] () mutable {
1611 completionHandler(domainsWithData);
1615 HashSet<String> hostNamesWithCookies;
1616 HashSet<String> hostNamesWithHSTSCache;
1618 Vector<RegistrableDomain> domainsToDeleteCookiesFor;
1619 Vector<RegistrableDomain> domainsToDeleteAllButHttpOnlyCookiesFor;
1620 Vector<RegistrableDomain> domainsToDeleteAllButCookiesFor;
1621 Vector<String> hostnamesWithCookiesToDelete;
1622 if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
1623 for (auto& domain : domains.keys()) {
1624 domainsToDeleteAllButCookiesFor.append(domain);
1625 switch (domains.get(domain)) {
1626 case WebsiteDataToRemove::All:
1627 domainsToDeleteCookiesFor.append(domain);
1629 case WebsiteDataToRemove::AllButHttpOnlyCookies:
1630 domainsToDeleteAllButHttpOnlyCookiesFor.append(domain);
1632 case WebsiteDataToRemove::AllButCookies:
1637 if (auto* networkStorageSession = storageSession(sessionID)) {
1638 networkStorageSession->getHostnamesWithCookies(hostNamesWithCookies);
1640 hostnamesWithCookiesToDelete = filterForRegistrableDomains(domainsToDeleteCookiesFor, hostNamesWithCookies);
1641 networkStorageSession->deleteCookiesForHostnames(hostnamesWithCookiesToDelete, WebCore::IncludeHttpOnlyCookies::Yes);
1643 for (const auto& host : hostnamesWithCookiesToDelete)
1644 callbackAggregator->m_domains.add(RegistrableDomain::uncheckedCreateFromHost(host));
1646 hostnamesWithCookiesToDelete = filterForRegistrableDomains(domainsToDeleteAllButHttpOnlyCookiesFor, hostNamesWithCookies);
1647 networkStorageSession->deleteCookiesForHostnames(hostnamesWithCookiesToDelete, WebCore::IncludeHttpOnlyCookies::No);
1649 for (const auto& host : hostnamesWithCookiesToDelete)
1650 callbackAggregator->m_domains.add(RegistrableDomain::uncheckedCreateFromHost(host));
1653 for (auto& domain : domains.keys())
1654 domainsToDeleteAllButCookiesFor.append(domain);
1657 Vector<String> hostnamesWithHSTSToDelete;
1659 if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
1660 if (auto* networkStorageSession = storageSession(sessionID)) {
1661 getHostNamesWithHSTSCache(*networkStorageSession, hostNamesWithHSTSCache);
1662 hostnamesWithHSTSToDelete = filterForRegistrableDomains(domainsToDeleteAllButCookiesFor, hostNamesWithHSTSCache);
1664 for (const auto& host : hostnamesWithHSTSToDelete)
1665 callbackAggregator->m_domains.add(RegistrableDomain::uncheckedCreateFromHost(host));
1667 deleteHSTSCacheForHostNames(*networkStorageSession, hostnamesWithHSTSToDelete);
1672 if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
1673 if (auto* session = storageSession(sessionID)) {
1674 auto origins = session->credentialStorage().originsWithCredentials();
1675 auto originsToDelete = filterForRegistrableDomains(origins, domainsToDeleteAllButCookiesFor, callbackAggregator->m_domains);
1676 for (auto& origin : originsToDelete)
1677 session->credentialStorage().removeCredentialsWithOrigin(origin);
1680 auto origins = WebCore::CredentialStorage::originsWithSessionCredentials();
1681 auto originsToDelete = filterForRegistrableDomains(origins, domainsToDeleteAllButCookiesFor, callbackAggregator->m_domains);
1682 WebCore::CredentialStorage::removeSessionCredentialsWithOrigins(originsToDelete);
1685 if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) {
1686 CacheStorage::Engine::fetchEntries(*this, sessionID, fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes), [this, domainsToDeleteAllButCookiesFor, sessionID, callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
1688 auto entriesToDelete = filterForRegistrableDomains(domainsToDeleteAllButCookiesFor, entries);
1690 for (const auto& entry : entriesToDelete)
1691 callbackAggregator->m_domains.add(RegistrableDomain::uncheckedCreateFromHost(entry.origin.host));
1693 for (auto& entry : entriesToDelete)
1694 CacheStorage::Engine::clearCachesForOrigin(*this, sessionID, SecurityOriginData { entry.origin }, [callbackAggregator = callbackAggregator.copyRef()] { });
1698 auto* session = networkSession(sessionID);
1700 auto& storageManager = session->storageManager();
1701 if (websiteDataTypes.contains(WebsiteDataType::SessionStorage)) {
1702 storageManager.getSessionStorageOrigins([storageManager = makeRefPtr(storageManager), callbackAggregator = callbackAggregator.copyRef(), domainsToDeleteAllButCookiesFor](auto&& origins) {
1703 auto originsToDelete = filterForRegistrableDomains(origins, domainsToDeleteAllButCookiesFor, callbackAggregator->m_domains);
1704 storageManager->deleteSessionStorageEntriesForOrigins(originsToDelete, [callbackAggregator = callbackAggregator.copyRef()] { });
1708 if (websiteDataTypes.contains(WebsiteDataType::LocalStorage)) {
1709 storageManager.getLocalStorageOrigins([storageManager = makeRefPtr(storageManager), callbackAggregator = callbackAggregator.copyRef(), domainsToDeleteAllButCookiesFor](auto&& origins) {
1710 auto originsToDelete = filterForRegistrableDomains(origins, domainsToDeleteAllButCookiesFor, callbackAggregator->m_domains);
1711 storageManager->deleteLocalStorageEntriesForOrigins(originsToDelete, [callbackAggregator = callbackAggregator.copyRef()] { });
1716 #if ENABLE(INDEXED_DATABASE)
1717 auto path = m_idbDatabasePaths.get(sessionID);
1718 if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases)) {
1719 // FIXME: Pick the right database store based on the session ID.
1720 postStorageTask(CrossThreadTask([this, sessionID, callbackAggregator = callbackAggregator.copyRef(), path = WTFMove(path), domainsToDeleteAllButCookiesFor]() mutable {
1721 RunLoop::main().dispatch([this, sessionID, domainsToDeleteAllButCookiesFor = crossThreadCopy(domainsToDeleteAllButCookiesFor), callbackAggregator = callbackAggregator.copyRef(), securityOrigins = indexedDatabaseOrigins(path)] {
1722 Vector<SecurityOriginData> entriesToDelete;
1723 for (const auto& securityOrigin : securityOrigins) {
1724 auto domain = RegistrableDomain::uncheckedCreateFromHost(securityOrigin.host);
1725 if (!domainsToDeleteAllButCookiesFor.contains(domain))
1728 entriesToDelete.append(securityOrigin);
1729 callbackAggregator->m_domains.add(domain);
1732 idbServer(sessionID).closeAndDeleteDatabasesForOrigins(entriesToDelete, [callbackAggregator = callbackAggregator.copyRef()] { });
1738 #if ENABLE(SERVICE_WORKER)
1739 path = m_swDatabasePaths.get(sessionID);
1740 if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations)) {
1741 swServerForSession(sessionID).getOriginsWithRegistrations([this, sessionID, domainsToDeleteAllButCookiesFor, callbackAggregator = callbackAggregator.copyRef()](const HashSet<SecurityOriginData>& securityOrigins) mutable {
1742 for (auto& securityOrigin : securityOrigins) {
1743 if (!domainsToDeleteAllButCookiesFor.contains(RegistrableDomain::uncheckedCreateFromHost(securityOrigin.host)))
1745 callbackAggregator->m_domains.add(RegistrableDomain::uncheckedCreateFromHost(securityOrigin.host));
1746 swServerForSession(sessionID).clear(securityOrigin, [callbackAggregator = callbackAggregator.copyRef()] { });
1752 if (websiteDataTypes.contains(WebsiteDataType::DiskCache)) {
1753 fetchDiskCacheEntries(cache(), sessionID, fetchOptions, [this, domainsToDeleteAllButCookiesFor, callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
1755 Vector<SecurityOriginData> entriesToDelete;
1756 for (auto& entry : entries) {
1757 if (!domainsToDeleteAllButCookiesFor.contains(RegistrableDomain::uncheckedCreateFromHost(entry.origin.host)))
1759 entriesToDelete.append(entry.origin);
1760 callbackAggregator->m_domains.add(RegistrableDomain::uncheckedCreateFromHost(entry.origin.host));
1762 clearDiskCacheEntries(cache(), entriesToDelete, [callbackAggregator = callbackAggregator.copyRef()] { });
1766 auto dataTypesForUIProcess = WebsiteData::filter(websiteDataTypes, WebsiteDataProcessType::UI);
1767 if (!dataTypesForUIProcess.isEmpty() && !domainsToDeleteAllButCookiesFor.isEmpty()) {
1768 CompletionHandler<void(const HashSet<RegistrableDomain>&)> completionHandler = [callbackAggregator = callbackAggregator.copyRef()] (const HashSet<RegistrableDomain>& domains) {
1769 for (auto& domain : domains)
1770 callbackAggregator->m_domains.add(domain);
1772 parentProcessConnection()->sendWithAsyncReply(Messages::NetworkProcessProxy::DeleteWebsiteDataInUIProcessForRegistrableDomains(sessionID, dataTypesForUIProcess, fetchOptions, domainsToDeleteAllButCookiesFor), WTFMove(completionHandler));
1776 void NetworkProcess::deleteCookiesForTesting(PAL::SessionID sessionID, RegistrableDomain domain, bool includeHttpOnlyCookies, CompletionHandler<void()>&& completionHandler)
1778 OptionSet<WebsiteDataType> cookieType = WebsiteDataType::Cookies;
1779 HashMap<RegistrableDomain, WebsiteDataToRemove> toDeleteFor;
1780 toDeleteFor.add(domain, includeHttpOnlyCookies ? WebsiteDataToRemove::All : WebsiteDataToRemove::AllButHttpOnlyCookies);
1781 deleteWebsiteDataForRegistrableDomains(sessionID, cookieType, WTFMove(toDeleteFor), true, [completionHandler = WTFMove(completionHandler)] (const HashSet<RegistrableDomain>& domainsDeletedFor) mutable {
1782 UNUSED_PARAM(domainsDeletedFor);
1783 completionHandler();
1787 void NetworkProcess::registrableDomainsWithWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, bool shouldNotifyPage, CompletionHandler<void(HashSet<RegistrableDomain>&&)>&& completionHandler)
1789 ASSERT(sessionID.isValid());
1790 if (!sessionID.isValid())
1793 OptionSet<WebsiteDataFetchOption> fetchOptions = WebsiteDataFetchOption::DoNotCreateProcesses;
1795 struct CallbackAggregator final : public ThreadSafeRefCounted<CallbackAggregator> {
1796 explicit CallbackAggregator(CompletionHandler<void(HashSet<RegistrableDomain>&&)>&& completionHandler)
1797 : m_completionHandler(WTFMove(completionHandler))
1801 ~CallbackAggregator()
1803 RunLoop::main().dispatch([completionHandler = WTFMove(m_completionHandler), websiteData = WTFMove(m_websiteData)] () mutable {
1804 HashSet<RegistrableDomain> domains;
1805 for (const auto& hostnameWithCookies : websiteData.hostNamesWithCookies)
1806 domains.add(RegistrableDomain::uncheckedCreateFromHost(hostnameWithCookies));
1808 for (const auto& hostnameWithHSTS : websiteData.hostNamesWithHSTSCache)
1809 domains.add(RegistrableDomain::uncheckedCreateFromHost(hostnameWithHSTS));
1811 for (const auto& entry : websiteData.entries)
1812 domains.add(RegistrableDomain::uncheckedCreateFromHost(entry.origin.host));
1814 completionHandler(WTFMove(domains));
1818 CompletionHandler<void(HashSet<RegistrableDomain>&&)> m_completionHandler;
1819 WebsiteData m_websiteData;
1822 auto callbackAggregator = adoptRef(*new CallbackAggregator([this, completionHandler = WTFMove(completionHandler), shouldNotifyPage] (HashSet<RegistrableDomain>&& domainsWithData) mutable {
1823 if (shouldNotifyPage)
1824 parentProcessConnection()->send(Messages::NetworkProcessProxy::NotifyWebsiteDataScanForRegistrableDomainsFinished(), 0);
1826 RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), domainsWithData = crossThreadCopy(domainsWithData)] () mutable {
1827 completionHandler(WTFMove(domainsWithData));
1831 auto& websiteDataStore = callbackAggregator->m_websiteData;
1833 Vector<String> hostnamesWithCookiesToDelete;
1834 if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
1835 if (auto* networkStorageSession = storageSession(sessionID))
1836 networkStorageSession->getHostnamesWithCookies(websiteDataStore.hostNamesWithCookies);
1839 Vector<String> hostnamesWithHSTSToDelete;
1841 if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
1842 if (auto* networkStorageSession = storageSession(sessionID))
1843 getHostNamesWithHSTSCache(*networkStorageSession, websiteDataStore.hostNamesWithHSTSCache);
1847 if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
1848 if (auto* networkStorageSession = storageSession(sessionID)) {
1849 auto securityOrigins = networkStorageSession->credentialStorage().originsWithCredentials();
1850 for (auto& securityOrigin : securityOrigins)
1851 callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::Credentials, 0 });
1855 if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) {
1856 CacheStorage::Engine::fetchEntries(*this, sessionID, fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes), [callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
1857 callbackAggregator->m_websiteData.entries.appendVector(entries);
1861 #if ENABLE(INDEXED_DATABASE)
1862 auto path = m_idbDatabasePaths.get(sessionID);
1863 if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases)) {
1864 // FIXME: Pick the right database store based on the session ID.
1865 postStorageTask(CrossThreadTask([this, callbackAggregator = callbackAggregator.copyRef(), path = WTFMove(path)]() mutable {
1866 RunLoop::main().dispatch([callbackAggregator = callbackAggregator.copyRef(), securityOrigins = indexedDatabaseOrigins(path)] {
1867 for (const auto& securityOrigin : securityOrigins)
1868 callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::IndexedDBDatabases, 0 });
1874 #if ENABLE(SERVICE_WORKER)
1875 path = m_swDatabasePaths.get(sessionID);
1876 if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations)) {
1877 swServerForSession(sessionID).getOriginsWithRegistrations([callbackAggregator = callbackAggregator.copyRef()](const HashSet<SecurityOriginData>& securityOrigins) mutable {
1878 for (auto& securityOrigin : securityOrigins)
1879 callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::ServiceWorkerRegistrations, 0 });
1884 if (websiteDataTypes.contains(WebsiteDataType::DiskCache)) {
1885 fetchDiskCacheEntries(cache(), sessionID, fetchOptions, [callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
1886 callbackAggregator->m_websiteData.entries.appendVector(entries);
1890 #endif // ENABLE(RESOURCE_LOAD_STATISTICS)
1892 CacheStorage::Engine* NetworkProcess::findCacheEngine(const PAL::SessionID& sessionID)
1894 return m_cacheEngines.get(sessionID);
1897 CacheStorage::Engine& NetworkProcess::ensureCacheEngine(const PAL::SessionID& sessionID, Function<Ref<CacheStorage::Engine>()>&& functor)
1899 return m_cacheEngines.ensure(sessionID, WTFMove(functor)).iterator->value;
1902 void NetworkProcess::removeCacheEngine(const PAL::SessionID& sessionID)
1904 m_cacheEngines.remove(sessionID);
1907 void NetworkProcess::downloadRequest(PAL::SessionID sessionID, DownloadID downloadID, const ResourceRequest& request, const String& suggestedFilename)
1909 downloadManager().startDownload(sessionID, downloadID, request, suggestedFilename);
1912 void NetworkProcess::resumeDownload(PAL::SessionID sessionID, DownloadID downloadID, const IPC::DataReference& resumeData, const String& path, WebKit::SandboxExtension::Handle&& sandboxExtensionHandle)
1914 downloadManager().resumeDownload(sessionID, downloadID, resumeData, path, WTFMove(sandboxExtensionHandle));
1917 void NetworkProcess::cancelDownload(DownloadID downloadID)
1919 downloadManager().cancelDownload(downloadID);
1923 void NetworkProcess::publishDownloadProgress(DownloadID downloadID, const URL& url, SandboxExtension::Handle&& sandboxExtensionHandle)
1925 downloadManager().publishDownloadProgress(downloadID, url, WTFMove(sandboxExtensionHandle));
1929 void NetworkProcess::continueWillSendRequest(DownloadID downloadID, WebCore::ResourceRequest&& request)
1931 downloadManager().continueWillSendRequest(downloadID, WTFMove(request));
1934 void NetworkProcess::pendingDownloadCanceled(DownloadID downloadID)
1936 downloadProxyConnection()->send(Messages::DownloadProxy::DidCancel({ }), downloadID.downloadID());
1939 void NetworkProcess::findPendingDownloadLocation(NetworkDataTask& networkDataTask, ResponseCompletionHandler&& completionHandler, const ResourceResponse& response)
1941 uint64_t destinationID = networkDataTask.pendingDownloadID().downloadID();
1942 downloadProxyConnection()->send(Messages::DownloadProxy::DidReceiveResponse(response), destinationID);
1944 downloadManager().willDecidePendingDownloadDestination(networkDataTask, WTFMove(completionHandler));
1946 // As per https://html.spec.whatwg.org/#as-a-download (step 2), the filename from the Content-Disposition header
1947 // should override the suggested filename from the download attribute.
1948 String suggestedFilename = response.isAttachmentWithFilename() ? response.suggestedFilename() : networkDataTask.suggestedFilename();
1949 suggestedFilename = MIMETypeRegistry::appendFileExtensionIfNecessary(suggestedFilename, response.mimeType());
1951 downloadProxyConnection()->send(Messages::DownloadProxy::DecideDestinationWithSuggestedFilenameAsync(networkDataTask.pendingDownloadID(), suggestedFilename), destinationID);
1954 void NetworkProcess::continueDecidePendingDownloadDestination(DownloadID downloadID, String destination, SandboxExtension::Handle&& sandboxExtensionHandle, bool allowOverwrite)
1956 if (destination.isEmpty())
1957 downloadManager().cancelDownload(downloadID);
1959 downloadManager().continueDecidePendingDownloadDestination(downloadID, destination, WTFMove(sandboxExtensionHandle), allowOverwrite);
1962 void NetworkProcess::setCacheModel(CacheModel cacheModel)
1964 if (m_hasSetCacheModel && (cacheModel == m_cacheModel))
1967 m_hasSetCacheModel = true;
1968 m_cacheModel = cacheModel;
1970 unsigned urlCacheMemoryCapacity = 0;
1971 uint64_t urlCacheDiskCapacity = 0;
1972 uint64_t diskFreeSize = 0;
1973 if (FileSystem::getVolumeFreeSpace(m_diskCacheDirectory, diskFreeSize)) {
1974 // As a fudge factor, use 1000 instead of 1024, in case the reported byte
1975 // count doesn't align exactly to a megabyte boundary.
1976 diskFreeSize /= KB * 1000;
1977 calculateURLCacheSizes(cacheModel, diskFreeSize, urlCacheMemoryCapacity, urlCacheDiskCapacity);
1981 m_cache->setCapacity(urlCacheDiskCapacity);
1984 void NetworkProcess::setCanHandleHTTPSServerTrustEvaluation(bool value)
1986 m_canHandleHTTPSServerTrustEvaluation = value;
1989 void NetworkProcess::getNetworkProcessStatistics(uint64_t callbackID)
1991 StatisticsData data;
1993 data.statisticsNumbers.set("DownloadsActiveCount", downloadManager().activeDownloadCount());
1994 data.statisticsNumbers.set("OutstandingAuthenticationChallengesCount", authenticationManager().outstandingAuthenticationChallengeCount());
1996 parentProcessConnection()->send(Messages::WebProcessPool::DidGetStatistics(data, callbackID), 0);
1999 void NetworkProcess::setAllowsAnySSLCertificateForWebSocket(bool allows, CompletionHandler<void()>&& completionHandler)
2001 DeprecatedGlobalSettings::setAllowsAnySSLCertificate(allows);
2002 completionHandler();
2005 void NetworkProcess::logDiagnosticMessage(PageIdentifier webPageID, const String& message, const String& description, ShouldSample shouldSample)
2007 if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
2010 parentProcessConnection()->send(Messages::NetworkProcessProxy::LogDiagnosticMessage(webPageID, message, description, ShouldSample::No), 0);
2013 void NetworkProcess::logDiagnosticMessageWithResult(PageIdentifier webPageID, const String& message, const String& description, DiagnosticLoggingResultType result, ShouldSample shouldSample)
2015 if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
2018 parentProcessConnection()->send(Messages::NetworkProcessProxy::LogDiagnosticMessageWithResult(webPageID, message, description, result, ShouldSample::No), 0);
2021 void NetworkProcess::logDiagnosticMessageWithValue(PageIdentifier webPageID, const String& message, const String& description, double value, unsigned significantFigures, ShouldSample shouldSample)
2023 if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
2026 parentProcessConnection()->send(Messages::NetworkProcessProxy::LogDiagnosticMessageWithValue(webPageID, message, description, value, significantFigures, ShouldSample::No), 0);
2029 void NetworkProcess::terminate()
2031 platformTerminate();
2032 AuxiliaryProcess::terminate();
2035 void NetworkProcess::processDidTransitionToForeground()
2037 platformProcessDidTransitionToForeground();
2040 void NetworkProcess::processDidTransitionToBackground()
2042 platformProcessDidTransitionToBackground();
2045 void NetworkProcess::actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend shouldAcknowledgeWhenReadyToSuspend)
2047 #if PLATFORM(IOS_FAMILY)
2048 m_webSQLiteDatabaseTracker.setIsSuspended(true);
2051 lowMemoryHandler(Critical::Yes);
2053 RefPtr<CallbackAggregator> callbackAggregator;
2054 if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) {
2055 callbackAggregator = CallbackAggregator::create([this] {
2056 RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::notifyProcessReadyToSuspend() Sending ProcessReadyToSuspend IPC message", this);
2057 if (parentProcessConnection())
2058 parentProcessConnection()->send(Messages::NetworkProcessProxy::ProcessReadyToSuspend(), 0);
2062 platformPrepareToSuspend([callbackAggregator] { });
2063 platformSyncAllCookies([callbackAggregator] { });
2065 for (auto& connection : m_webProcessConnections)
2066 connection->cleanupForSuspension([callbackAggregator] { });
2068 #if ENABLE(SERVICE_WORKER)
2069 for (auto& server : m_swServers.values()) {
2070 ASSERT(m_swServers.get(server->sessionID()) == server.get());
2071 server->startSuspension([callbackAggregator] { });
2075 for (auto& session : m_networkSessions)
2076 session.value->storageManager().suspend([callbackAggregator] { });
2079 void NetworkProcess::processWillSuspendImminently()
2081 RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::processWillSuspendImminently() BEGIN", this);
2082 #if PLATFORM(IOS_FAMILY) && ENABLE(INDEXED_DATABASE)
2083 for (auto& server : m_idbServers.values())
2084 server->tryStop(IDBServer::ShouldForceStop::Yes);
2086 actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::No);
2087 RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::processWillSuspendImminently() END", this);
2090 void NetworkProcess::prepareToSuspend()
2092 RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::prepareToSuspend()", this);
2094 #if PLATFORM(IOS_FAMILY) && ENABLE(INDEXED_DATABASE)
2095 for (auto& server : m_idbServers.values())
2096 server->tryStop(IDBServer::ShouldForceStop::No);
2098 actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::Yes);
2101 void NetworkProcess::cancelPrepareToSuspend()
2103 // Although it is tempting to send a NetworkProcessProxy::DidCancelProcessSuspension message from here
2104 // we do not because prepareToSuspend() already replied with a NetworkProcessProxy::ProcessReadyToSuspend
2105 // message. And NetworkProcessProxy expects to receive either a NetworkProcessProxy::ProcessReadyToSuspend-
2106 // or NetworkProcessProxy::DidCancelProcessSuspension- message, but not both.
2107 RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::cancelPrepareToSuspend()", this);
2111 void NetworkProcess::applicationDidEnterBackground()
2113 m_downloadManager.applicationDidEnterBackground();
2116 void NetworkProcess::applicationWillEnterForeground()
2118 m_downloadManager.applicationWillEnterForeground();
2121 void NetworkProcess::processDidResume()
2123 RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::processDidResume()", this);
2127 void NetworkProcess::resume()
2129 #if PLATFORM(IOS_FAMILY)
2130 m_webSQLiteDatabaseTracker.setIsSuspended(false);
2133 platformProcessDidResume();
2134 for (auto& connection : m_webProcessConnections)
2135 connection->endSuspension();
2137 #if ENABLE(SERVICE_WORKER)
2138 for (auto& server : m_swServers.values())
2139 server->endSuspension();
2141 #if PLATFORM(IOS_FAMILY) && ENABLE(INDEXED_DATABASE)
2142 for (auto& server : m_idbServers.values())
2146 for (auto& session : m_networkSessions)
2147 session.value->storageManager().resume();
2150 void NetworkProcess::prefetchDNS(const String& hostname)
2152 WebCore::prefetchDNS(hostname);
2155 void NetworkProcess::cacheStorageRootPath(PAL::SessionID sessionID, CacheStorageRootPathCallback&& callback)
2157 m_cacheStorageParametersCallbacks.ensure(sessionID, [&] {
2158 parentProcessConnection()->send(Messages::NetworkProcessProxy::RetrieveCacheStorageParameters { sessionID }, 0);
2159 return Vector<CacheStorageRootPathCallback> { };
2160 }).iterator->value.append(WTFMove(callback));
2163 void NetworkProcess::setCacheStorageParameters(PAL::SessionID sessionID, String&& cacheStorageDirectory, SandboxExtension::Handle&& handle)
2165 auto iterator = m_cacheStorageParametersCallbacks.find(sessionID);
2166 if (iterator == m_cacheStorageParametersCallbacks.end())
2169 SandboxExtension::consumePermanently(handle);
2170 auto callbacks = WTFMove(iterator->value);
2171 m_cacheStorageParametersCallbacks.remove(iterator);
2172 for (auto& callback : callbacks)
2173 callback(String { cacheStorageDirectory });
2176 void NetworkProcess::preconnectTo(const URL& url, WebCore::StoredCredentialsPolicy storedCredentialsPolicy)
2178 #if ENABLE(SERVER_PRECONNECT)
2179 NetworkLoadParameters parameters;
2180 parameters.request = ResourceRequest { url };
2181 parameters.sessionID = PAL::SessionID::defaultSessionID();
2182 parameters.storedCredentialsPolicy = storedCredentialsPolicy;
2183 parameters.shouldPreconnectOnly = PreconnectOnly::Yes;
2185 new PreconnectTask(*this, WTFMove(parameters));
2188 UNUSED_PARAM(storedCredentialsPolicy);
2192 void NetworkProcess::registerURLSchemeAsSecure(const String& scheme) const
2194 SchemeRegistry::registerURLSchemeAsSecure(scheme);
2197 void NetworkProcess::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme) const
2199 SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
2202 void NetworkProcess::registerURLSchemeAsLocal(const String& scheme) const
2204 SchemeRegistry::registerURLSchemeAsLocal(scheme);
2207 void NetworkProcess::registerURLSchemeAsNoAccess(const String& scheme) const
2209 SchemeRegistry::registerURLSchemeAsNoAccess(scheme);
2212 void NetworkProcess::registerURLSchemeAsDisplayIsolated(const String& scheme) const
2214 SchemeRegistry::registerURLSchemeAsDisplayIsolated(scheme);
2217 void NetworkProcess::registerURLSchemeAsCORSEnabled(const String& scheme) const
2219 SchemeRegistry::registerURLSchemeAsCORSEnabled(scheme);
2222 void NetworkProcess::registerURLSchemeAsCanDisplayOnlyIfCanRequest(const String& scheme) const
2224 SchemeRegistry::registerAsCanDisplayOnlyIfCanRequest(scheme);
2227 void NetworkProcess::didSyncAllCookies()
2229 parentProcessConnection()->send(Messages::NetworkProcessProxy::DidSyncAllCookies(), 0);
2232 #if ENABLE(INDEXED_DATABASE)
2233 Ref<IDBServer::IDBServer> NetworkProcess::createIDBServer(PAL::SessionID sessionID)
2236 if (!sessionID.isEphemeral()) {
2237 ASSERT(m_idbDatabasePaths.contains(sessionID));
2238 path = m_idbDatabasePaths.get(sessionID);
2241 auto server = IDBServer::IDBServer::create(sessionID, path, *this, [this, weakThis = makeWeakPtr(this)](PAL::SessionID sessionID, const auto& origin) -> StorageQuotaManager* {
2244 return &this->storageQuotaManager(sessionID, origin);
2246 server->setPerOriginQuota(m_idbPerOriginQuota);
2250 IDBServer::IDBServer& NetworkProcess::idbServer(PAL::SessionID sessionID)
2252 return *m_idbServers.ensure(sessionID, [this, sessionID] {
2253 return this->createIDBServer(sessionID);
2257 void NetworkProcess::ensurePathExists(const String& path)
2259 ASSERT(!RunLoop::isMain());
2261 if (!FileSystem::makeAllDirectories(path))
2262 LOG_ERROR("Failed to make all directories for path '%s'", path.utf8().data());
2265 void NetworkProcess::postStorageTask(CrossThreadTask&& task)
2267 ASSERT(RunLoop::isMain());
2269 LockHolder locker(m_storageTaskMutex);
2271 m_storageTasks.append(WTFMove(task));
2273 m_storageTaskQueue->dispatch([this] {
2274 performNextStorageTask();
2278 void NetworkProcess::performNextStorageTask()
2280 ASSERT(!RunLoop::isMain());
2282 CrossThreadTask task;
2284 LockHolder locker(m_storageTaskMutex);
2285 ASSERT(!m_storageTasks.isEmpty());
2286 task = m_storageTasks.takeFirst();
2292 void NetworkProcess::accessToTemporaryFileComplete(const String& path)
2294 // We've either hard linked the temporary blob file to the database directory, copied it there,
2295 // or the transaction is being aborted.
2296 // In any of those cases, we can delete the temporary blob file now.
2297 FileSystem::deleteFile(path);
2300 void NetworkProcess::collectIndexedDatabaseOriginsForVersion(const String& path, HashSet<WebCore::SecurityOriginData>& securityOrigins)
2305 for (auto& topOriginPath : FileSystem::listDirectory(path, "*")) {
2306 auto databaseIdentifier = FileSystem::pathGetFileName(topOriginPath);
2307 if (auto securityOrigin = SecurityOriginData::fromDatabaseIdentifier(databaseIdentifier)) {
2308 securityOrigins.add(WTFMove(*securityOrigin));
2310 for (auto& originPath : FileSystem::listDirectory(topOriginPath, "*")) {
2311 databaseIdentifier = FileSystem::pathGetFileName(originPath);
2312 if (auto securityOrigin = SecurityOriginData::fromDatabaseIdentifier(databaseIdentifier))
2313 securityOrigins.add(WTFMove(*securityOrigin));
2319 HashSet<WebCore::SecurityOriginData> NetworkProcess::indexedDatabaseOrigins(const String& path)
2324 HashSet<WebCore::SecurityOriginData> securityOrigins;
2325 collectIndexedDatabaseOriginsForVersion(FileSystem::pathByAppendingComponent(path, "v0"), securityOrigins);
2326 collectIndexedDatabaseOriginsForVersion(FileSystem::pathByAppendingComponent(path, "v1"), securityOrigins);
2328 return securityOrigins;
2331 void NetworkProcess::addIndexedDatabaseSession(PAL::SessionID sessionID, String& indexedDatabaseDirectory, SandboxExtension::Handle& handle)
2334 // IMPORTANT: Do not change the directory structure for indexed databases on disk without first consulting a reviewer from Apple (<rdar://problem/17454712>)
2336 auto addResult = m_idbDatabasePaths.add(sessionID, indexedDatabaseDirectory);
2337 if (addResult.isNewEntry) {
2338 SandboxExtension::consumePermanently(handle);
2339 if (!indexedDatabaseDirectory.isEmpty())
2340 postStorageTask(createCrossThreadTask(*this, &NetworkProcess::ensurePathExists, indexedDatabaseDirectory));
2344 void NetworkProcess::setIDBPerOriginQuota(uint64_t quota)
2346 m_idbPerOriginQuota = quota;
2348 for (auto& server : m_idbServers.values())
2349 server->setPerOriginQuota(quota);
2351 #endif // ENABLE(INDEXED_DATABASE)
2353 void NetworkProcess::updateQuotaBasedOnSpaceUsageForTesting(PAL::SessionID sessionID, const ClientOrigin& origin)
2355 auto& manager = storageQuotaManager(sessionID, origin);
2356 manager.resetQuota(m_storageQuotaManagers.find(sessionID)->value.defaultQuota(origin));
2357 manager.updateQuotaBasedOnSpaceUsage();
2360 #if ENABLE(SANDBOX_EXTENSIONS)
2361 void NetworkProcess::getSandboxExtensionsForBlobFiles(const Vector<String>& filenames, CompletionHandler<void(SandboxExtension::HandleArray&&)>&& completionHandler)
2363 parentProcessConnection()->sendWithAsyncReply(Messages::NetworkProcessProxy::GetSandboxExtensionsForBlobFiles(filenames), WTFMove(completionHandler));
2365 #endif // ENABLE(SANDBOX_EXTENSIONS)
2367 #if ENABLE(SERVICE_WORKER)
2368 WebSWServerToContextConnection* NetworkProcess::connectionToContextProcessFromIPCConnection(IPC::Connection& connection)
2370 for (auto& serverToContextConnection : m_serverToContextConnections.values()) {
2371 if (serverToContextConnection->ipcConnection() == &connection)
2372 return serverToContextConnection.get();
2377 void NetworkProcess::connectionToContextProcessWasClosed(Ref<WebSWServerToContextConnection>&& serverToContextConnection)
2379 auto& registrableDomain = serverToContextConnection->registrableDomain();
2381 serverToContextConnection->connectionClosed();
2382 m_serverToContextConnections.remove(registrableDomain);
2384 for (auto& swServer : m_swServers.values())
2385 swServer->markAllWorkersForRegistrableDomainAsTerminated(registrableDomain);
2387 if (needsServerToContextConnectionForRegistrableDomain(registrableDomain)) {
2388 RELEASE_LOG(ServiceWorker, "Connection to service worker process was closed but is still needed, relaunching it");
2389 createServerToContextConnection(registrableDomain, WTF::nullopt);
2393 bool NetworkProcess::needsServerToContextConnectionForRegistrableDomain(const RegistrableDomain& registrableDomain) const
2395 return WTF::anyOf(m_swServers.values(), [&](auto& swServer) {
2396 return swServer->needsServerToContextConnectionForRegistrableDomain(registrableDomain);
2400 SWServer& NetworkProcess::swServerForSession(PAL::SessionID sessionID)
2402 ASSERT(sessionID.isValid());
2404 auto result = m_swServers.ensure(sessionID, [&] {
2405 auto path = m_swDatabasePaths.get(sessionID);
2406 // There should already be a registered path for this PAL::SessionID.
2407 // If there's not, then where did this PAL::SessionID come from?
2408 ASSERT(sessionID.isEphemeral() || !path.isEmpty());
2410 auto value = std::make_unique<SWServer>(makeUniqueRef<WebSWOriginStore>(), WTFMove(path), sessionID);
2411 if (m_shouldDisableServiceWorkerProcessTerminationDelay)
2412 value->disableServiceWorkerProcessTerminationDelay();
2416 return *result.iterator->value;
2419 WebSWOriginStore* NetworkProcess::existingSWOriginStoreForSession(PAL::SessionID sessionID) const
2421 ASSERT(sessionID.isValid());
2422 if (!sessionID.isValid())
2425 auto* swServer = m_swServers.get(sessionID);
2428 return &static_cast<WebSWOriginStore&>(swServer->originStore());
2431 WebSWServerToContextConnection* NetworkProcess::serverToContextConnectionForRegistrableDomain(const RegistrableDomain& registrableDomain)
2433 return m_serverToContextConnections.get(registrableDomain);
2436 void NetworkProcess::createServerToContextConnection(const RegistrableDomain& registrableDomain, Optional<PAL::SessionID> sessionID)
2438 if (m_waitingForServerToContextProcessConnection)
2441 m_waitingForServerToContextProcessConnection = true;
2443 parentProcessConnection()->send(Messages::NetworkProcessProxy::EstablishWorkerContextConnectionToNetworkProcessForExplicitSession(registrableDomain, *sessionID), 0);
2445 parentProcessConnection()->send(Messages::NetworkProcessProxy::EstablishWorkerContextConnectionToNetworkProcess(registrableDomain), 0);
2448 void NetworkProcess::postMessageToServiceWorkerClient(const ServiceWorkerClientIdentifier& destinationIdentifier, MessageWithMessagePorts&& message, ServiceWorkerIdentifier sourceIdentifier, const String& sourceOrigin)
2450 if (auto* connection = m_swServerConnections.get(destinationIdentifier.serverConnectionIdentifier))
2451 connection->postMessageToServiceWorkerClient(destinationIdentifier.contextIdentifier, WTFMove(message), sourceIdentifier, sourceOrigin);
2454 void NetworkProcess::postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destination, WebCore::MessageWithMessagePorts&& message, const WebCore::ServiceWorkerOrClientIdentifier& source, SWServerConnectionIdentifier connectionIdentifier)
2456 if (auto* connection = m_swServerConnections.get(connectionIdentifier))
2457 connection->postMessageToServiceWorker(destination, WTFMove(message), source);
2460 void NetworkProcess::registerSWServerConnection(WebSWServerConnection& connection)
2462 ASSERT(parentProcessHasServiceWorkerEntitlement());
2463 ASSERT(!m_swServerConnections.contains(connection.identifier()));
2464 m_swServerConnections.add(connection.identifier(), &connection);
2465 auto* store = existingSWOriginStoreForSession(connection.sessionID());
2468 store->registerSWServerConnection(connection);
2471 void NetworkProcess::unregisterSWServerConnection(WebSWServerConnection& connection)
2473 ASSERT(m_swServerConnections.get(connection.identifier()) == &connection);
2474 m_swServerConnections.remove(connection.identifier());
2475 if (auto* store = existingSWOriginStoreForSession(connection.sessionID()))
2476 store->unregisterSWServerConnection(connection);
2479 void NetworkProcess::swContextConnectionMayNoLongerBeNeeded(WebSWServerToContextConnection& serverToContextConnection)
2481 auto& registrableDomain = serverToContextConnection.registrableDomain();
2482 if (needsServerToContextConnectionForRegistrableDomain(registrableDomain))
2485 RELEASE_LOG(ServiceWorker, "Service worker process is no longer needed, terminating it");
2486 serverToContextConnection.terminate();
2488 for (auto& swServer : m_swServers.values())
2489 swServer->markAllWorkersForRegistrableDomainAsTerminated(registrableDomain);
2491 serverToContextConnection.connectionClosed();
2492 m_serverToContextConnections.remove(registrableDomain);
2495 void NetworkProcess::disableServiceWorkerProcessTerminationDelay()
2497 if (m_shouldDisableServiceWorkerProcessTerminationDelay)
2500 m_shouldDisableServiceWorkerProcessTerminationDelay = true;
2501 for (auto& swServer : m_swServers.values())
2502 swServer->disableServiceWorkerProcessTerminationDelay();
2505 void NetworkProcess::addServiceWorkerSession(PAL::SessionID sessionID, String& serviceWorkerRegistrationDirectory, const SandboxExtension::Handle& handle)
2507 auto addResult = m_swDatabasePaths.add(sessionID, serviceWorkerRegistrationDirectory);
2508 if (addResult.isNewEntry) {
2509 SandboxExtension::consumePermanently(handle);
2510 if (!serviceWorkerRegistrationDirectory.isEmpty())
2511 postStorageTask(createCrossThreadTask(*this, &NetworkProcess::ensurePathExists, serviceWorkerRegistrationDirectory));
2514 #endif // ENABLE(SERVICE_WORKER)
2516 void NetworkProcess::requestStorageSpace(PAL::SessionID sessionID, const ClientOrigin& origin, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t>)>&& callback)
2518 parentProcessConnection()->sendWithAsyncReply(Messages::NetworkProcessProxy::RequestStorageSpace { sessionID, origin, quota, currentSize, spaceRequired }, WTFMove(callback), 0);
2521 class QuotaUserInitializer final : public WebCore::StorageQuotaUser {
2523 explicit QuotaUserInitializer(StorageQuotaManager& manager)
2524 : m_manager(makeWeakPtr(manager))
2526 manager.addUser(*this);
2529 ~QuotaUserInitializer()
2532 m_manager->removeUser(*this);
2538 // StorageQuotaUser API.
2539 uint64_t spaceUsed() const final
2541 ASSERT_NOT_REACHED();
2545 void whenInitialized(CompletionHandler<void()>&& callback) final
2547 m_callback = WTFMove(callback);
2550 WeakPtr<StorageQuotaManager> m_manager;
2551 CompletionHandler<void()> m_callback;
2554 void NetworkProcess::initializeQuotaUsers(StorageQuotaManager& manager, PAL::SessionID sessionID, const ClientOrigin& origin)
2556 RunLoop::main().dispatch([this, weakThis = makeWeakPtr(this), sessionID, origin, user = std::make_unique<QuotaUserInitializer>(manager)]() mutable {
2559 this->idbServer(sessionID).initializeQuotaUser(origin);
2560 CacheStorage::Engine::initializeQuotaUser(*this, sessionID, origin, [user = WTFMove(user)] { });
2564 StorageQuotaManager& NetworkProcess::storageQuotaManager(PAL::SessionID sessionID, const ClientOrigin& origin)
2566 auto& storageQuotaManagers = m_storageQuotaManagers.ensure(sessionID, [] {
2567 return StorageQuotaManagers { };
2569 return *storageQuotaManagers.managersPerOrigin().ensure(origin, [this, &storageQuotaManagers, sessionID, &origin] {
2570 auto manager = std::make_unique<StorageQuotaManager>(storageQuotaManagers.defaultQuota(origin), [this, sessionID, origin](uint64_t quota, uint64_t currentSpace, uint64_t spaceIncrease, auto callback) {
2571 this->requestStorageSpace(sessionID, origin, quota, currentSpace, spaceIncrease, WTFMove(callback));
2573 initializeQuotaUsers(*manager, sessionID, origin);
2578 #if !PLATFORM(COCOA)
2579 void NetworkProcess::initializeProcess(const AuxiliaryProcessInitializationParameters&)
2583 void NetworkProcess::initializeProcessName(const AuxiliaryProcessInitializationParameters&)
2587 void NetworkProcess::initializeSandbox(const AuxiliaryProcessInitializationParameters&, SandboxInitializationParameters&)
2591 void NetworkProcess::syncAllCookies()
2595 void NetworkProcess::platformSyncAllCookies(CompletionHandler<void()>&& completionHandler)
2597 completionHandler();
2602 void NetworkProcess::storeAdClickAttribution(PAL::SessionID sessionID, WebCore::AdClickAttribution&& adClickAttribution)
2604 if (auto* session = networkSession(sessionID))
2605 session->storeAdClickAttribution(WTFMove(adClickAttribution));
2608 void NetworkProcess::dumpAdClickAttribution(PAL::SessionID sessionID, CompletionHandler<void(String)>&& completionHandler)
2610 if (auto* session = networkSession(sessionID))
2611 return session->dumpAdClickAttribution(WTFMove(completionHandler));
2613 completionHandler({ });
2616 void NetworkProcess::clearAdClickAttribution(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
2618 if (auto* session = networkSession(sessionID))
2619 session->clearAdClickAttribution();
2621 completionHandler();
2624 void NetworkProcess::setAdClickAttributionOverrideTimerForTesting(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
2626 if (auto* session = networkSession(sessionID))
2627 session->setAdClickAttributionOverrideTimerForTesting(value);
2629 completionHandler();
2632 void NetworkProcess::setAdClickAttributionConversionURLForTesting(PAL::SessionID sessionID, URL&& url, CompletionHandler<void()>&& completionHandler)
2634 if (auto* session = networkSession(sessionID))
2635 session->setAdClickAttributionConversionURLForTesting(WTFMove(url));
2637 completionHandler();
2640 void NetworkProcess::markAdClickAttributionsAsExpiredForTesting(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
2642 if (auto* session = networkSession(sessionID))
2643 session->markAdClickAttributionsAsExpiredForTesting();
2645 completionHandler();
2648 void NetworkProcess::addKeptAliveLoad(Ref<NetworkResourceLoader>&& loader)
2650 if (auto* session = networkSession(loader->sessionID()))
2651 session->addKeptAliveLoad(WTFMove(loader));
2654 void NetworkProcess::removeKeptAliveLoad(NetworkResourceLoader& loader)
2656 if (auto* session = networkSession(loader.sessionID()))
2657 session->removeKeptAliveLoad(loader);
2660 void NetworkProcess::webPageWasAdded(IPC::Connection& connection, PAL::SessionID sessionID, PageIdentifier pageID, PageIdentifier oldPageID)
2662 if (!pageID || !oldPageID) {
2663 LOG_ERROR("Cannot add page with invalid id");
2667 auto* session = networkSession(sessionID);
2669 LOG_ERROR("Cannot add page to an unknown session");
2672 auto& storageManager = session->storageManager();
2674 auto addResult = m_sessionByConnection.add(connection.uniqueID(), sessionID);
2675 ASSERT_UNUSED(addResult, addResult.iterator->value == sessionID);
2677 storageManager.createSessionStorageNamespace(pageID.toUInt64(), std::numeric_limits<unsigned>::max());
2678 storageManager.addAllowedSessionStorageNamespaceConnection(pageID.toUInt64(), connection);
2679 if (pageID != oldPageID)
2680 storageManager.cloneSessionStorageNamespace(oldPageID.toUInt64(), pageID.toUInt64());
2683 void NetworkProcess::webPageWasRemoved(IPC::Connection& connection, PAL::SessionID sessionID, PageIdentifier pageID)
2686 LOG_ERROR("Cannot remove page with invalid id");
2690 auto* session = networkSession(sessionID);
2691 // Session can be destroyed before page gets removed.
2695 auto& storageManager = session->storageManager();
2696 storageManager.removeAllowedSessionStorageNamespaceConnection(pageID.toUInt64(), connection);
2697 storageManager.destroySessionStorageNamespace(pageID.toUInt64());
2700 void NetworkProcess::webProcessWasDisconnected(IPC::Connection& connection)
2702 auto sessionID = m_sessionByConnection.take(connection.uniqueID());
2703 if (!sessionID.isValid())
2706 if (auto* session = networkSession(sessionID))
2707 session->storageManager().processDidCloseConnection(connection);
2710 void NetworkProcess::webProcessSessionChanged(IPC::Connection& connection, PAL::SessionID newSessionID, const Vector<PageIdentifier>& pageIDs)
2712 auto connectionID = connection.uniqueID();
2713 ASSERT(m_sessionByConnection.contains(connectionID));
2714 if (m_sessionByConnection.get(connectionID) == newSessionID)
2717 webProcessWasDisconnected(connection);
2718 for (auto& pageID : pageIDs)
2719 webPageWasAdded(connection, newSessionID, pageID, pageID);
2722 void NetworkProcess::getLocalStorageOriginDetails(PAL::SessionID sessionID, CompletionHandler<void(Vector<LocalStorageDatabaseTracker::OriginDetails>&&)>&& completionHandler)
2724 auto* session = networkSession(sessionID);
2726 LOG_ERROR("Cannot get local storage information for an unknown session");
2730 auto& storageManager = session->storageManager();
2731 storageManager.getLocalStorageOriginDetails([completionHandler = WTFMove(completionHandler)](auto&& details) mutable {
2732 completionHandler(WTFMove(details));
2736 } // namespace WebKit