d6bbcb223a7efaca9d7fbf139c492c669cce65d3
[WebKit-https.git] / Source / WebKit2 / NetworkProcess / NetworkProcess.cpp
1 /*
2  * Copyright (C) 2012 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 #if ENABLE(NETWORK_PROCESS)
30
31 #include "ArgumentCoders.h"
32 #include "Attachment.h"
33 #include "AuthenticationManager.h"
34 #include "CustomProtocolManager.h"
35 #include "Logging.h"
36 #include "NetworkConnectionToWebProcess.h"
37 #include "NetworkProcessCreationParameters.h"
38 #include "NetworkProcessPlatformStrategies.h"
39 #include "NetworkProcessProxyMessages.h"
40 #include "NetworkResourceLoader.h"
41 #include "RemoteNetworkingContext.h"
42 #include "SessionTracker.h"
43 #include "StatisticsData.h"
44 #include "WebCookieManager.h"
45 #include "WebProcessPoolMessages.h"
46 #include "WebsiteDataTypes.h"
47 #include <WebCore/Logging.h>
48 #include <WebCore/MemoryPressureHandler.h>
49 #include <WebCore/PlatformCookieJar.h>
50 #include <WebCore/ResourceRequest.h>
51 #include <WebCore/SessionID.h>
52 #include <wtf/RunLoop.h>
53 #include <wtf/text/CString.h>
54
55 #if ENABLE(SEC_ITEM_SHIM)
56 #include "SecItemShim.h"
57 #endif
58
59 using namespace WebCore;
60
61 namespace WebKit {
62
63 NetworkProcess& NetworkProcess::shared()
64 {
65     static NeverDestroyed<NetworkProcess> networkProcess;
66     return networkProcess;
67 }
68
69 NetworkProcess::NetworkProcess()
70     : m_hasSetCacheModel(false)
71     , m_cacheModel(CacheModelDocumentViewer)
72     , m_diskCacheIsDisabledForTesting(false)
73     , m_canHandleHTTPSServerTrustEvaluation(true)
74 #if PLATFORM(COCOA)
75     , m_clearCacheDispatchGroup(0)
76 #endif
77 {
78     NetworkProcessPlatformStrategies::initialize();
79
80     addSupplement<AuthenticationManager>();
81     addSupplement<WebCookieManager>();
82     addSupplement<CustomProtocolManager>();
83 }
84
85 NetworkProcess::~NetworkProcess()
86 {
87 }
88
89 AuthenticationManager& NetworkProcess::authenticationManager()
90 {
91     return *supplement<AuthenticationManager>();
92 }
93
94 DownloadManager& NetworkProcess::downloadManager()
95 {
96     static NeverDestroyed<DownloadManager> downloadManager(this);
97     return downloadManager;
98 }
99
100 void NetworkProcess::removeNetworkConnectionToWebProcess(NetworkConnectionToWebProcess* connection)
101 {
102     size_t vectorIndex = m_webProcessConnections.find(connection);
103     ASSERT(vectorIndex != notFound);
104
105     m_webProcessConnections.remove(vectorIndex);
106 }
107
108 bool NetworkProcess::shouldTerminate()
109 {
110     // Network process keeps session cookies and credentials, so it should never terminate (as long as UI process connection is alive).
111     return false;
112 }
113
114 void NetworkProcess::didReceiveMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder)
115 {
116     if (messageReceiverMap().dispatchMessage(connection, decoder))
117         return;
118
119     didReceiveNetworkProcessMessage(connection, decoder);
120 }
121
122 void NetworkProcess::didReceiveSyncMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder)
123 {
124     messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder);
125 }
126
127 void NetworkProcess::didClose(IPC::Connection&)
128 {
129     // The UIProcess just exited.
130     RunLoop::current().stop();
131 }
132
133 void NetworkProcess::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference)
134 {
135     RunLoop::current().stop();
136 }
137
138 void NetworkProcess::didCreateDownload()
139 {
140     disableTermination();
141 }
142
143 void NetworkProcess::didDestroyDownload()
144 {
145     enableTermination();
146 }
147
148 IPC::Connection* NetworkProcess::downloadProxyConnection()
149 {
150     return parentProcessConnection();
151 }
152
153 AuthenticationManager& NetworkProcess::downloadsAuthenticationManager()
154 {
155     return authenticationManager();
156 }
157
158 void NetworkProcess::initializeNetworkProcess(const NetworkProcessCreationParameters& parameters)
159 {
160     platformInitializeNetworkProcess(parameters);
161
162     WTF::setCurrentThreadIsUserInitiated();
163
164     memoryPressureHandler().setLowMemoryHandler(lowMemoryHandler);
165     memoryPressureHandler().install();
166
167     m_diskCacheIsDisabledForTesting = parameters.shouldUseTestingNetworkSession;
168     setCacheModel(static_cast<uint32_t>(parameters.cacheModel));
169
170     setCanHandleHTTPSServerTrustEvaluation(parameters.canHandleHTTPSServerTrustEvaluation);
171
172 #if PLATFORM(MAC) || USE(CFNETWORK)
173     SessionTracker::setIdentifierBase(parameters.uiProcessBundleIdentifier);
174 #endif
175
176     // FIXME: instead of handling this here, a message should be sent later (scales to multiple sessions)
177     if (parameters.privateBrowsingEnabled)
178         RemoteNetworkingContext::ensurePrivateBrowsingSession(SessionID::legacyPrivateSessionID());
179
180     if (parameters.shouldUseTestingNetworkSession)
181         NetworkStorageSession::switchToNewTestingSession();
182
183     NetworkProcessSupplementMap::const_iterator it = m_supplements.begin();
184     NetworkProcessSupplementMap::const_iterator end = m_supplements.end();
185     for (; it != end; ++it)
186         it->value->initialize(parameters);
187 }
188
189 void NetworkProcess::initializeConnection(IPC::Connection* connection)
190 {
191     ChildProcess::initializeConnection(connection);
192
193 #if ENABLE(SEC_ITEM_SHIM)
194     SecItemShim::shared().initializeConnection(connection);
195 #endif
196
197     NetworkProcessSupplementMap::const_iterator it = m_supplements.begin();
198     NetworkProcessSupplementMap::const_iterator end = m_supplements.end();
199     for (; it != end; ++it)
200         it->value->initializeConnection(connection);
201 }
202
203 void NetworkProcess::createNetworkConnectionToWebProcess()
204 {
205 #if OS(DARWIN)
206     // Create the listening port.
207     mach_port_t listeningPort;
208     mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort);
209
210     // Create a listening connection.
211     RefPtr<NetworkConnectionToWebProcess> connection = NetworkConnectionToWebProcess::create(IPC::Connection::Identifier(listeningPort));
212     m_webProcessConnections.append(connection.release());
213
214     IPC::Attachment clientPort(listeningPort, MACH_MSG_TYPE_MAKE_SEND);
215     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientPort), 0);
216 #elif USE(UNIX_DOMAIN_SOCKETS)
217     IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection();
218
219     RefPtr<NetworkConnectionToWebProcess> connection = NetworkConnectionToWebProcess::create(socketPair.server);
220     m_webProcessConnections.append(connection.release());
221
222     IPC::Attachment clientSocket(socketPair.client);
223     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientSocket), 0);
224 #else
225     notImplemented();
226 #endif
227 }
228
229 void NetworkProcess::ensurePrivateBrowsingSession(SessionID sessionID)
230 {
231     RemoteNetworkingContext::ensurePrivateBrowsingSession(sessionID);
232 }
233
234 void NetworkProcess::destroyPrivateBrowsingSession(SessionID sessionID)
235 {
236     SessionTracker::destroySession(sessionID);
237 }
238
239 void NetworkProcess::deleteWebsiteData(WebCore::SessionID sessionID, uint64_t websiteDataTypes, std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID)
240 {
241     if (websiteDataTypes & WebsiteDataTypeCookies) {
242         if (auto* networkStorageSession = SessionTracker::session(sessionID))
243             deleteAllCookiesModifiedSince(*networkStorageSession, modifiedSince);
244     }
245
246     auto completionHandler = [this, callbackID] {
247         parentProcessConnection()->send(Messages::NetworkProcessProxy::DidDeleteWebsiteData(callbackID), 0);
248     };
249
250     if ((websiteDataTypes & WebsiteDataTypeDiskCache) & !sessionID.isEphemeral()) {
251         clearDiskCache(modifiedSince, WTF::move(completionHandler));
252         return;
253     }
254
255     completionHandler();
256 }
257
258 void NetworkProcess::downloadRequest(uint64_t downloadID, const ResourceRequest& request)
259 {
260     downloadManager().startDownload(downloadID, request);
261 }
262
263 void NetworkProcess::resumeDownload(uint64_t downloadID, const IPC::DataReference& resumeData, const String& path, const WebKit::SandboxExtension::Handle& sandboxExtensionHandle)
264 {
265     downloadManager().resumeDownload(downloadID, resumeData, path, sandboxExtensionHandle);
266 }
267
268 void NetworkProcess::cancelDownload(uint64_t downloadID)
269 {
270     downloadManager().cancelDownload(downloadID);
271 }
272
273 void NetworkProcess::setCacheModel(uint32_t cm)
274 {
275     CacheModel cacheModel = static_cast<CacheModel>(cm);
276
277     if (!m_hasSetCacheModel || cacheModel != m_cacheModel) {
278         m_hasSetCacheModel = true;
279         m_cacheModel = cacheModel;
280         platformSetCacheModel(cacheModel);
281     }
282 }
283
284 void NetworkProcess::setCanHandleHTTPSServerTrustEvaluation(bool value)
285 {
286     m_canHandleHTTPSServerTrustEvaluation = value;
287 }
288
289 void NetworkProcess::getNetworkProcessStatistics(uint64_t callbackID)
290 {
291     NetworkResourceLoadScheduler& scheduler = NetworkProcess::shared().networkResourceLoadScheduler();
292
293     StatisticsData data;
294
295     data.statisticsNumbers.set("LoadsPendingCount", scheduler.loadsPendingCount());
296     data.statisticsNumbers.set("LoadsActiveCount", scheduler.loadsActiveCount());
297     data.statisticsNumbers.set("DownloadsActiveCount", shared().downloadManager().activeDownloadCount());
298     data.statisticsNumbers.set("OutstandingAuthenticationChallengesCount", shared().authenticationManager().outstandingAuthenticationChallengeCount());
299
300     parentProcessConnection()->send(Messages::WebProcessPool::DidGetStatistics(data, callbackID), 0);
301 }
302
303 void NetworkProcess::terminate()
304 {
305     platformTerminate();
306     ChildProcess::terminate();
307 }
308
309 void NetworkProcess::lowMemoryHandler(bool critical)
310 {
311     platformLowMemoryHandler(critical);
312     WTF::releaseFastMallocFreeMemory();
313 }
314
315 #if !PLATFORM(COCOA)
316 void NetworkProcess::initializeProcess(const ChildProcessInitializationParameters&)
317 {
318 }
319
320 void NetworkProcess::initializeProcessName(const ChildProcessInitializationParameters&)
321 {
322 }
323
324 void NetworkProcess::initializeSandbox(const ChildProcessInitializationParameters&, SandboxInitializationParameters&)
325 {
326 }
327
328 void NetworkProcess::platformLowMemoryHandler(bool)
329 {
330 }
331 #endif
332
333 } // namespace WebKit
334
335 #endif // ENABLE(NETWORK_PROCESS)