| /* |
| * Copyright (C) 2012 Igalia S.L. |
| * Copyright (C) 2017 Endless Mobile, Inc. |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public License |
| * along with this library; see the file COPYING.LIB. If not, write to |
| * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| */ |
| |
| #include "config.h" |
| |
| #include "WebKitTestServer.h" |
| #include "WebViewTest.h" |
| #include <WebCore/GUniquePtrSoup.h> |
| #include <glib/gstdio.h> |
| |
| static WebKitTestServer* kServer; |
| |
| static const char* kFirstPartyDomain = "127.0.0.1"; |
| static const char* kThirdPartyDomain = "localhost"; |
| |
| static const char* kCookieName = "foo"; |
| static const char* kCookieValue = "bar"; |
| static const char* kCookiePath = "/"; |
| |
| static const char* kCookiePathNew = "/new"; |
| static const char* kCookieValueNew = "new-value"; |
| |
| static const char* kIndexHtmlFormat = |
| "<html><body>" |
| " <p>WebKitGTK+ Cookie Manager test</p>" |
| " <img src='http://localhost:%u/image.png' width=5 height=5></img>" |
| "</body></html>"; |
| |
| class CookieManagerTest: public WebViewTest { |
| public: |
| MAKE_GLIB_TEST_FIXTURE(CookieManagerTest); |
| |
| static void cookiesChangedCallback(WebKitCookieManager*, CookieManagerTest* test) |
| { |
| test->m_cookiesChanged = true; |
| if (test->m_finishLoopWhenCookiesChange && !(--test->m_cookiesExpectedToChangeCount)) |
| g_main_loop_quit(test->m_mainLoop); |
| } |
| |
| CookieManagerTest() |
| : WebViewTest() |
| , m_cookieManager(webkit_web_context_get_cookie_manager(m_webContext.get())) |
| { |
| g_assert_true(webkit_website_data_manager_get_cookie_manager(webkit_web_context_get_website_data_manager(m_webContext.get())) == m_cookieManager); |
| g_signal_connect(m_cookieManager, "changed", G_CALLBACK(cookiesChangedCallback), this); |
| } |
| |
| ~CookieManagerTest() |
| { |
| g_strfreev(m_domains); |
| g_list_free_full(m_cookies, reinterpret_cast<GDestroyNotify>(soup_cookie_free)); |
| |
| g_signal_handlers_disconnect_matched(m_cookieManager, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); |
| if (m_cookiesTextFile) |
| g_unlink(m_cookiesTextFile.get()); |
| if (m_cookiesSQLiteFile) |
| g_unlink(m_cookiesSQLiteFile.get()); |
| } |
| |
| void setPersistentStorage(WebKitCookiePersistentStorage storage) |
| { |
| const char* filename = 0; |
| switch (storage) { |
| case WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT: |
| if (!m_cookiesTextFile) |
| m_cookiesTextFile.reset(g_build_filename(Test::dataDirectory(), "cookies.txt", nullptr)); |
| filename = m_cookiesTextFile.get(); |
| break; |
| case WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE: |
| if (!m_cookiesSQLiteFile) |
| m_cookiesSQLiteFile.reset(g_build_filename(Test::dataDirectory(), "cookies.db", nullptr)); |
| filename = m_cookiesSQLiteFile.get(); |
| break; |
| default: |
| g_assert_not_reached(); |
| } |
| webkit_cookie_manager_set_persistent_storage(m_cookieManager, filename, storage); |
| } |
| |
| static void getAcceptPolicyReadyCallback(GObject* object, GAsyncResult* result, gpointer userData) |
| { |
| GUniqueOutPtr<GError> error; |
| WebKitCookieAcceptPolicy policy = webkit_cookie_manager_get_accept_policy_finish(WEBKIT_COOKIE_MANAGER(object), result, &error.outPtr()); |
| g_assert_no_error(error.get()); |
| |
| CookieManagerTest* test = static_cast<CookieManagerTest*>(userData); |
| test->m_acceptPolicy = policy; |
| g_main_loop_quit(test->m_mainLoop); |
| } |
| |
| WebKitCookieAcceptPolicy getAcceptPolicy() |
| { |
| m_acceptPolicy = WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY; |
| webkit_cookie_manager_get_accept_policy(m_cookieManager, 0, getAcceptPolicyReadyCallback, this); |
| g_main_loop_run(m_mainLoop); |
| |
| return m_acceptPolicy; |
| } |
| |
| static void addCookieReadyCallback(GObject* object, GAsyncResult* result, gpointer userData) |
| { |
| GUniqueOutPtr<GError> error; |
| bool added = webkit_cookie_manager_add_cookie_finish(WEBKIT_COOKIE_MANAGER(object), result, &error.outPtr()); |
| g_assert_no_error(error.get()); |
| g_assert_true(added); |
| |
| CookieManagerTest* test = static_cast<CookieManagerTest*>(userData); |
| g_main_loop_quit(test->m_mainLoop); |
| } |
| |
| void addCookie(SoupCookie* cookie) |
| { |
| webkit_cookie_manager_add_cookie(m_cookieManager, cookie, 0, addCookieReadyCallback, this); |
| g_main_loop_run(m_mainLoop); |
| } |
| |
| static void getCookiesReadyCallback(GObject* object, GAsyncResult* result, gpointer userData) |
| { |
| GUniqueOutPtr<GError> error; |
| GList* cookies = webkit_cookie_manager_get_cookies_finish(WEBKIT_COOKIE_MANAGER(object), result, &error.outPtr()); |
| g_assert_no_error(error.get()); |
| |
| CookieManagerTest* test = static_cast<CookieManagerTest*>(userData); |
| test->m_cookies = cookies; |
| g_main_loop_quit(test->m_mainLoop); |
| } |
| |
| GList* getCookies(const char* uri) |
| { |
| g_list_free_full(m_cookies, reinterpret_cast<GDestroyNotify>(soup_cookie_free)); |
| m_cookies = nullptr; |
| webkit_cookie_manager_get_cookies(m_cookieManager, uri, 0, getCookiesReadyCallback, this); |
| g_main_loop_run(m_mainLoop); |
| |
| return m_cookies; |
| } |
| |
| static void deleteCookieReadyCallback(GObject* object, GAsyncResult* result, gpointer userData) |
| { |
| GUniqueOutPtr<GError> error; |
| bool deleted = webkit_cookie_manager_delete_cookie_finish(WEBKIT_COOKIE_MANAGER(object), result, &error.outPtr()); |
| g_assert_no_error(error.get()); |
| g_assert_true(deleted); |
| |
| CookieManagerTest* test = static_cast<CookieManagerTest*>(userData); |
| g_main_loop_quit(test->m_mainLoop); |
| } |
| |
| void deleteCookie(SoupCookie* cookie) |
| { |
| webkit_cookie_manager_delete_cookie(m_cookieManager, cookie, 0, deleteCookieReadyCallback, this); |
| g_main_loop_run(m_mainLoop); |
| } |
| |
| void setAcceptPolicy(WebKitCookieAcceptPolicy policy) |
| { |
| webkit_cookie_manager_set_accept_policy(m_cookieManager, policy); |
| } |
| |
| static void getDomainsReadyCallback(GObject* object, GAsyncResult* result, gpointer userData) |
| { |
| GUniqueOutPtr<GError> error; |
| G_GNUC_BEGIN_IGNORE_DEPRECATIONS; |
| char** domains = webkit_cookie_manager_get_domains_with_cookies_finish(WEBKIT_COOKIE_MANAGER(object), result, &error.outPtr()); |
| G_GNUC_END_IGNORE_DEPRECATIONS; |
| g_assert_no_error(error.get()); |
| |
| CookieManagerTest* test = static_cast<CookieManagerTest*>(userData); |
| test->m_domains = domains; |
| g_main_loop_quit(test->m_mainLoop); |
| } |
| |
| char** getDomains() |
| { |
| g_strfreev(m_domains); |
| m_domains = 0; |
| G_GNUC_BEGIN_IGNORE_DEPRECATIONS; |
| webkit_cookie_manager_get_domains_with_cookies(m_cookieManager, 0, getDomainsReadyCallback, this); |
| G_GNUC_END_IGNORE_DEPRECATIONS; |
| g_main_loop_run(m_mainLoop); |
| |
| return m_domains; |
| } |
| |
| bool hasDomain(const char* domain) |
| { |
| if (!m_domains) |
| return false; |
| |
| for (size_t i = 0; m_domains[i]; ++i) { |
| if (g_str_equal(m_domains[i], domain)) |
| return true; |
| } |
| return false; |
| } |
| |
| void deleteCookiesForDomain(const char* domain) |
| { |
| G_GNUC_BEGIN_IGNORE_DEPRECATIONS; |
| webkit_cookie_manager_delete_cookies_for_domain(m_cookieManager, domain); |
| G_GNUC_END_IGNORE_DEPRECATIONS; |
| } |
| |
| void deleteAllCookies() |
| { |
| G_GNUC_BEGIN_IGNORE_DEPRECATIONS; |
| webkit_cookie_manager_delete_all_cookies(m_cookieManager); |
| G_GNUC_END_IGNORE_DEPRECATIONS; |
| } |
| |
| void waitUntilCookiesChanged(int cookiesExpectedToChangeCount = 1) |
| { |
| m_cookiesChanged = false; |
| m_cookiesExpectedToChangeCount = cookiesExpectedToChangeCount; |
| m_finishLoopWhenCookiesChange = true; |
| g_main_loop_run(m_mainLoop); |
| m_finishLoopWhenCookiesChange = false; |
| } |
| |
| WebKitCookieManager* m_cookieManager { nullptr }; |
| WebKitCookieAcceptPolicy m_acceptPolicy { WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY }; |
| char** m_domains { nullptr }; |
| GList* m_cookies { nullptr }; |
| bool m_cookiesChanged { false }; |
| int m_cookiesExpectedToChangeCount { 0 }; |
| bool m_finishLoopWhenCookiesChange { false }; |
| GUniquePtr<char> m_cookiesTextFile; |
| GUniquePtr<char> m_cookiesSQLiteFile; |
| }; |
| |
| static void testCookieManagerAcceptPolicy(CookieManagerTest* test, gconstpointer) |
| { |
| // Default policy is NO_THIRD_PARTY. |
| g_assert_cmpint(test->getAcceptPolicy(), ==, WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY); |
| test->loadURI(kServer->getURIForPath("/index.html").data()); |
| test->waitUntilLoadFinished(); |
| char** domains = test->getDomains(); |
| g_assert_nonnull(domains); |
| g_assert_cmpint(g_strv_length(domains), ==, 1); |
| g_assert_cmpstr(domains[0], ==, kFirstPartyDomain); |
| test->deleteAllCookies(); |
| |
| test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); |
| g_assert_cmpint(test->getAcceptPolicy(), ==, WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); |
| test->loadURI(kServer->getURIForPath("/index.html").data()); |
| test->waitUntilLoadFinished(); |
| domains = test->getDomains(); |
| g_assert_nonnull(domains); |
| g_assert_cmpint(g_strv_length(domains), ==, 2); |
| g_assert_true(test->hasDomain(kFirstPartyDomain)); |
| g_assert_true(test->hasDomain(kThirdPartyDomain)); |
| test->deleteAllCookies(); |
| |
| test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_NEVER); |
| g_assert_cmpint(test->getAcceptPolicy(), ==, WEBKIT_COOKIE_POLICY_ACCEPT_NEVER); |
| test->loadURI(kServer->getURIForPath("/index.html").data()); |
| test->waitUntilLoadFinished(); |
| domains = test->getDomains(); |
| g_assert_nonnull(domains); |
| g_assert_cmpint(g_strv_length(domains), ==, 0); |
| } |
| |
| static void testCookieManagerAddCookie(CookieManagerTest* test, gconstpointer) |
| { |
| // Load the html content, with the default NO_THIRD_PARTY accept policy, |
| // which will automatically add one cookie. |
| test->loadURI(kServer->getURIForPath("/index.html").data()); |
| test->waitUntilLoadFinished(); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 1); |
| |
| // Check the cookies that have been added for the domain. |
| GUniquePtr<char> uri(g_strdup_printf("%s://%s", SOUP_URI_SCHEME_HTTP, kFirstPartyDomain)); |
| GList* foundCookies = test->getCookies(uri.get()); |
| g_assert_cmpint(g_list_length(foundCookies), ==, 1); |
| |
| SoupCookie* foundCookie = static_cast<SoupCookie*>(foundCookies->data); |
| g_assert_cmpstr(soup_cookie_get_name(foundCookie), ==, kCookieName); |
| g_assert_cmpstr(soup_cookie_get_domain(foundCookie), ==, kFirstPartyDomain); |
| g_assert_cmpstr(soup_cookie_get_path(foundCookie), ==, kCookiePath); |
| g_assert_cmpstr(soup_cookie_get_value(foundCookie), ==, kCookieValue); |
| |
| // Try to add now a cookie with same (name, domain, path) than the ones already added. |
| GUniquePtr<SoupCookie> firstCookie(soup_cookie_new(kCookieName, kCookieValueNew, kFirstPartyDomain, kCookiePath, SOUP_COOKIE_MAX_AGE_ONE_HOUR)); |
| test->addCookie(firstCookie.get()); |
| |
| // Still one cookie, since (name, domain, path) are the same than the already existing |
| // one, but the new value is now stored as replaced by the recently added cookie. |
| foundCookies = test->getCookies(uri.get()); |
| g_assert_cmpint(g_list_length(foundCookies), ==, 1); |
| |
| foundCookie = static_cast<SoupCookie*>(foundCookies->data); |
| g_assert_cmpstr(soup_cookie_get_name(foundCookie), ==, kCookieName); |
| g_assert_cmpstr(soup_cookie_get_domain(foundCookie), ==, kFirstPartyDomain); |
| g_assert_cmpstr(soup_cookie_get_path(foundCookie), ==, kCookiePath); |
| g_assert_cmpstr(soup_cookie_get_value(foundCookie), ==, kCookieValueNew); |
| |
| // Now create another cookie with a different path and add it. |
| GUniquePtr<SoupCookie> secondCookie(soup_cookie_new(kCookieName, kCookieValueNew, kFirstPartyDomain, kCookiePathNew, SOUP_COOKIE_MAX_AGE_ONE_HOUR)); |
| test->addCookie(secondCookie.get()); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 1); |
| |
| // Retrieve the list of cookies for the same domain and path again now and check. |
| uri.reset(g_strdup_printf("%s://%s%s", SOUP_URI_SCHEME_HTTP, kFirstPartyDomain, kCookiePathNew)); |
| foundCookies = test->getCookies(uri.get()); |
| |
| // We have now two cookies that would apply to the passed URL, one is the cookie initially |
| // loaded with the web content and the other cookie the one we manually added. |
| g_assert_cmpint(g_list_length(foundCookies), ==, 2); |
| |
| // Add a third new cookie for a different domain than the previous ones. |
| GUniquePtr<SoupCookie> thirdCookie(soup_cookie_new(kCookieName, kCookieValueNew, kThirdPartyDomain, kCookiePathNew, SOUP_COOKIE_MAX_AGE_ONE_HOUR)); |
| test->addCookie(thirdCookie.get()); |
| |
| // Only one cookie now, since the domain is different. |
| uri.reset(g_strdup_printf("%s://%s%s", SOUP_URI_SCHEME_HTTP, kThirdPartyDomain, kCookiePathNew)); |
| foundCookies = test->getCookies(uri.get()); |
| g_assert_cmpint(g_list_length(foundCookies), ==, 1); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 2); |
| |
| foundCookie = static_cast<SoupCookie*>(foundCookies->data); |
| g_assert_cmpstr(soup_cookie_get_name(foundCookie), ==, kCookieName); |
| g_assert_cmpstr(soup_cookie_get_domain(foundCookie), ==, kThirdPartyDomain); |
| g_assert_cmpstr(soup_cookie_get_path(foundCookie), ==, kCookiePathNew); |
| g_assert_cmpstr(soup_cookie_get_value(foundCookie), ==, kCookieValueNew); |
| |
| // Finally, delete all cookies and check they are all gone. |
| test->deleteAllCookies(); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); |
| } |
| |
| static void testCookieManagerGetCookies(CookieManagerTest* test, gconstpointer) |
| { |
| // Load the html content and retrieve the two cookies automatically added with ALWAYS policy. |
| test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); |
| test->loadURI(kServer->getURIForPath("/index.html").data()); |
| test->waitUntilLoadFinished(); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 2); |
| |
| // Retrieve the first cookie using a HTTP scheme. |
| GUniquePtr<char> uri(g_strdup_printf("%s://%s", SOUP_URI_SCHEME_HTTP, kFirstPartyDomain)); |
| GList* foundCookies = test->getCookies(uri.get()); |
| g_assert_cmpint(g_list_length(foundCookies), ==, 1); |
| |
| SoupCookie* foundCookie = static_cast<SoupCookie*>(foundCookies->data); |
| g_assert_cmpstr(soup_cookie_get_name(foundCookie), ==, kCookieName); |
| g_assert_cmpstr(soup_cookie_get_domain(foundCookie), ==, kFirstPartyDomain); |
| g_assert_cmpstr(soup_cookie_get_path(foundCookie), ==, kCookiePath); |
| g_assert_cmpstr(soup_cookie_get_value(foundCookie), ==, kCookieValue); |
| |
| // Retrieve the second cookie using a HTTPS scheme. |
| uri.reset(g_strdup_printf("%s://%s", SOUP_URI_SCHEME_HTTPS, kThirdPartyDomain)); |
| foundCookies = test->getCookies(uri.get()); |
| g_assert_cmpint(g_list_length(foundCookies), ==, 1); |
| |
| foundCookie = static_cast<SoupCookie*>(foundCookies->data); |
| g_assert_cmpstr(soup_cookie_get_name(foundCookie), ==, kCookieName); |
| g_assert_cmpstr(soup_cookie_get_domain(foundCookie), ==, kThirdPartyDomain); |
| g_assert_cmpstr(soup_cookie_get_path(foundCookie), ==, kCookiePath); |
| g_assert_cmpstr(soup_cookie_get_value(foundCookie), ==, kCookieValue); |
| |
| // Create a new cookie and add it to the first domain. |
| GUniquePtr<SoupCookie> newCookie(soup_cookie_new(kCookieName, kCookieValueNew, kFirstPartyDomain, kCookiePathNew, SOUP_COOKIE_MAX_AGE_ONE_HOUR)); |
| test->addCookie(newCookie.get()); |
| |
| // We should get two cookies that would apply to the same URL passed, since |
| // http://127.0.0.1/new is a subset of the http://127.0.0.1/ URL. |
| uri.reset(g_strdup_printf("%s://%s%s", SOUP_URI_SCHEME_HTTP, kFirstPartyDomain, kCookiePathNew)); |
| foundCookies = test->getCookies(uri.get()); |
| g_assert_cmpint(g_list_length(foundCookies), ==, 2); |
| |
| // We have now two cookies that would apply to the passed URL, one is the cookie initially |
| // loaded with the web content and the other cookie the one we manually added. |
| g_assert_cmpint(g_list_length(foundCookies), ==, 2); |
| |
| bool newPathChecked = false; |
| const char* pathFound = nullptr; |
| const char* valueFound = nullptr; |
| for (uint i = 0; i < 2; i++) { |
| foundCookie = static_cast<SoupCookie*>(g_list_nth_data(foundCookies, i)); |
| g_assert_cmpstr(soup_cookie_get_name(foundCookie), ==, kCookieName); |
| g_assert_cmpstr(soup_cookie_get_domain(foundCookie), ==, kFirstPartyDomain); |
| |
| // Cookies will have different values for 'value' and 'path', so make sure that |
| // we check for both possibilities, but different ones for each cookie found. |
| pathFound = soup_cookie_get_path(foundCookie); |
| valueFound = soup_cookie_get_value(foundCookie); |
| if (i > 0) { |
| if (newPathChecked) { |
| g_assert_cmpstr(pathFound, ==, kCookiePath); |
| g_assert_cmpstr(valueFound, ==, kCookieValue); |
| } else { |
| g_assert_cmpstr(pathFound, ==, kCookiePathNew); |
| g_assert_cmpstr(valueFound, ==, kCookieValueNew); |
| } |
| } else { |
| if (g_strcmp0(pathFound, kCookiePath)) { |
| g_assert_cmpstr(pathFound, ==, kCookiePathNew); |
| g_assert_cmpstr(valueFound, ==, kCookieValueNew); |
| newPathChecked = true; |
| } |
| |
| if (g_strcmp0(pathFound, kCookiePathNew)) { |
| g_assert_cmpstr(pathFound, ==, kCookiePath); |
| g_assert_cmpstr(valueFound, ==, kCookieValue); |
| newPathChecked = false; |
| } |
| } |
| } |
| |
| // We should get 1 cookie only if we specify http://127.0.0.1/, though. |
| uri.reset(g_strdup_printf("%s://%s", SOUP_URI_SCHEME_HTTP, kFirstPartyDomain)); |
| foundCookies = test->getCookies(uri.get()); |
| g_assert_cmpint(g_list_length(foundCookies), ==, 1); |
| |
| foundCookie = static_cast<SoupCookie*>(foundCookies->data); |
| g_assert_cmpstr(soup_cookie_get_name(foundCookie), ==, kCookieName); |
| g_assert_cmpstr(soup_cookie_get_domain(foundCookie), ==, kFirstPartyDomain); |
| g_assert_cmpstr(soup_cookie_get_path(foundCookie), ==, kCookiePath); |
| g_assert_cmpstr(soup_cookie_get_value(foundCookie), ==, kCookieValue); |
| |
| // Finally, delete all cookies and try to retrieve them again, one by one. |
| test->deleteAllCookies(); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); |
| |
| uri.reset(g_strdup_printf("%s://%s", SOUP_URI_SCHEME_HTTP, kFirstPartyDomain)); |
| foundCookies = test->getCookies(uri.get()); |
| g_assert_null(foundCookies); |
| } |
| |
| static void testCookieManagerDeleteCookie(CookieManagerTest* test, gconstpointer) |
| { |
| test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); |
| test->loadURI(kServer->getURIForPath("/index.html").data()); |
| test->waitUntilLoadFinished(); |
| |
| // Initially, there should be two cookies available. |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 2); |
| |
| // Delete the cookie for the first party domain. |
| GUniquePtr<char> uri(g_strdup_printf("%s://%s", SOUP_URI_SCHEME_HTTP, kFirstPartyDomain)); |
| GList* foundCookies = test->getCookies(uri.get()); |
| g_assert_cmpint(g_list_length(foundCookies), ==, 1); |
| |
| GUniquePtr<SoupCookie> firstPartyCookie(soup_cookie_copy(static_cast<SoupCookie*>(foundCookies->data))); |
| test->deleteCookie(firstPartyCookie.get()); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 1); |
| |
| // Try deleting a non-existent cookie (wrong name). |
| GUniquePtr<SoupCookie> wrongCookie(soup_cookie_new("wrong-name", kCookieValue, kThirdPartyDomain, kCookiePath, -1)); |
| test->deleteCookie(wrongCookie.get()); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 1); |
| |
| // Try deleting a non-existent cookie (wrong domain). |
| wrongCookie.reset(soup_cookie_new(kCookieName, kCookieValue, "wrong-domain", kCookiePath, -1)); |
| test->deleteCookie(wrongCookie.get()); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 1); |
| |
| // Try deleting a non-existent cookie (wrong path). |
| wrongCookie.reset(soup_cookie_new(kCookieName, kCookieValue, kThirdPartyDomain, "wrong-path", -1)); |
| test->deleteCookie(wrongCookie.get()); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 1); |
| |
| // Delete the cookie for the third party domain. |
| uri.reset(g_strdup_printf("%s://%s", SOUP_URI_SCHEME_HTTP, kThirdPartyDomain)); |
| foundCookies = test->getCookies(uri.get()); |
| g_assert_cmpint(g_list_length(foundCookies), ==, 1); |
| |
| GUniquePtr<SoupCookie> thirdPartyCookie(soup_cookie_copy(static_cast<SoupCookie*>(foundCookies->data))); |
| test->deleteCookie(thirdPartyCookie.get()); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); |
| |
| // Finally, add a new cookie now we don't have any and delete it afterwards. |
| GUniquePtr<SoupCookie> newCookie(soup_cookie_new(kCookieName, kCookieValueNew, kFirstPartyDomain, kCookiePathNew, SOUP_COOKIE_MAX_AGE_ONE_HOUR)); |
| test->addCookie(newCookie.get()); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 1); |
| test->deleteCookie(newCookie.get()); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); |
| } |
| |
| static void testCookieManagerDeleteCookies(CookieManagerTest* test, gconstpointer) |
| { |
| test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); |
| test->loadURI(kServer->getURIForPath("/index.html").data()); |
| test->waitUntilLoadFinished(); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 2); |
| |
| // Delete first party cookies. |
| test->deleteCookiesForDomain(kFirstPartyDomain); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 1); |
| |
| // Delete third party cookies. |
| test->deleteCookiesForDomain(kThirdPartyDomain); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); |
| |
| test->loadURI(kServer->getURIForPath("/index.html").data()); |
| test->waitUntilLoadFinished(); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 2); |
| |
| // Delete all cookies. |
| test->deleteAllCookies(); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); |
| } |
| |
| static void testCookieManagerCookiesChanged(CookieManagerTest* test, gconstpointer) |
| { |
| g_assert_false(test->m_cookiesChanged); |
| test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); |
| test->loadURI(kServer->getURIForPath("/index.html").data()); |
| test->waitUntilLoadFinished(); |
| g_assert_true(test->m_cookiesChanged); |
| |
| test->deleteCookiesForDomain(kFirstPartyDomain); |
| test->waitUntilCookiesChanged(); |
| g_assert_true(test->m_cookiesChanged); |
| |
| test->deleteAllCookies(); |
| test->waitUntilCookiesChanged(); |
| g_assert_true(test->m_cookiesChanged); |
| } |
| |
| class CookiePersistentStorageTest : public CookieManagerTest { |
| public: |
| MAKE_GLIB_TEST_FIXTURE_WITH_SETUP_TEARDOWN(CookiePersistentStorageTest, setup, teardown); |
| |
| static void setup() |
| { |
| WebViewTest::shouldInitializeWebViewInConstructor = false; |
| } |
| |
| static void teardown() |
| { |
| WebViewTest::shouldInitializeWebViewInConstructor = true; |
| } |
| }; |
| |
| static void testCookieManagerPersistentStorage(CookiePersistentStorageTest* test, gconstpointer) |
| { |
| test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); |
| |
| g_unlink(test->m_cookiesTextFile.get()); |
| g_unlink(test->m_cookiesSQLiteFile.get()); |
| |
| // Text storage using a new file. |
| test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT); |
| char** domains = test->getDomains(); |
| g_assert_nonnull(domains); |
| g_assert_cmpint(g_strv_length(domains), ==, 0); |
| |
| // Initialization of web view is deferred to ensure it's not required for |
| // setting persistent storage to work. |
| test->initializeWebView(); |
| test->loadURI(kServer->getURIForPath("/index.html").data()); |
| test->waitUntilLoadFinished(); |
| g_assert_true(test->m_cookiesChanged); |
| domains = test->getDomains(); |
| g_assert_nonnull(domains); |
| g_assert_cmpint(g_strv_length(domains), ==, 2); |
| g_assert_true(g_file_test(test->m_cookiesTextFile.get(), G_FILE_TEST_EXISTS)); |
| |
| // SQLite storage using a new file. |
| test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE); |
| domains = test->getDomains(); |
| g_assert_nonnull(domains); |
| g_assert_cmpint(g_strv_length(domains), ==, 0); |
| |
| test->loadURI(kServer->getURIForPath("/index.html").data()); |
| test->waitUntilLoadFinished(); |
| g_assert_true(test->m_cookiesChanged); |
| domains = test->getDomains(); |
| g_assert_nonnull(domains); |
| g_assert_cmpint(g_strv_length(domains), ==, 2); |
| g_assert_true(g_file_test(test->m_cookiesSQLiteFile.get(), G_FILE_TEST_EXISTS)); |
| |
| // Text storage using an existing file. |
| test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT); |
| domains = test->getDomains(); |
| g_assert_nonnull(domains); |
| g_assert_cmpint(g_strv_length(domains), ==, 2); |
| test->deleteAllCookies(); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); |
| |
| // SQLite storage with an existing file. |
| test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE); |
| domains = test->getDomains(); |
| g_assert_nonnull(domains); |
| g_assert_cmpint(g_strv_length(domains), ==, 2); |
| test->deleteAllCookies(); |
| g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); |
| } |
| |
| static void testCookieManagerPersistentStorageDeleteAll(CookieManagerTest* test, gconstpointer) |
| { |
| // This checks that we can remove all the cookies of an existing file before a web process is created. |
| // See bug https://bugs.webkit.org/show_bug.cgi?id=175265. |
| static const char cookiesFileFormat[] = "127.0.0.1\tFALSE\t/\tFALSE\t%ld\tfoo\tbar\nlocalhost\tFALSE\t/\tFALSE\t%ld\tbaz\tqux\n"; |
| time_t expires = time(nullptr) + 60; |
| GUniquePtr<char> cookiesFileContents(g_strdup_printf(cookiesFileFormat, expires, expires)); |
| GUniquePtr<char> cookiesFile(g_build_filename(Test::dataDirectory(), "cookies.txt", nullptr)); |
| g_assert_true(g_file_set_contents(cookiesFile.get(), cookiesFileContents.get(), -1, nullptr)); |
| |
| test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT); |
| test->deleteAllCookies(); |
| // Changed signal is emitted for every deleted cookie, twice in this case. |
| test->waitUntilCookiesChanged(2); |
| |
| // Ensure the web process is created and load something without cookies. |
| test->m_cookiesChanged = false; |
| test->loadURI(kServer->getURIForPath("/no-cookies.html").data()); |
| test->waitUntilLoadFinished(); |
| g_assert_false(test->m_cookiesChanged); |
| char** domains = test->getDomains(); |
| g_assert_nonnull(domains); |
| g_assert_cmpint(g_strv_length(domains), ==, 0); |
| } |
| |
| static void ephemeralViewloadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent, WebViewTest* test) |
| { |
| if (loadEvent != WEBKIT_LOAD_FINISHED) |
| return; |
| g_signal_handlers_disconnect_by_func(webView, reinterpret_cast<void*>(ephemeralViewloadChanged), test); |
| test->quitMainLoop(); |
| } |
| |
| static void testCookieManagerEphemeral(CookieManagerTest* test, gconstpointer) |
| { |
| test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); |
| test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT); |
| char** domains = test->getDomains(); |
| g_assert_nonnull(domains); |
| g_assert_cmpint(g_strv_length(domains), ==, 0); |
| |
| auto webView = Test::adoptView(g_object_new(WEBKIT_TYPE_WEB_VIEW, |
| #if PLATFORM(WPE) |
| "backend", Test::createWebViewBackend(), |
| #endif |
| "web-context", webkit_web_view_get_context(test->m_webView), |
| "is-ephemeral", TRUE, |
| nullptr)); |
| g_assert_true(webkit_web_view_is_ephemeral(webView.get())); |
| g_assert_false(webkit_web_context_is_ephemeral(webkit_web_view_get_context(webView.get()))); |
| |
| g_signal_connect(webView.get(), "load-changed", G_CALLBACK(ephemeralViewloadChanged), test); |
| webkit_web_view_load_uri(webView.get(), kServer->getURIForPath("/index.html").data()); |
| g_main_loop_run(test->m_mainLoop); |
| |
| domains = test->getDomains(); |
| g_assert_nonnull(domains); |
| g_assert_cmpint(g_strv_length(domains), ==, 0); |
| |
| auto* viewDataManager = webkit_web_view_get_website_data_manager(webView.get()); |
| g_assert_true(WEBKIT_IS_WEBSITE_DATA_MANAGER(viewDataManager)); |
| test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(viewDataManager)); |
| g_assert_true(viewDataManager != webkit_web_context_get_website_data_manager(webkit_web_view_get_context(test->m_webView))); |
| auto* cookieManager = webkit_website_data_manager_get_cookie_manager(viewDataManager); |
| g_assert_true(WEBKIT_IS_COOKIE_MANAGER(cookieManager)); |
| test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(cookieManager)); |
| g_assert_true(cookieManager != test->m_cookieManager); |
| G_GNUC_BEGIN_IGNORE_DEPRECATIONS; |
| webkit_cookie_manager_get_domains_with_cookies(cookieManager, nullptr, [](GObject* object, GAsyncResult* result, gpointer userData) { |
| auto* test = static_cast<CookieManagerTest*>(userData); |
| GUniquePtr<char*> domains(webkit_cookie_manager_get_domains_with_cookies_finish(WEBKIT_COOKIE_MANAGER(object), result, nullptr)); |
| g_assert_nonnull(domains); |
| g_assert_cmpint(g_strv_length(domains.get()), ==, 1); |
| g_assert_cmpstr(domains.get()[0], ==, kFirstPartyDomain); |
| test->quitMainLoop(); |
| }, test); |
| G_GNUC_END_IGNORE_DEPRECATIONS; |
| g_main_loop_run(test->m_mainLoop); |
| } |
| |
| static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) |
| { |
| if (message->method != SOUP_METHOD_GET) { |
| soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); |
| return; |
| } |
| |
| soup_message_set_status(message, SOUP_STATUS_OK); |
| gchar* header_str = g_strdup_printf("%s=%s; Max-Age=60", kCookieName, kCookieValue); |
| |
| if (g_str_equal(path, "/index.html")) { |
| char* indexHtml = g_strdup_printf(kIndexHtmlFormat, soup_server_get_port(server)); |
| soup_message_headers_replace(message->response_headers, "Set-Cookie", header_str); |
| soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, indexHtml, strlen(indexHtml)); |
| } else if (g_str_equal(path, "/image.png")) |
| soup_message_headers_replace(message->response_headers, "Set-Cookie", header_str); |
| else if (g_str_equal(path, "/no-cookies.html")) { |
| static const char* indexHtml = "<html><body><p>No cookies</p></body></html>"; |
| soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, indexHtml, strlen(indexHtml)); |
| } else |
| soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); |
| soup_message_body_complete(message->response_body); |
| } |
| |
| void beforeAll() |
| { |
| kServer = new WebKitTestServer(); |
| kServer->run(serverCallback); |
| |
| CookieManagerTest::add("WebKitCookieManager", "accept-policy", testCookieManagerAcceptPolicy); |
| CookieManagerTest::add("WebKitCookieManager", "add-cookie", testCookieManagerAddCookie); |
| CookieManagerTest::add("WebKitCookieManager", "get-cookies", testCookieManagerGetCookies); |
| CookieManagerTest::add("WebKitCookieManager", "delete-cookie", testCookieManagerDeleteCookie); |
| CookieManagerTest::add("WebKitCookieManager", "delete-cookies", testCookieManagerDeleteCookies); |
| CookieManagerTest::add("WebKitCookieManager", "cookies-changed", testCookieManagerCookiesChanged); |
| CookiePersistentStorageTest::add("WebKitCookieManager", "persistent-storage", testCookieManagerPersistentStorage); |
| CookieManagerTest::add("WebKitCookieManager", "persistent-storage-delete-all", testCookieManagerPersistentStorageDeleteAll); |
| CookieManagerTest::add("WebKitCookieManager", "ephemeral", testCookieManagerEphemeral); |
| } |
| |
| void afterAll() |
| { |
| delete kServer; |
| } |