1/*
2    Copyright (C) 2010 ProFUSION embedded systems
3    Copyright (C) 2010 Samsung Electronics
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Library General Public
7    License as published by the Free Software Foundation; either
8    version 2 of the License, or (at your option) any later version.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Library General Public License for more details.
14
15    You should have received a copy of the GNU Library General Public License
16    along with this library; see the file COPYING.LIB.  If not, write to
17    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18    Boston, MA 02110-1301, USA.
19*/
20
21#include "config.h"
22#include "ewk_cookies.h"
23
24#if USE(SOUP)
25#include "CookieJarSoup.h"
26#endif
27#include "EWebKit.h"
28#include "ResourceHandle.h"
29
30#include <Eina.h>
31#include <eina_safety_checks.h>
32#if USE(SOUP)
33#include <glib.h>
34#include <libsoup/soup.h>
35#endif
36#include <wtf/text/CString.h>
37
38
39/**
40 * Sets the path where the cookies are going to be stored. Use @c NULL for keep
41 * them just in memory.
42 *
43 * @param filename path to the cookies.txt file.
44 *
45 * @return @c EINA_FALSE if it wasn't possible to create the cookie jar,
46 *          @c EINA_FALSE otherwise.
47 */
48EAPI Eina_Bool ewk_cookies_file_set(const char *filename)
49{
50#if USE(SOUP)
51    SoupCookieJar* cookieJar = 0;
52    if (filename)
53        cookieJar = soup_cookie_jar_text_new(filename, FALSE);
54    else
55        cookieJar = soup_cookie_jar_new();
56
57    if (!cookieJar)
58        return EINA_FALSE;
59
60    soup_cookie_jar_set_accept_policy(cookieJar, SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY);
61
62    SoupSession* session = WebCore::ResourceHandle::defaultSession();
63    SoupSessionFeature* oldjar = soup_session_get_feature(session, SOUP_TYPE_COOKIE_JAR);
64    if (oldjar)
65        soup_session_remove_feature(session, oldjar);
66
67    WebCore::setDefaultCookieJar(cookieJar);
68    soup_session_add_feature(session, SOUP_SESSION_FEATURE(cookieJar));
69
70    return EINA_TRUE;
71#else
72    return EINA_FALSE;
73#endif
74}
75
76/**
77 * Clears all the cookies from the cookie jar.
78 */
79EAPI void ewk_cookies_clear(void)
80{
81#if USE(SOUP)
82    GSList* l;
83    GSList* p;
84    SoupCookieJar* cookieJar = WebCore::defaultCookieJar();
85
86    l = soup_cookie_jar_all_cookies(cookieJar);
87    for (p = l; p; p = p->next)
88        soup_cookie_jar_delete_cookie(cookieJar, (SoupCookie*)p->data);
89
90    soup_cookies_free(l);
91#endif
92}
93
94/**
95 * Returns a list of cookies in the cookie jar.
96 *
97 * @return an @c Eina_List with all the cookies in the cookie jar.
98 */
99EAPI Eina_List* ewk_cookies_get_all(void)
100{
101    Eina_List* el = 0;
102#if USE(SOUP)
103    GSList* l;
104    GSList* p;
105    SoupCookieJar* cookieJar = WebCore::defaultCookieJar();
106
107    l = soup_cookie_jar_all_cookies(cookieJar);
108    for (p = l; p; p = p->next) {
109        SoupCookie* cookie = static_cast<SoupCookie*>(p->data);
110        Ewk_Cookie* c = static_cast<Ewk_Cookie*>(malloc(sizeof(*c)));
111        c->name = strdup(cookie->name);
112        c->value = strdup(cookie->value);
113        c->domain = strdup(cookie->domain);
114        c->path = strdup(cookie->path);
115        c->expires = soup_date_to_time_t(cookie->expires);
116        c->secure = static_cast<Eina_Bool>(cookie->secure);
117        c->http_only = static_cast<Eina_Bool>(cookie->http_only);
118        el = eina_list_append(el, c);
119    }
120
121    soup_cookies_free(l);
122#endif
123    return el;
124}
125
126/**
127 * Deletes a cookie from the cookie jar.
128 *
129 * Note that the fields name, value, domain and path are used to match this
130 * cookie in the cookie jar.
131 *
132 * @param cookie an @c Ewk_Cookie that has the info relative to that cookie.
133 */
134EAPI void ewk_cookies_cookie_del(Ewk_Cookie *cookie)
135{
136#if USE(SOUP)
137    EINA_SAFETY_ON_NULL_RETURN(cookie);
138    GSList* l;
139    GSList* p;
140    SoupCookieJar* cookieJar = WebCore::defaultCookieJar();
141    SoupCookie* c1 = soup_cookie_new(
142        cookie->name, cookie->value, cookie->domain, cookie->path, -1);
143
144    l = soup_cookie_jar_all_cookies(cookieJar);
145    for (p = l; p; p = p->next) {
146        SoupCookie* c2 = static_cast<SoupCookie*>(p->data);
147        if (soup_cookie_equal(c1, c2)) {
148            soup_cookie_jar_delete_cookie(cookieJar, c2);
149            break;
150        }
151    }
152
153    soup_cookie_free(c1);
154    soup_cookies_free(l);
155#endif
156}
157
158/**
159 * Frees the memory used by a cookie.
160 *
161 * @param cookie the Ewk_Cookie struct that will be freed.
162 */
163EAPI void ewk_cookies_cookie_free(Ewk_Cookie *cookie)
164{
165#if USE(SOUP)
166    EINA_SAFETY_ON_NULL_RETURN(cookie);
167    free(cookie->name);
168    free(cookie->value);
169    free(cookie->domain);
170    free(cookie->path);
171    free(cookie);
172#endif
173}
174
175/**
176 * Sets the cookies accept policy.
177 *
178 * @param p the acceptance policy
179 * @see Ewk_Cookie_Policy
180 */
181EAPI void ewk_cookies_policy_set(Ewk_Cookie_Policy p)
182{
183#if USE(SOUP)
184    SoupCookieJar* cookieJar = WebCore::defaultCookieJar();
185    SoupCookieJarAcceptPolicy policy;
186
187    policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
188    switch (p) {
189    case EWK_COOKIE_JAR_ACCEPT_NEVER:
190        policy = SOUP_COOKIE_JAR_ACCEPT_NEVER;
191        break;
192    case EWK_COOKIE_JAR_ACCEPT_ALWAYS:
193        policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
194        break;
195    case EWK_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY:
196        policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY;
197        break;
198    }
199
200    soup_cookie_jar_set_accept_policy(cookieJar, policy);
201#endif
202}
203
204/**
205 * Gets the acceptance policy used in the current cookie jar.
206 *
207 * @return the current acceptance policy
208 * @see Ewk_Cookie_Policy
209 */
210EAPI Ewk_Cookie_Policy ewk_cookies_policy_get(void)
211{
212    Ewk_Cookie_Policy ewk_policy = EWK_COOKIE_JAR_ACCEPT_ALWAYS;
213#if USE(SOUP)
214    SoupCookieJar* cookieJar = WebCore::defaultCookieJar();
215    SoupCookieJarAcceptPolicy policy;
216
217    policy = soup_cookie_jar_get_accept_policy(cookieJar);
218    switch (policy) {
219    case SOUP_COOKIE_JAR_ACCEPT_NEVER:
220        ewk_policy = EWK_COOKIE_JAR_ACCEPT_NEVER;
221        break;
222    case SOUP_COOKIE_JAR_ACCEPT_ALWAYS:
223        ewk_policy = EWK_COOKIE_JAR_ACCEPT_ALWAYS;
224        break;
225    case SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY:
226        ewk_policy = EWK_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY;
227        break;
228    }
229#endif
230
231    return ewk_policy;
232}
233