REGRESSION: We see authentication challenge sheets for favicon requests.
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebCoreSupport / WebPlatformStrategies.cpp
1 /*
2  * Copyright (C) 2010, 2011, 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 "WebPlatformStrategies.h"
28
29 #if USE(PLATFORM_STRATEGIES)
30
31 #include "BlockingResponseMap.h"
32 #include "DataReference.h"
33 #include "NetworkResourceLoadParameters.h"
34 #include "PluginInfoStore.h"
35 #include "StorageNamespaceImpl.h"
36 #include "WebContextMessages.h"
37 #include "WebCookieManager.h"
38 #include "WebCoreArgumentCoders.h"
39 #include "WebErrors.h"
40 #include "WebPage.h"
41 #include "WebProcess.h"
42 #include "WebProcessProxyMessages.h"
43 #include <WebCore/Color.h>
44 #include <WebCore/KURL.h>
45 #include <WebCore/LoaderStrategy.h>
46 #include <WebCore/NetworkStorageSession.h>
47 #include <WebCore/NetworkingContext.h>
48 #include <WebCore/Page.h>
49 #include <WebCore/PlatformCookieJar.h>
50 #include <WebCore/PlatformPasteboard.h>
51 #include <WebCore/ResourceError.h>
52 #include <WebCore/StorageNamespace.h>
53 #include <wtf/Atomics.h>
54
55 #if ENABLE(NETWORK_PROCESS)
56 #include "BlobRegistryProxy.h"
57 #include "NetworkConnectionToWebProcessMessages.h"
58 #include "NetworkProcessConnection.h"
59 #include "WebResourceLoadScheduler.h"
60 #endif
61
62 // FIXME: Remove this once it works well enough to be the default.
63 #define ENABLE_UI_PROCESS_STORAGE 0
64
65 using namespace WebCore;
66
67 namespace WebKit {
68
69 void WebPlatformStrategies::initialize()
70 {
71     DEFINE_STATIC_LOCAL(WebPlatformStrategies, platformStrategies, ());
72     setPlatformStrategies(&platformStrategies);
73 }
74
75 WebPlatformStrategies::WebPlatformStrategies()
76 #if ENABLE(NETSCAPE_PLUGIN_API)
77     : m_pluginCacheIsPopulated(false)
78     , m_shouldRefreshPlugins(false)
79 #endif // ENABLE(NETSCAPE_PLUGIN_API)
80 {
81 }
82
83 CookiesStrategy* WebPlatformStrategies::createCookiesStrategy()
84 {
85     return this;
86 }
87
88 DatabaseStrategy* WebPlatformStrategies::createDatabaseStrategy()
89 {
90     return this;
91 }
92
93 LoaderStrategy* WebPlatformStrategies::createLoaderStrategy()
94 {
95     return this;
96 }
97
98 PasteboardStrategy* WebPlatformStrategies::createPasteboardStrategy()
99 {
100     return this;
101 }
102
103 PluginStrategy* WebPlatformStrategies::createPluginStrategy()
104 {
105     return this;
106 }
107
108 SharedWorkerStrategy* WebPlatformStrategies::createSharedWorkerStrategy()
109 {
110     return this;
111 }
112
113 StorageStrategy* WebPlatformStrategies::createStorageStrategy()
114 {
115     return this;
116 }
117
118 VisitedLinkStrategy* WebPlatformStrategies::createVisitedLinkStrategy()
119 {
120     return this;
121 }
122
123 // CookiesStrategy
124
125 String WebPlatformStrategies::cookiesForDOM(const NetworkStorageSession& session, const KURL& firstParty, const KURL& url)
126 {
127 #if ENABLE(NETWORK_PROCESS)
128     if (WebProcess::shared().usesNetworkProcess()) {
129         String result;
130         if (!WebProcess::shared().networkConnection()->connection()->sendSync(Messages::NetworkConnectionToWebProcess::CookiesForDOM(session.isPrivateBrowsingSession(), firstParty, url), Messages::NetworkConnectionToWebProcess::CookiesForDOM::Reply(result), 0))
131             return String();
132         return result;
133     }
134 #endif
135
136     return WebCore::cookiesForDOM(session, firstParty, url);
137 }
138
139 void WebPlatformStrategies::setCookiesFromDOM(const NetworkStorageSession& session, const KURL& firstParty, const KURL& url, const String& cookieString)
140 {
141 #if ENABLE(NETWORK_PROCESS)
142     if (WebProcess::shared().usesNetworkProcess()) {
143         WebProcess::shared().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::SetCookiesFromDOM(session.isPrivateBrowsingSession(), firstParty, url, cookieString), 0);
144         return;
145     }
146 #endif
147
148     WebCore::setCookiesFromDOM(session, firstParty, url, cookieString);
149 }
150
151 bool WebPlatformStrategies::cookiesEnabled(const NetworkStorageSession& session, const KURL& firstParty, const KURL& url)
152 {
153 #if ENABLE(NETWORK_PROCESS)
154     if (WebProcess::shared().usesNetworkProcess()) {
155         bool result;
156         if (!WebProcess::shared().networkConnection()->connection()->sendSync(Messages::NetworkConnectionToWebProcess::CookiesEnabled(session.isPrivateBrowsingSession(), firstParty, url), Messages::NetworkConnectionToWebProcess::CookiesEnabled::Reply(result), 0))
157             return false;
158         return result;
159     }
160 #endif
161
162     return WebCore::cookiesEnabled(session, firstParty, url);
163 }
164
165 String WebPlatformStrategies::cookieRequestHeaderFieldValue(const NetworkStorageSession& session, const KURL& firstParty, const KURL& url)
166 {
167 #if ENABLE(NETWORK_PROCESS)
168     if (WebProcess::shared().usesNetworkProcess()) {
169         String result;
170         if (!WebProcess::shared().networkConnection()->connection()->sendSync(Messages::NetworkConnectionToWebProcess::CookieRequestHeaderFieldValue(session.isPrivateBrowsingSession(), firstParty, url), Messages::NetworkConnectionToWebProcess::CookieRequestHeaderFieldValue::Reply(result), 0))
171             return String();
172         return result;
173     }
174 #endif
175
176     return WebCore::cookieRequestHeaderFieldValue(session, firstParty, url);
177 }
178
179 bool WebPlatformStrategies::getRawCookies(const NetworkStorageSession& session, const KURL& firstParty, const KURL& url, Vector<Cookie>& rawCookies)
180 {
181 #if ENABLE(NETWORK_PROCESS)
182     if (WebProcess::shared().usesNetworkProcess()) {
183         if (!WebProcess::shared().networkConnection()->connection()->sendSync(Messages::NetworkConnectionToWebProcess::GetRawCookies(session.isPrivateBrowsingSession(), firstParty, url), Messages::NetworkConnectionToWebProcess::GetRawCookies::Reply(rawCookies), 0))
184             return false;
185         return true;
186     }
187 #endif
188
189     return WebCore::getRawCookies(session, firstParty, url, rawCookies);
190 }
191
192 void WebPlatformStrategies::deleteCookie(const NetworkStorageSession& session, const KURL& url, const String& cookieName)
193 {
194 #if ENABLE(NETWORK_PROCESS)
195     if (WebProcess::shared().usesNetworkProcess()) {
196         WebProcess::shared().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::DeleteCookie(session.isPrivateBrowsingSession(), url, cookieName), 0);
197         return;
198     }
199 #endif
200
201     WebCore::deleteCookie(session, url, cookieName);
202 }
203
204 // DatabaseStrategy
205
206 #if ENABLE(SQL_DATABASE)
207 AbstractDatabaseServer* WebPlatformStrategies::getDatabaseServer()
208 {
209     return DatabaseStrategy::getDatabaseServer(); // Use the default for now.
210 }
211 #endif
212
213 // LoaderStrategy
214
215 #if ENABLE(NETWORK_PROCESS)
216 ResourceLoadScheduler* WebPlatformStrategies::resourceLoadScheduler()
217 {
218     static ResourceLoadScheduler* scheduler;
219     if (!scheduler) {
220         if (WebProcess::shared().usesNetworkProcess())
221             scheduler = &WebProcess::shared().webResourceLoadScheduler();
222         else
223             scheduler = WebCore::resourceLoadScheduler();
224     }
225     
226     return scheduler;
227 }
228
229 void WebPlatformStrategies::loadResourceSynchronously(NetworkingContext* context, unsigned long resourceLoadIdentifier, const ResourceRequest& request, StoredCredentials storedCredentials, ClientCredentialPolicy clientCredentialPolicy, ResourceError& error, ResourceResponse& response, Vector<char>& data)
230 {
231     if (!WebProcess::shared().usesNetworkProcess()) {
232         LoaderStrategy::loadResourceSynchronously(context, resourceLoadIdentifier, request, storedCredentials, clientCredentialPolicy, error, response, data);
233         return;
234     }
235
236     CoreIPC::DataReference dataReference;
237
238     NetworkResourceLoadParameters loadParameters;
239     loadParameters.identifier = resourceLoadIdentifier;
240     loadParameters.request = request;
241     loadParameters.priority = ResourceLoadPriorityHighest;
242     loadParameters.contentSniffingPolicy = SniffContent;
243     loadParameters.allowStoredCredentials = storedCredentials;
244     loadParameters.clientCredentialPolicy = clientCredentialPolicy;
245     loadParameters.inPrivateBrowsingMode = context->storageSession().isPrivateBrowsingSession();
246     loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = context->shouldClearReferrerOnHTTPSToHTTPRedirect();
247
248     if (!WebProcess::shared().networkConnection()->connection()->sendSync(Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad(loadParameters), Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::Reply(error, response, dataReference), 0)) {
249         response = ResourceResponse();
250         error = internalError(request.url());
251         data.resize(0);
252
253         return;
254     }
255
256     data.resize(dataReference.size());
257     memcpy(data.data(), dataReference.data(), dataReference.size());
258 }
259
260 #if ENABLE(BLOB)
261 BlobRegistry* WebPlatformStrategies::createBlobRegistry()
262 {
263     if (!WebProcess::shared().usesNetworkProcess())
264         return LoaderStrategy::createBlobRegistry();
265     return new BlobRegistryProxy;    
266 }
267 #endif
268 #endif
269
270 // PluginStrategy
271
272 void WebPlatformStrategies::refreshPlugins()
273 {
274 #if ENABLE(NETSCAPE_PLUGIN_API)
275     m_cachedPlugins.clear();
276     m_pluginCacheIsPopulated = false;
277     m_shouldRefreshPlugins = true;
278
279     populatePluginCache();
280 #endif // ENABLE(NETSCAPE_PLUGIN_API)
281 }
282
283 void WebPlatformStrategies::getPluginInfo(const WebCore::Page*, Vector<WebCore::PluginInfo>& plugins)
284 {
285 #if ENABLE(NETSCAPE_PLUGIN_API)
286     populatePluginCache();
287     plugins = m_cachedPlugins;
288 #endif // ENABLE(NETSCAPE_PLUGIN_API)
289 }
290
291 #if ENABLE(NETSCAPE_PLUGIN_API)
292 void WebPlatformStrategies::populatePluginCache()
293 {
294     if (m_pluginCacheIsPopulated)
295         return;
296
297     ASSERT(m_cachedPlugins.isEmpty());
298     
299     // FIXME: Should we do something in case of error here?
300     if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::GetPlugins(m_shouldRefreshPlugins), Messages::WebProcessProxy::GetPlugins::Reply(m_cachedPlugins), 0))
301         return;
302
303     m_shouldRefreshPlugins = false;
304     m_pluginCacheIsPopulated = true;
305 }
306 #endif // ENABLE(NETSCAPE_PLUGIN_API)
307
308 // StorageStrategy
309
310 PassRefPtr<StorageNamespace> WebPlatformStrategies::localStorageNamespace(PageGroup* pageGroup)
311 {
312 #if ENABLE(UI_PROCESS_STORAGE)
313     return StorageNamespaceImpl::createLocalStorageNamespace(pageGroup);
314 #else
315     return StorageStrategy::localStorageNamespace(pageGroup);
316 #endif
317 }
318
319 PassRefPtr<StorageNamespace> WebPlatformStrategies::sessionStorageNamespace(Page* page)
320 {
321 #if ENABLE(UI_PROCESS_STORAGE)
322     return StorageNamespaceImpl::createSessionStorageNamespace(WebPage::fromCorePage(page));
323 #else
324     return StorageStrategy::sessionStorageNamespace(page);
325 #endif
326 }
327
328 // VisitedLinkStrategy
329
330 bool WebPlatformStrategies::isLinkVisited(Page*, LinkHash linkHash, const KURL&, const AtomicString&)
331 {
332     return WebProcess::shared().isLinkVisited(linkHash);
333 }
334
335 void WebPlatformStrategies::addVisitedLink(Page*, LinkHash linkHash)
336 {
337     WebProcess::shared().addVisitedLink(linkHash);
338 }
339
340 #if PLATFORM(MAC)
341 // PasteboardStrategy
342
343 void WebPlatformStrategies::getTypes(Vector<String>& types, const String& pasteboardName)
344 {
345     WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPasteboardTypes(pasteboardName),
346                                                 Messages::WebContext::GetPasteboardTypes::Reply(types), 0);
347 }
348
349 PassRefPtr<WebCore::SharedBuffer> WebPlatformStrategies::bufferForType(const String& pasteboardType, const String& pasteboardName)
350 {
351     SharedMemory::Handle handle;
352     uint64_t size = 0;
353     WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPasteboardBufferForType(pasteboardName, pasteboardType),
354                                                 Messages::WebContext::GetPasteboardBufferForType::Reply(handle, size), 0);
355     if (handle.isNull())
356         return 0;
357     RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::create(handle, SharedMemory::ReadOnly);
358     return SharedBuffer::create(static_cast<unsigned char *>(sharedMemoryBuffer->data()), size);
359 }
360
361 void WebPlatformStrategies::getPathnamesForType(Vector<String>& pathnames, const String& pasteboardType, const String& pasteboardName)
362 {
363     WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPasteboardPathnamesForType(pasteboardName, pasteboardType),
364                                                 Messages::WebContext::GetPasteboardPathnamesForType::Reply(pathnames), 0);
365 }
366
367 String WebPlatformStrategies::stringForType(const String& pasteboardType, const String& pasteboardName)
368 {
369     String value;
370     WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPasteboardStringForType(pasteboardName, pasteboardType),
371                                                 Messages::WebContext::GetPasteboardStringForType::Reply(value), 0);
372     return value;
373 }
374
375 void WebPlatformStrategies::copy(const String& fromPasteboard, const String& toPasteboard)
376 {
377     WebProcess::shared().connection()->send(Messages::WebContext::PasteboardCopy(fromPasteboard, toPasteboard), 0);
378 }
379
380 int WebPlatformStrategies::changeCount(const WTF::String &pasteboardName)
381 {
382     uint64_t changeCount;
383     WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPasteboardChangeCount(pasteboardName),
384                                                 Messages::WebContext::GetPasteboardChangeCount::Reply(changeCount), 0);
385     return changeCount;
386 }
387
388 String WebPlatformStrategies::uniqueName()
389 {
390     String pasteboardName;
391     WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPasteboardUniqueName(),
392                                                 Messages::WebContext::GetPasteboardUniqueName::Reply(pasteboardName), 0);
393     return pasteboardName;
394 }
395
396 Color WebPlatformStrategies::color(const String& pasteboardName)
397 {
398     Color color;
399     WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPasteboardColor(pasteboardName),
400                                                 Messages::WebContext::GetPasteboardColor::Reply(color), 0);
401     return color;
402 }
403
404 KURL WebPlatformStrategies::url(const String& pasteboardName)
405 {
406     String urlString;
407     WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPasteboardURL(pasteboardName),
408                                                 Messages::WebContext::GetPasteboardURL::Reply(urlString), 0);
409     return KURL(ParsedURLString, urlString);
410 }
411
412 void WebPlatformStrategies::addTypes(const Vector<String>& pasteboardTypes, const String& pasteboardName)
413 {
414     WebProcess::shared().connection()->send(Messages::WebContext::AddPasteboardTypes(pasteboardName, pasteboardTypes), 0);
415 }
416
417 void WebPlatformStrategies::setTypes(const Vector<String>& pasteboardTypes, const String& pasteboardName)
418 {
419     WebProcess::shared().connection()->send(Messages::WebContext::SetPasteboardTypes(pasteboardName, pasteboardTypes), 0);
420 }
421
422 void WebPlatformStrategies::setBufferForType(PassRefPtr<SharedBuffer> buffer, const String& pasteboardType, const String& pasteboardName)
423 {
424     SharedMemory::Handle handle;
425     if (buffer) {
426         RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::create(buffer->size());
427         memcpy(sharedMemoryBuffer->data(), buffer->data(), buffer->size());
428         sharedMemoryBuffer->createHandle(handle, SharedMemory::ReadOnly);
429     }
430     WebProcess::shared().connection()->send(Messages::WebContext::SetPasteboardBufferForType(pasteboardName, pasteboardType, handle, buffer ? buffer->size() : 0), 0);
431 }
432
433 void WebPlatformStrategies::setPathnamesForType(const Vector<String>& pathnames, const String& pasteboardType, const String& pasteboardName)
434 {
435     WebProcess::shared().connection()->send(Messages::WebContext::SetPasteboardPathnamesForType(pasteboardName, pasteboardType, pathnames), 0);
436 }
437
438 void WebPlatformStrategies::setStringForType(const String& string, const String& pasteboardType, const String& pasteboardName)
439 {
440     WebProcess::shared().connection()->send(Messages::WebContext::SetPasteboardStringForType(pasteboardName, pasteboardType, string), 0);
441 }
442 #endif
443
444 } // namespace WebKit
445
446 #endif // USE(PLATFORM_STRATEGIES)