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