5537a94257b44571d05258cb00243f2271799ead
[WebKit-https.git] / Source / WebKit / NetworkProcess / NetworkProcess.cpp
1 /*
2  * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "NetworkProcess.h"
28
29 #include "ArgumentCoders.h"
30 #include "Attachment.h"
31 #include "AuthenticationManager.h"
32 #include "ChildProcessMessages.h"
33 #include "DataReference.h"
34 #include "DownloadProxyMessages.h"
35 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
36 #include "LegacyCustomProtocolManager.h"
37 #endif
38 #include "Logging.h"
39 #include "NetworkConnectionToWebProcess.h"
40 #include "NetworkProcessCreationParameters.h"
41 #include "NetworkProcessPlatformStrategies.h"
42 #include "NetworkProcessProxyMessages.h"
43 #include "NetworkResourceLoader.h"
44 #include "NetworkSession.h"
45 #include "PreconnectTask.h"
46 #include "RemoteNetworkingContext.h"
47 #include "SessionTracker.h"
48 #include "StatisticsData.h"
49 #include "WebCookieManager.h"
50 #include "WebCoreArgumentCoders.h"
51 #include "WebPageProxyMessages.h"
52 #include "WebProcessPoolMessages.h"
53 #include "WebsiteData.h"
54 #include "WebsiteDataFetchOption.h"
55 #include "WebsiteDataStore.h"
56 #include "WebsiteDataStoreParameters.h"
57 #include "WebsiteDataType.h"
58 #include <WebCore/DNS.h>
59 #include <WebCore/DeprecatedGlobalSettings.h>
60 #include <WebCore/DiagnosticLoggingClient.h>
61 #include <WebCore/LogInitialization.h>
62 #include <WebCore/MIMETypeRegistry.h>
63 #include <WebCore/NetworkStorageSession.h>
64 #include <WebCore/PlatformCookieJar.h>
65 #include <WebCore/ResourceRequest.h>
66 #include <WebCore/RuntimeApplicationChecks.h>
67 #include <WebCore/SecurityOriginData.h>
68 #include <WebCore/SecurityOriginHash.h>
69 #include <WebCore/Settings.h>
70 #include <WebCore/URLParser.h>
71 #include <pal/SessionID.h>
72 #include <wtf/CallbackAggregator.h>
73 #include <wtf/OptionSet.h>
74 #include <wtf/RunLoop.h>
75 #include <wtf/text/AtomicString.h>
76 #include <wtf/text/CString.h>
77
78 #if ENABLE(SEC_ITEM_SHIM)
79 #include "SecItemShim.h"
80 #endif
81
82 #include "NetworkCache.h"
83 #include "NetworkCacheCoders.h"
84
85 #if ENABLE(NETWORK_CAPTURE)
86 #include "NetworkCaptureManager.h"
87 #endif
88
89 #if PLATFORM(COCOA)
90 #include "NetworkSessionCocoa.h"
91 #endif
92
93 using namespace WebCore;
94
95 namespace WebKit {
96
97 NetworkProcess& NetworkProcess::singleton()
98 {
99     static NeverDestroyed<NetworkProcess> networkProcess;
100     return networkProcess;
101 }
102
103 NetworkProcess::NetworkProcess()
104     : m_hasSetCacheModel(false)
105     , m_cacheModel(CacheModelDocumentViewer)
106     , m_diskCacheIsDisabledForTesting(false)
107     , m_canHandleHTTPSServerTrustEvaluation(true)
108 #if PLATFORM(COCOA)
109     , m_clearCacheDispatchGroup(0)
110 #endif
111 #if PLATFORM(IOS)
112     , m_webSQLiteDatabaseTracker(*this)
113 #endif
114 {
115     NetworkProcessPlatformStrategies::initialize();
116
117     addSupplement<AuthenticationManager>();
118     addSupplement<WebCookieManager>();
119 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
120     addSupplement<LegacyCustomProtocolManager>();
121 #endif
122 }
123
124 NetworkProcess::~NetworkProcess()
125 {
126 }
127
128 AuthenticationManager& NetworkProcess::authenticationManager()
129 {
130     return *supplement<AuthenticationManager>();
131 }
132
133 DownloadManager& NetworkProcess::downloadManager()
134 {
135     static NeverDestroyed<DownloadManager> downloadManager(*this);
136     return downloadManager;
137 }
138
139 void NetworkProcess::removeNetworkConnectionToWebProcess(NetworkConnectionToWebProcess* connection)
140 {
141     size_t vectorIndex = m_webProcessConnections.find(connection);
142     ASSERT(vectorIndex != notFound);
143
144     m_webProcessConnections.remove(vectorIndex);
145 }
146
147 bool NetworkProcess::shouldTerminate()
148 {
149     // Network process keeps session cookies and credentials, so it should never terminate (as long as UI process connection is alive).
150     return false;
151 }
152
153 void NetworkProcess::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
154 {
155     if (messageReceiverMap().dispatchMessage(connection, decoder))
156         return;
157
158     if (decoder.messageReceiverName() == Messages::ChildProcess::messageReceiverName()) {
159         ChildProcess::didReceiveMessage(connection, decoder);
160         return;
161     }
162
163     didReceiveNetworkProcessMessage(connection, decoder);
164 }
165
166 void NetworkProcess::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder)
167 {
168     if (messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder))
169         return;
170
171     didReceiveSyncNetworkProcessMessage(connection, decoder, replyEncoder);
172 }
173
174 void NetworkProcess::didClose(IPC::Connection&)
175 {
176     // The UIProcess just exited.
177     stopRunLoop();
178 }
179
180 void NetworkProcess::didCreateDownload()
181 {
182     disableTermination();
183 }
184
185 void NetworkProcess::didDestroyDownload()
186 {
187     enableTermination();
188 }
189
190 IPC::Connection* NetworkProcess::downloadProxyConnection()
191 {
192     return parentProcessConnection();
193 }
194
195 AuthenticationManager& NetworkProcess::downloadsAuthenticationManager()
196 {
197     return authenticationManager();
198 }
199
200 void NetworkProcess::lowMemoryHandler(Critical critical)
201 {
202     if (m_suppressMemoryPressureHandler)
203         return;
204
205     WTF::releaseFastMallocFreeMemory();
206 }
207
208 void NetworkProcess::initializeNetworkProcess(NetworkProcessCreationParameters&& parameters)
209 {
210     WebCore::setPresentingApplicationPID(parameters.presentingApplicationPID);
211     platformInitializeNetworkProcess(parameters);
212
213     WTF::Thread::setCurrentThreadIsUserInitiated();
214     AtomicString::init();
215
216     m_suppressMemoryPressureHandler = parameters.shouldSuppressMemoryPressureHandler;
217     m_loadThrottleLatency = parameters.loadThrottleLatency;
218     if (!m_suppressMemoryPressureHandler) {
219         auto& memoryPressureHandler = MemoryPressureHandler::singleton();
220 #if OS(LINUX)
221         if (parameters.memoryPressureMonitorHandle.fileDescriptor() != -1)
222             memoryPressureHandler.setMemoryPressureMonitorHandle(parameters.memoryPressureMonitorHandle.releaseFileDescriptor());
223 #endif
224         memoryPressureHandler.setLowMemoryHandler([this] (Critical critical, Synchronous) {
225             lowMemoryHandler(critical);
226         });
227         memoryPressureHandler.install();
228     }
229
230 #if ENABLE(NETWORK_CAPTURE)
231     NetworkCapture::Manager::singleton().initialize(
232         parameters.recordReplayMode,
233         parameters.recordReplayCacheLocation);
234 #endif
235
236     m_diskCacheIsDisabledForTesting = parameters.shouldUseTestingNetworkSession;
237
238     m_diskCacheSizeOverride = parameters.diskCacheSizeOverride;
239     setCacheModel(static_cast<uint32_t>(parameters.cacheModel));
240
241     setCanHandleHTTPSServerTrustEvaluation(parameters.canHandleHTTPSServerTrustEvaluation);
242
243     // FIXME: instead of handling this here, a message should be sent later (scales to multiple sessions)
244     if (parameters.privateBrowsingEnabled)
245         RemoteNetworkingContext::ensureWebsiteDataStoreSession(WebsiteDataStoreParameters::legacyPrivateSessionParameters());
246
247     if (parameters.shouldUseTestingNetworkSession)
248         NetworkStorageSession::switchToNewTestingSession();
249
250 #if USE(NETWORK_SESSION)
251 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
252     parameters.defaultSessionParameters.legacyCustomProtocolManager = supplement<LegacyCustomProtocolManager>();
253 #endif
254     SessionTracker::setSession(PAL::SessionID::defaultSessionID(), NetworkSession::create(WTFMove(parameters.defaultSessionParameters)));
255 #endif
256
257     for (auto& supplement : m_supplements.values())
258         supplement->initialize(parameters);
259 }
260
261 void NetworkProcess::initializeConnection(IPC::Connection* connection)
262 {
263     ChildProcess::initializeConnection(connection);
264
265     for (auto& supplement : m_supplements.values())
266         supplement->initializeConnection(connection);
267 }
268
269 void NetworkProcess::createNetworkConnectionToWebProcess()
270 {
271 #if USE(UNIX_DOMAIN_SOCKETS)
272     IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection();
273
274     auto connection = NetworkConnectionToWebProcess::create(socketPair.server);
275     m_webProcessConnections.append(WTFMove(connection));
276
277     IPC::Attachment clientSocket(socketPair.client);
278     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientSocket), 0);
279 #elif OS(DARWIN)
280     // Create the listening port.
281     mach_port_t listeningPort;
282     mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort);
283
284     // Create a listening connection.
285     auto connection = NetworkConnectionToWebProcess::create(IPC::Connection::Identifier(listeningPort));
286     m_webProcessConnections.append(WTFMove(connection));
287
288     IPC::Attachment clientPort(listeningPort, MACH_MSG_TYPE_MAKE_SEND);
289     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientPort), 0);
290 #else
291     notImplemented();
292 #endif
293 }
294
295 void NetworkProcess::clearCachedCredentials()
296 {
297     NetworkStorageSession::defaultStorageSession().credentialStorage().clearCredentials();
298 #if USE(NETWORK_SESSION)
299     if (auto* networkSession = SessionTracker::networkSession(PAL::SessionID::defaultSessionID()))
300         networkSession->clearCredentials();
301     else
302         ASSERT_NOT_REACHED();
303 #endif
304 }
305
306 void NetworkProcess::addWebsiteDataStore(WebsiteDataStoreParameters&& parameters)
307 {
308     RemoteNetworkingContext::ensureWebsiteDataStoreSession(WTFMove(parameters));
309 }
310
311 void NetworkProcess::destroySession(PAL::SessionID sessionID)
312 {
313     SessionTracker::destroySession(sessionID);
314 }
315
316 void NetworkProcess::grantSandboxExtensionsToStorageProcessForBlobs(const Vector<String>& filenames, Function<void ()>&& completionHandler)
317 {
318     static uint64_t lastRequestID;
319
320     uint64_t requestID = ++lastRequestID;
321     m_sandboxExtensionForBlobsCompletionHandlers.set(requestID, WTFMove(completionHandler));
322     parentProcessConnection()->send(Messages::NetworkProcessProxy::GrantSandboxExtensionsToStorageProcessForBlobs(requestID, filenames), 0);
323 }
324
325 void NetworkProcess::didGrantSandboxExtensionsToStorageProcessForBlobs(uint64_t requestID)
326 {
327     if (auto handler = m_sandboxExtensionForBlobsCompletionHandlers.take(requestID))
328         handler();
329 }
330
331 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
332 void NetworkProcess::updatePrevalentDomainsToPartitionOrBlockCookies(PAL::SessionID sessionID, const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, bool shouldClearFirst)
333 {
334     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
335         networkStorageSession->setPrevalentDomainsToPartitionOrBlockCookies(domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, shouldClearFirst);
336 }
337
338 void NetworkProcess::hasStorageAccessForPrevalentDomains(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, uint64_t contextId)
339 {
340     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
341         parentProcessConnection()->send(Messages::NetworkProcessProxy::StorageAccessRequestResult(networkStorageSession->isStorageAccessGranted(resourceDomain, firstPartyDomain, frameID, pageID), contextId), 0);
342     else
343         ASSERT_NOT_REACHED();
344 }
345
346 void NetworkProcess::updateStorageAccessForPrevalentDomains(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, bool shouldGrantStorage, uint64_t contextId)
347 {
348     bool isStorageGranted = false;
349     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID)) {
350         networkStorageSession->setStorageAccessGranted(resourceDomain, firstPartyDomain, frameID, pageID, shouldGrantStorage);
351         ASSERT(networkStorageSession->isStorageAccessGranted(resourceDomain, firstPartyDomain, frameID, pageID) == shouldGrantStorage);
352         isStorageGranted = shouldGrantStorage;
353     } else
354         ASSERT_NOT_REACHED();
355
356     parentProcessConnection()->send(Messages::NetworkProcessProxy::StorageAccessRequestResult(isStorageGranted, contextId), 0);
357 }
358
359 void NetworkProcess::removePrevalentDomains(PAL::SessionID sessionID, const Vector<String>& domains)
360 {
361     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
362         networkStorageSession->removePrevalentDomains(domains);
363 }
364 #endif
365
366 static void fetchDiskCacheEntries(PAL::SessionID sessionID, OptionSet<WebsiteDataFetchOption> fetchOptions, Function<void (Vector<WebsiteData::Entry>)>&& completionHandler)
367 {
368     if (auto* cache = NetworkProcess::singleton().cache()) {
369         HashMap<SecurityOriginData, uint64_t> originsAndSizes;
370         cache->traverse([fetchOptions, completionHandler = WTFMove(completionHandler), originsAndSizes = WTFMove(originsAndSizes)](auto* traversalEntry) mutable {
371             if (!traversalEntry) {
372                 Vector<WebsiteData::Entry> entries;
373
374                 for (auto& originAndSize : originsAndSizes)
375                     entries.append(WebsiteData::Entry { originAndSize.key, WebsiteDataType::DiskCache, originAndSize.value });
376
377                 RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), entries = WTFMove(entries)] {
378                     completionHandler(entries);
379                 });
380
381                 return;
382             }
383
384             auto url = traversalEntry->entry.response().url();
385             auto result = originsAndSizes.add({url.protocol().toString(), url.host(), url.port()}, 0);
386
387             if (fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes))
388                 result.iterator->value += traversalEntry->entry.sourceStorageRecord().header.size() + traversalEntry->recordInfo.bodySize;
389         });
390
391         return;
392     }
393
394     RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler)] {
395         completionHandler({ });
396     });
397 }
398
399 void NetworkProcess::fetchWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, uint64_t callbackID)
400 {
401     struct CallbackAggregator final : public RefCounted<CallbackAggregator> {
402         explicit CallbackAggregator(Function<void (WebsiteData)>&& completionHandler)
403             : m_completionHandler(WTFMove(completionHandler))
404         {
405         }
406
407         ~CallbackAggregator()
408         {
409             ASSERT(RunLoop::isMain());
410
411             RunLoop::main().dispatch([completionHandler = WTFMove(m_completionHandler), websiteData = WTFMove(m_websiteData)] {
412                 completionHandler(websiteData);
413             });
414         }
415
416         Function<void (WebsiteData)> m_completionHandler;
417         WebsiteData m_websiteData;
418     };
419
420     auto callbackAggregator = adoptRef(*new CallbackAggregator([this, callbackID] (WebsiteData websiteData) {
421         parentProcessConnection()->send(Messages::NetworkProcessProxy::DidFetchWebsiteData(callbackID, websiteData), 0);
422     }));
423
424     if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
425         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
426             getHostnamesWithCookies(*networkStorageSession, callbackAggregator->m_websiteData.hostNamesWithCookies);
427     }
428
429     if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
430         if (NetworkStorageSession::storageSession(sessionID))
431             callbackAggregator->m_websiteData.originsWithCredentials = NetworkStorageSession::storageSession(sessionID)->credentialStorage().originsWithCredentials();
432     }
433
434     if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) {
435         CacheStorage::Engine::fetchEntries(sessionID, fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes), [callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
436             callbackAggregator->m_websiteData.entries.appendVector(entries);
437         });
438     }
439
440     if (websiteDataTypes.contains(WebsiteDataType::DiskCache)) {
441         fetchDiskCacheEntries(sessionID, fetchOptions, [callbackAggregator = WTFMove(callbackAggregator)](auto entries) mutable {
442             callbackAggregator->m_websiteData.entries.appendVector(entries);
443         });
444     }
445 }
446
447 void NetworkProcess::deleteWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID)
448 {
449 #if PLATFORM(COCOA)
450     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
451         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
452             clearHSTSCache(*networkStorageSession, modifiedSince);
453     }
454 #endif
455
456     if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
457         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
458             deleteAllCookiesModifiedSince(*networkStorageSession, modifiedSince);
459     }
460
461     if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
462         if (NetworkStorageSession::storageSession(sessionID))
463             NetworkStorageSession::storageSession(sessionID)->credentialStorage().clearCredentials();
464     }
465
466     auto clearTasksHandler = WTF::CallbackAggregator::create([this, callbackID] {
467         parentProcessConnection()->send(Messages::NetworkProcessProxy::DidDeleteWebsiteData(callbackID), 0);
468     });
469
470     if (websiteDataTypes.contains(WebsiteDataType::DOMCache))
471         CacheStorage::Engine::from(sessionID).clearAllCaches(clearTasksHandler);
472
473     if (websiteDataTypes.contains(WebsiteDataType::DiskCache) && !sessionID.isEphemeral())
474         clearDiskCache(modifiedSince, [clearTasksHandler = WTFMove(clearTasksHandler)] { });
475 }
476
477 static void clearDiskCacheEntries(const Vector<SecurityOriginData>& origins, Function<void ()>&& completionHandler)
478 {
479     if (auto* cache = NetworkProcess::singleton().cache()) {
480         HashSet<RefPtr<SecurityOrigin>> originsToDelete;
481         for (auto& origin : origins)
482             originsToDelete.add(origin.securityOrigin());
483
484         Vector<NetworkCache::Key> cacheKeysToDelete;
485         cache->traverse([cache, completionHandler = WTFMove(completionHandler), originsToDelete = WTFMove(originsToDelete), cacheKeysToDelete = WTFMove(cacheKeysToDelete)](auto* traversalEntry) mutable {
486             if (traversalEntry) {
487                 if (originsToDelete.contains(SecurityOrigin::create(traversalEntry->entry.response().url())))
488                     cacheKeysToDelete.append(traversalEntry->entry.key());
489                 return;
490             }
491
492             cache->remove(cacheKeysToDelete, WTFMove(completionHandler));
493             return;
494         });
495
496         return;
497     }
498
499     RunLoop::main().dispatch(WTFMove(completionHandler));
500 }
501
502 void NetworkProcess::deleteWebsiteDataForOrigins(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, const Vector<SecurityOriginData>& originDatas, const Vector<String>& cookieHostNames, uint64_t callbackID)
503 {
504     if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
505         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
506             deleteCookiesForHostnames(*networkStorageSession, cookieHostNames);
507     }
508
509     auto clearTasksHandler = WTF::CallbackAggregator::create([this, callbackID] {
510         parentProcessConnection()->send(Messages::NetworkProcessProxy::DidDeleteWebsiteDataForOrigins(callbackID), 0);
511     });
512
513     if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) {
514         for (auto& originData : originDatas) {
515             auto origin = originData.securityOrigin()->toString();
516             CacheStorage::Engine::from(sessionID).clearCachesForOrigin(origin, clearTasksHandler);
517         }
518     }
519
520     if (websiteDataTypes.contains(WebsiteDataType::DiskCache) && !sessionID.isEphemeral())
521         clearDiskCacheEntries(originDatas, [clearTasksHandler = WTFMove(clearTasksHandler)] { });
522 }
523
524 void NetworkProcess::downloadRequest(PAL::SessionID sessionID, DownloadID downloadID, const ResourceRequest& request, const String& suggestedFilename)
525 {
526     downloadManager().startDownload(nullptr, sessionID, downloadID, request, suggestedFilename);
527 }
528
529 void NetworkProcess::resumeDownload(PAL::SessionID sessionID, DownloadID downloadID, const IPC::DataReference& resumeData, const String& path, WebKit::SandboxExtension::Handle&& sandboxExtensionHandle)
530 {
531     downloadManager().resumeDownload(sessionID, downloadID, resumeData, path, WTFMove(sandboxExtensionHandle));
532 }
533
534 void NetworkProcess::cancelDownload(DownloadID downloadID)
535 {
536     downloadManager().cancelDownload(downloadID);
537 }
538     
539 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
540 static uint64_t generateCanAuthenticateIdentifier()
541 {
542     static uint64_t lastLoaderID = 0;
543     return ++lastLoaderID;
544 }
545
546 void NetworkProcess::canAuthenticateAgainstProtectionSpace(NetworkResourceLoader& loader, const WebCore::ProtectionSpace& protectionSpace)
547 {
548     uint64_t loaderID = generateCanAuthenticateIdentifier();
549     m_waitingNetworkResourceLoaders.set(loaderID, loader);
550     parentProcessConnection()->send(Messages::NetworkProcessProxy::CanAuthenticateAgainstProtectionSpace(loaderID, loader.pageID(), loader.frameID(), protectionSpace), 0);
551 }
552
553 #if ENABLE(SERVER_PRECONNECT)
554 void NetworkProcess::canAuthenticateAgainstProtectionSpace(PreconnectTask& preconnectTask, const WebCore::ProtectionSpace& protectionSpace)
555 {
556     uint64_t loaderID = generateCanAuthenticateIdentifier();
557     m_waitingPreconnectTasks.set(loaderID, preconnectTask.createWeakPtr());
558     parentProcessConnection()->send(Messages::NetworkProcessProxy::CanAuthenticateAgainstProtectionSpace(loaderID, preconnectTask.pageID(), preconnectTask.frameID(), protectionSpace), 0);
559 }
560 #endif
561
562 void NetworkProcess::continueCanAuthenticateAgainstProtectionSpace(uint64_t loaderID, bool canAuthenticate)
563 {
564     if (auto resourceLoader = m_waitingNetworkResourceLoaders.take(loaderID)) {
565         resourceLoader.value()->continueCanAuthenticateAgainstProtectionSpace(canAuthenticate);
566         return;
567     }
568 #if ENABLE(SERVER_PRECONNECT)
569     if (auto preconnectTask = m_waitingPreconnectTasks.take(loaderID)) {
570         preconnectTask->continueCanAuthenticateAgainstProtectionSpace(canAuthenticate);
571         return;
572     }
573 #endif
574 }
575
576 #endif
577
578 #if USE(NETWORK_SESSION)
579 void NetworkProcess::continueWillSendRequest(DownloadID downloadID, WebCore::ResourceRequest&& request)
580 {
581     downloadManager().continueWillSendRequest(downloadID, WTFMove(request));
582 }
583
584 void NetworkProcess::pendingDownloadCanceled(DownloadID downloadID)
585 {
586     downloadProxyConnection()->send(Messages::DownloadProxy::DidCancel({ }), downloadID.downloadID());
587 }
588
589 void NetworkProcess::findPendingDownloadLocation(NetworkDataTask& networkDataTask, ResponseCompletionHandler&& completionHandler, const ResourceResponse& response)
590 {
591     uint64_t destinationID = networkDataTask.pendingDownloadID().downloadID();
592     downloadProxyConnection()->send(Messages::DownloadProxy::DidReceiveResponse(response), destinationID);
593
594     downloadManager().willDecidePendingDownloadDestination(networkDataTask, WTFMove(completionHandler));
595
596     // As per https://html.spec.whatwg.org/#as-a-download (step 2), the filename from the Content-Disposition header
597     // should override the suggested filename from the download attribute.
598     String suggestedFilename = response.isAttachmentWithFilename() ? response.suggestedFilename() : networkDataTask.suggestedFilename();
599     suggestedFilename = MIMETypeRegistry::appendFileExtensionIfNecessary(suggestedFilename, response.mimeType());
600
601     downloadProxyConnection()->send(Messages::DownloadProxy::DecideDestinationWithSuggestedFilenameAsync(networkDataTask.pendingDownloadID(), suggestedFilename), destinationID);
602 }
603 #endif
604
605 void NetworkProcess::continueDecidePendingDownloadDestination(DownloadID downloadID, String destination, SandboxExtension::Handle&& sandboxExtensionHandle, bool allowOverwrite)
606 {
607     if (destination.isEmpty())
608         downloadManager().cancelDownload(downloadID);
609     else
610         downloadManager().continueDecidePendingDownloadDestination(downloadID, destination, WTFMove(sandboxExtensionHandle), allowOverwrite);
611 }
612
613 void NetworkProcess::setCacheModel(uint32_t cm)
614 {
615     CacheModel cacheModel = static_cast<CacheModel>(cm);
616
617     if (m_hasSetCacheModel && (cacheModel == m_cacheModel))
618         return;
619
620     m_hasSetCacheModel = true;
621     m_cacheModel = cacheModel;
622
623     unsigned urlCacheMemoryCapacity = 0;
624     uint64_t urlCacheDiskCapacity = 0;
625     uint64_t diskFreeSize = 0;
626     if (WebCore::FileSystem::getVolumeFreeSpace(m_diskCacheDirectory, diskFreeSize)) {
627         // As a fudge factor, use 1000 instead of 1024, in case the reported byte
628         // count doesn't align exactly to a megabyte boundary.
629         diskFreeSize /= KB * 1000;
630         calculateURLCacheSizes(cacheModel, diskFreeSize, urlCacheMemoryCapacity, urlCacheDiskCapacity);
631     }
632
633     if (m_diskCacheSizeOverride >= 0)
634         urlCacheDiskCapacity = m_diskCacheSizeOverride;
635
636     if (m_cache) {
637         m_cache->setCapacity(urlCacheDiskCapacity);
638         return;
639     }
640
641     platformSetURLCacheSize(urlCacheMemoryCapacity, urlCacheDiskCapacity);
642 }
643
644 void NetworkProcess::setCanHandleHTTPSServerTrustEvaluation(bool value)
645 {
646     m_canHandleHTTPSServerTrustEvaluation = value;
647 }
648
649 void NetworkProcess::getNetworkProcessStatistics(uint64_t callbackID)
650 {
651     StatisticsData data;
652
653     auto& networkProcess = NetworkProcess::singleton();
654     data.statisticsNumbers.set("DownloadsActiveCount", networkProcess.downloadManager().activeDownloadCount());
655     data.statisticsNumbers.set("OutstandingAuthenticationChallengesCount", networkProcess.authenticationManager().outstandingAuthenticationChallengeCount());
656
657     parentProcessConnection()->send(Messages::WebProcessPool::DidGetStatistics(data, callbackID), 0);
658 }
659
660 void NetworkProcess::setAllowsAnySSLCertificateForWebSocket(bool allows)
661 {
662     DeprecatedGlobalSettings::setAllowsAnySSLCertificate(allows);
663 }
664
665 void NetworkProcess::logDiagnosticMessage(uint64_t webPageID, const String& message, const String& description, ShouldSample shouldSample)
666 {
667     if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
668         return;
669
670     parentProcessConnection()->send(Messages::NetworkProcessProxy::LogDiagnosticMessage(webPageID, message, description, ShouldSample::No), 0);
671 }
672
673 void NetworkProcess::logDiagnosticMessageWithResult(uint64_t webPageID, const String& message, const String& description, DiagnosticLoggingResultType result, ShouldSample shouldSample)
674 {
675     if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
676         return;
677
678     parentProcessConnection()->send(Messages::NetworkProcessProxy::LogDiagnosticMessageWithResult(webPageID, message, description, result, ShouldSample::No), 0);
679 }
680
681 void NetworkProcess::logDiagnosticMessageWithValue(uint64_t webPageID, const String& message, const String& description, double value, unsigned significantFigures, ShouldSample shouldSample)
682 {
683     if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
684         return;
685
686     parentProcessConnection()->send(Messages::NetworkProcessProxy::LogDiagnosticMessageWithValue(webPageID, message, description, value, significantFigures, ShouldSample::No), 0);
687 }
688
689 void NetworkProcess::terminate()
690 {
691 #if ENABLE(NETWORK_CAPTURE)
692     NetworkCapture::Manager::singleton().terminate();
693 #endif
694
695     platformTerminate();
696     ChildProcess::terminate();
697 }
698
699 // FIXME: We can remove this one by adapting RefCounter.
700 class TaskCounter : public RefCounted<TaskCounter> {
701 public:
702     explicit TaskCounter(Function<void()>&& callback) : m_callback(WTFMove(callback)) { }
703     ~TaskCounter() { m_callback(); };
704
705 private:
706     Function<void()> m_callback;
707 };
708
709 void NetworkProcess::actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend shouldAcknowledgeWhenReadyToSuspend)
710 {
711     lowMemoryHandler(Critical::Yes);
712
713     RefPtr<TaskCounter> delayedTaskCounter;
714     if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) {
715         delayedTaskCounter = adoptRef(new TaskCounter([this] {
716             RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::notifyProcessReadyToSuspend() Sending ProcessReadyToSuspend IPC message", this);
717             if (parentProcessConnection())
718                 parentProcessConnection()->send(Messages::NetworkProcessProxy::ProcessReadyToSuspend(), 0);
719         }));
720     }
721
722     for (auto& connection : m_webProcessConnections)
723         connection->cleanupForSuspension([delayedTaskCounter] { });
724 }
725
726 void NetworkProcess::processWillSuspendImminently(bool& handled)
727 {
728     actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::No);
729     handled = true;
730 }
731
732 void NetworkProcess::prepareToSuspend()
733 {
734     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::prepareToSuspend()", this);
735     actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::Yes);
736 }
737
738 void NetworkProcess::cancelPrepareToSuspend()
739 {
740     // Although it is tempting to send a NetworkProcessProxy::DidCancelProcessSuspension message from here
741     // we do not because prepareToSuspend() already replied with a NetworkProcessProxy::ProcessReadyToSuspend
742     // message. And NetworkProcessProxy expects to receive either a NetworkProcessProxy::ProcessReadyToSuspend-
743     // or NetworkProcessProxy::DidCancelProcessSuspension- message, but not both.
744     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::cancelPrepareToSuspend()", this);
745     for (auto& connection : m_webProcessConnections)
746         connection->endSuspension();
747 }
748
749 void NetworkProcess::processDidResume()
750 {
751     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::processDidResume()", this);
752     for (auto& connection : m_webProcessConnections)
753         connection->endSuspension();
754 }
755
756 void NetworkProcess::prefetchDNS(const String& hostname)
757 {
758     WebCore::prefetchDNS(hostname);
759 }
760
761 String NetworkProcess::cacheStorageDirectory(PAL::SessionID sessionID) const
762 {
763     if (sessionID.isEphemeral())
764         return { };
765
766     if (sessionID == PAL::SessionID::defaultSessionID())
767         return m_cacheStorageDirectory;
768
769     auto* session = NetworkStorageSession::storageSession(sessionID);
770     if (!session)
771         return { };
772
773     return session->cacheStorageDirectory();
774 }
775
776 void NetworkProcess::preconnectTo(const WebCore::URL& url, WebCore::StoredCredentialsPolicy storedCredentialsPolicy)
777 {
778 #if ENABLE(SERVER_PRECONNECT)
779     NetworkLoadParameters parameters;
780     parameters.request = ResourceRequest { url };
781     parameters.sessionID = PAL::SessionID::defaultSessionID();
782     parameters.storedCredentialsPolicy = storedCredentialsPolicy;
783     parameters.shouldPreconnectOnly = PreconnectOnly::Yes;
784
785     new PreconnectTask(WTFMove(parameters));
786 #else
787     UNUSED_PARAM(url);
788     UNUSED_PARAM(storedCredentialsPolicy);
789 #endif
790 }
791
792 uint64_t NetworkProcess::cacheStoragePerOriginQuota() const
793 {
794     return m_cacheStoragePerOriginQuota;
795 }
796
797 #if !PLATFORM(COCOA)
798 void NetworkProcess::initializeProcess(const ChildProcessInitializationParameters&)
799 {
800 }
801
802 void NetworkProcess::initializeProcessName(const ChildProcessInitializationParameters&)
803 {
804 }
805
806 void NetworkProcess::initializeSandbox(const ChildProcessInitializationParameters&, SandboxInitializationParameters&)
807 {
808 }
809
810 void NetworkProcess::syncAllCookies()
811 {
812 }
813
814 #endif
815
816 } // namespace WebKit