Use NetworkSession for pings
[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 #if USE(NETWORK_SESSION)
47 #include "PingLoad.h"
48 #endif
49
50 using namespace WebCore;
51
52 namespace WebKit {
53
54 Ref<NetworkConnectionToWebProcess> NetworkConnectionToWebProcess::create(IPC::Connection::Identifier connectionIdentifier)
55 {
56     return adoptRef(*new NetworkConnectionToWebProcess(connectionIdentifier));
57 }
58
59 NetworkConnectionToWebProcess::NetworkConnectionToWebProcess(IPC::Connection::Identifier connectionIdentifier)
60 {
61     m_connection = IPC::Connection::createServerConnection(connectionIdentifier, *this);
62     m_connection->open();
63 }
64
65 NetworkConnectionToWebProcess::~NetworkConnectionToWebProcess()
66 {
67 }
68
69 void NetworkConnectionToWebProcess::didCleanupResourceLoader(NetworkResourceLoader& loader)
70 {
71     ASSERT(m_networkResourceLoaders.get(loader.identifier()) == &loader);
72
73     m_networkResourceLoaders.remove(loader.identifier());
74 }
75     
76 void NetworkConnectionToWebProcess::didReceiveMessage(IPC::Connection& connection, IPC::MessageDecoder& decoder)
77 {
78     if (decoder.messageReceiverName() == Messages::NetworkConnectionToWebProcess::messageReceiverName()) {
79         didReceiveNetworkConnectionToWebProcessMessage(connection, decoder);
80         return;
81     }
82
83     if (decoder.messageReceiverName() == Messages::NetworkResourceLoader::messageReceiverName()) {
84         HashMap<ResourceLoadIdentifier, RefPtr<NetworkResourceLoader>>::iterator loaderIterator = m_networkResourceLoaders.find(decoder.destinationID());
85         if (loaderIterator != m_networkResourceLoaders.end())
86             loaderIterator->value->didReceiveNetworkResourceLoaderMessage(connection, decoder);
87         return;
88     }
89     
90     ASSERT_NOT_REACHED();
91 }
92
93 void NetworkConnectionToWebProcess::didReceiveSyncMessage(IPC::Connection& connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& reply)
94 {
95     if (decoder.messageReceiverName() == Messages::NetworkConnectionToWebProcess::messageReceiverName()) {
96         didReceiveSyncNetworkConnectionToWebProcessMessage(connection, decoder, reply);
97         return;
98     }
99     ASSERT_NOT_REACHED();
100 }
101
102 void NetworkConnectionToWebProcess::didClose(IPC::Connection&)
103 {
104     // Protect ourself as we might be otherwise be deleted during this function.
105     Ref<NetworkConnectionToWebProcess> protector(*this);
106
107     Vector<RefPtr<NetworkResourceLoader>> loaders;
108     copyValuesToVector(m_networkResourceLoaders, loaders);
109     for (auto& loader : loaders)
110         loader->abort();
111     ASSERT(m_networkResourceLoaders.isEmpty());
112
113     NetworkBlobRegistry::singleton().connectionToWebProcessDidClose(this);
114     NetworkProcess::singleton().removeNetworkConnectionToWebProcess(this);
115 }
116
117 void NetworkConnectionToWebProcess::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference)
118 {
119 }
120
121 void NetworkConnectionToWebProcess::scheduleResourceLoad(const NetworkResourceLoadParameters& loadParameters)
122 {
123     auto loader = NetworkResourceLoader::create(loadParameters, *this);
124     m_networkResourceLoaders.add(loadParameters.identifier, loader.ptr());
125     loader->start();
126 }
127
128 void NetworkConnectionToWebProcess::performSynchronousLoad(const NetworkResourceLoadParameters& loadParameters, RefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply>&& reply)
129 {
130     auto loader = NetworkResourceLoader::create(loadParameters, *this, WTFMove(reply));
131     m_networkResourceLoaders.add(loadParameters.identifier, loader.ptr());
132     loader->start();
133 }
134
135 void NetworkConnectionToWebProcess::loadPing(const NetworkResourceLoadParameters& loadParameters)
136 {
137 #if USE(NETWORK_SESSION)
138     // PingLoad manages its own lifetime, deleting itself when its purpose has been fulfilled.
139     new PingLoad(loadParameters);
140 #else
141     RefPtr<NetworkingContext> context = RemoteNetworkingContext::create(loadParameters.sessionID, loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect);
142
143     // PingHandle manages its own lifetime, deleting itself when its purpose has been fulfilled.
144     new PingHandle(context.get(), loadParameters.request, loadParameters.allowStoredCredentials == AllowStoredCredentials, PingHandle::UsesAsyncCallbacks::Yes);
145 #endif
146 }
147
148 void NetworkConnectionToWebProcess::removeLoadIdentifier(ResourceLoadIdentifier identifier)
149 {
150     RefPtr<NetworkResourceLoader> loader = m_networkResourceLoaders.get(identifier);
151
152     // It's possible we have no loader for this identifier if the NetworkProcess crashed and this was a respawned NetworkProcess.
153     if (!loader)
154         return;
155
156     // Abort the load now, as the WebProcess won't be able to respond to messages any more which might lead
157     // to leaked loader resources (connections, threads, etc).
158     loader->abort();
159     ASSERT(!m_networkResourceLoaders.contains(identifier));
160 }
161
162 void NetworkConnectionToWebProcess::setDefersLoading(ResourceLoadIdentifier identifier, bool defers)
163 {
164     RefPtr<NetworkResourceLoader> loader = m_networkResourceLoaders.get(identifier);
165     if (!loader)
166         return;
167
168     loader->setDefersLoading(defers);
169 }
170
171 void NetworkConnectionToWebProcess::prefetchDNS(const String& hostname)
172 {
173     NetworkProcess::singleton().prefetchDNS(hostname);
174 }
175
176 static NetworkStorageSession& storageSession(SessionID sessionID)
177 {
178     if (sessionID.isEphemeral()) {
179         NetworkStorageSession* privateStorageSession = SessionTracker::storageSession(sessionID);
180         if (privateStorageSession)
181             return *privateStorageSession;
182         // Some requests with private browsing mode requested may still be coming shortly after NetworkProcess was told to destroy its session.
183         // FIXME: Find a way to track private browsing sessions more rigorously.
184         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.");
185     }
186     return NetworkStorageSession::defaultStorageSession();
187 }
188
189 void NetworkConnectionToWebProcess::startDownload(SessionID sessionID, DownloadID downloadID, const ResourceRequest& request)
190 {
191     NetworkProcess::singleton().downloadManager().startDownload(sessionID, downloadID, request);
192 }
193
194 void NetworkConnectionToWebProcess::convertMainResourceLoadToDownload(SessionID sessionID, uint64_t mainResourceLoadIdentifier, DownloadID downloadID, const ResourceRequest& request, const ResourceResponse& response)
195 {
196     auto& networkProcess = NetworkProcess::singleton();
197     if (!mainResourceLoadIdentifier) {
198         networkProcess.downloadManager().startDownload(sessionID, downloadID, request);
199         return;
200     }
201
202     NetworkResourceLoader* loader = m_networkResourceLoaders.get(mainResourceLoadIdentifier);
203     if (!loader) {
204         // If we're trying to download a blob here loader can be null.
205         return;
206     }
207
208 #if USE(NETWORK_SESSION)
209     loader->networkLoad()->convertTaskToDownload(downloadID);
210 #else
211     networkProcess.downloadManager().convertHandleToDownload(downloadID, loader->networkLoad()->handle(), request, response);
212
213     // Unblock the URL connection operation queue.
214     loader->networkLoad()->handle()->continueDidReceiveResponse();
215     
216 #endif
217     loader->didConvertToDownload();
218 }
219
220 void NetworkConnectionToWebProcess::cookiesForDOM(SessionID sessionID, const URL& firstParty, const URL& url, String& result)
221 {
222     result = WebCore::cookiesForDOM(storageSession(sessionID), firstParty, url);
223 }
224
225 void NetworkConnectionToWebProcess::setCookiesFromDOM(SessionID sessionID, const URL& firstParty, const URL& url, const String& cookieString)
226 {
227     WebCore::setCookiesFromDOM(storageSession(sessionID), firstParty, url, cookieString);
228 }
229
230 void NetworkConnectionToWebProcess::cookiesEnabled(SessionID sessionID, const URL& firstParty, const URL& url, bool& result)
231 {
232     result = WebCore::cookiesEnabled(storageSession(sessionID), firstParty, url);
233 }
234
235 void NetworkConnectionToWebProcess::cookieRequestHeaderFieldValue(SessionID sessionID, const URL& firstParty, const URL& url, String& result)
236 {
237     result = WebCore::cookieRequestHeaderFieldValue(storageSession(sessionID), firstParty, url);
238 }
239
240 void NetworkConnectionToWebProcess::getRawCookies(SessionID sessionID, const URL& firstParty, const URL& url, Vector<Cookie>& result)
241 {
242     WebCore::getRawCookies(storageSession(sessionID), firstParty, url, result);
243 }
244
245 void NetworkConnectionToWebProcess::deleteCookie(SessionID sessionID, const URL& url, const String& cookieName)
246 {
247     WebCore::deleteCookie(storageSession(sessionID), url, cookieName);
248 }
249
250 void NetworkConnectionToWebProcess::registerFileBlobURL(const URL& url, const String& path, const SandboxExtension::Handle& extensionHandle, const String& contentType)
251 {
252     RefPtr<SandboxExtension> extension = SandboxExtension::create(extensionHandle);
253
254     NetworkBlobRegistry::singleton().registerFileBlobURL(this, url, path, WTFMove(extension), contentType);
255 }
256
257 void NetworkConnectionToWebProcess::registerBlobURL(const URL& url, Vector<BlobPart> blobParts, const String& contentType)
258 {
259     NetworkBlobRegistry::singleton().registerBlobURL(this, url, WTFMove(blobParts), contentType);
260 }
261
262 void NetworkConnectionToWebProcess::registerBlobURLFromURL(const URL& url, const URL& srcURL)
263 {
264     NetworkBlobRegistry::singleton().registerBlobURL(this, url, srcURL);
265 }
266
267 void NetworkConnectionToWebProcess::registerBlobURLForSlice(const URL& url, const URL& srcURL, int64_t start, int64_t end)
268 {
269     NetworkBlobRegistry::singleton().registerBlobURLForSlice(this, url, srcURL, start, end);
270 }
271
272 void NetworkConnectionToWebProcess::unregisterBlobURL(const URL& url)
273 {
274     NetworkBlobRegistry::singleton().unregisterBlobURL(this, url);
275 }
276
277 void NetworkConnectionToWebProcess::blobSize(const URL& url, uint64_t& resultSize)
278 {
279     resultSize = NetworkBlobRegistry::singleton().blobSize(this, url);
280 }
281
282 void NetworkConnectionToWebProcess::ensureLegacyPrivateBrowsingSession()
283 {
284     NetworkProcess::singleton().ensurePrivateBrowsingSession(SessionID::legacyPrivateSessionID());
285 }
286
287 } // namespace WebKit