48a329a0a9c1da75e73af6aa8a6ef7baaf6695de
[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 #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
46 using namespace WebCore;
47
48 namespace WebKit {
49
50 PassRefPtr<NetworkConnectionToWebProcess> NetworkConnectionToWebProcess::create(IPC::Connection::Identifier connectionIdentifier)
51 {
52     return adoptRef(new NetworkConnectionToWebProcess(connectionIdentifier));
53 }
54
55 NetworkConnectionToWebProcess::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
62 NetworkConnectionToWebProcess::~NetworkConnectionToWebProcess()
63 {
64 }
65
66 void NetworkConnectionToWebProcess::didCleanupResourceLoader(NetworkResourceLoader& loader)
67 {
68     RefPtr<NetworkResourceLoader> removedLoader = m_networkResourceLoaders.take(loader.identifier());
69     ASSERT(removedLoader == &loader);
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::shared().connectionToWebProcessDidClose(this);
110     NetworkProcess::shared().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     RefPtr<NetworkResourceLoader> loader = NetworkResourceLoader::create(loadParameters, this);
120     m_networkResourceLoaders.add(loadParameters.identifier, loader);
121     NetworkProcess::shared().networkResourceLoadScheduler().scheduleLoader(loader.get());
122 }
123
124 void NetworkConnectionToWebProcess::performSynchronousLoad(const NetworkResourceLoadParameters& loadParameters, PassRefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply> reply)
125 {
126     RefPtr<NetworkResourceLoader> loader = NetworkResourceLoader::create(loadParameters, this, reply);
127     m_networkResourceLoaders.add(loadParameters.identifier, loader);
128     NetworkProcess::shared().networkResourceLoadScheduler().scheduleLoader(loader.get());
129 }
130
131 void NetworkConnectionToWebProcess::removeLoadIdentifier(ResourceLoadIdentifier identifier)
132 {
133     RefPtr<NetworkResourceLoader> loader = m_networkResourceLoaders.get(identifier);
134
135     // It's possible we have no loader for this identifier if the NetworkProcess crashed and this was a respawned NetworkProcess.
136     if (!loader)
137         return;
138
139     // Abort the load now, as the WebProcess won't be able to respond to messages any more which might lead
140     // to leaked loader resources (connections, threads, etc).
141     loader->abort();
142     ASSERT(!m_networkResourceLoaders.contains(identifier));
143 }
144
145 void NetworkConnectionToWebProcess::setDefersLoading(ResourceLoadIdentifier identifier, bool defers)
146 {
147     RefPtr<NetworkResourceLoader> loader = m_networkResourceLoaders.get(identifier);
148     if (!loader)
149         return;
150
151     loader->setDefersLoading(defers);
152 }
153
154 void NetworkConnectionToWebProcess::servePendingRequests(uint32_t)
155 {
156 }
157
158 void NetworkConnectionToWebProcess::setSerialLoadingEnabled(bool enabled)
159 {
160     m_serialLoadingEnabled = enabled;
161 }
162
163 static NetworkStorageSession& storageSession(SessionID sessionID)
164 {
165     if (sessionID.isEphemeral()) {
166         NetworkStorageSession* privateSession = SessionTracker::session(sessionID);
167         if (privateSession)
168             return *privateSession;
169         // Some requests with private browsing mode requested may still be coming shortly after NetworkProcess was told to destroy its session.
170         // FIXME: Find a way to track private browsing sessions more rigorously.
171         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.");
172     }
173     return NetworkStorageSession::defaultStorageSession();
174 }
175
176 void NetworkConnectionToWebProcess::startDownload(SessionID, uint64_t downloadID, const ResourceRequest& request)
177 {
178     // FIXME: Do something with the session ID.
179     NetworkProcess::shared().downloadManager().startDownload(downloadID, request);
180 }
181
182 void NetworkConnectionToWebProcess::convertMainResourceLoadToDownload(uint64_t mainResourceLoadIdentifier, uint64_t downloadID, const ResourceRequest& request, const ResourceResponse& response)
183 {
184     if (!mainResourceLoadIdentifier) {
185         NetworkProcess::shared().downloadManager().startDownload(downloadID, request);
186         return;
187     }
188
189     NetworkResourceLoader* loader = m_networkResourceLoaders.get(mainResourceLoadIdentifier);
190     NetworkProcess::shared().downloadManager().convertHandleToDownload(downloadID, loader->handle(), request, response);
191
192     // Unblock the URL connection operation queue.
193     loader->handle()->continueDidReceiveResponse();
194     
195     loader->didConvertHandleToDownload();
196 }
197
198 void NetworkConnectionToWebProcess::cookiesForDOM(SessionID sessionID, const URL& firstParty, const URL& url, String& result)
199 {
200     result = WebCore::cookiesForDOM(storageSession(sessionID), firstParty, url);
201 }
202
203 void NetworkConnectionToWebProcess::setCookiesFromDOM(SessionID sessionID, const URL& firstParty, const URL& url, const String& cookieString)
204 {
205     WebCore::setCookiesFromDOM(storageSession(sessionID), firstParty, url, cookieString);
206 }
207
208 void NetworkConnectionToWebProcess::cookiesEnabled(SessionID sessionID, const URL& firstParty, const URL& url, bool& result)
209 {
210     result = WebCore::cookiesEnabled(storageSession(sessionID), firstParty, url);
211 }
212
213 void NetworkConnectionToWebProcess::cookieRequestHeaderFieldValue(SessionID sessionID, const URL& firstParty, const URL& url, String& result)
214 {
215     result = WebCore::cookieRequestHeaderFieldValue(storageSession(sessionID), firstParty, url);
216 }
217
218 void NetworkConnectionToWebProcess::getRawCookies(SessionID sessionID, const URL& firstParty, const URL& url, Vector<Cookie>& result)
219 {
220     WebCore::getRawCookies(storageSession(sessionID), firstParty, url, result);
221 }
222
223 void NetworkConnectionToWebProcess::deleteCookie(SessionID sessionID, const URL& url, const String& cookieName)
224 {
225     WebCore::deleteCookie(storageSession(sessionID), url, cookieName);
226 }
227
228 void NetworkConnectionToWebProcess::registerFileBlobURL(const URL& url, const String& path, const SandboxExtension::Handle& extensionHandle, const String& contentType)
229 {
230     RefPtr<SandboxExtension> extension = SandboxExtension::create(extensionHandle);
231
232     NetworkBlobRegistry::shared().registerFileBlobURL(this, url, path, extension.release(), contentType);
233 }
234
235 void NetworkConnectionToWebProcess::registerBlobURL(const URL& url, Vector<BlobPart> blobParts, const String& contentType)
236 {
237     NetworkBlobRegistry::shared().registerBlobURL(this, url, WTF::move(blobParts), contentType);
238 }
239
240 void NetworkConnectionToWebProcess::registerBlobURLFromURL(const URL& url, const URL& srcURL)
241 {
242     NetworkBlobRegistry::shared().registerBlobURL(this, url, srcURL);
243 }
244
245 void NetworkConnectionToWebProcess::registerBlobURLForSlice(const URL& url, const URL& srcURL, int64_t start, int64_t end)
246 {
247     NetworkBlobRegistry::shared().registerBlobURLForSlice(this, url, srcURL, start, end);
248 }
249
250 void NetworkConnectionToWebProcess::unregisterBlobURL(const URL& url)
251 {
252     NetworkBlobRegistry::shared().unregisterBlobURL(this, url);
253 }
254
255 void NetworkConnectionToWebProcess::blobSize(const URL& url, uint64_t& resultSize)
256 {
257     resultSize = NetworkBlobRegistry::shared().blobSize(this, url);
258 }
259
260 } // namespace WebKit
261
262 #endif // ENABLE(NETWORK_PROCESS)