[GTK] Add webkit_cookie_manager_set_persistent_storage() to WebKit2 GTK+ API
authorcarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Jul 2012 08:12:52 +0000 (08:12 +0000)
committercarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Jul 2012 08:12:52 +0000 (08:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=83016

Reviewed by Martin Robinson.

Source/WebCore:

* platform/network/soup/CookieStorageSoup.cpp:
(WebCore::soupCookiesChanged): Do not notify about changes in
other cookie jars than the current one.

Source/WebKit2:

Add a custom implementation of SoupCookieJarSqlite based on
libsoup code but using WebCore SQLite classes. SoupCookieJarSqlite
is part of libsoup-gnome, it's not a lot of code and it doesn't
change often, so it's better to simply have our own implementation
instead of making this important feature depend on an optional
dependency. There are plans to move the implementation to libsoup,
if that eventually happens we will remove our code to use libsoup
directly.

* GNUmakefile.am: Add new dirs to include path.
* GNUmakefile.list.am: Add new files to compilation.
* PlatformEfl.cmake: Ditto.
* Shared/soup/SoupCookiePersistentStorageType.h: Added.
* UIProcess/API/gtk/WebKitCookieManager.cpp:
(webkit_cookie_manager_set_persistent_storage): Set a persistent
storage for cookies.
* UIProcess/API/gtk/WebKitCookieManager.h:
* UIProcess/API/gtk/docs/webkit2gtk-sections.txt: Add new symbols
* UIProcess/API/gtk/tests/TestCookieManager.cpp:
(testCookieManagerPersistentStorage):
(serverCallback):
(beforeAll):
(afterAll):
* UIProcess/WebCookieManagerProxy.h:
(WebCookieManagerProxy): Add setCookiePersistentStorage() method
when using soup.
* UIProcess/soup/WebCookieManagerProxySoup.cpp: Added.
(WebKit::WebCookieManagerProxy::setCookiePersistentStorage): Send
SetCookiePersistentStorage message to the web process.
* WebProcess/Cookies/WebCookieManager.h:
(WebCookieManager): Add setCookiePersistentStorage() method when
using soup.
* WebProcess/Cookies/WebCookieManager.messages.in: Add
SetCookiePersistentStorage message when using soup.
* WebProcess/Cookies/soup/WebCookieManagerSoup.cpp:
(WebKit::WebCookieManager::setCookiePersistentStorage): Create a
new cookie jar for the given filename and storage type and add it
to the soup session.
* WebProcess/Cookies/soup/WebKitSoupCookieJarSqlite.cpp: Added.
(webkitSoupCookieJarSqliteOpenDatabase): Open SQLite database.
(webkitSoupCookieJarSqliteCreateTable): Create moz_cookies if it
doesn't exist.
(webkitSoupCookieJarSqliteLoad): Load the initial set of cookies
from the database.
(webkitSoupCookieJarSqliteInsertCookie): Insert a new cookie into
the database.
(webkitSoupCookieJarSqliteDeleteCookie): Delete an exising cookie
from the database.
(webkitSoupCookieJarSqliteChanged): Insert/delete cookies
depending on the change.
(webkitSoupCookieJarSqliteFinalize):
(webkit_soup_cookie_jar_sqlite_init):
(webkit_soup_cookie_jar_sqlite_class_init):
(webkitSoupCookieJarSqliteNew):
* WebProcess/Cookies/soup/WebKitSoupCookieJarSqlite.h: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@122425 268f45cc-cd09-0410-ab3c-d52691b4dbfc

18 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/network/soup/CookieStorageSoup.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/GNUmakefile.am
Source/WebKit2/GNUmakefile.list.am
Source/WebKit2/PlatformEfl.cmake
Source/WebKit2/Shared/soup/SoupCookiePersistentStorageType.h [new file with mode: 0644]
Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp
Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h
Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt
Source/WebKit2/UIProcess/API/gtk/tests/TestCookieManager.cpp
Source/WebKit2/UIProcess/WebCookieManagerProxy.h
Source/WebKit2/UIProcess/soup/WebCookieManagerProxySoup.cpp [new file with mode: 0644]
Source/WebKit2/WebProcess/Cookies/WebCookieManager.h
Source/WebKit2/WebProcess/Cookies/WebCookieManager.messages.in
Source/WebKit2/WebProcess/Cookies/soup/WebCookieManagerSoup.cpp
Source/WebKit2/WebProcess/Cookies/soup/WebKitSoupCookieJarSqlite.cpp [new file with mode: 0644]
Source/WebKit2/WebProcess/Cookies/soup/WebKitSoupCookieJarSqlite.h [new file with mode: 0644]

index fa6711d..d2c13d0 100644 (file)
@@ -1,3 +1,14 @@
+2012-07-11  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [GTK] Add webkit_cookie_manager_set_persistent_storage() to WebKit2 GTK+ API
+        https://bugs.webkit.org/show_bug.cgi?id=83016
+
+        Reviewed by Martin Robinson.
+
+        * platform/network/soup/CookieStorageSoup.cpp:
+        (WebCore::soupCookiesChanged): Do not notify about changes in
+        other cookie jars than the current one.
+
 2012-07-12  Philip Rogers  <pdr@google.com>
 
         Refactor RenderSVGShape bounding box code
index 2d71747..f309e5d 100644 (file)
@@ -37,8 +37,10 @@ void setCookieStoragePrivateBrowsingEnabled(bool enabled)
 }
 
 #if USE(PLATFORM_STRATEGIES)
-static void soupCookiesChanged(SoupCookieJar*, SoupCookie*, SoupCookie*, gpointer)
+static void soupCookiesChanged(SoupCookieJar* jar, SoupCookie*, SoupCookie*, gpointer)
 {
+    if (jar != soupCookieJar())
+        return;
     platformStrategies()->cookiesStrategy()->notifyCookiesChanged();
 }
 #endif
index e268f1b..2f3b035 100644 (file)
@@ -1,3 +1,66 @@
+2012-07-11  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [GTK] Add webkit_cookie_manager_set_persistent_storage() to WebKit2 GTK+ API
+        https://bugs.webkit.org/show_bug.cgi?id=83016
+
+        Reviewed by Martin Robinson.
+
+        Add a custom implementation of SoupCookieJarSqlite based on
+        libsoup code but using WebCore SQLite classes. SoupCookieJarSqlite
+        is part of libsoup-gnome, it's not a lot of code and it doesn't
+        change often, so it's better to simply have our own implementation
+        instead of making this important feature depend on an optional
+        dependency. There are plans to move the implementation to libsoup,
+        if that eventually happens we will remove our code to use libsoup
+        directly.
+
+        * GNUmakefile.am: Add new dirs to include path.
+        * GNUmakefile.list.am: Add new files to compilation.
+        * PlatformEfl.cmake: Ditto.
+        * Shared/soup/SoupCookiePersistentStorageType.h: Added.
+        * UIProcess/API/gtk/WebKitCookieManager.cpp:
+        (webkit_cookie_manager_set_persistent_storage): Set a persistent
+        storage for cookies.
+        * UIProcess/API/gtk/WebKitCookieManager.h:
+        * UIProcess/API/gtk/docs/webkit2gtk-sections.txt: Add new symbols
+        * UIProcess/API/gtk/tests/TestCookieManager.cpp:
+        (testCookieManagerPersistentStorage):
+        (serverCallback):
+        (beforeAll):
+        (afterAll):
+        * UIProcess/WebCookieManagerProxy.h:
+        (WebCookieManagerProxy): Add setCookiePersistentStorage() method
+        when using soup.
+        * UIProcess/soup/WebCookieManagerProxySoup.cpp: Added.
+        (WebKit::WebCookieManagerProxy::setCookiePersistentStorage): Send
+        SetCookiePersistentStorage message to the web process.
+        * WebProcess/Cookies/WebCookieManager.h:
+        (WebCookieManager): Add setCookiePersistentStorage() method when
+        using soup.
+        * WebProcess/Cookies/WebCookieManager.messages.in: Add
+        SetCookiePersistentStorage message when using soup.
+        * WebProcess/Cookies/soup/WebCookieManagerSoup.cpp:
+        (WebKit::WebCookieManager::setCookiePersistentStorage): Create a
+        new cookie jar for the given filename and storage type and add it
+        to the soup session.
+        * WebProcess/Cookies/soup/WebKitSoupCookieJarSqlite.cpp: Added.
+        (webkitSoupCookieJarSqliteOpenDatabase): Open SQLite database.
+        (webkitSoupCookieJarSqliteCreateTable): Create moz_cookies if it
+        doesn't exist.
+        (webkitSoupCookieJarSqliteLoad): Load the initial set of cookies
+        from the database.
+        (webkitSoupCookieJarSqliteInsertCookie): Insert a new cookie into
+        the database.
+        (webkitSoupCookieJarSqliteDeleteCookie): Delete an exising cookie
+        from the database.
+        (webkitSoupCookieJarSqliteChanged): Insert/delete cookies
+        depending on the change.
+        (webkitSoupCookieJarSqliteFinalize):
+        (webkit_soup_cookie_jar_sqlite_init):
+        (webkit_soup_cookie_jar_sqlite_class_init):
+        (webkitSoupCookieJarSqliteNew):
+        * WebProcess/Cookies/soup/WebKitSoupCookieJarSqlite.h: Added.
+
 2012-07-11  Christophe Dumez  <christophe.dumez@intel.com>
 
         [WK2][EFL] Ewk_View should provide more resource loading notifications
index b0c0724..3e2ecae 100644 (file)
@@ -40,6 +40,7 @@ libwebkit2gtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_la_CPP
        -I$(srcdir)/Source/WebKit2/Shared/Plugins \
        -I$(srcdir)/Source/WebKit2/Shared/Plugins/Netscape \
        -I$(srcdir)/Source/WebKit2/Shared/Plugins/Netscape/x11 \
+       -I$(srcdir)/Source/WebKit2/Shared/soup \
        -I$(srcdir)/Source/WebKit2/UIProcess \
        -I$(srcdir)/Source/WebKit2/UIProcess/API \
        -I$(srcdir)/Source/WebKit2/UIProcess/API/C \
@@ -418,6 +419,7 @@ Programs_WebKitPluginProcess_CPPFLAGS = \
        -I$(srcdir)/Source/WebKit2/UIProcess/Launcher \
        -I$(srcdir)/Source/WebKit2/WebProcess/Plugins/ \
        -I$(srcdir)/Source/WebKit2/WebProcess/Plugins/Netscape/ \
+       -I$(srcdir)/Source/WebKit2/Shared/soup \
        -I$(top_builddir)/DerivedSources/WebKit2 \
        -I$(top_builddir)/DerivedSources/WebKit2/include \
        -I$(top_builddir)/DerivedSources/WebKit2/include/JavaScriptCore \
index d420afa..c6fc36f 100644 (file)
@@ -427,6 +427,7 @@ webkit2_sources += \
        Source/WebKit2/Shared/StatisticsData.cpp \
        Source/WebKit2/Shared/StatisticsData.h \
        Source/WebKit2/Shared/StringPairVector.h \
+       Source/WebKit2/Shared/soup/SoupCookiePersistentStorageType.h \
        Source/WebKit2/Shared/TextCheckerState.h \
        Source/WebKit2/Shared/UserMessageCoders.h \
        Source/WebKit2/Shared/UpdateInfo.cpp \
@@ -788,6 +789,7 @@ webkit2_sources += \
        Source/WebKit2/UIProcess/ProcessModel.h \
        Source/WebKit2/UIProcess/ResponsivenessTimer.cpp \
        Source/WebKit2/UIProcess/ResponsivenessTimer.h \
+       Source/WebKit2/UIProcess/soup/WebCookieManagerProxySoup.cpp \
        Source/WebKit2/UIProcess/soup/WebSoupRequestManagerClient.cpp \
        Source/WebKit2/UIProcess/soup/WebSoupRequestManagerClient.h \
        Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.cpp \
@@ -910,6 +912,8 @@ webkit2_sources += \
        Source/WebKit2/WebProcess/Cookies/WebCookieManager.h \
        Source/WebKit2/WebProcess/Cookies/WebCookieManager.cpp \
        Source/WebKit2/WebProcess/Cookies/soup/WebCookieManagerSoup.cpp \
+       Source/WebKit2/WebProcess/Cookies/soup/WebKitSoupCookieJarSqlite.cpp \
+       Source/WebKit2/WebProcess/Cookies/soup/WebKitSoupCookieJarSqlite.h \
        Source/WebKit2/WebProcess/Downloads/Download.cpp \
        Source/WebKit2/WebProcess/Downloads/Download.h \
        Source/WebKit2/WebProcess/Downloads/DownloadAuthenticationClient.h \
index f9b4745..73669d4 100644 (file)
@@ -54,6 +54,7 @@ LIST(APPEND WebKit2_SOURCES
     UIProcess/efl/WebPageProxyEfl.cpp
     UIProcess/efl/WebPreferencesEfl.cpp
 
+    UIProcess/soup/WebCookieManagerProxySoup.cpp
     UIProcess/soup/WebSoupRequestManagerClient.cpp
     UIProcess/soup/WebSoupRequestManagerProxy.cpp
 
@@ -63,6 +64,7 @@ LIST(APPEND WebKit2_SOURCES
     UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp
 
     WebProcess/Cookies/soup/WebCookieManagerSoup.cpp
+    WebProcess/Cookies/soup/WebKitSoupCookieJarSqlite.cpp
 
     WebProcess/Downloads/efl/DownloadEfl.cpp
     WebProcess/Downloads/efl/FileDownloaderEfl.cpp
@@ -97,6 +99,7 @@ LIST(APPEND WebKit2_INCLUDE_DIRECTORIES
     "${WEBCORE_DIR}/platform/network/soup"
     "${WEBCORE_DIR}/svg/graphics"
     "${WEBKIT2_DIR}/Shared/efl"
+    "${WEBKIT2_DIR}/Shared/soup"
     "${WEBKIT2_DIR}/UIProcess/API/C/efl"
     "${WEBKIT2_DIR}/UIProcess/API/C/soup"
     "${WEBKIT2_DIR}/UIProcess/API/efl"
diff --git a/Source/WebKit2/Shared/soup/SoupCookiePersistentStorageType.h b/Source/WebKit2/Shared/soup/SoupCookiePersistentStorageType.h
new file mode 100644 (file)
index 0000000..9fc1c3c
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * 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.
+ */
+
+#ifndef SoupCookiePersistentStorageType_h
+#define SoupCookiePersistentStorageType_h
+
+namespace WebKit {
+
+enum SoupCookiePersistentStorageType {
+    SoupCookiePersistentStorageText,
+    SoupCookiePersistentStorageSQLite
+};
+
+} // namespace WebKit
+
+#endif // SoupCookiePersistentStorageType_h
index 7d8a10e..8790c7c 100644 (file)
@@ -20,6 +20,8 @@
 #include "config.h"
 #include "WebKitCookieManager.h"
 
+#include "SoupCookiePersistentStorageType.h"
+#include "WebCookieManagerProxy.h"
 #include "WebKitCookieManagerPrivate.h"
 #include "WebKitEnumTypes.h"
 #include <wtf/gobject/GRefPtr.h>
@@ -41,6 +43,9 @@ static guint signals[LAST_SIGNAL] = { 0, };
 
 G_DEFINE_TYPE(WebKitCookieManager, webkit_cookie_manager, G_TYPE_OBJECT)
 
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT, SoupCookiePersistentStorageText);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE, SoupCookiePersistentStorageSQLite);
+
 COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS, kWKHTTPCookieAcceptPolicyAlways);
 COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_NEVER, kWKHTTPCookieAcceptPolicyNever);
 COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY, kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain);
@@ -104,6 +109,30 @@ WebKitCookieManager* webkitCookieManagerCreate(WKCookieManagerRef wkCookieManage
 }
 
 /**
+ * webkit_cookie_manager_set_persistent_storage:
+ * @cookie_manager: a #WebKitCookieManager
+ * @filename: the filename to read to/write from
+ * @storage: a #WebKitCookiePersistentStorage
+ *
+ * Set the @filename where non-session cookies are stored persistently using
+ * @storage as the format to read/write the cookies.
+ * Cookies are initially read from @filename to create an initial set of cookies.
+ * Then, non-session cookies will be written to @filename when the WebKitCookieManager::changed
+ * signal is emitted.
+ * By default, @cookie_manager doesn't store the cookies persistenly, so you need to call this
+ * method to keep cookies saved across sessions.
+ */
+void webkit_cookie_manager_set_persistent_storage(WebKitCookieManager* manager, const char* filename, WebKitCookiePersistentStorage storage)
+{
+    g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
+    g_return_if_fail(filename);
+
+    WKCookieManagerStopObservingCookieChanges(manager->priv->wkCookieManager.get());
+    toImpl(manager->priv->wkCookieManager.get())->setCookiePersistentStorage(String::fromUTF8(filename), storage);
+    WKCookieManagerStartObservingCookieChanges(manager->priv->wkCookieManager.get());
+}
+
+/**
  * webkit_cookie_manager_set_accept_policy:
  * @cookie_manager: a #WebKitCookieManager
  * @policy: a #WebKitCookieAcceptPolicy
index 2472d96..28dfe28 100644 (file)
@@ -42,6 +42,20 @@ typedef struct _WebKitCookieManagerClass   WebKitCookieManagerClass;
 typedef struct _WebKitCookieManagerPrivate WebKitCookieManagerPrivate;
 
 /**
+ * WebKitCookiePersistentStorage:
+ * @WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT: Cookies are stored in a text
+ *  file in the Mozilla "cookies.txt" format.
+ * @WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE: Cookies are stored in a SQLite
+ *  file in the current Mozilla format.
+ *
+ * Enum values used to denote the cookie persistent storage types.
+ */
+typedef enum {
+    WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT,
+    WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE
+} WebKitCookiePersistentStorage;
+
+/**
  * WebKitCookieAcceptPolicy:
  * @WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS: Accept all cookies unconditionally.
  * @WEBKIT_COOKIE_POLICY_ACCEPT_NEVER: Reject all cookies unconditionally.
@@ -69,37 +83,42 @@ WEBKIT_API GType
 webkit_cookie_manager_get_type                        (void);
 
 WEBKIT_API void
-webkit_cookie_manager_set_accept_policy               (WebKitCookieManager     *cookie_manager,
-                                                       WebKitCookieAcceptPolicy policy);
+webkit_cookie_manager_set_persistent_storage          (WebKitCookieManager          *cookie_manager,
+                                                       const gchar                  *filename,
+                                                       WebKitCookiePersistentStorage storage);
+
+WEBKIT_API void
+webkit_cookie_manager_set_accept_policy               (WebKitCookieManager          *cookie_manager,
+                                                       WebKitCookieAcceptPolicy      policy);
 
 WEBKIT_API void
-webkit_cookie_manager_get_accept_policy               (WebKitCookieManager     *cookie_manager,
-                                                       GCancellable            *cancellable,
-                                                       GAsyncReadyCallback      callback,
-                                                       gpointer                 user_data);
+webkit_cookie_manager_get_accept_policy               (WebKitCookieManager          *cookie_manager,
+                                                       GCancellable                 *cancellable,
+                                                       GAsyncReadyCallback           callback,
+                                                       gpointer                      user_data);
 
 WEBKIT_API WebKitCookieAcceptPolicy
-webkit_cookie_manager_get_accept_policy_finish        (WebKitCookieManager     *cookie_manager,
-                                                       GAsyncResult            *result,
-                                                       GError                 **error);
+webkit_cookie_manager_get_accept_policy_finish        (WebKitCookieManager          *cookie_manager,
+                                                       GAsyncResult                 *result,
+                                                       GError                      **error);
 
 WEBKIT_API void
-webkit_cookie_manager_get_domains_with_cookies        (WebKitCookieManager     *cookie_manager,
-                                                       GCancellable            *cancellable,
-                                                       GAsyncReadyCallback      callback,
-                                                       gpointer                 user_data);
+webkit_cookie_manager_get_domains_with_cookies        (WebKitCookieManager          *cookie_manager,
+                                                       GCancellable                 *cancellable,
+                                                       GAsyncReadyCallback           callback,
+                                                       gpointer                      user_data);
 
 WEBKIT_API gchar **
-webkit_cookie_manager_get_domains_with_cookies_finish (WebKitCookieManager     *cookie_manager,
-                                                       GAsyncResult            *result,
-                                                       GError                 **error);
+webkit_cookie_manager_get_domains_with_cookies_finish (WebKitCookieManager          *cookie_manager,
+                                                       GAsyncResult                 *result,
+                                                       GError                      **error);
 
 WEBKIT_API void
-webkit_cookie_manager_delete_cookies_for_domain       (WebKitCookieManager     *cookie_manager,
-                                                       const gchar             *domain);
+webkit_cookie_manager_delete_cookies_for_domain       (WebKitCookieManager          *cookie_manager,
+                                                       const gchar                  *domain);
 
 WEBKIT_API void
-webkit_cookie_manager_delete_all_cookies              (WebKitCookieManager     *cookie_manager);
+webkit_cookie_manager_delete_all_cookies              (WebKitCookieManager          *cookie_manager);
 
 G_END_DECLS
 
index ed66eb4..59d5b5a 100644 (file)
@@ -636,7 +636,9 @@ webkit_find_controller_get_type
 <SECTION>
 <FILE>WebKitCookieManager</FILE>
 WebKitCookieManager
+WebKitCookiePersistentStorage
 WebKitCookieAcceptPolicy
+webkit_cookie_manager_set_persistent_storage
 webkit_cookie_manager_set_accept_policy
 webkit_cookie_manager_get_accept_policy
 webkit_cookie_manager_get_accept_policy_finish
index 1ddfd82..2fe8998 100644 (file)
 
 #include "WebKitTestServer.h"
 #include "WebViewTest.h"
+#include <glib/gstdio.h>
 
 static WebKitTestServer* kServer;
+static char* kTempDirectory;
 
 static const char* kFirstPartyDomain = "127.0.0.1";
 static const char* kThirdPartyDomain = "localhost";
@@ -58,6 +60,30 @@ public:
     {
         g_strfreev(m_domains);
         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.set(g_build_filename(kTempDirectory, "cookies.txt", NULL));
+            filename = m_cookiesTextFile.get();
+            break;
+        case WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE:
+            if (!m_cookiesSQLiteFile)
+                m_cookiesSQLiteFile.set(g_build_filename(kTempDirectory, "cookies.db", NULL));
+            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)
@@ -129,6 +155,8 @@ public:
     char** m_domains;
     bool m_cookiesChanged;
     bool m_finishLoopWhenCookiesChange;
+    GOwnPtr<char> m_cookiesTextFile;
+    GOwnPtr<char> m_cookiesSQLiteFile;
 };
 
 static void testCookieManagerAcceptPolicy(CookieManagerTest* test, gconstpointer)
@@ -204,6 +232,54 @@ static void testCookieManagerCookiesChanged(CookieManagerTest* test, gconstpoint
     g_assert(test->m_cookiesChanged);
 }
 
+static void testCookieManagerPersistentStorage(CookieManagerTest* test, gconstpointer)
+{
+    test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS);
+
+    // Text storage using a new file.
+    test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT);
+    char** domains = test->getDomains();
+    g_assert(domains);
+    g_assert_cmpint(g_strv_length(domains), ==, 0);
+
+    test->loadURI(kServer->getURIForPath("/index.html").data());
+    test->waitUntilLoadFinished();
+    g_assert(test->m_cookiesChanged);
+    domains = test->getDomains();
+    g_assert(domains);
+    g_assert_cmpint(g_strv_length(domains), ==, 2);
+
+
+    // SQLite storage using a new file.
+    test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE);
+    domains = test->getDomains();
+    g_assert(domains);
+    g_assert_cmpint(g_strv_length(domains), ==, 0);
+
+    test->loadURI(kServer->getURIForPath("/index.html").data());
+    test->waitUntilLoadFinished();
+    g_assert(test->m_cookiesChanged);
+    domains = test->getDomains();
+    g_assert(domains);
+    g_assert_cmpint(g_strv_length(domains), ==, 2);
+
+    // Text storage using an existing file.
+    test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT);
+    domains = test->getDomains();
+    g_assert(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(domains);
+    g_assert_cmpint(g_strv_length(domains), ==, 2);
+    test->deleteAllCookies();
+    g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0);
+}
+
 static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
 {
     if (message->method != SOUP_METHOD_GET) {
@@ -214,10 +290,10 @@ static void serverCallback(SoupServer* server, SoupMessage* message, const char*
     soup_message_set_status(message, SOUP_STATUS_OK);
     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");
+        soup_message_headers_replace(message->response_headers, "Set-Cookie", "foo=bar; Max-Age=60");
         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");
+        soup_message_headers_replace(message->response_headers, "Set-Cookie", "baz=qux; Max-Age=60");
     else
         g_assert_not_reached();
     soup_message_body_complete(message->response_body);
@@ -228,12 +304,17 @@ void beforeAll()
     kServer = new WebKitTestServer();
     kServer->run(serverCallback);
 
+    kTempDirectory = g_dir_make_tmp("WebKit2Tests-XXXXXX", 0);
+    g_assert(kTempDirectory);
+
     CookieManagerTest::add("WebKitCookieManager", "accept-policy", testCookieManagerAcceptPolicy);
     CookieManagerTest::add("WebKitCookieManager", "delete-cookies", testCookieManagerDeleteCookies);
     CookieManagerTest::add("WebKitCookieManager", "cookies-changed", testCookieManagerCookiesChanged);
+    CookieManagerTest::add("WebKitCookieManager", "persistent-storage", testCookieManagerPersistentStorage);
 }
 
 void afterAll()
 {
     delete kServer;
+    g_rmdir(kTempDirectory);
 }
index 7dc20d5..cf1c15b 100644 (file)
@@ -70,6 +70,10 @@ public:
     void startObservingCookieChanges();
     void stopObservingCookieChanges();
 
+#if USE(SOUP)
+    void setCookiePersistentStorage(const String& storagePath, uint32_t storageType);
+#endif
+
     void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
 
     bool shouldTerminate(WebProcessProxy*) const;
diff --git a/Source/WebKit2/UIProcess/soup/WebCookieManagerProxySoup.cpp b/Source/WebKit2/UIProcess/soup/WebCookieManagerProxySoup.cpp
new file mode 100644 (file)
index 0000000..08914ed
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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 "WebCookieManagerProxy.h"
+
+#include "WebContext.h"
+#include "WebCookieManagerMessages.h"
+
+namespace WebKit {
+
+void WebCookieManagerProxy::setCookiePersistentStorage(const String& storagePath, uint32_t storageType)
+{
+    m_webContext->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebCookieManager::SetCookiePersistentStorage(storagePath, storageType));
+}
+
+}
index c0bd1f3..cf78a11 100644 (file)
 #include <wtf/Noncopyable.h>
 #include <wtf/text/WTFString.h>
 
+#if USE(SOUP)
+#include "SoupCookiePersistentStorageType.h"
+#endif
+
 namespace CoreIPC {
     class ArgumentDecoder;
     class Connection;
@@ -63,6 +67,10 @@ private:
     void startObservingCookieChanges();
     void stopObservingCookieChanges();
 
+#if USE(SOUP)
+    void setCookiePersistentStorage(const String& storagePath, uint32_t storageType);
+#endif
+
     void didReceiveWebCookieManagerMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
 };
 
index 15de9b6..0ae1155 100644 (file)
@@ -33,4 +33,8 @@
     
     void StartObservingCookieChanges()
     void StopObservingCookieChanges()
+
+#if USE(SOUP)
+    SetCookiePersistentStorage(WTF::String storagePath, uint32_t storageType)
+#endif
 }
index da21808..9b3fbaf 100644 (file)
 #include "config.h"
 #include "WebCookieManager.h"
 
+#include "WebKitSoupCookieJarSqlite.h"
 #include <WebCore/CookieJarSoup.h>
+#include <WebCore/ResourceHandle.h>
 #include <libsoup/soup.h>
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
 
 using namespace WebCore;
 
@@ -77,4 +81,27 @@ HTTPCookieAcceptPolicy WebCookieManager::platformGetHTTPCookieAcceptPolicy()
     return policy;
 }
 
+void WebCookieManager::setCookiePersistentStorage(const String& storagePath, uint32_t storageType)
+{
+    GRefPtr<SoupCookieJar> jar;
+    switch (storageType) {
+    case SoupCookiePersistentStorageText:
+        jar = adoptGRef(soup_cookie_jar_text_new(storagePath.utf8().data(), FALSE));
+        break;
+    case SoupCookiePersistentStorageSQLite:
+        jar = adoptGRef(webkitSoupCookieJarSqliteNew(storagePath));
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+
+    SoupCookieJar* currentJar = WebCore::soupCookieJar();
+    soup_cookie_jar_set_accept_policy(jar.get(), soup_cookie_jar_get_accept_policy(currentJar));
+    SoupSession* session = ResourceHandle::defaultSession();
+    soup_session_remove_feature(session, SOUP_SESSION_FEATURE(currentJar));
+    soup_session_add_feature(session, SOUP_SESSION_FEATURE(jar.get()));
+
+    WebCore::setSoupCookieJar(jar.get());
+}
+
 } // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/Cookies/soup/WebKitSoupCookieJarSqlite.cpp b/Source/WebKit2/WebProcess/Cookies/soup/WebKitSoupCookieJarSqlite.cpp
new file mode 100644 (file)
index 0000000..ef71247
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2,1 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 "WebKitSoupCookieJarSqlite.h"
+
+#include <WebCore/SQLiteDatabase.h>
+#include <WebCore/SQLiteStatement.h>
+#include <WebCore/SQLiteTransaction.h>
+#include <libsoup/soup.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/MathExtras.h>
+
+using namespace WebCore;
+
+struct _WebKitSoupCookieJarSqlitePrivate {
+    String databasePath;
+    SQLiteDatabase database;
+    bool isLoading;
+};
+
+G_DEFINE_TYPE(WebKitSoupCookieJarSqlite, webkit_soup_cookie_jar_sqlite, SOUP_TYPE_COOKIE_JAR)
+
+enum {
+    ColumnID,
+    ColumnName,
+    ColumnValue,
+    ColumnHost,
+    ColumnPath,
+    ColumnExpiry,
+    ColumnLastAccess,
+    ColumnSecure,
+    ColumnHTTPOnly
+};
+
+static bool webkitSoupCookieJarSqliteOpenDatabase(WebKitSoupCookieJarSqlite* sqliteJar)
+{
+    WebKitSoupCookieJarSqlitePrivate* priv = sqliteJar->priv;
+    if (priv->database.isOpen())
+        return true;
+
+    ASSERT(!priv->databasePath.isEmpty());
+    if (!priv->database.open(priv->databasePath)) {
+        g_warning("Can't open database %s", priv->databasePath.utf8().data());
+        return false;
+    }
+
+    priv->database.setSynchronous(SQLiteDatabase::SyncOff);
+    priv->database.executeCommand("PRAGMA secure_delete = 1;");
+
+    return true;
+}
+
+static bool webkitSoupCookieJarSqliteCreateTable(WebKitSoupCookieJarSqlite* sqliteJar)
+{
+    WebKitSoupCookieJarSqlitePrivate* priv = sqliteJar->priv;
+    if (priv->database.tableExists("moz_cookies"))
+        return true;
+
+    if (!priv->database.executeCommand("CREATE TABLE moz_cookies (id INTEGER PRIMARY KEY, name TEXT, value TEXT, host TEXT, path TEXT, expiry INTEGER, lastAccessed INTEGER, isSecure INTEGER, isHttpOnly INTEGER)")) {
+        g_warning("Failed to create table moz_cookies: (%i) - %s", priv->database.lastError(), priv->database.lastErrorMsg());
+        priv->database.close();
+
+        return false;
+    }
+
+    return true;
+}
+
+static void webkitSoupCookieJarSqliteLoad(WebKitSoupCookieJarSqlite* sqliteJar)
+{
+    if (!webkitSoupCookieJarSqliteOpenDatabase(sqliteJar))
+        return;
+    if (!webkitSoupCookieJarSqliteCreateTable(sqliteJar))
+        return;
+
+    WebKitSoupCookieJarSqlitePrivate* priv = sqliteJar->priv;
+    priv->isLoading = true;
+    SQLiteStatement query(priv->database, "SELECT id, name, value, host, path, expiry, lastAccessed, isSecure, isHttpOnly FROM moz_cookies;");
+    if (query.prepare() != SQLResultOk) {
+        g_warning("Failed to prepare all cookies query");
+        priv->isLoading = false;
+        return;
+    }
+
+    SoupCookieJar* jar = SOUP_COOKIE_JAR(sqliteJar);
+    time_t now = floorf(currentTime());
+    int result;
+    while ((result = query.step()) == SQLResultRow) {
+        int expireTime = query.getColumnInt(ColumnExpiry);
+        if (now >= expireTime)
+            continue;
+
+        SoupCookie* cookie = soup_cookie_new(query.getColumnText(ColumnName).utf8().data(), query.getColumnText(ColumnValue).utf8().data(),
+                                             query.getColumnText(ColumnHost).utf8().data(), query.getColumnText(ColumnPath).utf8().data(),
+                                             expireTime - now <= G_MAXINT ? expireTime - now : G_MAXINT);
+        if (query.getColumnInt(ColumnSecure))
+            soup_cookie_set_secure(cookie, TRUE);
+        if (query.getColumnInt(ColumnHTTPOnly))
+            soup_cookie_set_http_only(cookie, TRUE);
+
+        soup_cookie_jar_add_cookie(jar, cookie);
+    }
+
+    if (result != SQLResultDone)
+        g_warning("Error reading cookies from database");
+    priv->isLoading = false;
+}
+
+static bool webkitSoupCookieJarSqliteInsertCookie(WebKitSoupCookieJarSqlite* sqliteJar, SoupCookie* cookie)
+{
+    WebKitSoupCookieJarSqlitePrivate* priv = sqliteJar->priv;
+    SQLiteStatement query(priv->database, "INSERT INTO moz_cookies VALUES(NULL, ?, ?, ?, ?, ?, NULL, ?, ?);");
+    if (query.prepare() != SQLResultOk) {
+        g_warning("Failed to prepare insert cookies query");
+        return false;
+    }
+
+    query.bindText(1, String::fromUTF8(cookie->name));
+    query.bindText(2, String::fromUTF8(cookie->value));
+    query.bindText(3, String::fromUTF8(cookie->domain));
+    query.bindText(4, String::fromUTF8(cookie->path));
+    query.bindInt(5, static_cast<int64_t>(soup_date_to_time_t(cookie->expires)));
+    query.bindInt(6, cookie->secure);
+    query.bindInt(7, cookie->http_only);
+    if (query.step() != SQLResultDone) {
+        g_warning("Error adding cookie (name=%s, domain=%s) to database", cookie->name, cookie->name);
+        return false;
+    }
+
+    return true;
+}
+
+static bool webkitSoupCookieJarSqliteDeleteCookie(WebKitSoupCookieJarSqlite* sqliteJar, SoupCookie* cookie)
+{
+    WebKitSoupCookieJarSqlitePrivate* priv = sqliteJar->priv;
+    SQLiteStatement query(priv->database, "DELETE FROM moz_cookies WHERE name = (?) AND host = (?);");
+    if (query.prepare() != SQLResultOk) {
+        g_warning("Failed to prepare delete cookies query");
+        return false;
+    }
+
+    query.bindText(1, String::fromUTF8(cookie->name));
+    query.bindText(2, String::fromUTF8(cookie->domain));
+    if (query.step() != SQLResultDone) {
+        g_warning("Error deleting cookie (name=%s, domain=%s) from database", cookie->name, cookie->name);
+        return false;
+    }
+
+    return true;
+}
+
+static void webkitSoupCookieJarSqliteChanged(SoupCookieJar* jar, SoupCookie* oldCookie, SoupCookie* newCookie)
+{
+    WebKitSoupCookieJarSqlite* sqliteJar = WEBKIT_SOUP_COOKIE_JAR_SQLITE(jar);
+    if (sqliteJar->priv->isLoading)
+        return;
+    if (!webkitSoupCookieJarSqliteOpenDatabase(sqliteJar))
+        return;
+    if (!oldCookie && (!newCookie || !newCookie->expires))
+        return;
+    if (!webkitSoupCookieJarSqliteCreateTable(sqliteJar))
+        return;
+
+    SQLiteTransaction updateTransaction(sqliteJar->priv->database);
+    updateTransaction.begin();
+
+    if (oldCookie && !webkitSoupCookieJarSqliteDeleteCookie(sqliteJar, oldCookie))
+        return;
+
+    if (newCookie && newCookie->expires && !webkitSoupCookieJarSqliteInsertCookie(sqliteJar, newCookie))
+        return;
+
+    updateTransaction.commit();
+}
+
+static void webkitSoupCookieJarSqliteFinalize(GObject* object)
+{
+    WEBKIT_SOUP_COOKIE_JAR_SQLITE(object)->priv->~WebKitSoupCookieJarSqlitePrivate();
+    G_OBJECT_CLASS(webkit_soup_cookie_jar_sqlite_parent_class)->finalize(object);
+}
+
+static void webkit_soup_cookie_jar_sqlite_init(WebKitSoupCookieJarSqlite* sqliteJar)
+{
+    WebKitSoupCookieJarSqlitePrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(sqliteJar, WEBKIT_TYPE_SOUP_COOKIE_JAR_SQLITE, WebKitSoupCookieJarSqlitePrivate);
+    sqliteJar->priv = priv;
+    new (priv) WebKitSoupCookieJarSqlitePrivate();
+}
+
+static void webkit_soup_cookie_jar_sqlite_class_init(WebKitSoupCookieJarSqliteClass* sqliteJarClass)
+{
+    SoupCookieJarClass* cookieJarClass = SOUP_COOKIE_JAR_CLASS(sqliteJarClass);
+    cookieJarClass->changed = webkitSoupCookieJarSqliteChanged;
+
+    GObjectClass* gObjectClass = G_OBJECT_CLASS(sqliteJarClass);
+    gObjectClass->finalize = webkitSoupCookieJarSqliteFinalize;
+
+    g_type_class_add_private(sqliteJarClass, sizeof(WebKitSoupCookieJarSqlitePrivate));
+}
+
+SoupCookieJar* webkitSoupCookieJarSqliteNew(const String& databasePath)
+{
+    ASSERT(!priv->databasePath.isEmpty());
+    WebKitSoupCookieJarSqlite* sqliteJar = WEBKIT_SOUP_COOKIE_JAR_SQLITE(g_object_new(WEBKIT_TYPE_SOUP_COOKIE_JAR_SQLITE, NULL));
+    sqliteJar->priv->databasePath = databasePath;
+    webkitSoupCookieJarSqliteLoad(sqliteJar);
+    return SOUP_COOKIE_JAR(sqliteJar);
+}
diff --git a/Source/WebKit2/WebProcess/Cookies/soup/WebKitSoupCookieJarSqlite.h b/Source/WebKit2/WebProcess/Cookies/soup/WebKitSoupCookieJarSqlite.h
new file mode 100644 (file)
index 0000000..86a0904
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2,1 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.
+ */
+
+#ifndef WebKitSoupCookieJarSqlite_h
+#define WebKitSoupCookieJarSqlite_h
+
+#include <libsoup/soup-cookie-jar.h>
+#include <wtf/text/WTFString.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_SOUP_COOKIE_JAR_SQLITE            (webkit_soup_cookie_jar_sqlite_get_type())
+#define WEBKIT_SOUP_COOKIE_JAR_SQLITE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), WEBKIT_TYPE_SOUP_COOKIE_JAR_SQLITE, WebKitSoupCookieJarSqlite))
+#define WEBKIT_IS_SOUP_COOKIE_JAR_SQLITE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WEBKIT_TYPE_SOUP_COOKIE_JAR_SQLITE))
+#define WEBKIT_SOUP_COOKIE_JAR_SQLITE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), WEBKIT_TYPE_SOUP_COOKIE_JAR_SQLITE, WebKitSoupCookieJarSqliteClass))
+#define WEBKIT_IS_SOUP_COOKIE_JAR_SQLITE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), WEBKIT_TYPE_SOUP_COOKIE_JAR_SQLITE))
+#define WEBKIT_SOUP_COOKIE_JAR_SQLITE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), WEBKIT_TYPE_SOUP_COOKIE_JAR_SQLITE, WebKitSoupCookieJarSqliteClass))
+
+typedef struct _WebKitSoupCookieJarSqlite WebKitSoupCookieJarSqlite;
+typedef struct _WebKitSoupCookieJarSqliteClass WebKitSoupCookieJarSqliteClass;
+typedef struct _WebKitSoupCookieJarSqlitePrivate WebKitSoupCookieJarSqlitePrivate;
+
+struct _WebKitSoupCookieJarSqlite {
+    SoupCookieJar parent;
+
+    WebKitSoupCookieJarSqlitePrivate* priv;
+};
+
+struct _WebKitSoupCookieJarSqliteClass {
+    SoupCookieJarClass parentClass;
+};
+
+GType webkit_soup_cookie_jar_sqlite_get_type();
+SoupCookieJar* webkitSoupCookieJarSqliteNew(const String& databasePath);
+
+G_END_DECLS
+
+#endif // WebKitSoupCookieJarSqlite.h