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