Diff
Modified: trunk/Source/WebCore/ChangeLog (225053 => 225054)
--- trunk/Source/WebCore/ChangeLog 2017-11-20 21:20:15 UTC (rev 225053)
+++ trunk/Source/WebCore/ChangeLog 2017-11-20 22:02:46 UTC (rev 225054)
@@ -1,3 +1,28 @@
+2017-11-20 Mario Sanchez Prada <[email protected]>
+
+ [GTK] New API to add, retrieve and delete cookies via WebKitCookieManager
+ https://bugs.webkit.org/show_bug.cgi?id=177932
+
+ Reviewed by Carlos Garcia Campos.
+
+ Implemented setCookie(), getCookies() and deleteCookie() in the Soup
+ backend, and refactored some utility functions and conversions out of
+ NetworkStorageSessionSoup into a new CookieSoup.cpp file, so
+ that we now can convert between SoupCookie* and WebCore::Cookie
+ easily from anywhere (this is now needed from the UI Process).
+
+ * platform/Cookie.h: Add declarations for the new conversions.
+ * platform/SourcesSoup.txt: Add CookieSoup.cpp.
+ * platform/network/soup/CookieSoup.cpp: Added.
+ (WebCore::Cookie::Cookie): New constructor, creates a WebCore::Cookie out of a SoupCookie*.
+ (WebCore::msToSoupDate): Moved from NetworkStorageSessionSoup.cpp.
+ (WebCore::Cookie::toSoupCookie): New, based on toSoupCookie() from NetworkStorageSessionSoup.cpp.
+ * platform/network/soup/NetworkStorageSessionSoup.cpp:
+ (WebCore::NetworkStorageSession::setCookies): Used the new implicit conversion.
+ (WebCore::NetworkStorageSession::setCookie): Newly implemented.
+ (WebCore::NetworkStorageSession::deleteCookie): Newly implemented.
+ (WebCore::NetworkStorageSession::getCookies): Newly implemented.
+
2017-11-20 Zalan Bujtas <[email protected]>
Remove slow repaint object from FrameView when style changes.
Modified: trunk/Source/WebCore/platform/Cookie.h (225053 => 225054)
--- trunk/Source/WebCore/platform/Cookie.h 2017-11-20 21:20:15 UTC (rev 225053)
+++ trunk/Source/WebCore/platform/Cookie.h 2017-11-20 22:02:46 UTC (rev 225054)
@@ -67,6 +67,9 @@
#ifdef __OBJC__
WEBCORE_EXPORT Cookie(NSHTTPCookie *);
WEBCORE_EXPORT operator NSHTTPCookie *() const;
+#elif USE(SOUP)
+ explicit Cookie(SoupCookie*);
+ SoupCookie* toSoupCookie() const;
#endif
bool isNull() const
Modified: trunk/Source/WebCore/platform/SourcesSoup.txt (225053 => 225054)
--- trunk/Source/WebCore/platform/SourcesSoup.txt 2017-11-20 21:20:15 UTC (rev 225053)
+++ trunk/Source/WebCore/platform/SourcesSoup.txt 2017-11-20 22:02:46 UTC (rev 225054)
@@ -24,6 +24,7 @@
platform/network/soup/AuthenticationChallengeSoup.cpp
platform/network/soup/CertificateInfo.cpp
platform/network/soup/CookieJarSoup.cpp
+platform/network/soup/CookieSoup.cpp
platform/network/soup/CookieStorageSoup.cpp
platform/network/soup/CredentialStorageSoup.cpp
platform/network/soup/DNSSoup.cpp
Added: trunk/Source/WebCore/platform/network/soup/CookieSoup.cpp (0 => 225054)
--- trunk/Source/WebCore/platform/network/soup/CookieSoup.cpp (rev 0)
+++ trunk/Source/WebCore/platform/network/soup/CookieSoup.cpp 2017-11-20 22:02:46 UTC (rev 225054)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 Igalia S.L.
+ * Copyright (C) 2017 Endless Mobile, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Cookie.h"
+
+#include <wtf/DateMath.h>
+
+namespace WebCore {
+
+Cookie::Cookie(SoupCookie* cookie)
+ : name(String::fromUTF8(cookie->name))
+ , value(String::fromUTF8(cookie->value))
+ , domain(String::fromUTF8(cookie->domain))
+ , path(String::fromUTF8(cookie->path))
+ , expires(cookie->expires ? static_cast<double>(soup_date_to_time_t(cookie->expires)) * 1000 : 0)
+ , httpOnly(cookie->http_only)
+ , secure(cookie->secure)
+ , session(!cookie->expires)
+
+{
+}
+
+static SoupDate* msToSoupDate(double ms)
+{
+ int year = msToYear(ms);
+ int dayOfYear = dayInYear(ms, year);
+ bool leapYear = isLeapYear(year);
+
+ // monthFromDayInYear() returns a value in the [0,11] range, while soup_date_new() expects
+ // a value in the [1,12] range, meaning we have to manually adjust the month value.
+ return soup_date_new(year, monthFromDayInYear(dayOfYear, leapYear) + 1, dayInMonthFromDayInYear(dayOfYear, leapYear), msToHours(ms), msToMinutes(ms), static_cast<int>(ms / 1000) % 60);
+}
+
+SoupCookie* Cookie::toSoupCookie() const
+{
+ if (name.isNull() || value.isNull() || domain.isNull() || path.isNull())
+ return nullptr;
+
+ SoupCookie* soupCookie = soup_cookie_new(name.utf8().data(), value.utf8().data(),
+ domain.utf8().data(), path.utf8().data(), -1);
+
+ soup_cookie_set_http_only(soupCookie, httpOnly);
+ soup_cookie_set_secure(soupCookie, secure);
+
+ if (!session) {
+ SoupDate* date = msToSoupDate(expires);
+ soup_cookie_set_expires(soupCookie, date);
+ soup_date_free(date);
+ }
+
+ return soupCookie;
+}
+
+} // namespace WebCore
Modified: trunk/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp (225053 => 225054)
--- trunk/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp 2017-11-20 21:20:15 UTC (rev 225053)
+++ trunk/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp 2017-11-20 22:02:46 UTC (rev 225054)
@@ -2,6 +2,7 @@
* Copyright (C) 2013 Apple Inc. All rights reserved.
* Copyright (C) 2013 University of Szeged. All rights reserved.
* Copyright (C) 2016 Igalia S.L.
+ * Copyright (C) 2017 Endless Mobile, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,6 +34,7 @@
#include "Cookie.h"
#include "ResourceHandle.h"
#include "SoupNetworkSession.h"
+#include <WebCore/GUniquePtrSoup.h>
#include <libsoup/soup.h>
#include <wtf/DateMath.h>
#include <wtf/MainThread.h>
@@ -283,45 +285,21 @@
#endif
}
-static SoupDate* msToSoupDate(double ms)
-{
- int year = msToYear(ms);
- int dayOfYear = dayInYear(ms, year);
- bool leapYear = isLeapYear(year);
-
- // monthFromDayInYear() returns a value in the [0,11] range, while soup_date_new() expects
- // a value in the [1,12] range, meaning we have to manually adjust the month value.
- return soup_date_new(year, monthFromDayInYear(dayOfYear, leapYear) + 1, dayInMonthFromDayInYear(dayOfYear, leapYear), msToHours(ms), msToMinutes(ms), static_cast<int>(ms / 1000) % 60);
-}
-
-static SoupCookie* toSoupCookie(const Cookie& cookie)
-{
- SoupCookie* soupCookie = soup_cookie_new(cookie.name.utf8().data(), cookie.value.utf8().data(),
- cookie.domain.utf8().data(), cookie.path.utf8().data(), -1);
- soup_cookie_set_http_only(soupCookie, cookie.httpOnly);
- soup_cookie_set_secure(soupCookie, cookie.secure);
- if (!cookie.session) {
- SoupDate* date = msToSoupDate(cookie.expires);
- soup_cookie_set_expires(soupCookie, date);
- soup_date_free(date);
- }
- return soupCookie;
-}
-
void NetworkStorageSession::setCookies(const Vector<Cookie>& cookies, const URL&, const URL&)
{
for (auto cookie : cookies)
- soup_cookie_jar_add_cookie(cookieStorage(), toSoupCookie(cookie));
+ soup_cookie_jar_add_cookie(cookieStorage(), cookie.toSoupCookie());
}
-void NetworkStorageSession::setCookie(const Cookie&)
+void NetworkStorageSession::setCookie(const Cookie& cookie)
{
- // FIXME: Implement for WK2 to use.
+ soup_cookie_jar_add_cookie(cookieStorage(), cookie.toSoupCookie());
}
-void NetworkStorageSession::deleteCookie(const Cookie&)
+void NetworkStorageSession::deleteCookie(const Cookie& cookie)
{
- // FIXME: Implement for WK2 to use.
+ GUniquePtr<SoupCookie> targetCookie(cookie.toSoupCookie());
+ soup_cookie_jar_delete_cookie(cookieStorage(), targetCookie.get());
}
Vector<Cookie> NetworkStorageSession::getAllCookies()
@@ -330,10 +308,17 @@
return { };
}
-Vector<Cookie> NetworkStorageSession::getCookies(const URL&)
+Vector<Cookie> NetworkStorageSession::getCookies(const URL& url)
{
- // FIXME: Implement for WK2 to use.
- return { };
+ Vector<Cookie> cookies;
+ GUniquePtr<SoupURI> uri = url.createSoupURI();
+ GUniquePtr<GSList> cookiesList(soup_cookie_jar_get_cookie_list(cookieStorage(), uri.get(), TRUE));
+ for (GSList* item = cookiesList.get(); item; item = g_slist_next(item)) {
+ GUniquePtr<SoupCookie> soupCookie(static_cast<SoupCookie*>(item->data));
+ cookies.append(WebCore::Cookie(soupCookie.get()));
+ }
+
+ return cookies;
}
void NetworkStorageSession::flushCookieStore()
Modified: trunk/Source/WebKit/ChangeLog (225053 => 225054)
--- trunk/Source/WebKit/ChangeLog 2017-11-20 21:20:15 UTC (rev 225053)
+++ trunk/Source/WebKit/ChangeLog 2017-11-20 22:02:46 UTC (rev 225054)
@@ -1,3 +1,24 @@
+2017-11-20 Mario Sanchez Prada <[email protected]>
+
+ [GTK] New API to add, retrieve and delete cookies via WebKitCookieManager
+ https://bugs.webkit.org/show_bug.cgi?id=177932
+
+ Reviewed by Carlos Garcia Campos.
+
+ Added new API to WebKitCookieManager to add, retrieve and delete complete
+ cookies into/out-of a running session, and updated documentation sections.
+
+ * UIProcess/API/glib/WebKitCookieManager.cpp:
+ (webkit_cookie_manager_add_cookie): New function.
+ (webkit_cookie_manager_add_cookie_finish): Ditto.
+ (webkit_cookie_manager_get_cookies): Ditto.
+ (webkit_cookie_manager_get_cookies_finish): Ditto.
+ (webkit_cookie_manager_delete_cookie): Ditto.
+ (webkit_cookie_manager_delete_cookie_finish): Ditto.
+ * UIProcess/API/gtk/WebKitCookieManager.h: Added new functions.
+ * UIProcess/API/wpe/WebKitCookieManager.h: Ditto.
+ * UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt: Ditto.
+
2017-11-20 Carlos Garcia Campos <[email protected]>
[WPE] webkit_web_view_new() should enable specifying wpe_view_backend object
Modified: trunk/Source/WebKit/UIProcess/API/glib/WebKitCookieManager.cpp (225053 => 225054)
--- trunk/Source/WebKit/UIProcess/API/glib/WebKitCookieManager.cpp 2017-11-20 21:20:15 UTC (rev 225053)
+++ trunk/Source/WebKit/UIProcess/API/glib/WebKitCookieManager.cpp 2017-11-20 22:02:46 UTC (rev 225054)
@@ -1,5 +1,6 @@
/*
* 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 Lesser General Public
@@ -27,6 +28,7 @@
#include "WebKitWebsiteDataManagerPrivate.h"
#include "WebKitWebsiteDataPrivate.h"
#include "WebsiteDataRecord.h"
+#include <glib/gi18n-lib.h>
#include <pal/SessionID.h>
#include <wtf/glib/GRefPtr.h>
#include <wtf/glib/WTFGType.h>
@@ -233,6 +235,192 @@
}
/**
+ * webkit_cookie_manager_add_cookie:
+ * @cookie_manager: a #WebKitCookieManager
+ * @cookie: the #SoupCookie to be added
+ * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
+ * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * Asynchronously add a #SoupCookie to the underlying storage.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * webkit_cookie_manager_add_cookie_finish() to get the result of the operation.
+ *
+ * Since: 2.20
+ */
+void webkit_cookie_manager_add_cookie(WebKitCookieManager* manager, SoupCookie* cookie, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
+ g_return_if_fail(cookie);
+
+ GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData));
+
+ auto sessionID = webkitWebsiteDataManagerGetDataStore(manager->priv->dataManager).websiteDataStore().sessionID();
+ const auto& processPools = webkitWebsiteDataManagerGetProcessPools(manager->priv->dataManager);
+
+ // Cookies are read/written from/to the same SQLite database on disk regardless
+ // of the process we access them from, so just use the first process pool.
+ processPools[0]->supplement<WebCookieManagerProxy>()->setCookie(sessionID, WebCore::Cookie(cookie), [task = WTFMove(task)](CallbackBase::Error error) {
+ if (error != CallbackBase::Error::None) {
+ // This can only happen in cases where the web process is not available,
+ // consider the operation "cancelled" from the point of view of the client.
+ g_task_return_new_error(task.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED, _("Operation was cancelled"));
+ return;
+ }
+
+ g_task_return_boolean(task.get(), TRUE);
+ });
+}
+
+/**
+ * webkit_cookie_manager_add_cookie_finish:
+ * @cookie_manager: a #WebKitCookieManager
+ * @result: a #GAsyncResult
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_cookie_manager_add_cookie().
+ *
+ * Returns: %TRUE if the cookie was added or %FALSE in case of error.
+ *
+ * Since: 2.20
+ */
+gboolean webkit_cookie_manager_add_cookie_finish(WebKitCookieManager* manager, GAsyncResult* result, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager), FALSE);
+ g_return_val_if_fail(g_task_is_valid(result, manager), FALSE);
+
+ return g_task_propagate_boolean(G_TASK(result), error);
+}
+
+/**
+ * webkit_cookie_manager_get_cookies:
+ * @cookie_manager: a #WebKitCookieManager
+ * @uri: the URI associated to the cookies to be retrieved
+ * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
+ * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * Asynchronously get a list of #SoupCookie from @cookie_manager associated with @uri, which
+ * must be either an HTTP or an HTTPS URL.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * webkit_cookie_manager_get_cookies_finish() to get the result of the operation.
+ *
+ * Since: 2.20
+ */
+void webkit_cookie_manager_get_cookies(WebKitCookieManager* manager, const gchar* uri, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
+ g_return_if_fail(uri);
+
+ GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData));
+
+ auto sessionID = webkitWebsiteDataManagerGetDataStore(manager->priv->dataManager).websiteDataStore().sessionID();
+ const auto& processPools = webkitWebsiteDataManagerGetProcessPools(manager->priv->dataManager);
+
+ // Cookies are read/written from/to the same SQLite database on disk regardless
+ // of the process we access them from, so just use the first process pool.
+ processPools[0]->supplement<WebCookieManagerProxy>()->getCookies(sessionID, WebCore::URL(WebCore::URL(), String::fromUTF8(uri)), [task = WTFMove(task)](const Vector<WebCore::Cookie>& cookies, CallbackBase::Error error) {
+ if (error != CallbackBase::Error::None) {
+ // This can only happen in cases where the web process is not available,
+ // consider the operation "cancelled" from the point of view of the client.
+ g_task_return_new_error(task.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED, _("Operation was cancelled"));
+ return;
+ }
+
+ GList* cookiesList = nullptr;
+ for (auto& cookie : cookies)
+ cookiesList = g_list_prepend(cookiesList, cookie.toSoupCookie());
+
+ g_task_return_pointer(task.get(), g_list_reverse(cookiesList), [](gpointer data) {
+ g_list_free_full(static_cast<GList*>(data), reinterpret_cast<GDestroyNotify>(soup_cookie_free));
+ });
+ });
+}
+
+/**
+ * webkit_cookie_manager_get_cookies_finish:
+ * @cookie_manager: a #WebKitCookieManager
+ * @result: a #GAsyncResult
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_cookie_manager_get_cookies().
+ * The return value is a #GSList of #SoupCookie instances which should be released
+ * with g_list_free_full() and soup_cookie_free().
+ *
+ * Returns: (element-type SoupCookie) (transfer full): A #GList of #SoupCookie instances.
+ *
+ * Since: 2.20
+ */
+GList* webkit_cookie_manager_get_cookies_finish(WebKitCookieManager* manager, GAsyncResult* result, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager), nullptr);
+ g_return_val_if_fail(g_task_is_valid(result, manager), nullptr);
+
+ return reinterpret_cast<GList*>(g_task_propagate_pointer(G_TASK(result), error));
+}
+
+/**
+ * webkit_cookie_manager_delete_cookie:
+ * @cookie_manager: a #WebKitCookieManager
+ * @cookie: the #SoupCookie to be deleted
+ * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
+ * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * Asynchronously delete a #SoupCookie from the current session.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * webkit_cookie_manager_delete_cookie_finish() to get the result of the operation.
+ *
+ * Since: 2.20
+ */
+void webkit_cookie_manager_delete_cookie(WebKitCookieManager* manager, SoupCookie* cookie, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
+ g_return_if_fail(cookie);
+
+ GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData));
+
+ auto sessionID = webkitWebsiteDataManagerGetDataStore(manager->priv->dataManager).websiteDataStore().sessionID();
+ const auto& processPools = webkitWebsiteDataManagerGetProcessPools(manager->priv->dataManager);
+
+ // Cookies are read/written from/to the same SQLite database on disk regardless
+ // of the process we access them from, so just use the first process pool.
+ processPools[0]->supplement<WebCookieManagerProxy>()->deleteCookie(sessionID, WebCore::Cookie(cookie), [task = WTFMove(task)](CallbackBase::Error error) {
+ if (error != CallbackBase::Error::None) {
+ // This can only happen in cases where the web process is not available,
+ // consider the operation "cancelled" from the point of view of the client.
+ g_task_return_new_error(task.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED, _("Operation was cancelled"));
+ return;
+ }
+
+ g_task_return_boolean(task.get(), TRUE);
+ });
+}
+
+/**
+ * webkit_cookie_manager_delete_cookie_finish:
+ * @cookie_manager: a #WebKitCookieManager
+ * @result: a #GAsyncResult
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_cookie_manager_delete_cookie().
+ *
+ * Returns: %TRUE if the cookie was deleted or %FALSE in case of error.
+ *
+ * Since: 2.20
+ */
+gboolean webkit_cookie_manager_delete_cookie_finish(WebKitCookieManager* manager, GAsyncResult* result, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager), FALSE);
+ g_return_val_if_fail(g_task_is_valid(result, manager), FALSE);
+
+ return g_task_propagate_boolean(G_TASK(result), error);
+}
+
+/**
* webkit_cookie_manager_get_domains_with_cookies:
* @cookie_manager: a #WebKitCookieManager
* @cancellable: (allow-none): a #GCancellable or %NULL to ignore
Modified: trunk/Source/WebKit/UIProcess/API/gtk/WebKitCookieManager.h (225053 => 225054)
--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitCookieManager.h 2017-11-20 21:20:15 UTC (rev 225053)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitCookieManager.h 2017-11-20 22:02:46 UTC (rev 225054)
@@ -1,5 +1,6 @@
/*
* 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 Lesser General Public
@@ -26,6 +27,7 @@
#include <gio/gio.h>
#include <glib-object.h>
+#include <libsoup/soup.h>
#include <webkit2/WebKitDefines.h>
G_BEGIN_DECLS
@@ -107,6 +109,42 @@
GAsyncResult *result,
GError **error);
+WEBKIT_API void
+webkit_cookie_manager_add_cookie (WebKitCookieManager *cookie_manager,
+ SoupCookie *cookie,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+WEBKIT_API gboolean
+webkit_cookie_manager_add_cookie_finish (WebKitCookieManager *cookie_manager,
+ GAsyncResult *result,
+ GError **error);
+
+WEBKIT_API void
+webkit_cookie_manager_get_cookies (WebKitCookieManager *cookie_manager,
+ const gchar *uri,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+WEBKIT_API GList *
+webkit_cookie_manager_get_cookies_finish (WebKitCookieManager *cookie_manager,
+ GAsyncResult *result,
+ GError **error);
+
+WEBKIT_API void
+webkit_cookie_manager_delete_cookie (WebKitCookieManager *cookie_manager,
+ SoupCookie *cookie,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+WEBKIT_API gboolean
+webkit_cookie_manager_delete_cookie_finish (WebKitCookieManager *cookie_manager,
+ GAsyncResult *result,
+ GError **error);
+
WEBKIT_DEPRECATED_FOR(webkit_website_data_manager_fetch) void
webkit_cookie_manager_get_domains_with_cookies (WebKitCookieManager *cookie_manager,
GCancellable *cancellable,
Modified: trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt (225053 => 225054)
--- trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt 2017-11-20 21:20:15 UTC (rev 225053)
+++ trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt 2017-11-20 22:02:46 UTC (rev 225054)
@@ -1006,6 +1006,12 @@
webkit_cookie_manager_get_accept_policy_finish
webkit_cookie_manager_get_domains_with_cookies
webkit_cookie_manager_get_domains_with_cookies_finish
+webkit_cookie_manager_add_cookie
+webkit_cookie_manager_add_cookie_finish
+webkit_cookie_manager_get_cookies
+webkit_cookie_manager_get_cookies_finish
+webkit_cookie_manager_delete_cookie
+webkit_cookie_manager_delete_cookie_finish
webkit_cookie_manager_delete_cookies_for_domain
webkit_cookie_manager_delete_all_cookies
Modified: trunk/Source/WebKit/UIProcess/API/wpe/WebKitCookieManager.h (225053 => 225054)
--- trunk/Source/WebKit/UIProcess/API/wpe/WebKitCookieManager.h 2017-11-20 21:20:15 UTC (rev 225053)
+++ trunk/Source/WebKit/UIProcess/API/wpe/WebKitCookieManager.h 2017-11-20 22:02:46 UTC (rev 225054)
@@ -1,5 +1,6 @@
/*
* 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 Lesser General Public
@@ -26,6 +27,7 @@
#include <gio/gio.h>
#include <glib-object.h>
+#include <libsoup/soup.h>
#include <wpe/WebKitDefines.h>
G_BEGIN_DECLS
@@ -107,6 +109,42 @@
GAsyncResult *result,
GError **error);
+WEBKIT_API void
+webkit_cookie_manager_add_cookie (WebKitCookieManager *cookie_manager,
+ SoupCookie *cookie,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+WEBKIT_API gboolean
+webkit_cookie_manager_add_cookie_finish (WebKitCookieManager *cookie_manager,
+ GAsyncResult *result,
+ GError **error);
+
+WEBKIT_API void
+webkit_cookie_manager_get_cookies (WebKitCookieManager *cookie_manager,
+ const gchar *uri,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+WEBKIT_API GList *
+webkit_cookie_manager_get_cookies_finish (WebKitCookieManager *cookie_manager,
+ GAsyncResult *result,
+ GError **error);
+
+WEBKIT_API void
+webkit_cookie_manager_delete_cookie (WebKitCookieManager *cookie_manager,
+ SoupCookie *cookie,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+WEBKIT_API gboolean
+webkit_cookie_manager_delete_cookie_finish (WebKitCookieManager *cookie_manager,
+ GAsyncResult *result,
+ GError **error);
+
WEBKIT_DEPRECATED_FOR(webkit_website_data_manager_fetch) void
webkit_cookie_manager_get_domains_with_cookies (WebKitCookieManager *cookie_manager,
GCancellable *cancellable,
Modified: trunk/Tools/ChangeLog (225053 => 225054)
--- trunk/Tools/ChangeLog 2017-11-20 21:20:15 UTC (rev 225053)
+++ trunk/Tools/ChangeLog 2017-11-20 22:02:46 UTC (rev 225054)
@@ -1,3 +1,21 @@
+2017-11-20 Mario Sanchez Prada <[email protected]>
+
+ [GTK] New API to add, retrieve and delete cookies via WebKitCookieManager
+ https://bugs.webkit.org/show_bug.cgi?id=177932
+
+ Reviewed by Carlos Garcia Campos.
+
+ Added new test cases to cover the newly added API for WebKitCookieManager:
+ webkit_cookie_manager_add_cookie, webkit_cookie_manager_get_cookies and
+ webkit_cookie_manager_delete_cookie.
+
+ * TestWebKitAPI/Tests/WebKitGLib/TestCookieManager.cpp:
+ (testCookieManagerAddCookie): Added.
+ (testCookieManagerGetCookies): Added.
+ (testCookieManagerDeleteCookie): Added.
+ (serverCallback): Small update to avoid hardcoding strings we reuse.
+ (beforeAll): Added the new test cases to the test suite.
+
2017-11-20 Stephan Szabo <[email protected]>
[Win] Update ruby JSC test writer for gigacage changes
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestCookieManager.cpp (225053 => 225054)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestCookieManager.cpp 2017-11-20 21:20:15 UTC (rev 225053)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestCookieManager.cpp 2017-11-20 22:02:46 UTC (rev 225054)
@@ -1,5 +1,6 @@
/*
* 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
@@ -21,6 +22,7 @@
#include "WebKitTestServer.h"
#include "WebViewTest.h"
+#include <WebCore/GUniquePtrSoup.h>
#include <glib/gstdio.h>
static WebKitTestServer* kServer;
@@ -27,6 +29,14 @@
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>"
@@ -55,6 +65,8 @@
~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());
@@ -102,6 +114,61 @@
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(!error.get());
+ g_assert(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(!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(!error.get());
+ g_assert(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);
@@ -170,6 +237,7 @@
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 };
@@ -209,6 +277,223 @@
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);
@@ -386,12 +671,14 @@
}
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", "foo=bar; Max-Age=60");
+ 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", "baz=qux; Max-Age=60");
+ 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));
@@ -406,6 +693,9 @@
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);
CookieManagerTest::add("WebKitCookieManager", "persistent-storage", testCookieManagerPersistentStorage);