Title: [95568] trunk/Source
Revision
95568
Author
[email protected]
Date
2011-09-20 14:01:12 -0700 (Tue, 20 Sep 2011)

Log Message

[Qt] [WK2] Implement a persistent cookie storage.
https://bugs.webkit.org/show_bug.cgi?id=65309

Reviewed by Chang Shu.

Source/WebCore:

Implement a cookie storage for the Qt port on WebKit2.
The implementation is using a SQLite database to store the cookies
and restore them. It uses a static object as CookieJar is not an
object but a set of global functions. The actual saving/restoring is on
the WebProcess side where our network stack lives.

Existing tests cover the new implementation. Unfortunately there is one
case that we can't easily simulate : login in a website, make sure that the webprocess
is not running and then going back to this website and see that we are logged.

* WebCore.pri:
* WebCore.pro:
* platform/qt/CookieJarQt.cpp:
(WebCore::getHostnamesWithCookies):
(WebCore::deleteCookiesForHostname):
(WebCore::deleteAllCookies):
(WebCore::SharedCookieJarQt::shared):
(WebCore::SharedCookieJarQt::create):
(WebCore::SharedCookieJarQt::destroy):
(WebCore::SharedCookieJarQt::getHostnamesWithCookies):
(WebCore::SharedCookieJarQt::deleteCookiesForHostname):
(WebCore::SharedCookieJarQt::deleteAllCookies):
(WebCore::SharedCookieJarQt::SharedCookieJarQt):
(WebCore::SharedCookieJarQt::~SharedCookieJarQt):
(WebCore::SharedCookieJarQt::setCookiesFromUrl):
(WebCore::SharedCookieJarQt::ensureDatabaseTable):
(WebCore::SharedCookieJarQt::loadCookies):
* platform/qt/CookieJarQt.h: Added.

Source/WebKit2:

Add parameter to the WebProcess creation to specify where cookies should be saved.
It also use the new cookie storage implementation and set it to our network stack
so cookies are used when using it.

* Shared/WebProcessCreationParameters.cpp:
(WebKit::WebProcessCreationParameters::encode):
(WebKit::WebProcessCreationParameters::decode):
* Shared/WebProcessCreationParameters.h:
* UIProcess/qt/WebContextQt.cpp:
(WebKit::WebContext::platformInitializeWebProcess):
* WebProcess/qt/WebProcessQt.cpp:
(WebKit::WebProcess::platformInitializeWebProcess):
(WebKit::WebProcess::platformTerminate):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (95567 => 95568)


--- trunk/Source/WebCore/ChangeLog	2011-09-20 20:26:13 UTC (rev 95567)
+++ trunk/Source/WebCore/ChangeLog	2011-09-20 21:01:12 UTC (rev 95568)
@@ -1,3 +1,39 @@
+2011-09-20  Alexis Menard  <[email protected]>
+
+        [Qt] [WK2] Implement a persistent cookie storage.
+        https://bugs.webkit.org/show_bug.cgi?id=65309
+
+        Reviewed by Chang Shu.
+
+        Implement a cookie storage for the Qt port on WebKit2.
+        The implementation is using a SQLite database to store the cookies
+        and restore them. It uses a static object as CookieJar is not an
+        object but a set of global functions. The actual saving/restoring is on
+        the WebProcess side where our network stack lives.
+
+        Existing tests cover the new implementation. Unfortunately there is one
+        case that we can't easily simulate : login in a website, make sure that the webprocess
+        is not running and then going back to this website and see that we are logged.
+
+        * WebCore.pri:
+        * WebCore.pro:
+        * platform/qt/CookieJarQt.cpp:
+        (WebCore::getHostnamesWithCookies):
+        (WebCore::deleteCookiesForHostname):
+        (WebCore::deleteAllCookies):
+        (WebCore::SharedCookieJarQt::shared):
+        (WebCore::SharedCookieJarQt::create):
+        (WebCore::SharedCookieJarQt::destroy):
+        (WebCore::SharedCookieJarQt::getHostnamesWithCookies):
+        (WebCore::SharedCookieJarQt::deleteCookiesForHostname):
+        (WebCore::SharedCookieJarQt::deleteAllCookies):
+        (WebCore::SharedCookieJarQt::SharedCookieJarQt):
+        (WebCore::SharedCookieJarQt::~SharedCookieJarQt):
+        (WebCore::SharedCookieJarQt::setCookiesFromUrl):
+        (WebCore::SharedCookieJarQt::ensureDatabaseTable):
+        (WebCore::SharedCookieJarQt::loadCookies):
+        * platform/qt/CookieJarQt.h: Added.
+
 2011-09-20  David Hyatt  <[email protected]>
 
         https://bugs.webkit.org/show_bug.cgi?id=68314

Modified: trunk/Source/WebCore/WebCore.pri (95567 => 95568)


--- trunk/Source/WebCore/WebCore.pri	2011-09-20 20:26:13 UTC (rev 95567)
+++ trunk/Source/WebCore/WebCore.pri	2011-09-20 21:01:12 UTC (rev 95568)
@@ -5,7 +5,7 @@
 # We enable TextureMapper by default; remove this line to enable GraphicsLayerQt.
 CONFIG += texmap
 
-QT *= network
+QT *= network sql
 
 SOURCE_DIR = $$replace(PWD, /WebCore, "")
 

Modified: trunk/Source/WebCore/WebCore.pro (95567 => 95568)


--- trunk/Source/WebCore/WebCore.pro	2011-09-20 20:26:13 UTC (rev 95567)
+++ trunk/Source/WebCore/WebCore.pro	2011-09-20 21:01:12 UTC (rev 95568)
@@ -2096,6 +2096,7 @@
     platform/PlatformTouchPoint.h \
     platform/PopupMenu.h \
     platform/qt/ClipboardQt.h \
+    platform/qt/CookieJarQt.h \
     platform/qt/QWebPageClient.h \
     platform/qt/QtStyleOptionWebComboBox.h \
     platform/qt/RenderThemeQt.h \

Modified: trunk/Source/WebCore/platform/qt/CookieJarQt.cpp (95567 => 95568)


--- trunk/Source/WebCore/platform/qt/CookieJarQt.cpp	2011-09-20 20:26:13 UTC (rev 95567)
+++ trunk/Source/WebCore/platform/qt/CookieJarQt.cpp	2011-09-20 21:01:12 UTC (rev 95568)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2006 George Staikos <[email protected]>
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
  *
  * All rights reserved.
  *
@@ -26,6 +27,8 @@
  */
 
 #include "config.h"
+#include "CookieJarQt.h"
+
 #include "CookieJar.h"
 
 #include "Cookie.h"
@@ -38,12 +41,17 @@
 #include "qwebframe.h"
 #include "qwebpage.h"
 #include "qwebsettings.h"
+#include <QDateTime>
+#include <QDir>
 #include <QNetworkAccessManager>
 #include <QNetworkCookie>
+#include <QSqlQuery>
 #include <QStringList>
 
 namespace WebCore {
 
+static SharedCookieJarQt* s_sharedCookieJarQt = 0;
+
 static QNetworkCookieJar *cookieJar(const Document *document)
 {
     if (!document)
@@ -144,19 +152,137 @@
 
 void getHostnamesWithCookies(HashSet<String>& hostnames)
 {
-    // FIXME: Not yet implemented
+    SharedCookieJarQt* jar = SharedCookieJarQt::shared();
+    if (jar)
+        jar->getHostnamesWithCookies(hostnames);
 }
 
 void deleteCookiesForHostname(const String& hostname)
 {
-    // FIXME: Not yet implemented
+    SharedCookieJarQt* jar = SharedCookieJarQt::shared();
+    if (jar)
+        jar->deleteCookiesForHostname(hostname);
 }
 
 void deleteAllCookies()
 {
-    // FIXME: Not yet implemented
+    SharedCookieJarQt* jar = SharedCookieJarQt::shared();
+    if (jar)
+        jar->deleteAllCookies();
 }
 
+SharedCookieJarQt* SharedCookieJarQt::shared()
+{
+    return s_sharedCookieJarQt;
 }
 
+SharedCookieJarQt* SharedCookieJarQt::create(const String& cookieStorageDirectory)
+{
+    if (!s_sharedCookieJarQt)
+        s_sharedCookieJarQt = new SharedCookieJarQt(cookieStorageDirectory);
+
+    return s_sharedCookieJarQt;
+}
+
+void SharedCookieJarQt::destroy()
+{
+    delete s_sharedCookieJarQt;
+    s_sharedCookieJarQt = 0;
+}
+
+void SharedCookieJarQt::getHostnamesWithCookies(HashSet<String>& hostnames)
+{
+    QList<QNetworkCookie> cookies = allCookies();
+    foreach (const QNetworkCookie& networkCookie, cookies)
+        hostnames.add(networkCookie.domain());
+}
+
+void SharedCookieJarQt::deleteCookiesForHostname(const String& hostname)
+{
+    QList<QNetworkCookie> cookies = allCookies();
+    QList<QNetworkCookie>::Iterator it = cookies.begin();
+    QList<QNetworkCookie>::Iterator end = cookies.end();
+    QSqlQuery sqlQuery(m_database);
+    sqlQuery.prepare(QLatin1String("DELETE FROM cookies WHERE cookieId=:cookieIdvalue"));
+    while (it != end) {
+        if (it->domain() == QString(hostname)) {
+            sqlQuery.bindValue(QLatin1String(":cookieIdvalue"), it->domain().append(QLatin1String(it->name())));
+            sqlQuery.exec();
+            it = cookies.erase(it);
+        } else
+            it++;
+    }
+    setAllCookies(cookies);
+}
+
+void SharedCookieJarQt::deleteAllCookies()
+{
+    QSqlQuery sqlQuery(m_database);
+    sqlQuery.prepare(QLatin1String("DELETE * FROM cookies"));
+    sqlQuery.exec();
+    setAllCookies(QList<QNetworkCookie>());
+}
+
+SharedCookieJarQt::SharedCookieJarQt(const String& cookieStorageDirectory)
+{
+    m_database = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"));
+    const QString cookieStoragePath = cookieStorageDirectory;
+    QDir().mkpath(cookieStoragePath + QLatin1String(".QtWebKit/"));
+    const QString dataBaseName = cookieStoragePath + QLatin1String(".QtWebKit/cookies.db");
+    m_database.setDatabaseName(dataBaseName);
+    ensureDatabaseTable();
+    loadCookies();
+}
+
+SharedCookieJarQt::~SharedCookieJarQt()
+{
+    m_database.close();
+}
+
+bool SharedCookieJarQt::setCookiesFromUrl(const QList<QNetworkCookie>& cookieList, const QUrl& url)
+{
+    if (!QNetworkCookieJar::setCookiesFromUrl(cookieList, url))
+        return false;
+    QSqlQuery sqlQuery(m_database);
+    sqlQuery.prepare(QLatin1String("INSERT OR REPLACE INTO cookies (cookieId, cookie) VALUES (:cookieIdvalue, :cookievalue)"));
+    QVariantList cookiesIds;
+    QVariantList cookiesValues;
+    foreach (const QNetworkCookie &cookie, cookiesForUrl(url)) {
+        if (cookie.isSessionCookie())
+            continue;
+        cookiesIds.append(cookie.domain().append(QLatin1String(cookie.name())));
+        cookiesValues.append(cookie.toRawForm());
+    }
+    sqlQuery.bindValue(QLatin1String(":cookieIdvalue"), cookiesIds);
+    sqlQuery.bindValue(QLatin1String(":cookievalue"), cookiesValues);
+    sqlQuery.execBatch();
+    return true;
+}
+
+void SharedCookieJarQt::ensureDatabaseTable()
+{
+    if (!m_database.open()) {
+        qWarning("Can't open cookie database");
+        return;
+    }
+    QSqlQuery sqlQuery(m_database);
+    sqlQuery.prepare(QLatin1String("CREATE TABLE IF NOT EXISTS cookies (cookieId VARCHAR PRIMARY KEY, cookie BLOB);"));
+    sqlQuery.exec();
+}
+
+void SharedCookieJarQt::loadCookies()
+{
+    QList<QNetworkCookie> cookies;
+    QSqlQuery sqlQuery(m_database);
+    sqlQuery.prepare(QLatin1String("SELECT cookie FROM cookies"));
+    sqlQuery.exec();
+    while (sqlQuery.next())
+        cookies.append(QNetworkCookie::parseCookies(sqlQuery.value(0).toByteArray()));
+    setAllCookies(cookies);
+}
+
+#include "moc_CookieJarQt.cpp"
+
+}
+
 // vim: ts=4 sw=4 et

Added: trunk/Source/WebCore/platform/qt/CookieJarQt.h (0 => 95568)


--- trunk/Source/WebCore/platform/qt/CookieJarQt.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/qt/CookieJarQt.h	2011-09-20 21:01:12 UTC (rev 95568)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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.
+ *
+ */
+
+#ifndef CookieJarQt_h
+#define CookieJarQt_h
+
+#include <QtCore/QObject>
+#include <QtNetwork/QNetworkCookieJar>
+#include <QtSql/QSqlDatabase>
+
+#include <wtf/HashSet.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class SharedCookieJarQt : public QNetworkCookieJar {
+    Q_OBJECT
+public:
+    static SharedCookieJarQt* shared();
+    static SharedCookieJarQt* create(const String&);
+    void destroy();
+
+    void getHostnamesWithCookies(HashSet<String>&);
+    void deleteCookiesForHostname(const String&);
+    void deleteAllCookies();
+    bool setCookiesFromUrl(const QList<QNetworkCookie>&, const QUrl&);
+    void loadCookies();
+
+private:
+    SharedCookieJarQt(const String&);
+    ~SharedCookieJarQt();
+    void ensureDatabaseTable();
+
+    QSqlDatabase m_database;
+};
+
+}
+
+#endif

Modified: trunk/Source/WebKit2/ChangeLog (95567 => 95568)


--- trunk/Source/WebKit2/ChangeLog	2011-09-20 20:26:13 UTC (rev 95567)
+++ trunk/Source/WebKit2/ChangeLog	2011-09-20 21:01:12 UTC (rev 95568)
@@ -1,3 +1,24 @@
+2011-09-20  Alexis Menard  <[email protected]>
+
+        [Qt] [WK2] Implement a persistent cookie storage.
+        https://bugs.webkit.org/show_bug.cgi?id=65309
+
+        Reviewed by Chang Shu.
+
+        Add parameter to the WebProcess creation to specify where cookies should be saved.
+        It also use the new cookie storage implementation and set it to our network stack
+        so cookies are used when using it.
+
+        * Shared/WebProcessCreationParameters.cpp:
+        (WebKit::WebProcessCreationParameters::encode):
+        (WebKit::WebProcessCreationParameters::decode):
+        * Shared/WebProcessCreationParameters.h:
+        * UIProcess/qt/WebContextQt.cpp:
+        (WebKit::WebContext::platformInitializeWebProcess):
+        * WebProcess/qt/WebProcessQt.cpp:
+        (WebKit::WebProcess::platformInitializeWebProcess):
+        (WebKit::WebProcess::platformTerminate):
+
 2011-09-20  Nayan Kumar K  <[email protected]>
 
         Added WKHitTestResult API's.

Modified: trunk/Source/WebKit2/Shared/WebProcessCreationParameters.cpp (95567 => 95568)


--- trunk/Source/WebKit2/Shared/WebProcessCreationParameters.cpp	2011-09-20 20:26:13 UTC (rev 95567)
+++ trunk/Source/WebKit2/Shared/WebProcessCreationParameters.cpp	2011-09-20 21:01:12 UTC (rev 95568)
@@ -91,6 +91,9 @@
         CoreIPC::encode(encoder, storageSession);
 #endif // USE(CFURLSTORAGESESSIONS)
 #endif
+#if PLATFORM(QT)
+    encoder->encode(cookieStorageDirectory);
+#endif
 }
 
 bool WebProcessCreationParameters::decode(CoreIPC::ArgumentDecoder* decoder, WebProcessCreationParameters& parameters)
@@ -172,6 +175,11 @@
 #endif // USE(CFURLSTORAGESESSIONS)
 #endif
 
+#if PLATFORM(QT)
+    if (!decoder->decode(parameters.cookieStorageDirectory))
+        return false;
+#endif
+
     return true;
 }
 

Modified: trunk/Source/WebKit2/Shared/WebProcessCreationParameters.h (95567 => 95568)


--- trunk/Source/WebKit2/Shared/WebProcessCreationParameters.h	2011-09-20 20:26:13 UTC (rev 95567)
+++ trunk/Source/WebKit2/Shared/WebProcessCreationParameters.h	2011-09-20 21:01:12 UTC (rev 95568)
@@ -111,6 +111,9 @@
     RetainPtr<CFDataRef> serializedDefaultStorageSession;
 #endif // USE(CFURLSTORAGESESSIONS)
 #endif // PLATFORM(WIN)
+#if PLATFORM(QT)
+    String cookieStorageDirectory;
+#endif
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/UIProcess/qt/WebContextQt.cpp (95567 => 95568)


--- trunk/Source/WebKit2/UIProcess/qt/WebContextQt.cpp	2011-09-20 20:26:13 UTC (rev 95567)
+++ trunk/Source/WebKit2/UIProcess/qt/WebContextQt.cpp	2011-09-20 21:01:12 UTC (rev 95568)
@@ -29,6 +29,7 @@
 
 #include "ApplicationCacheStorage.h"
 #include "WebProcessCreationParameters.h"
+#include <QDesktopServices>
 #include <QProcess>
 
 namespace WebKit {
@@ -42,9 +43,10 @@
 #endif
 }
 
-void WebContext::platformInitializeWebProcess(WebProcessCreationParameters&)
+void WebContext::platformInitializeWebProcess(WebProcessCreationParameters& parameters)
 {
     qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
+    parameters.cookieStorageDirectory = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
 }
 
 void WebContext::platformInvalidateContext()

Modified: trunk/Source/WebKit2/WebProcess/qt/WebProcessQt.cpp (95567 => 95568)


--- trunk/Source/WebKit2/WebProcess/qt/WebProcessQt.cpp	2011-09-20 20:26:13 UTC (rev 95567)
+++ trunk/Source/WebKit2/WebProcess/qt/WebProcessQt.cpp	2011-09-20 21:01:12 UTC (rev 95568)
@@ -29,6 +29,8 @@
 #include "WebProcessCreationParameters.h"
 #include <WebCore/RuntimeEnabledFeatures.h>
 #include <QNetworkAccessManager>
+#include <QNetworkCookieJar>
+#include <WebCore/CookieJarQt.h>
 
 namespace WebKit {
 
@@ -44,6 +46,11 @@
 void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::ArgumentDecoder* arguments)
 {
     m_networkAccessManager = new QNetworkAccessManager;
+    ASSERT(!parameters.cookieStorageDirectory.isEmpty() && !parameters.cookieStorageDirectory.isNull());
+    WebCore::SharedCookieJarQt* jar = WebCore::SharedCookieJarQt::create(parameters.cookieStorageDirectory);
+    m_networkAccessManager->setCookieJar(jar);
+    // Do not let QNetworkAccessManager delete the jar.
+    jar->setParent(0);
 
     // Disable runtime enabled features that have no WebKit2 implementation yet.
 #if ENABLE(DEVICE_ORIENTATION)
@@ -59,6 +66,7 @@
 {
     delete m_networkAccessManager;
     m_networkAccessManager = 0;
+    WebCore::SharedCookieJarQt::shared()->destroy();
 }
 
 } // namespace WebKit
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to