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