blob: d4f1a68a58dfa30ce2f50106196c6de988be108c [file] [log] [blame]
/*
* Copyright (C) 2006 George Staikos <staikos@kde.org>
* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
*
* All rights reserved.
*
* 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 COMPUTER, 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 COMPUTER, 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 "CookieJarQt.h"
#include "Cookie.h"
#include "KURL.h"
#include "NetworkingContext.h"
#include "PlatformCookieJar.h"
#include "ThirdPartyCookiesQt.h"
#include <QDateTime>
#include <QNetworkAccessManager>
#include <QNetworkCookie>
#include <QSqlQuery>
#include <QStringList>
#include <QVariant>
#include <wtf/text/WTFString.h>
namespace WebCore {
static SharedCookieJarQt* s_sharedCookieJarQt = 0;
void setCookiesFromDOM(NetworkingContext* context, const KURL& firstParty, const KURL& url, const String& value)
{
QNetworkCookieJar* jar = context ? context->networkAccessManager()->cookieJar() : SharedCookieJarQt::shared();
if (!jar)
return;
QUrl urlForCookies(url);
QUrl firstPartyUrl(firstParty);
if (!thirdPartyCookiePolicyPermits(context, urlForCookies, firstPartyUrl))
return;
QList<QNetworkCookie> cookies = QNetworkCookie::parseCookies(QString(value).toLatin1());
QList<QNetworkCookie>::Iterator it = cookies.begin();
while (it != cookies.end()) {
if (it->isHttpOnly())
it = cookies.erase(it);
else
++it;
}
jar->setCookiesFromUrl(cookies, urlForCookies);
}
String cookiesForDOM(NetworkingContext* context, const KURL& firstParty, const KURL& url)
{
QNetworkCookieJar* jar = context ? context->networkAccessManager()->cookieJar() : SharedCookieJarQt::shared();
if (!jar)
return String();
QUrl urlForCookies(url);
QUrl firstPartyUrl(firstParty);
if (!thirdPartyCookiePolicyPermits(context, urlForCookies, firstPartyUrl))
return String();
QList<QNetworkCookie> cookies = jar->cookiesForUrl(urlForCookies);
if (cookies.isEmpty())
return String();
QStringList resultCookies;
foreach (const QNetworkCookie& networkCookie, cookies) {
if (networkCookie.isHttpOnly())
continue;
resultCookies.append(QString::fromLatin1(networkCookie.toRawForm(QNetworkCookie::NameAndValueOnly).constData()));
}
return resultCookies.join(QLatin1String("; "));
}
String cookieRequestHeaderFieldValue(NetworkingContext* context, const KURL &url)
{
QNetworkCookieJar* jar = context ? context->networkAccessManager()->cookieJar() : SharedCookieJarQt::shared();
if (!jar)
return String();
QList<QNetworkCookie> cookies = jar->cookiesForUrl(QUrl(url));
if (cookies.isEmpty())
return String();
QStringList resultCookies;
foreach (QNetworkCookie networkCookie, cookies)
resultCookies.append(QString::fromLatin1(networkCookie.toRawForm(QNetworkCookie::NameAndValueOnly).constData()));
return resultCookies.join(QLatin1String("; "));
}
bool cookiesEnabled(NetworkingContext* context)
{
QNetworkCookieJar* jar = context ? context->networkAccessManager()->cookieJar() : SharedCookieJarQt::shared();
return !!jar;
}
bool getRawCookies(NetworkingContext*, const KURL&, Vector<Cookie>& rawCookies)
{
// FIXME: Not yet implemented
rawCookies.clear();
return false; // return true when implemented
}
void deleteCookie(NetworkingContext*, const KURL&, const String&)
{
// FIXME: Not yet implemented
}
void getHostnamesWithCookies(NetworkingContext* context, HashSet<String>& hostnames)
{
ASSERT_UNUSED(context, !context); // Not yet implemented for cookie jars other than the shared one.
SharedCookieJarQt* jar = SharedCookieJarQt::shared();
if (jar)
jar->getHostnamesWithCookies(hostnames);
}
void deleteCookiesForHostname(NetworkingContext* context, const String& hostname)
{
ASSERT_UNUSED(context, !context); // Not yet implemented for cookie jars other than the shared one.
SharedCookieJarQt* jar = SharedCookieJarQt::shared();
if (jar)
jar->deleteCookiesForHostname(hostname);
}
void deleteAllCookies(NetworkingContext* context)
{
ASSERT_UNUSED(context, !context); // Not yet implemented for cookie jars other than the shared one.
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());
}
bool SharedCookieJarQt::deleteCookie(const QNetworkCookie& cookie)
{
if (!QNetworkCookieJar::deleteCookie(cookie))
return false;
if (!m_database.isOpen())
return false;
QSqlQuery sqlQuery(m_database);
sqlQuery.prepare(QLatin1String("DELETE FROM cookies WHERE cookieId=:cookieIdvalue"));
sqlQuery.bindValue(QLatin1String(":cookieIdvalue"), cookie.domain().append(QLatin1String(cookie.name())));
sqlQuery.exec();
return true;
}
void SharedCookieJarQt::deleteCookiesForHostname(const String& hostname)
{
if (!m_database.isOpen())
return;
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()
{
if (!m_database.isOpen())
return;
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;
const QString dataBaseName = cookieStoragePath + QLatin1String("/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;
if (!m_database.isOpen())
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;
}
m_database.exec(QLatin1String("PRAGMA synchronous=OFF"));
QSqlQuery sqlQuery(m_database);
sqlQuery.prepare(QLatin1String("CREATE TABLE IF NOT EXISTS cookies (cookieId VARCHAR PRIMARY KEY, cookie BLOB);"));
sqlQuery.exec();
}
void SharedCookieJarQt::loadCookies()
{
if (!m_database.isOpen())
return;
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