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 "NetworkConnectionToWebProcess.h" 28 29#if ENABLE(NETWORK_PROCESS) 30 31#include "ConnectionStack.h" 32#include "NetworkBlobRegistry.h" 33#include "NetworkConnectionToWebProcessMessages.h" 34#include "NetworkProcess.h" 35#include "NetworkResourceLoadParameters.h" 36#include "NetworkResourceLoader.h" 37#include "NetworkResourceLoaderMessages.h" 38#include "RemoteNetworkingContext.h" 39#include "SessionTracker.h" 40#include <WebCore/PlatformCookieJar.h> 41#include <WebCore/ResourceLoaderOptions.h> 42#include <WebCore/ResourceRequest.h> 43#include <WebCore/SessionID.h> 44#include <wtf/RunLoop.h> 45 46using namespace WebCore; 47 48namespace WebKit { 49 50PassRefPtr<NetworkConnectionToWebProcess> NetworkConnectionToWebProcess::create(IPC::Connection::Identifier connectionIdentifier) 51{ 52 return adoptRef(new NetworkConnectionToWebProcess(connectionIdentifier)); 53} 54 55NetworkConnectionToWebProcess::NetworkConnectionToWebProcess(IPC::Connection::Identifier connectionIdentifier) 56 : m_serialLoadingEnabled(false) 57{ 58 m_connection = IPC::Connection::createServerConnection(connectionIdentifier, this, RunLoop::main()); 59 m_connection->open(); 60} 61 62NetworkConnectionToWebProcess::~NetworkConnectionToWebProcess() 63{ 64} 65 66void NetworkConnectionToWebProcess::didReceiveMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder) 67{ 68 if (decoder.messageReceiverName() == Messages::NetworkConnectionToWebProcess::messageReceiverName()) { 69 didReceiveNetworkConnectionToWebProcessMessage(connection, decoder); 70 return; 71 } 72 73 if (decoder.messageReceiverName() == Messages::NetworkResourceLoader::messageReceiverName()) { 74 HashMap<ResourceLoadIdentifier, RefPtr<NetworkResourceLoader>>::iterator loaderIterator = m_networkResourceLoaders.find(decoder.destinationID()); 75 if (loaderIterator != m_networkResourceLoaders.end()) 76 loaderIterator->value->didReceiveNetworkResourceLoaderMessage(connection, decoder); 77 return; 78 } 79 80 ASSERT_NOT_REACHED(); 81} 82 83void NetworkConnectionToWebProcess::didReceiveSyncMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& reply) 84{ 85 if (decoder.messageReceiverName() == Messages::NetworkConnectionToWebProcess::messageReceiverName()) { 86 didReceiveSyncNetworkConnectionToWebProcessMessage(connection, decoder, reply); 87 return; 88 } 89 ASSERT_NOT_REACHED(); 90} 91 92void NetworkConnectionToWebProcess::didClose(IPC::Connection*) 93{ 94 // Protect ourself as we might be otherwise be deleted during this function. 95 Ref<NetworkConnectionToWebProcess> protector(*this); 96 97 HashMap<ResourceLoadIdentifier, RefPtr<NetworkResourceLoader>>::iterator end = m_networkResourceLoaders.end(); 98 for (HashMap<ResourceLoadIdentifier, RefPtr<NetworkResourceLoader>>::iterator i = m_networkResourceLoaders.begin(); i != end; ++i) 99 i->value->abort(); 100 101 NetworkBlobRegistry::shared().connectionToWebProcessDidClose(this); 102 103 m_networkResourceLoaders.clear(); 104 105 NetworkProcess::shared().removeNetworkConnectionToWebProcess(this); 106} 107 108void NetworkConnectionToWebProcess::didReceiveInvalidMessage(IPC::Connection*, IPC::StringReference, IPC::StringReference) 109{ 110} 111 112void NetworkConnectionToWebProcess::scheduleResourceLoad(const NetworkResourceLoadParameters& loadParameters) 113{ 114 RefPtr<NetworkResourceLoader> loader = NetworkResourceLoader::create(loadParameters, this); 115 m_networkResourceLoaders.add(loadParameters.identifier, loader); 116 NetworkProcess::shared().networkResourceLoadScheduler().scheduleLoader(loader.get()); 117} 118 119void NetworkConnectionToWebProcess::performSynchronousLoad(const NetworkResourceLoadParameters& loadParameters, PassRefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply> reply) 120{ 121 RefPtr<NetworkResourceLoader> loader = NetworkResourceLoader::create(loadParameters, this, reply); 122 m_networkResourceLoaders.add(loadParameters.identifier, loader); 123 NetworkProcess::shared().networkResourceLoadScheduler().scheduleLoader(loader.get()); 124} 125 126void NetworkConnectionToWebProcess::removeLoadIdentifier(ResourceLoadIdentifier identifier) 127{ 128 RefPtr<NetworkResourceLoader> loader = m_networkResourceLoaders.take(identifier); 129 130 // It's possible we have no loader for this identifier if the NetworkProcess crashed and this was a respawned NetworkProcess. 131 if (!loader) 132 return; 133 134 // Abort the load now, as the WebProcess won't be able to respond to messages any more which might lead 135 // to leaked loader resources (connections, threads, etc). 136 loader->abort(); 137} 138 139void NetworkConnectionToWebProcess::setDefersLoading(ResourceLoadIdentifier identifier, bool defers) 140{ 141 RefPtr<NetworkResourceLoader> loader = m_networkResourceLoaders.get(identifier); 142 if (!loader) 143 return; 144 145 loader->setDefersLoading(defers); 146} 147 148void NetworkConnectionToWebProcess::servePendingRequests(uint32_t resourceLoadPriority) 149{ 150 NetworkProcess::shared().networkResourceLoadScheduler().servePendingRequests(static_cast<ResourceLoadPriority>(resourceLoadPriority)); 151} 152 153void NetworkConnectionToWebProcess::setSerialLoadingEnabled(bool enabled) 154{ 155 m_serialLoadingEnabled = enabled; 156} 157 158static NetworkStorageSession& storageSession(SessionID sessionID) 159{ 160 if (sessionID.isEphemeral()) { 161 NetworkStorageSession* privateSession = SessionTracker::session(sessionID); 162 if (privateSession) 163 return *privateSession; 164 // Some requests with private browsing mode requested may still be coming shortly after NetworkProcess was told to destroy its session. 165 // FIXME: Find a way to track private browsing sessions more rigorously. 166 LOG_ERROR("Private browsing was requested, but there was no session for it. Please file a bug unless you just disabled private browsing, in which case it's an expected race."); 167 } 168 return NetworkStorageSession::defaultStorageSession(); 169} 170 171void NetworkConnectionToWebProcess::startDownload(SessionID, uint64_t downloadID, const ResourceRequest& request) 172{ 173 // FIXME: Do something with the session ID. 174 NetworkProcess::shared().downloadManager().startDownload(downloadID, request); 175} 176 177void NetworkConnectionToWebProcess::convertMainResourceLoadToDownload(uint64_t mainResourceLoadIdentifier, uint64_t downloadID, const ResourceRequest& request, const ResourceResponse& response) 178{ 179 if (!mainResourceLoadIdentifier) { 180 NetworkProcess::shared().downloadManager().startDownload(downloadID, request); 181 return; 182 } 183 184 NetworkResourceLoader* loader = m_networkResourceLoaders.get(mainResourceLoadIdentifier); 185 NetworkProcess::shared().downloadManager().convertHandleToDownload(downloadID, loader->handle(), request, response); 186 187 // Unblock the URL connection operation queue. 188 loader->handle()->continueDidReceiveResponse(); 189 190 loader->didConvertHandleToDownload(); 191} 192 193void NetworkConnectionToWebProcess::cookiesForDOM(SessionID sessionID, const URL& firstParty, const URL& url, String& result) 194{ 195 result = WebCore::cookiesForDOM(storageSession(sessionID), firstParty, url); 196} 197 198void NetworkConnectionToWebProcess::setCookiesFromDOM(SessionID sessionID, const URL& firstParty, const URL& url, const String& cookieString) 199{ 200 WebCore::setCookiesFromDOM(storageSession(sessionID), firstParty, url, cookieString); 201} 202 203void NetworkConnectionToWebProcess::cookiesEnabled(SessionID sessionID, const URL& firstParty, const URL& url, bool& result) 204{ 205 result = WebCore::cookiesEnabled(storageSession(sessionID), firstParty, url); 206} 207 208void NetworkConnectionToWebProcess::cookieRequestHeaderFieldValue(SessionID sessionID, const URL& firstParty, const URL& url, String& result) 209{ 210 result = WebCore::cookieRequestHeaderFieldValue(storageSession(sessionID), firstParty, url); 211} 212 213void NetworkConnectionToWebProcess::getRawCookies(SessionID sessionID, const URL& firstParty, const URL& url, Vector<Cookie>& result) 214{ 215 WebCore::getRawCookies(storageSession(sessionID), firstParty, url, result); 216} 217 218void NetworkConnectionToWebProcess::deleteCookie(SessionID sessionID, const URL& url, const String& cookieName) 219{ 220 WebCore::deleteCookie(storageSession(sessionID), url, cookieName); 221} 222 223void NetworkConnectionToWebProcess::registerFileBlobURL(const URL& url, const String& path, const SandboxExtension::Handle& extensionHandle, const String& contentType) 224{ 225 RefPtr<SandboxExtension> extension = SandboxExtension::create(extensionHandle); 226 227 NetworkBlobRegistry::shared().registerFileBlobURL(this, url, path, extension.release(), contentType); 228} 229 230void NetworkConnectionToWebProcess::registerBlobURL(const URL& url, Vector<BlobPart> blobParts, const String& contentType) 231{ 232 NetworkBlobRegistry::shared().registerBlobURL(this, url, WTF::move(blobParts), contentType); 233} 234 235void NetworkConnectionToWebProcess::registerBlobURLFromURL(const URL& url, const URL& srcURL) 236{ 237 NetworkBlobRegistry::shared().registerBlobURL(this, url, srcURL); 238} 239 240void NetworkConnectionToWebProcess::registerBlobURLForSlice(const URL& url, const URL& srcURL, int64_t start, int64_t end) 241{ 242 NetworkBlobRegistry::shared().registerBlobURLForSlice(this, url, srcURL, start, end); 243} 244 245void NetworkConnectionToWebProcess::unregisterBlobURL(const URL& url) 246{ 247 NetworkBlobRegistry::shared().unregisterBlobURL(this, url); 248} 249 250void NetworkConnectionToWebProcess::blobSize(const URL& url, uint64_t& resultSize) 251{ 252 resultSize = NetworkBlobRegistry::shared().blobSize(this, url); 253} 254 255} // namespace WebKit 256 257#endif // ENABLE(NETWORK_PROCESS) 258