8f61c1a93fe2c9015c9ac6578007115c8c0bc5dd
[WebKit-https.git] / Source / WebKit2 / NetworkProcess / NetworkConnectionToWebProcess.cpp
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 "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>
45
46 using namespace WebCore;
47
48 namespace WebKit {
49
50 Ref<NetworkConnectionToWebProcess> NetworkConnectionToWebProcess::create(IPC::Connection::Identifier connectionIdentifier)
51 {
52     return adoptRef(*new NetworkConnectionToWebProcess(connectionIdentifier));
53 }
54
55 NetworkConnectionToWebProcess::NetworkConnectionToWebProcess(IPC::Connection::Identifier connectionIdentifier)
56 {
57     m_connection = IPC::Connection::createServerConnection(connectionIdentifier, *this);
58     m_connection->open();
59 }
60
61 NetworkConnectionToWebProcess::~NetworkConnectionToWebProcess()
62 {
63 }
64
65 void NetworkConnectionToWebProcess::didCleanupResourceLoader(NetworkResourceLoader& loader)
66 {
67     ASSERT(m_networkResourceLoaders.get(loader.identifier()) == &loader);
68
69     m_networkResourceLoaders.remove(loader.identifier());
70 }
71     
72 void NetworkConnectionToWebProcess::didReceiveMessage(IPC::Connection& connection, IPC::MessageDecoder& decoder)
73 {
74     if (decoder.messageReceiverName() == Messages::NetworkConnectionToWebProcess::messageReceiverName()) {
75         didReceiveNetworkConnectionToWebProcessMessage(connection, decoder);
76         return;
77     }
78
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);
83         return;
84     }
85     
86     ASSERT_NOT_REACHED();
87 }
88
89 void NetworkConnectionToWebProcess::didReceiveSyncMessage(IPC::Connection& connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& reply)
90 {
91     if (decoder.messageReceiverName() == Messages::NetworkConnectionToWebProcess::messageReceiverName()) {
92         didReceiveSyncNetworkConnectionToWebProcessMessage(connection, decoder, reply);
93         return;
94     }
95     ASSERT_NOT_REACHED();
96 }
97
98 void NetworkConnectionToWebProcess::didClose(IPC::Connection&)
99 {
100     // Protect ourself as we might be otherwise be deleted during this function.
101     Ref<NetworkConnectionToWebProcess> protector(*this);
102
103     Vector<RefPtr<NetworkResourceLoader>> loaders;
104     copyValuesToVector(m_networkResourceLoaders, loaders);
105     for (auto& loader : loaders)
106         loader->abort();
107     ASSERT(m_networkResourceLoaders.isEmpty());
108
109     NetworkBlobRegistry::singleton().connectionToWebProcessDidClose(this);
110     NetworkProcess::singleton().removeNetworkConnectionToWebProcess(this);
111 }
112
113 void NetworkConnectionToWebProcess::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference)
114 {
115 }
116
117 void NetworkConnectionToWebProcess::scheduleResourceLoad(const NetworkResourceLoadParameters& loadParameters)
118 {
119     auto loader = NetworkResourceLoader::create(loadParameters, *this);
120     m_networkResourceLoaders.add(loadParameters.identifier, loader.ptr());
121     loader->start();
122 }
123
124 void NetworkConnectionToWebProcess::performSynchronousLoad(const NetworkResourceLoadParameters& loadParameters, RefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply>&& reply)
125 {
126     auto loader = NetworkResourceLoader::create(loadParameters, *this, WTF::move(reply));
127     m_networkResourceLoaders.add(loadParameters.identifier, loader.ptr());
128     loader->start();
129 }
130
131 void NetworkConnectionToWebProcess::loadPing(const NetworkResourceLoadParameters& loadParameters)
132 {
133     RefPtr<NetworkingContext> context = RemoteNetworkingContext::create(loadParameters.sessionID, loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect);
134
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);
137 }
138
139 void NetworkConnectionToWebProcess::removeLoadIdentifier(ResourceLoadIdentifier identifier)
140 {
141     RefPtr<NetworkResourceLoader> loader = m_networkResourceLoaders.get(identifier);
142
143     // It's possible we have no loader for this identifier if the NetworkProcess crashed and this was a respawned NetworkProcess.
144     if (!loader)
145         return;
146
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).
149     loader->abort();
150     ASSERT(!m_networkResourceLoaders.contains(identifier));
151 }
152
153 void NetworkConnectionToWebProcess::setDefersLoading(ResourceLoadIdentifier identifier, bool defers)
154 {
155     RefPtr<NetworkResourceLoader> loader = m_networkResourceLoaders.get(identifier);
156     if (!loader)
157         return;
158
159     loader->setDefersLoading(defers);
160 }
161
162 void NetworkConnectionToWebProcess::prefetchDNS(const String& hostname)
163 {
164     NetworkProcess::singleton().prefetchDNS(hostname);
165 }
166
167 static NetworkStorageSession& storageSession(SessionID sessionID)
168 {
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.");
176     }
177     return NetworkStorageSession::defaultStorageSession();
178 }
179
180 void NetworkConnectionToWebProcess::startDownload(SessionID sessionID, uint64_t downloadID, const ResourceRequest& request)
181 {
182     NetworkProcess::singleton().downloadManager().startDownload(sessionID, downloadID, request);
183 }
184
185 void NetworkConnectionToWebProcess::convertMainResourceLoadToDownload(WebCore::SessionID sessionID, uint64_t mainResourceLoadIdentifier, uint64_t downloadID, const ResourceRequest& request, const ResourceResponse& response)
186 {
187     auto& networkProcess = NetworkProcess::singleton();
188     if (!mainResourceLoadIdentifier) {
189         networkProcess.downloadManager().startDownload(sessionID, downloadID, request);
190         return;
191     }
192
193     NetworkResourceLoader* loader = m_networkResourceLoaders.get(mainResourceLoadIdentifier);
194     if (!loader) {
195         // If we're trying to download a blob here loader can be null.
196         return;
197     }
198
199 #if USE(NETWORK_SESSION)
200     loader->networkLoad()->convertTaskToDownload();
201 #else
202     networkProcess.downloadManager().convertHandleToDownload(downloadID, loader->networkLoad()->handle(), request, response);
203
204     // Unblock the URL connection operation queue.
205     loader->networkLoad()->handle()->continueDidReceiveResponse();
206     
207     loader->didConvertToDownload();
208 #endif
209 }
210
211 void NetworkConnectionToWebProcess::cookiesForDOM(SessionID sessionID, const URL& firstParty, const URL& url, String& result)
212 {
213     result = WebCore::cookiesForDOM(storageSession(sessionID), firstParty, url);
214 }
215
216 void NetworkConnectionToWebProcess::setCookiesFromDOM(SessionID sessionID, const URL& firstParty, const URL& url, const String& cookieString)
217 {
218     WebCore::setCookiesFromDOM(storageSession(sessionID), firstParty, url, cookieString);
219 }
220
221 void NetworkConnectionToWebProcess::cookiesEnabled(SessionID sessionID, const URL& firstParty, const URL& url, bool& result)
222 {
223     result = WebCore::cookiesEnabled(storageSession(sessionID), firstParty, url);
224 }
225
226 void NetworkConnectionToWebProcess::cookieRequestHeaderFieldValue(SessionID sessionID, const URL& firstParty, const URL& url, String& result)
227 {
228     result = WebCore::cookieRequestHeaderFieldValue(storageSession(sessionID), firstParty, url);
229 }
230
231 void NetworkConnectionToWebProcess::getRawCookies(SessionID sessionID, const URL& firstParty, const URL& url, Vector<Cookie>& result)
232 {
233     WebCore::getRawCookies(storageSession(sessionID), firstParty, url, result);
234 }
235
236 void NetworkConnectionToWebProcess::deleteCookie(SessionID sessionID, const URL& url, const String& cookieName)
237 {
238     WebCore::deleteCookie(storageSession(sessionID), url, cookieName);
239 }
240
241 void NetworkConnectionToWebProcess::registerFileBlobURL(const URL& url, const String& path, const SandboxExtension::Handle& extensionHandle, const String& contentType)
242 {
243     RefPtr<SandboxExtension> extension = SandboxExtension::create(extensionHandle);
244
245     NetworkBlobRegistry::singleton().registerFileBlobURL(this, url, path, extension.release(), contentType);
246 }
247
248 void NetworkConnectionToWebProcess::registerBlobURL(const URL& url, Vector<BlobPart> blobParts, const String& contentType)
249 {
250     NetworkBlobRegistry::singleton().registerBlobURL(this, url, WTF::move(blobParts), contentType);
251 }
252
253 void NetworkConnectionToWebProcess::registerBlobURLFromURL(const URL& url, const URL& srcURL)
254 {
255     NetworkBlobRegistry::singleton().registerBlobURL(this, url, srcURL);
256 }
257
258 void NetworkConnectionToWebProcess::registerBlobURLForSlice(const URL& url, const URL& srcURL, int64_t start, int64_t end)
259 {
260     NetworkBlobRegistry::singleton().registerBlobURLForSlice(this, url, srcURL, start, end);
261 }
262
263 void NetworkConnectionToWebProcess::unregisterBlobURL(const URL& url)
264 {
265     NetworkBlobRegistry::singleton().unregisterBlobURL(this, url);
266 }
267
268 void NetworkConnectionToWebProcess::blobSize(const URL& url, uint64_t& resultSize)
269 {
270     resultSize = NetworkBlobRegistry::singleton().blobSize(this, url);
271 }
272
273 } // namespace WebKit