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 "NetworkProcessProxy.h" 28 29#if ENABLE(NETWORK_PROCESS) 30 31#include "AuthenticationChallengeProxy.h" 32#include "CustomProtocolManagerProxyMessages.h" 33#include "DownloadProxyMessages.h" 34#include "NetworkProcessCreationParameters.h" 35#include "NetworkProcessMessages.h" 36#include "WebContext.h" 37#include "WebProcessMessages.h" 38#include <wtf/RunLoop.h> 39 40#if ENABLE(SEC_ITEM_SHIM) 41#include "SecItemShimProxy.h" 42#endif 43 44#define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, connection()) 45 46using namespace WebCore; 47 48namespace WebKit { 49 50PassRefPtr<NetworkProcessProxy> NetworkProcessProxy::create(WebContext& webContext) 51{ 52 return adoptRef(new NetworkProcessProxy(webContext)); 53} 54 55NetworkProcessProxy::NetworkProcessProxy(WebContext& webContext) 56 : m_webContext(webContext) 57 , m_numPendingConnectionRequests(0) 58#if ENABLE(CUSTOM_PROTOCOLS) 59 , m_customProtocolManagerProxy(this, webContext) 60#endif 61{ 62 connect(); 63} 64 65NetworkProcessProxy::~NetworkProcessProxy() 66{ 67} 68 69void NetworkProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions) 70{ 71 launchOptions.processType = ProcessLauncher::NetworkProcess; 72 platformGetLaunchOptions(launchOptions); 73} 74 75void NetworkProcessProxy::connectionWillOpen(IPC::Connection* connection) 76{ 77#if ENABLE(SEC_ITEM_SHIM) 78 SecItemShimProxy::shared().initializeConnection(connection); 79#else 80 UNUSED_PARAM(connection); 81#endif 82} 83 84void NetworkProcessProxy::connectionWillClose(IPC::Connection*) 85{ 86} 87 88void NetworkProcessProxy::getNetworkProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply> reply) 89{ 90 m_pendingConnectionReplies.append(reply); 91 92 if (state() == State::Launching) { 93 m_numPendingConnectionRequests++; 94 return; 95 } 96 97 connection()->send(Messages::NetworkProcess::CreateNetworkConnectionToWebProcess(), 0, IPC::DispatchMessageEvenWhenWaitingForSyncReply); 98} 99 100DownloadProxy* NetworkProcessProxy::createDownloadProxy() 101{ 102 if (!m_downloadProxyMap) 103 m_downloadProxyMap = std::make_unique<DownloadProxyMap>(this); 104 105 return m_downloadProxyMap->createDownloadProxy(m_webContext); 106} 107 108void NetworkProcessProxy::networkProcessCrashedOrFailedToLaunch() 109{ 110 // The network process must have crashed or exited, send any pending sync replies we might have. 111 while (!m_pendingConnectionReplies.isEmpty()) { 112 RefPtr<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply> reply = m_pendingConnectionReplies.takeFirst(); 113 114#if OS(DARWIN) 115 reply->send(IPC::Attachment(0, MACH_MSG_TYPE_MOVE_SEND)); 116#elif USE(UNIX_DOMAIN_SOCKETS) 117 reply->send(IPC::Attachment()); 118#else 119 notImplemented(); 120#endif 121 } 122 123 // Tell the network process manager to forget about this network process proxy. This may cause us to be deleted. 124 m_webContext.networkProcessCrashed(this); 125} 126 127void NetworkProcessProxy::didReceiveMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder) 128{ 129 if (dispatchMessage(connection, decoder)) 130 return; 131 132 if (m_webContext.dispatchMessage(connection, decoder)) 133 return; 134 135 didReceiveNetworkProcessProxyMessage(connection, decoder); 136} 137 138void NetworkProcessProxy::didReceiveSyncMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder) 139{ 140 if (dispatchSyncMessage(connection, decoder, replyEncoder)) 141 return; 142 143 ASSERT_NOT_REACHED(); 144} 145 146void NetworkProcessProxy::didClose(IPC::Connection*) 147{ 148 if (m_downloadProxyMap) 149 m_downloadProxyMap->processDidClose(); 150 151 // This may cause us to be deleted. 152 networkProcessCrashedOrFailedToLaunch(); 153} 154 155void NetworkProcessProxy::didReceiveInvalidMessage(IPC::Connection*, IPC::StringReference, IPC::StringReference) 156{ 157} 158 159void NetworkProcessProxy::didCreateNetworkConnectionToWebProcess(const IPC::Attachment& connectionIdentifier) 160{ 161 ASSERT(!m_pendingConnectionReplies.isEmpty()); 162 163 // Grab the first pending connection reply. 164 RefPtr<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply> reply = m_pendingConnectionReplies.takeFirst(); 165 166#if OS(DARWIN) 167 reply->send(IPC::Attachment(connectionIdentifier.port(), MACH_MSG_TYPE_MOVE_SEND)); 168#elif USE(UNIX_DOMAIN_SOCKETS) 169 reply->send(connectionIdentifier); 170#else 171 notImplemented(); 172#endif 173} 174 175void NetworkProcessProxy::didReceiveAuthenticationChallenge(uint64_t pageID, uint64_t frameID, const WebCore::AuthenticationChallenge& coreChallenge, uint64_t challengeID) 176{ 177 WebPageProxy* page = WebProcessProxy::webPage(pageID); 178 MESSAGE_CHECK(page); 179 180 RefPtr<AuthenticationChallengeProxy> authenticationChallenge = AuthenticationChallengeProxy::create(coreChallenge, challengeID, connection()); 181 page->didReceiveAuthenticationChallengeProxy(frameID, authenticationChallenge.release()); 182} 183 184void NetworkProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Connection::Identifier connectionIdentifier) 185{ 186 ChildProcessProxy::didFinishLaunching(launcher, connectionIdentifier); 187 188 if (IPC::Connection::identifierIsNull(connectionIdentifier)) { 189 // FIXME: Do better cleanup here. 190 return; 191 } 192 193 for (unsigned i = 0; i < m_numPendingConnectionRequests; ++i) 194 connection()->send(Messages::NetworkProcess::CreateNetworkConnectionToWebProcess(), 0); 195 196 m_numPendingConnectionRequests = 0; 197 198#if PLATFORM(COCOA) 199 if (m_webContext.processSuppressionEnabled()) 200 setProcessSuppressionEnabled(true); 201#endif 202 203#if PLATFORM(IOS) && USE(XPC_SERVICES) 204 if (xpc_connection_t connection = this->connection()->xpcConnection()) 205 m_assertion = std::make_unique<ProcessAssertion>(xpc_connection_get_pid(connection), AssertionState::Foreground); 206#endif 207} 208 209} // namespace WebKit 210 211#endif // ENABLE(NETWORK_PROCESS) 212