2 * Copyright (C) 2012 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "NetworkConnectionToWebProcess.h"
29 #include "NetworkBlobRegistry.h"
30 #include "NetworkConnectionToWebProcessMessages.h"
31 #include "NetworkLoad.h"
32 #include "NetworkProcess.h"
33 #include "NetworkResourceLoadParameters.h"
34 #include "NetworkResourceLoader.h"
35 #include "NetworkResourceLoaderMessages.h"
36 #include "RemoteNetworkingContext.h"
37 #include "SessionTracker.h"
38 #include <WebCore/NotImplemented.h>
39 #include <WebCore/PingHandle.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>
46 using namespace WebCore;
50 Ref<NetworkConnectionToWebProcess> NetworkConnectionToWebProcess::create(IPC::Connection::Identifier connectionIdentifier)
52 return adoptRef(*new NetworkConnectionToWebProcess(connectionIdentifier));
55 NetworkConnectionToWebProcess::NetworkConnectionToWebProcess(IPC::Connection::Identifier connectionIdentifier)
57 m_connection = IPC::Connection::createServerConnection(connectionIdentifier, *this);
61 NetworkConnectionToWebProcess::~NetworkConnectionToWebProcess()
65 void NetworkConnectionToWebProcess::didCleanupResourceLoader(NetworkResourceLoader& loader)
67 ASSERT(m_networkResourceLoaders.get(loader.identifier()) == &loader);
69 m_networkResourceLoaders.remove(loader.identifier());
72 void NetworkConnectionToWebProcess::didReceiveMessage(IPC::Connection& connection, IPC::MessageDecoder& decoder)
74 if (decoder.messageReceiverName() == Messages::NetworkConnectionToWebProcess::messageReceiverName()) {
75 didReceiveNetworkConnectionToWebProcessMessage(connection, decoder);
79 if (decoder.messageReceiverName() == Messages::NetworkResourceLoader::messageReceiverName()) {
80 HashMap<ResourceLoadIdentifier, RefPtr<NetworkResourceLoader>>::iterator loaderIterator = m_networkResourceLoaders.find(decoder.destinationID());
81 if (loaderIterator != m_networkResourceLoaders.end())
82 loaderIterator->value->didReceiveNetworkResourceLoaderMessage(connection, decoder);
89 void NetworkConnectionToWebProcess::didReceiveSyncMessage(IPC::Connection& connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& reply)
91 if (decoder.messageReceiverName() == Messages::NetworkConnectionToWebProcess::messageReceiverName()) {
92 didReceiveSyncNetworkConnectionToWebProcessMessage(connection, decoder, reply);
98 void NetworkConnectionToWebProcess::didClose(IPC::Connection&)
100 // Protect ourself as we might be otherwise be deleted during this function.
101 Ref<NetworkConnectionToWebProcess> protector(*this);
103 Vector<RefPtr<NetworkResourceLoader>> loaders;
104 copyValuesToVector(m_networkResourceLoaders, loaders);
105 for (auto& loader : loaders)
107 ASSERT(m_networkResourceLoaders.isEmpty());
109 NetworkBlobRegistry::singleton().connectionToWebProcessDidClose(this);
110 NetworkProcess::singleton().removeNetworkConnectionToWebProcess(this);
113 void NetworkConnectionToWebProcess::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference)
117 void NetworkConnectionToWebProcess::scheduleResourceLoad(const NetworkResourceLoadParameters& loadParameters)
119 auto loader = NetworkResourceLoader::create(loadParameters, *this);
120 m_networkResourceLoaders.add(loadParameters.identifier, loader.ptr());
124 void NetworkConnectionToWebProcess::performSynchronousLoad(const NetworkResourceLoadParameters& loadParameters, RefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply>&& reply)
126 auto loader = NetworkResourceLoader::create(loadParameters, *this, WTF::move(reply));
127 m_networkResourceLoaders.add(loadParameters.identifier, loader.ptr());
131 void NetworkConnectionToWebProcess::loadPing(const NetworkResourceLoadParameters& loadParameters)
133 RefPtr<NetworkingContext> context = RemoteNetworkingContext::create(loadParameters.sessionID, loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect);
135 // PingHandle manages its own lifetime, deleting itself when its purpose has been fulfilled.
136 new PingHandle(context.get(), loadParameters.request, loadParameters.allowStoredCredentials == AllowStoredCredentials, PingHandle::UsesAsyncCallbacks::Yes);
139 void NetworkConnectionToWebProcess::removeLoadIdentifier(ResourceLoadIdentifier identifier)
141 RefPtr<NetworkResourceLoader> loader = m_networkResourceLoaders.get(identifier);
143 // It's possible we have no loader for this identifier if the NetworkProcess crashed and this was a respawned NetworkProcess.
147 // Abort the load now, as the WebProcess won't be able to respond to messages any more which might lead
148 // to leaked loader resources (connections, threads, etc).
150 ASSERT(!m_networkResourceLoaders.contains(identifier));
153 void NetworkConnectionToWebProcess::setDefersLoading(ResourceLoadIdentifier identifier, bool defers)
155 RefPtr<NetworkResourceLoader> loader = m_networkResourceLoaders.get(identifier);
159 loader->setDefersLoading(defers);
162 void NetworkConnectionToWebProcess::prefetchDNS(const String& hostname)
164 NetworkProcess::singleton().prefetchDNS(hostname);
167 static NetworkStorageSession& storageSession(SessionID sessionID)
169 if (sessionID.isEphemeral()) {
170 NetworkStorageSession* privateStorageSession = SessionTracker::storageSession(sessionID);
171 if (privateStorageSession)
172 return *privateStorageSession;
173 // Some requests with private browsing mode requested may still be coming shortly after NetworkProcess was told to destroy its session.
174 // FIXME: Find a way to track private browsing sessions more rigorously.
175 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.");
177 return NetworkStorageSession::defaultStorageSession();
180 void NetworkConnectionToWebProcess::startDownload(SessionID sessionID, uint64_t downloadID, const ResourceRequest& request)
182 NetworkProcess::singleton().downloadManager().startDownload(sessionID, downloadID, request);
185 void NetworkConnectionToWebProcess::convertMainResourceLoadToDownload(WebCore::SessionID sessionID, uint64_t mainResourceLoadIdentifier, uint64_t downloadID, const ResourceRequest& request, const ResourceResponse& response)
187 auto& networkProcess = NetworkProcess::singleton();
188 if (!mainResourceLoadIdentifier) {
189 networkProcess.downloadManager().startDownload(sessionID, downloadID, request);
193 NetworkResourceLoader* loader = m_networkResourceLoaders.get(mainResourceLoadIdentifier);
195 // If we're trying to download a blob here loader can be null.
199 #if USE(NETWORK_SESSION)
200 loader->networkLoad()->convertTaskToDownload();
202 networkProcess.downloadManager().convertHandleToDownload(downloadID, loader->networkLoad()->handle(), request, response);
204 // Unblock the URL connection operation queue.
205 loader->networkLoad()->handle()->continueDidReceiveResponse();
207 loader->didConvertToDownload();
211 void NetworkConnectionToWebProcess::cookiesForDOM(SessionID sessionID, const URL& firstParty, const URL& url, String& result)
213 result = WebCore::cookiesForDOM(storageSession(sessionID), firstParty, url);
216 void NetworkConnectionToWebProcess::setCookiesFromDOM(SessionID sessionID, const URL& firstParty, const URL& url, const String& cookieString)
218 WebCore::setCookiesFromDOM(storageSession(sessionID), firstParty, url, cookieString);
221 void NetworkConnectionToWebProcess::cookiesEnabled(SessionID sessionID, const URL& firstParty, const URL& url, bool& result)
223 result = WebCore::cookiesEnabled(storageSession(sessionID), firstParty, url);
226 void NetworkConnectionToWebProcess::cookieRequestHeaderFieldValue(SessionID sessionID, const URL& firstParty, const URL& url, String& result)
228 result = WebCore::cookieRequestHeaderFieldValue(storageSession(sessionID), firstParty, url);
231 void NetworkConnectionToWebProcess::getRawCookies(SessionID sessionID, const URL& firstParty, const URL& url, Vector<Cookie>& result)
233 WebCore::getRawCookies(storageSession(sessionID), firstParty, url, result);
236 void NetworkConnectionToWebProcess::deleteCookie(SessionID sessionID, const URL& url, const String& cookieName)
238 WebCore::deleteCookie(storageSession(sessionID), url, cookieName);
241 void NetworkConnectionToWebProcess::registerFileBlobURL(const URL& url, const String& path, const SandboxExtension::Handle& extensionHandle, const String& contentType)
243 RefPtr<SandboxExtension> extension = SandboxExtension::create(extensionHandle);
245 NetworkBlobRegistry::singleton().registerFileBlobURL(this, url, path, extension.release(), contentType);
248 void NetworkConnectionToWebProcess::registerBlobURL(const URL& url, Vector<BlobPart> blobParts, const String& contentType)
250 NetworkBlobRegistry::singleton().registerBlobURL(this, url, WTF::move(blobParts), contentType);
253 void NetworkConnectionToWebProcess::registerBlobURLFromURL(const URL& url, const URL& srcURL)
255 NetworkBlobRegistry::singleton().registerBlobURL(this, url, srcURL);
258 void NetworkConnectionToWebProcess::registerBlobURLForSlice(const URL& url, const URL& srcURL, int64_t start, int64_t end)
260 NetworkBlobRegistry::singleton().registerBlobURLForSlice(this, url, srcURL, start, end);
263 void NetworkConnectionToWebProcess::unregisterBlobURL(const URL& url)
265 NetworkBlobRegistry::singleton().unregisterBlobURL(this, url);
268 void NetworkConnectionToWebProcess::blobSize(const URL& url, uint64_t& resultSize)
270 resultSize = NetworkBlobRegistry::singleton().blobSize(this, url);
273 } // namespace WebKit