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 Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 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 22#include "WebKitTestServer.h" 23#include "WebViewTest.h" 24#include <glib/gstdio.h> 25 26static WebKitTestServer* kServer; 27static char* kTempDirectory; 28 29static const char* kFirstPartyDomain = "127.0.0.1"; 30static const char* kThirdPartyDomain = "localhost"; 31static const char* kIndexHtmlFormat = 32 "<html><body>" 33 " <p>WebKitGTK+ Cookie Manager test</p>" 34 " <img src='http://localhost:%u/image.png' width=5 height=5></img>" 35 "</body></html>"; 36 37class CookieManagerTest: public WebViewTest { 38public: 39 MAKE_GLIB_TEST_FIXTURE(CookieManagerTest); 40 41 static void cookiesChangedCallback(WebKitCookieManager*, CookieManagerTest* test) 42 { 43 test->m_cookiesChanged = true; 44 if (test->m_finishLoopWhenCookiesChange) 45 g_main_loop_quit(test->m_mainLoop); 46 } 47 48 CookieManagerTest() 49 : WebViewTest() 50 , m_cookieManager(webkit_web_context_get_cookie_manager(webkit_web_view_get_context(m_webView))) 51 , m_acceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY) 52 , m_domains(0) 53 , m_cookiesChanged(false) 54 , m_finishLoopWhenCookiesChange(false) 55 { 56 g_signal_connect(m_cookieManager, "changed", G_CALLBACK(cookiesChangedCallback), this); 57 } 58 59 ~CookieManagerTest() 60 { 61 g_strfreev(m_domains); 62 g_signal_handlers_disconnect_matched(m_cookieManager, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); 63 if (m_cookiesTextFile) 64 g_unlink(m_cookiesTextFile.get()); 65 if (m_cookiesSQLiteFile) 66 g_unlink(m_cookiesSQLiteFile.get()); 67 } 68 69 void setPersistentStorage(WebKitCookiePersistentStorage storage) 70 { 71 const char* filename = 0; 72 switch (storage) { 73 case WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT: 74 if (!m_cookiesTextFile) 75 m_cookiesTextFile.set(g_build_filename(kTempDirectory, "cookies.txt", NULL)); 76 filename = m_cookiesTextFile.get(); 77 break; 78 case WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE: 79 if (!m_cookiesSQLiteFile) 80 m_cookiesSQLiteFile.set(g_build_filename(kTempDirectory, "cookies.db", NULL)); 81 filename = m_cookiesSQLiteFile.get(); 82 break; 83 default: 84 g_assert_not_reached(); 85 } 86 webkit_cookie_manager_set_persistent_storage(m_cookieManager, filename, storage); 87 } 88 89 static void getAcceptPolicyReadyCallback(GObject* object, GAsyncResult* result, gpointer userData) 90 { 91 GOwnPtr<GError> error; 92 WebKitCookieAcceptPolicy policy = webkit_cookie_manager_get_accept_policy_finish(WEBKIT_COOKIE_MANAGER(object), result, &error.outPtr()); 93 g_assert(!error.get()); 94 95 CookieManagerTest* test = static_cast<CookieManagerTest*>(userData); 96 test->m_acceptPolicy = policy; 97 g_main_loop_quit(test->m_mainLoop); 98 } 99 100 WebKitCookieAcceptPolicy getAcceptPolicy() 101 { 102 m_acceptPolicy = WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY; 103 webkit_cookie_manager_get_accept_policy(m_cookieManager, 0, getAcceptPolicyReadyCallback, this); 104 g_main_loop_run(m_mainLoop); 105 106 return m_acceptPolicy; 107 } 108 109 void setAcceptPolicy(WebKitCookieAcceptPolicy policy) 110 { 111 webkit_cookie_manager_set_accept_policy(m_cookieManager, policy); 112 } 113 114 static void getDomainsReadyCallback(GObject* object, GAsyncResult* result, gpointer userData) 115 { 116 GOwnPtr<GError> error; 117 char** domains = webkit_cookie_manager_get_domains_with_cookies_finish(WEBKIT_COOKIE_MANAGER(object), result, &error.outPtr()); 118 g_assert(!error.get()); 119 120 CookieManagerTest* test = static_cast<CookieManagerTest*>(userData); 121 test->m_domains = domains; 122 g_main_loop_quit(test->m_mainLoop); 123 } 124 125 char** getDomains() 126 { 127 g_strfreev(m_domains); 128 m_domains = 0; 129 webkit_cookie_manager_get_domains_with_cookies(m_cookieManager, 0, getDomainsReadyCallback, this); 130 g_main_loop_run(m_mainLoop); 131 132 return m_domains; 133 } 134 135 bool hasDomain(const char* domain) 136 { 137 if (!m_domains) 138 return false; 139 140 for (size_t i = 0; m_domains[i]; ++i) 141 if (g_str_equal(m_domains[i], domain)) 142 return true; 143 return false; 144 } 145 146 void deleteCookiesForDomain(const char* domain) 147 { 148 webkit_cookie_manager_delete_cookies_for_domain(m_cookieManager, domain); 149 } 150 151 void deleteAllCookies() 152 { 153 webkit_cookie_manager_delete_all_cookies(m_cookieManager); 154 } 155 156 void waitUntilCookiesChanged() 157 { 158 m_cookiesChanged = false; 159 m_finishLoopWhenCookiesChange = true; 160 g_main_loop_run(m_mainLoop); 161 m_finishLoopWhenCookiesChange = false; 162 } 163 164 WebKitCookieManager* m_cookieManager; 165 WebKitCookieAcceptPolicy m_acceptPolicy; 166 char** m_domains; 167 bool m_cookiesChanged; 168 bool m_finishLoopWhenCookiesChange; 169 GOwnPtr<char> m_cookiesTextFile; 170 GOwnPtr<char> m_cookiesSQLiteFile; 171}; 172 173static void testCookieManagerAcceptPolicy(CookieManagerTest* test, gconstpointer) 174{ 175 // Default policy is NO_THIRD_PARTY. 176 g_assert_cmpint(test->getAcceptPolicy(), ==, WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY); 177 test->loadURI(kServer->getURIForPath("/index.html").data()); 178 test->waitUntilLoadFinished(); 179 char** domains = test->getDomains(); 180 g_assert(domains); 181 g_assert_cmpint(g_strv_length(domains), ==, 1); 182 g_assert_cmpstr(domains[0], ==, kFirstPartyDomain); 183 test->deleteAllCookies(); 184 185 test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); 186 g_assert_cmpint(test->getAcceptPolicy(), ==, WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); 187 test->loadURI(kServer->getURIForPath("/index.html").data()); 188 test->waitUntilLoadFinished(); 189 domains = test->getDomains(); 190 g_assert(domains); 191 g_assert_cmpint(g_strv_length(domains), ==, 2); 192 g_assert(test->hasDomain(kFirstPartyDomain)); 193 g_assert(test->hasDomain(kThirdPartyDomain)); 194 test->deleteAllCookies(); 195 196 test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_NEVER); 197 g_assert_cmpint(test->getAcceptPolicy(), ==, WEBKIT_COOKIE_POLICY_ACCEPT_NEVER); 198 test->loadURI(kServer->getURIForPath("/index.html").data()); 199 test->waitUntilLoadFinished(); 200 domains = test->getDomains(); 201 g_assert(domains); 202 g_assert_cmpint(g_strv_length(domains), ==, 0); 203} 204 205static void testCookieManagerDeleteCookies(CookieManagerTest* test, gconstpointer) 206{ 207 test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); 208 test->loadURI(kServer->getURIForPath("/index.html").data()); 209 test->waitUntilLoadFinished(); 210 g_assert_cmpint(g_strv_length(test->getDomains()), ==, 2); 211 212 // Delete first party cookies. 213 test->deleteCookiesForDomain(kFirstPartyDomain); 214 g_assert_cmpint(g_strv_length(test->getDomains()), ==, 1); 215 216 // Delete third party cookies. 217 test->deleteCookiesForDomain(kThirdPartyDomain); 218 g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); 219 220 test->loadURI(kServer->getURIForPath("/index.html").data()); 221 test->waitUntilLoadFinished(); 222 g_assert_cmpint(g_strv_length(test->getDomains()), ==, 2); 223 224 // Delete all cookies. 225 test->deleteAllCookies(); 226 g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); 227} 228 229static void testCookieManagerCookiesChanged(CookieManagerTest* test, gconstpointer) 230{ 231 g_assert(!test->m_cookiesChanged); 232 test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); 233 test->loadURI(kServer->getURIForPath("/index.html").data()); 234 test->waitUntilLoadFinished(); 235 g_assert(test->m_cookiesChanged); 236 237 test->deleteCookiesForDomain(kFirstPartyDomain); 238 test->waitUntilCookiesChanged(); 239 g_assert(test->m_cookiesChanged); 240 241 test->deleteAllCookies(); 242 test->waitUntilCookiesChanged(); 243 g_assert(test->m_cookiesChanged); 244} 245 246static void testCookieManagerPersistentStorage(CookieManagerTest* test, gconstpointer) 247{ 248 test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); 249 250 // Text storage using a new file. 251 test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT); 252 char** domains = test->getDomains(); 253 g_assert(domains); 254 g_assert_cmpint(g_strv_length(domains), ==, 0); 255 256 test->loadURI(kServer->getURIForPath("/index.html").data()); 257 test->waitUntilLoadFinished(); 258 g_assert(test->m_cookiesChanged); 259 domains = test->getDomains(); 260 g_assert(domains); 261 g_assert_cmpint(g_strv_length(domains), ==, 2); 262 263 264 // SQLite storage using a new file. 265 test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE); 266 domains = test->getDomains(); 267 g_assert(domains); 268 g_assert_cmpint(g_strv_length(domains), ==, 0); 269 270 test->loadURI(kServer->getURIForPath("/index.html").data()); 271 test->waitUntilLoadFinished(); 272 g_assert(test->m_cookiesChanged); 273 domains = test->getDomains(); 274 g_assert(domains); 275 g_assert_cmpint(g_strv_length(domains), ==, 2); 276 277 // Text storage using an existing file. 278 test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT); 279 domains = test->getDomains(); 280 g_assert(domains); 281 g_assert_cmpint(g_strv_length(domains), ==, 2); 282 test->deleteAllCookies(); 283 g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); 284 285 // SQLite storage with an existing file. 286 test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE); 287 domains = test->getDomains(); 288 g_assert(domains); 289 g_assert_cmpint(g_strv_length(domains), ==, 2); 290 test->deleteAllCookies(); 291 g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); 292} 293 294static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) 295{ 296 if (message->method != SOUP_METHOD_GET) { 297 soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); 298 return; 299 } 300 301 soup_message_set_status(message, SOUP_STATUS_OK); 302 if (g_str_equal(path, "/index.html")) { 303 char* indexHtml = g_strdup_printf(kIndexHtmlFormat, soup_server_get_port(server)); 304 soup_message_headers_replace(message->response_headers, "Set-Cookie", "foo=bar; Max-Age=60"); 305 soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, indexHtml, strlen(indexHtml)); 306 } else if (g_str_equal(path, "/image.png")) 307 soup_message_headers_replace(message->response_headers, "Set-Cookie", "baz=qux; Max-Age=60"); 308 else 309 soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); 310 soup_message_body_complete(message->response_body); 311} 312 313void beforeAll() 314{ 315 kServer = new WebKitTestServer(); 316 kServer->run(serverCallback); 317 318 kTempDirectory = g_dir_make_tmp("WebKit2Tests-XXXXXX", 0); 319 g_assert(kTempDirectory); 320 321 CookieManagerTest::add("WebKitCookieManager", "accept-policy", testCookieManagerAcceptPolicy); 322 CookieManagerTest::add("WebKitCookieManager", "delete-cookies", testCookieManagerDeleteCookies); 323 CookieManagerTest::add("WebKitCookieManager", "cookies-changed", testCookieManagerCookiesChanged); 324 CookieManagerTest::add("WebKitCookieManager", "persistent-storage", testCookieManagerPersistentStorage); 325} 326 327void afterAll() 328{ 329 delete kServer; 330 g_rmdir(kTempDirectory); 331} 332