1/*
2 * Copyright (C) 2012 Igalia S.L.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2,1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "config.h"
21#include "WebKitCookieManager.h"
22
23#include "WebKitCookieManagerPrivate.h"
24#include "WebKitEnumTypes.h"
25#include <wtf/gobject/GRefPtr.h>
26#include <wtf/text/CString.h>
27
28using namespace WebKit;
29
30struct _WebKitCookieManagerPrivate {
31 WKRetainPtr<WKCookieManagerRef> wkCookieManager;
32};
33
34G_DEFINE_TYPE(WebKitCookieManager, webkit_cookie_manager, G_TYPE_OBJECT)
35
36COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS, kWKHTTPCookieAcceptPolicyAlways);
37COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_NEVER, kWKHTTPCookieAcceptPolicyNever);
38COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY, kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain);
39
40static void webkit_cookie_manager_init(WebKitCookieManager* manager)
41{
42 WebKitCookieManagerPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(manager, WEBKIT_TYPE_COOKIE_MANAGER, WebKitCookieManagerPrivate);
43 manager->priv = priv;
44 new (priv) WebKitCookieManagerPrivate();
45}
46
47static void webkitCookieManagerFinalize(GObject* object)
48{
49 WEBKIT_COOKIE_MANAGER(object)->priv->~WebKitCookieManagerPrivate();
50 G_OBJECT_CLASS(webkit_cookie_manager_parent_class)->finalize(object);
51}
52
53static void webkit_cookie_manager_class_init(WebKitCookieManagerClass* findClass)
54{
55 GObjectClass* gObjectClass = G_OBJECT_CLASS(findClass);
56 gObjectClass->finalize = webkitCookieManagerFinalize;
57
58 g_type_class_add_private(findClass, sizeof(WebKitCookieManagerPrivate));
59}
60
61WebKitCookieManager* webkitCookieManagerCreate(WKCookieManagerRef wkCookieManager)
62{
63 WebKitCookieManager* manager = WEBKIT_COOKIE_MANAGER(g_object_new(WEBKIT_TYPE_COOKIE_MANAGER, NULL));
64 manager->priv->wkCookieManager = wkCookieManager;
65 return manager;
66}
67
68/**
69 * webkit_cookie_manager_set_accept_policy:
70 * @cookie_manager: a #WebKitCookieManager
71 * @policy: a #WebKitCookieAcceptPolicy
72 *
73 * Set the cookie acceptance policy of @cookie_manager as @policy.
74 */
75void webkit_cookie_manager_set_accept_policy(WebKitCookieManager* manager, WebKitCookieAcceptPolicy policy)
76{
77 g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
78
79 WKCookieManagerSetHTTPCookieAcceptPolicy(manager->priv->wkCookieManager.get(), policy);
80}
81
82static void webkitCookieManagerGetAcceptPolicyCallback(WKHTTPCookieAcceptPolicy policy, WKErrorRef, void* context)
83{
84 GRefPtr<GSimpleAsyncResult> result = adoptGRef(G_SIMPLE_ASYNC_RESULT(context));
85 g_simple_async_result_set_op_res_gpointer(result.get(), GUINT_TO_POINTER(policy), 0);
86 g_simple_async_result_complete(result.get());
87}
88
89/**
90 * webkit_cookie_manager_get_accept_policy:
91 * @cookie_manager: a #WebKitCookieManager
92 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
93 * @user_data: (closure): the data to pass to callback function
94 *
95 * Asynchronously get the cookie acceptance policy of @cookie_manager.
96 *
97 * When the operation is finished, @callback will be called. You can then call
98 * webkit_cookie_manager_get_accept_policy_finish() to get the result of the operation.
99 */
100void webkit_cookie_manager_get_accept_policy(WebKitCookieManager* manager, GAsyncReadyCallback callback, gpointer userData)
101{
102 g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
103
104 GSimpleAsyncResult* result = g_simple_async_result_new(G_OBJECT(manager), callback, userData,
105 reinterpret_cast<gpointer>(webkit_cookie_manager_get_accept_policy));
106 WKCookieManagerGetHTTPCookieAcceptPolicy(manager->priv->wkCookieManager.get(), result, webkitCookieManagerGetAcceptPolicyCallback);
107}
108
109/**
110 * webkit_cookie_manager_get_accept_policy_finish:
111 * @cookie_manager: a #WebKitCookieManager
112 * @result: a #GAsyncResult
113 * @error: return location for error or %NULL to ignore
114 *
115 * Finish an asynchronous operation started with webkit_cookie_manager_get_accept_policy().
116 *
117 * Returns: the cookie acceptance policy of @cookie_manager as a #WebKitCookieAcceptPolicy.
118 */
119WebKitCookieAcceptPolicy webkit_cookie_manager_get_accept_policy_finish(WebKitCookieManager* manager, GAsyncResult* result, GError** error)
120{
121 g_return_val_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager), WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY);
122 g_return_val_if_fail(G_IS_ASYNC_RESULT(result), WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY);
123
124 GSimpleAsyncResult* simpleResult = G_SIMPLE_ASYNC_RESULT(result);
125 g_warn_if_fail(g_simple_async_result_get_source_tag(simpleResult) == webkit_cookie_manager_get_accept_policy);
126
127 if (g_simple_async_result_propagate_error(simpleResult, error))
128 return WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY;
129
130 return static_cast<WebKitCookieAcceptPolicy>(GPOINTER_TO_UINT(g_simple_async_result_get_op_res_gpointer(simpleResult)));
131}
132
133static void webkitCookieManagerGetDomainsWithCookiesCallback(WKArrayRef wkDomains, WKErrorRef, void* context)
134{
135 GRefPtr<GSimpleAsyncResult> result = adoptGRef(G_SIMPLE_ASYNC_RESULT(context));
136 GPtrArray* domains = g_ptr_array_new_with_free_func(g_free);
137 for (size_t i = 0; i < WKArrayGetSize(wkDomains); ++i) {
138 WKStringRef wkDomain = static_cast<WKStringRef>(WKArrayGetItemAtIndex(wkDomains, i));
139 String domain = toImpl(wkDomain)->string();
140 if (domain.isEmpty())
141 continue;
142 g_ptr_array_add(domains, g_strdup(domain.utf8().data()));
143 }
144 g_ptr_array_add(domains, 0);
145 g_simple_async_result_set_op_res_gpointer(result.get(), domains, reinterpret_cast<GDestroyNotify>(g_ptr_array_unref));
146 g_simple_async_result_complete(result.get());
147}
148
149/**
150 * webkit_cookie_manager_get_domains_with_cookies:
151 * @cookie_manager: a #WebKitCookieManager
152 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
153 * @user_data: (closure): the data to pass to callback function
154 *
155 * Asynchronously get the list of domains for which @cookie_manager contains cookies.
156 *
157 * When the operation is finished, @callback will be called. You can then call
158 * webkit_cookie_manager_get_domains_with_cookies_finish() to get the result of the operation.
159 */
160void webkit_cookie_manager_get_domains_with_cookies(WebKitCookieManager* manager, GAsyncReadyCallback callback, gpointer userData)
161{
162 g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
163
164 GSimpleAsyncResult* result = g_simple_async_result_new(G_OBJECT(manager), callback, userData,
165 reinterpret_cast<gpointer>(webkit_cookie_manager_get_domains_with_cookies));
166 WKCookieManagerGetHostnamesWithCookies(manager->priv->wkCookieManager.get(), result, webkitCookieManagerGetDomainsWithCookiesCallback);
167}
168
169/**
170 * webkit_cookie_manager_get_domains_with_cookies_finish:
171 * @cookie_manager: a #WebKitCookieManager
172 * @result: a #GAsyncResult
173 * @error: return location for error or %NULL to ignore
174 *
175 * Finish an asynchronous operation started with webkit_cookie_manager_get_domains_with_cookies().
176 * The return value is a %NULL terminated list of strings which should
177 * be released with g_strfreev().
178 *
179 * Returns: (transfer full) (array zero-terminated=1): A %NULL terminated array of domain names
180 * or %NULL in case of error.
181 */
182gchar** webkit_cookie_manager_get_domains_with_cookies_finish(WebKitCookieManager* manager, GAsyncResult* result, GError** error)
183{
184 g_return_val_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager), 0);
185 g_return_val_if_fail(G_IS_ASYNC_RESULT(result), 0);
186
187 GSimpleAsyncResult* simpleResult = G_SIMPLE_ASYNC_RESULT(result);
188 g_warn_if_fail(g_simple_async_result_get_source_tag(simpleResult) == webkit_cookie_manager_get_domains_with_cookies);
189
190 if (g_simple_async_result_propagate_error(simpleResult, error))
191 return 0;
192
193 GPtrArray* domains = static_cast<GPtrArray*>(g_simple_async_result_get_op_res_gpointer(simpleResult));
194 return reinterpret_cast<char**>(g_ptr_array_free(domains, FALSE));
195}
196
197/**
198 * webkit_cookie_manager_delete_cookies_for_domain:
199 * @cookie_manager: a #WebKitCookieManager
200 * @domain: a domain name
201 *
202 * Remove all cookies of @cookie_manager for the given @domain.
203 */
204void webkit_cookie_manager_delete_cookies_for_domain(WebKitCookieManager* manager, const gchar* domain)
205{
206 g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
207 g_return_if_fail(domain);
208
209 WKRetainPtr<WKStringRef> wkDomain(AdoptWK, WKStringCreateWithUTF8CString(domain));
210 WKCookieManagerDeleteCookiesForHostname(manager->priv->wkCookieManager.get(), wkDomain.get());
211}
212
213/**
214 * webkit_cookie_manager_delete_all_cookies:
215 * @cookie_manager: a #WebKitCookieManager
216 *
217 * Delete all cookies of @cookie_manager
218 */
219void webkit_cookie_manager_delete_all_cookies(WebKitCookieManager* manager)
220{
221 g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
222
223 WKCookieManagerDeleteAllCookies(manager->priv->wkCookieManager.get());
224}