3b395d6253aaab93b85123ce0374472a23ee4227
[WebKit-https.git] / Source / WebKit2 / NetworkProcess / NetworkProcess.cpp
1 /*
2  * Copyright (C) 2012-2015 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 "CustomProtocolManager.h"
34 #include "DataReference.h"
35 #include "DownloadProxyMessages.h"
36 #include "Logging.h"
37 #include "NetworkConnectionToWebProcess.h"
38 #include "NetworkProcessCreationParameters.h"
39 #include "NetworkProcessPlatformStrategies.h"
40 #include "NetworkProcessProxyMessages.h"
41 #include "NetworkResourceLoader.h"
42 #include "RemoteNetworkingContext.h"
43 #include "SessionTracker.h"
44 #include "StatisticsData.h"
45 #include "WebCookieManager.h"
46 #include "WebCoreArgumentCoders.h"
47 #include "WebPageProxyMessages.h"
48 #include "WebProcessPoolMessages.h"
49 #include "WebsiteData.h"
50 #include "WebsiteDataFetchOption.h"
51 #include "WebsiteDataType.h"
52 #include <WebCore/DNS.h>
53 #include <WebCore/DiagnosticLoggingClient.h>
54 #include <WebCore/LogInitialization.h>
55 #include <WebCore/NetworkStorageSession.h>
56 #include <WebCore/PlatformCookieJar.h>
57 #include <WebCore/ResourceRequest.h>
58 #include <WebCore/RuntimeApplicationChecks.h>
59 #include <WebCore/SecurityOriginData.h>
60 #include <WebCore/SecurityOriginHash.h>
61 #include <WebCore/SessionID.h>
62 #include <WebCore/URLParser.h>
63 #include <wtf/OptionSet.h>
64 #include <wtf/RunLoop.h>
65 #include <wtf/text/CString.h>
66
67 #if ENABLE(SEC_ITEM_SHIM)
68 #include "SecItemShim.h"
69 #endif
70
71 #if ENABLE(NETWORK_CACHE)
72 #include "NetworkCache.h"
73 #include "NetworkCacheCoders.h"
74 #endif
75
76 using namespace WebCore;
77
78 namespace WebKit {
79
80 NetworkProcess& NetworkProcess::singleton()
81 {
82     static NeverDestroyed<NetworkProcess> networkProcess;
83     return networkProcess;
84 }
85
86 NetworkProcess::NetworkProcess()
87     : m_hasSetCacheModel(false)
88     , m_cacheModel(CacheModelDocumentViewer)
89     , m_diskCacheIsDisabledForTesting(false)
90     , m_canHandleHTTPSServerTrustEvaluation(true)
91 #if PLATFORM(COCOA)
92     , m_clearCacheDispatchGroup(0)
93 #endif
94 #if PLATFORM(IOS)
95     , m_webSQLiteDatabaseTracker(*this)
96 #endif
97 {
98     NetworkProcessPlatformStrategies::initialize();
99
100     addSupplement<AuthenticationManager>();
101     addSupplement<WebCookieManager>();
102     addSupplement<CustomProtocolManager>();
103 #if USE(NETWORK_SESSION)
104     NetworkSession::setCustomProtocolManager(supplement<CustomProtocolManager>());
105 #endif
106 }
107
108 NetworkProcess::~NetworkProcess()
109 {
110 }
111
112 AuthenticationManager& NetworkProcess::authenticationManager()
113 {
114     return *supplement<AuthenticationManager>();
115 }
116
117 DownloadManager& NetworkProcess::downloadManager()
118 {
119     static NeverDestroyed<DownloadManager> downloadManager(*this);
120     return downloadManager;
121 }
122
123 void NetworkProcess::removeNetworkConnectionToWebProcess(NetworkConnectionToWebProcess* connection)
124 {
125     size_t vectorIndex = m_webProcessConnections.find(connection);
126     ASSERT(vectorIndex != notFound);
127
128     m_webProcessConnections.remove(vectorIndex);
129 }
130
131 bool NetworkProcess::shouldTerminate()
132 {
133     // Network process keeps session cookies and credentials, so it should never terminate (as long as UI process connection is alive).
134     return false;
135 }
136
137 void NetworkProcess::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
138 {
139     if (messageReceiverMap().dispatchMessage(connection, decoder))
140         return;
141
142     if (decoder.messageReceiverName() == Messages::ChildProcess::messageReceiverName()) {
143         ChildProcess::didReceiveMessage(connection, decoder);
144         return;
145     }
146
147     didReceiveNetworkProcessMessage(connection, decoder);
148 }
149
150 void NetworkProcess::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder)
151 {
152     if (messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder))
153         return;
154
155     didReceiveSyncNetworkProcessMessage(connection, decoder, replyEncoder);
156 }
157
158 void NetworkProcess::didClose(IPC::Connection&)
159 {
160     // The UIProcess just exited.
161     stopRunLoop();
162 }
163
164 void NetworkProcess::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference)
165 {
166     stopRunLoop();
167 }
168
169 void NetworkProcess::didCreateDownload()
170 {
171     disableTermination();
172 }
173
174 void NetworkProcess::didDestroyDownload()
175 {
176     enableTermination();
177 }
178
179 IPC::Connection* NetworkProcess::downloadProxyConnection()
180 {
181     return parentProcessConnection();
182 }
183
184 AuthenticationManager& NetworkProcess::downloadsAuthenticationManager()
185 {
186     return authenticationManager();
187 }
188
189 void NetworkProcess::lowMemoryHandler(Critical critical)
190 {
191     if (m_suppressMemoryPressureHandler)
192         return;
193
194     platformLowMemoryHandler(critical);
195     WTF::releaseFastMallocFreeMemory();
196 }
197
198 void NetworkProcess::initializeNetworkProcess(NetworkProcessCreationParameters&& parameters)
199 {
200     URLParser::setEnabled(parameters.urlParserEnabled);
201
202     platformInitializeNetworkProcess(parameters);
203
204     WTF::setCurrentThreadIsUserInitiated();
205
206     m_suppressMemoryPressureHandler = parameters.shouldSuppressMemoryPressureHandler;
207     if (!m_suppressMemoryPressureHandler) {
208         auto& memoryPressureHandler = MemoryPressureHandler::singleton();
209 #if OS(LINUX)
210         if (parameters.memoryPressureMonitorHandle.fileDescriptor() != -1)
211             memoryPressureHandler.setMemoryPressureMonitorHandle(parameters.memoryPressureMonitorHandle.releaseFileDescriptor());
212 #endif
213         memoryPressureHandler.setLowMemoryHandler([this] (Critical critical, Synchronous) {
214             lowMemoryHandler(critical);
215         });
216         memoryPressureHandler.install();
217     }
218
219     m_diskCacheIsDisabledForTesting = parameters.shouldUseTestingNetworkSession;
220
221     m_diskCacheSizeOverride = parameters.diskCacheSizeOverride;
222     setCacheModel(static_cast<uint32_t>(parameters.cacheModel));
223
224     setCanHandleHTTPSServerTrustEvaluation(parameters.canHandleHTTPSServerTrustEvaluation);
225
226     // FIXME: instead of handling this here, a message should be sent later (scales to multiple sessions)
227     if (parameters.privateBrowsingEnabled)
228         RemoteNetworkingContext::ensurePrivateBrowsingSession(SessionID::legacyPrivateSessionID());
229
230     if (parameters.shouldUseTestingNetworkSession)
231         NetworkStorageSession::switchToNewTestingSession();
232
233     for (auto& supplement : m_supplements.values())
234         supplement->initialize(parameters);
235 }
236
237 void NetworkProcess::initializeConnection(IPC::Connection* connection)
238 {
239     ChildProcess::initializeConnection(connection);
240
241     for (auto& supplement : m_supplements.values())
242         supplement->initializeConnection(connection);
243 }
244
245 void NetworkProcess::createNetworkConnectionToWebProcess()
246 {
247 #if USE(UNIX_DOMAIN_SOCKETS)
248     IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection();
249
250     auto connection = NetworkConnectionToWebProcess::create(socketPair.server);
251     m_webProcessConnections.append(WTFMove(connection));
252
253     IPC::Attachment clientSocket(socketPair.client);
254     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientSocket), 0);
255 #elif OS(DARWIN)
256     // Create the listening port.
257     mach_port_t listeningPort;
258     mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort);
259
260     // Create a listening connection.
261     auto connection = NetworkConnectionToWebProcess::create(IPC::Connection::Identifier(listeningPort));
262     m_webProcessConnections.append(WTFMove(connection));
263
264     IPC::Attachment clientPort(listeningPort, MACH_MSG_TYPE_MAKE_SEND);
265     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientPort), 0);
266 #else
267     notImplemented();
268 #endif
269 }
270
271 void NetworkProcess::clearCachedCredentials()
272 {
273     NetworkStorageSession::defaultStorageSession().credentialStorage().clearCredentials();
274 #if USE(NETWORK_SESSION)
275     NetworkSession::defaultSession().clearCredentials();
276 #endif
277 }
278
279 void NetworkProcess::ensurePrivateBrowsingSession(SessionID sessionID)
280 {
281     RemoteNetworkingContext::ensurePrivateBrowsingSession(sessionID);
282 }
283
284 void NetworkProcess::destroyPrivateBrowsingSession(SessionID sessionID)
285 {
286     SessionTracker::destroySession(sessionID);
287 }
288
289 void NetworkProcess::grantSandboxExtensionsToDatabaseProcessForBlobs(const Vector<String>& filenames, Function<void ()>&& completionHandler)
290 {
291     static uint64_t lastRequestID;
292
293     uint64_t requestID = ++lastRequestID;
294     m_sandboxExtensionForBlobsCompletionHandlers.set(requestID, WTFMove(completionHandler));
295     parentProcessConnection()->send(Messages::NetworkProcessProxy::GrantSandboxExtensionsToDatabaseProcessForBlobs(requestID, filenames), 0);
296 }
297
298 void NetworkProcess::didGrantSandboxExtensionsToDatabaseProcessForBlobs(uint64_t requestID)
299 {
300     if (auto handler = m_sandboxExtensionForBlobsCompletionHandlers.take(requestID))
301         handler();
302 }
303
304 static void fetchDiskCacheEntries(SessionID sessionID, OptionSet<WebsiteDataFetchOption> fetchOptions, Function<void (Vector<WebsiteData::Entry>)>&& completionHandler)
305 {
306 #if ENABLE(NETWORK_CACHE)
307     if (NetworkCache::singleton().isEnabled()) {
308         HashMap<RefPtr<SecurityOrigin>, uint64_t> originsAndSizes;
309         NetworkCache::singleton().traverse([fetchOptions, completionHandler = WTFMove(completionHandler), originsAndSizes = WTFMove(originsAndSizes)](auto* traversalEntry) mutable {
310             if (!traversalEntry) {
311                 Vector<WebsiteData::Entry> entries;
312
313                 for (auto& originAndSize : originsAndSizes)
314                     entries.append(WebsiteData::Entry { originAndSize.key, WebsiteDataType::DiskCache, originAndSize.value });
315
316                 RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), entries = WTFMove(entries)] {
317                     completionHandler(entries);
318                 });
319
320                 return;
321             }
322
323             auto result = originsAndSizes.add(SecurityOrigin::create(traversalEntry->entry.response().url()), 0);
324
325             if (fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes))
326                 result.iterator->value += traversalEntry->entry.sourceStorageRecord().header.size() + traversalEntry->recordInfo.bodySize;
327         });
328
329         return;
330     }
331 #endif
332
333     Vector<WebsiteData::Entry> entries;
334
335 #if USE(CFURLCACHE)
336     for (auto& origin : NetworkProcess::cfURLCacheOrigins())
337         entries.append(WebsiteData::Entry { WTFMove(origin), WebsiteDataType::DiskCache, 0 });
338 #endif
339
340     RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), entries = WTFMove(entries)] {
341         completionHandler(entries);
342     });
343 }
344
345 void NetworkProcess::fetchWebsiteData(SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, uint64_t callbackID)
346 {
347     struct CallbackAggregator final : public RefCounted<CallbackAggregator> {
348         explicit CallbackAggregator(Function<void (WebsiteData)>&& completionHandler)
349             : m_completionHandler(WTFMove(completionHandler))
350         {
351         }
352
353         ~CallbackAggregator()
354         {
355             ASSERT(RunLoop::isMain());
356
357             RunLoop::main().dispatch([completionHandler = WTFMove(m_completionHandler), websiteData = WTFMove(m_websiteData)] {
358                 completionHandler(websiteData);
359             });
360         }
361
362         Function<void (WebsiteData)> m_completionHandler;
363         WebsiteData m_websiteData;
364     };
365
366     auto callbackAggregator = adoptRef(*new CallbackAggregator([this, callbackID] (WebsiteData websiteData) {
367         parentProcessConnection()->send(Messages::NetworkProcessProxy::DidFetchWebsiteData(callbackID, websiteData), 0);
368     }));
369
370     if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
371         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
372             getHostnamesWithCookies(*networkStorageSession, callbackAggregator->m_websiteData.hostNamesWithCookies);
373     }
374
375     if (websiteDataTypes.contains(WebsiteDataType::DiskCache)) {
376         fetchDiskCacheEntries(sessionID, fetchOptions, [callbackAggregator = WTFMove(callbackAggregator)](auto entries) mutable {
377             callbackAggregator->m_websiteData.entries.appendVector(entries);
378         });
379     }
380 }
381
382 void NetworkProcess::deleteWebsiteData(SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID)
383 {
384 #if PLATFORM(COCOA)
385     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
386         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
387             clearHSTSCache(*networkStorageSession, modifiedSince);
388     }
389 #endif
390
391     if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
392         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
393             deleteAllCookiesModifiedSince(*networkStorageSession, modifiedSince);
394     }
395
396     auto completionHandler = [this, callbackID] {
397         parentProcessConnection()->send(Messages::NetworkProcessProxy::DidDeleteWebsiteData(callbackID), 0);
398     };
399
400     if (websiteDataTypes.contains(WebsiteDataType::DiskCache) && !sessionID.isEphemeral()) {
401         clearDiskCache(modifiedSince, WTFMove(completionHandler));
402         return;
403     }
404
405     completionHandler();
406 }
407
408 static void clearDiskCacheEntries(const Vector<SecurityOriginData>& origins, Function<void ()>&& completionHandler)
409 {
410 #if ENABLE(NETWORK_CACHE)
411     if (NetworkCache::singleton().isEnabled()) {
412         HashSet<RefPtr<SecurityOrigin>> originsToDelete;
413         for (auto& origin : origins)
414             originsToDelete.add(origin.securityOrigin());
415
416         Vector<NetworkCache::Key> cacheKeysToDelete;
417         NetworkCache::singleton().traverse([completionHandler = WTFMove(completionHandler), originsToDelete = WTFMove(originsToDelete), cacheKeysToDelete = WTFMove(cacheKeysToDelete)](auto* traversalEntry) mutable {
418             if (traversalEntry) {
419                 if (originsToDelete.contains(SecurityOrigin::create(traversalEntry->entry.response().url())))
420                     cacheKeysToDelete.append(traversalEntry->entry.key());
421                 return;
422             }
423
424             for (auto& key : cacheKeysToDelete)
425                 NetworkCache::singleton().remove(key);
426
427             RunLoop::main().dispatch(WTFMove(completionHandler));
428             return;
429         });
430
431         return;
432     }
433 #endif
434
435 #if USE(CFURLCACHE)
436     NetworkProcess::clearCFURLCacheForOrigins(origins);
437 #endif
438
439     RunLoop::main().dispatch(WTFMove(completionHandler));
440 }
441
442 void NetworkProcess::deleteWebsiteDataForOrigins(SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, const Vector<SecurityOriginData>& origins, const Vector<String>& cookieHostNames, uint64_t callbackID)
443 {
444     if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
445         if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
446             deleteCookiesForHostnames(*networkStorageSession, cookieHostNames);
447     }
448
449     auto completionHandler = [this, callbackID] {
450         parentProcessConnection()->send(Messages::NetworkProcessProxy::DidDeleteWebsiteDataForOrigins(callbackID), 0);
451     };
452
453     if (websiteDataTypes.contains(WebsiteDataType::DiskCache) && !sessionID.isEphemeral()) {
454         clearDiskCacheEntries(origins, WTFMove(completionHandler));
455         return;
456     }
457
458     completionHandler();
459 }
460
461 void NetworkProcess::downloadRequest(SessionID sessionID, DownloadID downloadID, const ResourceRequest& request)
462 {
463     downloadManager().startDownload(sessionID, downloadID, request);
464 }
465
466 void NetworkProcess::resumeDownload(SessionID sessionID, DownloadID downloadID, const IPC::DataReference& resumeData, const String& path, const WebKit::SandboxExtension::Handle& sandboxExtensionHandle)
467 {
468     downloadManager().resumeDownload(sessionID, downloadID, resumeData, path, sandboxExtensionHandle);
469 }
470
471 void NetworkProcess::cancelDownload(DownloadID downloadID)
472 {
473     downloadManager().cancelDownload(downloadID);
474 }
475     
476 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
477 void NetworkProcess::canAuthenticateAgainstProtectionSpace(NetworkResourceLoader& loader, const WebCore::ProtectionSpace& protectionSpace)
478 {
479     static uint64_t lastLoaderID = 0;
480     uint64_t loaderID = ++lastLoaderID;
481     m_waitingNetworkResourceLoaders.set(lastLoaderID, loader);
482     parentProcessConnection()->send(Messages::NetworkProcessProxy::CanAuthenticateAgainstProtectionSpace(loaderID, loader.pageID(), loader.frameID(), protectionSpace), 0);
483 }
484
485 void NetworkProcess::continueCanAuthenticateAgainstProtectionSpace(uint64_t loaderID, bool canAuthenticate)
486 {
487     m_waitingNetworkResourceLoaders.take(loaderID).value()->continueCanAuthenticateAgainstProtectionSpace(canAuthenticate);
488 }
489 #endif
490
491 #if USE(NETWORK_SESSION)
492 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
493 void NetworkProcess::continueCanAuthenticateAgainstProtectionSpaceDownload(DownloadID downloadID, bool canAuthenticate)
494 {
495     downloadManager().continueCanAuthenticateAgainstProtectionSpace(downloadID, canAuthenticate);
496 }
497 #endif
498
499 void NetworkProcess::continueWillSendRequest(DownloadID downloadID, WebCore::ResourceRequest&& request)
500 {
501     downloadManager().continueWillSendRequest(downloadID, WTFMove(request));
502 }
503
504 void NetworkProcess::pendingDownloadCanceled(DownloadID downloadID)
505 {
506     downloadProxyConnection()->send(Messages::DownloadProxy::DidCancel({ }), downloadID.downloadID());
507 }
508
509 void NetworkProcess::findPendingDownloadLocation(NetworkDataTask& networkDataTask, ResponseCompletionHandler&& completionHandler, const ResourceResponse& response)
510 {
511     uint64_t destinationID = networkDataTask.pendingDownloadID().downloadID();
512     downloadProxyConnection()->send(Messages::DownloadProxy::DidReceiveResponse(response), destinationID);
513
514     downloadManager().willDecidePendingDownloadDestination(networkDataTask, WTFMove(completionHandler));
515     downloadProxyConnection()->send(Messages::DownloadProxy::DecideDestinationWithSuggestedFilenameAsync(networkDataTask.pendingDownloadID(), networkDataTask.suggestedFilename()), destinationID);
516 }
517 #endif
518
519 void NetworkProcess::continueDecidePendingDownloadDestination(DownloadID downloadID, String destination, const SandboxExtension::Handle& sandboxExtensionHandle, bool allowOverwrite)
520 {
521     if (destination.isEmpty())
522         downloadManager().cancelDownload(downloadID);
523     else
524         downloadManager().continueDecidePendingDownloadDestination(downloadID, destination, sandboxExtensionHandle, allowOverwrite);
525 }
526
527 void NetworkProcess::setCacheModel(uint32_t cm)
528 {
529     CacheModel cacheModel = static_cast<CacheModel>(cm);
530
531     if (m_hasSetCacheModel && (cacheModel == m_cacheModel))
532         return;
533
534     m_hasSetCacheModel = true;
535     m_cacheModel = cacheModel;
536
537     unsigned urlCacheMemoryCapacity = 0;
538     uint64_t urlCacheDiskCapacity = 0;
539     uint64_t diskFreeSize = 0;
540     if (WebCore::getVolumeFreeSpace(m_diskCacheDirectory, diskFreeSize)) {
541         // As a fudge factor, use 1000 instead of 1024, in case the reported byte
542         // count doesn't align exactly to a megabyte boundary.
543         diskFreeSize /= KB * 1000;
544         calculateURLCacheSizes(cacheModel, diskFreeSize, urlCacheMemoryCapacity, urlCacheDiskCapacity);
545     }
546
547     if (m_diskCacheSizeOverride >= 0)
548         urlCacheDiskCapacity = m_diskCacheSizeOverride;
549
550 #if ENABLE(NETWORK_CACHE)
551     auto& networkCache = NetworkCache::singleton();
552     if (networkCache.isEnabled()) {
553         networkCache.setCapacity(urlCacheDiskCapacity);
554         return;
555     }
556 #endif
557
558     platformSetURLCacheSize(urlCacheMemoryCapacity, urlCacheDiskCapacity);
559 }
560
561 void NetworkProcess::setCanHandleHTTPSServerTrustEvaluation(bool value)
562 {
563     m_canHandleHTTPSServerTrustEvaluation = value;
564 }
565
566 void NetworkProcess::getNetworkProcessStatistics(uint64_t callbackID)
567 {
568     StatisticsData data;
569
570     auto& networkProcess = NetworkProcess::singleton();
571     data.statisticsNumbers.set("DownloadsActiveCount", networkProcess.downloadManager().activeDownloadCount());
572     data.statisticsNumbers.set("OutstandingAuthenticationChallengesCount", networkProcess.authenticationManager().outstandingAuthenticationChallengeCount());
573
574     parentProcessConnection()->send(Messages::WebProcessPool::DidGetStatistics(data, callbackID), 0);
575 }
576
577 void NetworkProcess::logDiagnosticMessage(uint64_t webPageID, const String& message, const String& description, ShouldSample shouldSample)
578 {
579     if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
580         return;
581
582     parentProcessConnection()->send(Messages::NetworkProcessProxy::LogSampledDiagnosticMessage(webPageID, message, description), 0);
583 }
584
585 void NetworkProcess::logDiagnosticMessageWithResult(uint64_t webPageID, const String& message, const String& description, DiagnosticLoggingResultType result, ShouldSample shouldSample)
586 {
587     if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
588         return;
589
590     parentProcessConnection()->send(Messages::NetworkProcessProxy::LogSampledDiagnosticMessageWithResult(webPageID, message, description, result), 0);
591 }
592
593 void NetworkProcess::logDiagnosticMessageWithValue(uint64_t webPageID, const String& message, const String& description, const String& value, ShouldSample shouldSample)
594 {
595     if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
596         return;
597
598     parentProcessConnection()->send(Messages::NetworkProcessProxy::LogSampledDiagnosticMessageWithValue(webPageID, message, description, value), 0);
599 }
600
601 void NetworkProcess::terminate()
602 {
603     platformTerminate();
604     ChildProcess::terminate();
605 }
606
607 void NetworkProcess::processWillSuspendImminently(bool& handled)
608 {
609     lowMemoryHandler(Critical::Yes);
610     handled = true;
611 }
612
613 void NetworkProcess::prepareToSuspend()
614 {
615     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::prepareToSuspend()", this);
616     lowMemoryHandler(Critical::Yes);
617
618     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::prepareToSuspend() Sending ProcessReadyToSuspend IPC message", this);
619     parentProcessConnection()->send(Messages::NetworkProcessProxy::ProcessReadyToSuspend(), 0);
620 }
621
622 void NetworkProcess::cancelPrepareToSuspend()
623 {
624     // Although it is tempting to send a NetworkProcessProxy::DidCancelProcessSuspension message from here
625     // we do not because prepareToSuspend() already replied with a NetworkProcessProxy::ProcessReadyToSuspend
626     // message. And NetworkProcessProxy expects to receive either a NetworkProcessProxy::ProcessReadyToSuspend-
627     // or NetworkProcessProxy::DidCancelProcessSuspension- message, but not both.
628     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::cancelPrepareToSuspend()", this);
629 }
630
631 void NetworkProcess::processDidResume()
632 {
633     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::processDidResume()", this);
634 }
635
636 void NetworkProcess::prefetchDNS(const String& hostname)
637 {
638     WebCore::prefetchDNS(hostname);
639 }
640
641 #if !PLATFORM(COCOA)
642 void NetworkProcess::initializeProcess(const ChildProcessInitializationParameters&)
643 {
644 }
645
646 void NetworkProcess::initializeProcessName(const ChildProcessInitializationParameters&)
647 {
648 }
649
650 void NetworkProcess::initializeSandbox(const ChildProcessInitializationParameters&, SandboxInitializationParameters&)
651 {
652 }
653
654 void NetworkProcess::platformLowMemoryHandler(Critical)
655 {
656 }
657 #endif
658
659 } // namespace WebKit