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