04d0da2ebe28e2f08de6dc9b30e56f245dcca4f2
[WebKit.git] / Source / WebKit / UIProcess / WebCookieManagerProxy.cpp
1 /*
2  * Copyright (C) 2011, 2013 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 "WebCookieManagerProxy.h"
28
29 #include "APIArray.h"
30 #include "APISecurityOrigin.h"
31 #include "NetworkProcessMessages.h"
32 #include "OptionalCallbackID.h"
33 #include "WebCookieManagerMessages.h"
34 #include "WebCookieManagerProxyMessages.h"
35 #include "WebProcessPool.h"
36 #include <WebCore/Cookie.h>
37 #include <WebCore/SecurityOriginData.h>
38
39 namespace WebKit {
40 using namespace WebCore;
41
42 const char* WebCookieManagerProxy::supplementName()
43 {
44     return "WebCookieManagerProxy";
45 }
46
47 Ref<WebCookieManagerProxy> WebCookieManagerProxy::create(WebProcessPool* processPool)
48 {
49     return adoptRef(*new WebCookieManagerProxy(processPool));
50 }
51
52 WebCookieManagerProxy::WebCookieManagerProxy(WebProcessPool* processPool)
53     : WebContextSupplement(processPool)
54 {
55     WebContextSupplement::processPool()->addMessageReceiver(Messages::WebCookieManagerProxy::messageReceiverName(), *this);
56 }
57
58 WebCookieManagerProxy::~WebCookieManagerProxy()
59 {
60     ASSERT(m_cookieObservers.isEmpty());
61 }
62
63 void WebCookieManagerProxy::initializeClient(const WKCookieManagerClientBase* client)
64 {
65     m_client.initialize(client);
66 }
67
68 // WebContextSupplement
69
70 void WebCookieManagerProxy::processPoolDestroyed()
71 {
72     m_callbacks.invalidate(CallbackBase::Error::OwnerWasInvalidated);
73
74     Vector<Observer*> observers;
75     for (auto& observerSet : m_cookieObservers.values()) {
76         for (auto* observer : observerSet)
77             observers.append(observer);
78     }
79
80     for (auto* observer : observers)
81         observer->managerDestroyed();
82
83     ASSERT(m_cookieObservers.isEmpty());
84 }
85
86 void WebCookieManagerProxy::processDidClose(WebProcessProxy*)
87 {
88     m_callbacks.invalidate(CallbackBase::Error::ProcessExited);
89 }
90
91 void WebCookieManagerProxy::processDidClose(NetworkProcessProxy*)
92 {
93     m_callbacks.invalidate(CallbackBase::Error::ProcessExited);
94 }
95
96 void WebCookieManagerProxy::refWebContextSupplement()
97 {
98     API::Object::ref();
99 }
100
101 void WebCookieManagerProxy::derefWebContextSupplement()
102 {
103     API::Object::deref();
104 }
105
106 void WebCookieManagerProxy::getHostnamesWithCookies(PAL::SessionID sessionID, Function<void (API::Array*, CallbackBase::Error)>&& callbackFunction)
107 {
108     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), processPool()->ensureNetworkProcess().throttler().backgroundActivityToken());
109     processPool()->sendToNetworkingProcess(Messages::WebCookieManager::GetHostnamesWithCookies(sessionID, callbackID));
110 }
111
112 void WebCookieManagerProxy::didGetHostnamesWithCookies(const Vector<String>& hostnames, WebKit::CallbackID callbackID)
113 {
114     auto callback = m_callbacks.take<ArrayCallback>(callbackID);
115     if (!callback) {
116         // FIXME: Log error or assert.
117         return;
118     }
119
120     callback->performCallbackWithReturnValue(API::Array::createStringArray(hostnames).ptr());
121 }
122
123 void WebCookieManagerProxy::deleteCookiesForHostnames(PAL::SessionID sessionID, const Vector<String>& hostnames)
124 {
125     processPool()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::DeleteCookiesForHostnames(sessionID, hostnames));
126 }
127
128 void WebCookieManagerProxy::deleteAllCookies(PAL::SessionID sessionID)
129 {
130     processPool()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::DeleteAllCookies(sessionID));
131 }
132
133 void WebCookieManagerProxy::deleteCookie(PAL::SessionID sessionID, const Cookie& cookie, Function<void (CallbackBase::Error)>&& callbackFunction)
134 {
135     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), processPool()->ensureNetworkProcess().throttler().backgroundActivityToken());
136     processPool()->sendToNetworkingProcess(Messages::WebCookieManager::DeleteCookie(sessionID, cookie, callbackID));
137 }
138
139 void WebCookieManagerProxy::deleteAllCookiesModifiedSince(PAL::SessionID sessionID, WallTime time, Function<void (CallbackBase::Error)>&& callbackFunction)
140 {
141     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), processPool()->ensureNetworkProcess().throttler().backgroundActivityToken());
142     processPool()->sendToNetworkingProcess(Messages::WebCookieManager::DeleteAllCookiesModifiedSince(sessionID, time, callbackID));
143 }
144
145 void WebCookieManagerProxy::setCookies(PAL::SessionID sessionID, const Vector<Cookie>& cookies, Function<void(CallbackBase::Error)>&& callbackFunction)
146 {
147     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), processPool()->ensureNetworkProcess().throttler().backgroundActivityToken());
148     processPool()->sendToNetworkingProcess(Messages::WebCookieManager::SetCookie(sessionID, cookies, callbackID));
149 }
150
151 void WebCookieManagerProxy::setCookies(PAL::SessionID sessionID, const Vector<Cookie>& cookies, const URL& url, const URL& mainDocumentURL, Function<void (CallbackBase::Error)>&& callbackFunction)
152 {
153     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), processPool()->ensureNetworkProcess().throttler().backgroundActivityToken());
154     processPool()->sendToNetworkingProcess(Messages::WebCookieManager::SetCookies(sessionID, cookies, url, mainDocumentURL, callbackID));
155 }
156
157 void WebCookieManagerProxy::getAllCookies(PAL::SessionID sessionID, Function<void (const Vector<Cookie>&, CallbackBase::Error)>&& callbackFunction)
158 {
159     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), processPool()->ensureNetworkProcess().throttler().backgroundActivityToken());
160     processPool()->sendToNetworkingProcess(Messages::WebCookieManager::GetAllCookies(sessionID, callbackID));
161 }
162
163 void WebCookieManagerProxy::getCookies(PAL::SessionID sessionID, const URL& url, Function<void (const Vector<Cookie>&, CallbackBase::Error)>&& callbackFunction)
164 {
165     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), processPool()->ensureNetworkProcess().throttler().backgroundActivityToken());
166     processPool()->sendToNetworkingProcess(Messages::WebCookieManager::GetCookies(sessionID, url, callbackID));
167 }
168
169 void WebCookieManagerProxy::didSetCookies(WebKit::CallbackID callbackID)
170 {
171     m_callbacks.take<VoidCallback>(callbackID)->performCallback();
172 }
173
174 void WebCookieManagerProxy::didGetCookies(const Vector<Cookie>& cookies, WebKit::CallbackID callbackID)
175 {
176     m_callbacks.take<GetCookiesCallback>(callbackID)->performCallbackWithReturnValue(cookies);
177 }
178
179 void WebCookieManagerProxy::didDeleteCookies(WebKit::CallbackID callbackID)
180 {
181     m_callbacks.take<VoidCallback>(callbackID)->performCallback();
182 }
183
184 void WebCookieManagerProxy::startObservingCookieChanges(PAL::SessionID sessionID)
185 {
186     processPool()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::StartObservingCookieChanges(sessionID));
187 }
188
189 void WebCookieManagerProxy::stopObservingCookieChanges(PAL::SessionID sessionID)
190 {
191     processPool()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::StopObservingCookieChanges(sessionID));
192 }
193
194
195 void WebCookieManagerProxy::setCookieObserverCallback(PAL::SessionID sessionID, WTF::Function<void ()>&& callback)
196 {
197     if (callback)
198         m_legacyCookieObservers.set(sessionID, WTFMove(callback));
199     else
200         m_legacyCookieObservers.remove(sessionID);
201 }
202
203 void WebCookieManagerProxy::registerObserver(PAL::SessionID sessionID, Observer& observer)
204 {
205     auto result = m_cookieObservers.set(sessionID, HashSet<Observer*>());
206     result.iterator->value.add(&observer);
207
208     if (result.isNewEntry)
209         startObservingCookieChanges(sessionID);
210 }
211
212 void WebCookieManagerProxy::unregisterObserver(PAL::SessionID sessionID, Observer& observer)
213 {
214     auto iterator = m_cookieObservers.find(sessionID);
215     if (iterator == m_cookieObservers.end())
216         return;
217
218     iterator->value.remove(&observer);
219     if (!iterator->value.isEmpty())
220         return;
221
222     m_cookieObservers.remove(iterator);
223     stopObservingCookieChanges(sessionID);
224 }
225
226 void WebCookieManagerProxy::cookiesDidChange(PAL::SessionID sessionID)
227 {
228     m_client.cookiesDidChange(this);
229     auto legacyIterator = m_legacyCookieObservers.find(sessionID);
230     if (legacyIterator != m_legacyCookieObservers.end())
231         ((*legacyIterator).value)();
232
233     auto iterator = m_cookieObservers.find(sessionID);
234     if (iterator == m_cookieObservers.end())
235         return;
236
237     for (auto* observer : iterator->value)
238         observer->cookiesDidChange();
239 }
240
241 void WebCookieManagerProxy::setHTTPCookieAcceptPolicy(PAL::SessionID, HTTPCookieAcceptPolicy policy, Function<void (CallbackBase::Error)>&& callbackFunction)
242 {
243 #if PLATFORM(COCOA)
244     if (!processPool()->isUsingTestingNetworkSession())
245         persistHTTPCookieAcceptPolicy(policy);
246 #endif
247 #if USE(SOUP)
248     processPool()->setInitialHTTPCookieAcceptPolicy(policy);
249 #endif
250
251     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), processPool()->ensureNetworkProcess().throttler().backgroundActivityToken());
252     processPool()->sendToNetworkingProcess(Messages::WebCookieManager::SetHTTPCookieAcceptPolicy(policy, OptionalCallbackID(callbackID)));
253 }
254
255 void WebCookieManagerProxy::getHTTPCookieAcceptPolicy(PAL::SessionID, Function<void (HTTPCookieAcceptPolicy, CallbackBase::Error)>&& callbackFunction)
256 {
257     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), processPool()->ensureNetworkProcess().throttler().backgroundActivityToken());
258     processPool()->sendToNetworkingProcess(Messages::WebCookieManager::GetHTTPCookieAcceptPolicy(callbackID));
259 }
260
261 void WebCookieManagerProxy::didGetHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy, WebKit::CallbackID callbackID)
262 {
263     m_callbacks.take<HTTPCookieAcceptPolicyCallback>(callbackID)->performCallbackWithReturnValue(policy);
264 }
265
266 void WebCookieManagerProxy::didSetHTTPCookieAcceptPolicy(WebKit::CallbackID callbackID)
267 {
268     m_callbacks.take<VoidCallback>(callbackID)->performCallback();
269 }
270
271 } // namespace WebKit