summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonas M. Gastal <jgastal@profusion.mobi>2012-01-11 17:00:11 -0200
committerQt by Nokia <qt-info@nokia.com>2012-01-27 13:29:14 +0100
commited429ebfc9920c3a0fc97170ff8df6d5520eefb9 (patch)
treede94dc0f0c79d9cc2423cf1955006d0432140645
parent1166ad8603fe4fbd1b008aaa7c043ee1078780a5 (diff)
Gives QNetworkCookieJar a virtual API.
QNetworkCookieJar now has the following virtual methods: virtual bool validateCookie(QNetworkCookie &cookie); virtual bool insertCookie(const QNetworkCookie &cookie, const QUrl &url); virtual bool updateCookie(const QNetworkCookie &cookie); virtual void deleteCookie(const QNetworkCookie &cookie); Their implementation is such that the behavior the class previously had(in memory storage of the cookies) is mantained. Task-number: QTBUG-23145 Change-Id: I1420894d31e8072eca6903c3c7ffd6f06205a257 Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com> Reviewed-by: Alexis Menard <alexis.menard@openbossa.org> Reviewed-by: Lars Knoll <lars.knoll@nokia.com> Reviewed-by: Shane Kearns <ext-shane.2.kearns@nokia.com>
-rw-r--r--src/network/access/qnetworkcookie.cpp37
-rw-r--r--src/network/access/qnetworkcookie.h3
-rw-r--r--src/network/access/qnetworkcookiejar.cpp146
-rw-r--r--src/network/access/qnetworkcookiejar.h5
4 files changed, 128 insertions, 63 deletions
diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp
index df7920de40..38e2ef093c 100644
--- a/src/network/access/qnetworkcookie.cpp
+++ b/src/network/access/qnetworkcookie.cpp
@@ -156,7 +156,7 @@ QNetworkCookie &QNetworkCookie::operator=(const QNetworkCookie &other)
However, in some contexts, two cookies of the same name could be
considered equal.
- \sa operator!=()
+ \sa operator!=(), hasSameIdentifier()
*/
bool QNetworkCookie::operator==(const QNetworkCookie &other) const
{
@@ -172,6 +172,17 @@ bool QNetworkCookie::operator==(const QNetworkCookie &other) const
}
/*!
+ Returns true if this cookie has the same identifier tuple as \a other.
+ The identifier tuple is composed of the name, domain and path.
+
+ \sa operator==()
+*/
+bool QNetworkCookie::hasSameIdentifier(const QNetworkCookie &other) const
+{
+ return d->name == other.d->name && d->domain == other.d->domain && d->path == other.d->path;
+}
+
+/*!
Returns true if the "secure" option was specified in the cookie
string, false otherwise.
@@ -1042,6 +1053,30 @@ QList<QNetworkCookie> QNetworkCookiePrivate::parseSetCookieHeaderLine(const QByt
return result;
}
+/*!
+ This functions normalizes the path and domain of the cookie if they were previously empty.
+*/
+void QNetworkCookie::normalize(const QUrl &url)
+{
+ // don't do path checking. See http://bugreports.qt.nokia.com/browse/QTBUG-5815
+ if (d->path.isEmpty()) {
+ QString pathAndFileName = url.path();
+ QString defaultPath = pathAndFileName.left(pathAndFileName.lastIndexOf(QLatin1Char('/'))+1);
+ if (defaultPath.isEmpty())
+ defaultPath = QLatin1Char('/');
+ d->path = defaultPath;
+ }
+
+ if (d->domain.isEmpty())
+ d->domain = url.host();
+ else if (!d->domain.startsWith(QLatin1Char('.')))
+ // Ensure the domain starts with a dot if its field was not empty
+ // in the HTTP header. There are some servers that forget the
+ // leading dot and this is actually forbidden according to RFC 2109,
+ // but all browsers accept it anyway so we do that as well.
+ d->domain.prepend(QLatin1Char('.'));
+}
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug s, const QNetworkCookie &cookie)
{
diff --git a/src/network/access/qnetworkcookie.h b/src/network/access/qnetworkcookie.h
index ff68797702..b6dc4e62d0 100644
--- a/src/network/access/qnetworkcookie.h
+++ b/src/network/access/qnetworkcookie.h
@@ -97,6 +97,9 @@ public:
QByteArray toRawForm(RawForm form = Full) const;
+ bool hasSameIdentifier(const QNetworkCookie &other) const;
+ void normalize(const QUrl &url);
+
static QList<QNetworkCookie> parseCookies(const QByteArray &cookieString);
private:
diff --git a/src/network/access/qnetworkcookiejar.cpp b/src/network/access/qnetworkcookiejar.cpp
index 7d3f67cc6e..a49c5d7c10 100644
--- a/src/network/access/qnetworkcookiejar.cpp
+++ b/src/network/access/qnetworkcookiejar.cpp
@@ -155,8 +155,7 @@ static inline bool isParentDomain(QString domain, QString reference)
/*!
Adds the cookies in the list \a cookieList to this cookie
- jar. Default values for path and domain are taken from the \a
- url object.
+ jar. Before being inserted cookies are normalized.
Returns true if one or more cookies are set for \a url,
otherwise false.
@@ -173,72 +172,18 @@ static inline bool isParentDomain(QString domain, QString reference)
size. Reimplement this function to discard older cookies to create
room for new ones.
- \sa cookiesForUrl(), QNetworkAccessManager::setCookieJar()
+ \sa cookiesForUrl(), QNetworkAccessManager::setCookieJar(), QNetworkCookie::normalize()
*/
bool QNetworkCookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList,
const QUrl &url)
{
- Q_D(QNetworkCookieJar);
- QString defaultDomain = url.host();
- QString pathAndFileName = url.path();
- QString defaultPath = pathAndFileName.left(pathAndFileName.lastIndexOf(QLatin1Char('/'))+1);
- if (defaultPath.isEmpty())
- defaultPath = QLatin1Char('/');
-
- int added = 0;
- QDateTime now = QDateTime::currentDateTime();
+ bool added = false;
foreach (QNetworkCookie cookie, cookieList) {
- bool isDeletion = !cookie.isSessionCookie() &&
- cookie.expirationDate() < now;
-
- // validate the cookie & set the defaults if unset
- if (cookie.path().isEmpty())
- cookie.setPath(defaultPath);
- // don't do path checking. See http://bugreports.qt.nokia.com/browse/QTBUG-5815
-// else if (!isParentPath(pathAndFileName, cookie.path())) {
-// continue; // not accepted
-// }
- if (cookie.domain().isEmpty()) {
- cookie.setDomain(defaultDomain);
- } else {
- // Ensure the domain starts with a dot if its field was not empty
- // in the HTTP header. There are some servers that forget the
- // leading dot and this is actually forbidden according to RFC 2109,
- // but all browsers accept it anyway so we do that as well.
- if (!cookie.domain().startsWith(QLatin1Char('.')))
- cookie.setDomain(QLatin1Char('.') + cookie.domain());
-
- QString domain = cookie.domain();
- if (!(isParentDomain(domain, defaultDomain)
- || isParentDomain(defaultDomain, domain)))
- continue; // not accepted
-
- // the check for effective TLDs makes the "embedded dot" rule from RFC 2109 section 4.3.2
- // redundant; the "leading dot" rule has been relaxed anyway, see above
- // we remove the leading dot for this check
- if (qIsEffectiveTLD(domain.remove(0, 1)))
- continue; // not accepted
- }
-
- QList<QNetworkCookie>::Iterator it = d->allCookies.begin(),
- end = d->allCookies.end();
- for ( ; it != end; ++it)
- // does this cookie already exist?
- if (cookie.name() == it->name() &&
- cookie.domain() == it->domain() &&
- cookie.path() == it->path()) {
- // found a match
- d->allCookies.erase(it);
- break;
- }
-
- // did not find a match
- if (!isDeletion) {
- d->allCookies += cookie;
- ++added;
- }
+ cookie.normalize(url);
+ if (validateCookie(cookie, url) && insertCookie(cookie))
+ added = true;
}
- return (added > 0);
+ return added;
}
/*!
@@ -304,4 +249,81 @@ QList<QNetworkCookie> QNetworkCookieJar::cookiesForUrl(const QUrl &url) const
return result;
}
+/*!
+ Adds \a cookie to this cookie jar.
+
+ Returns true if \a cookie was added, false otherwise.
+
+ If a cookie with the same identifier already exists in the
+ cookie jar, it will be overridden.
+*/
+bool QNetworkCookieJar::insertCookie(const QNetworkCookie &cookie)
+{
+ Q_D(QNetworkCookieJar);
+ QDateTime now = QDateTime::currentDateTime();
+ bool isDeletion = !cookie.isSessionCookie() &&
+ cookie.expirationDate() < now;
+
+ deleteCookie(cookie);
+
+ if (!isDeletion) {
+ d->allCookies += cookie;
+ return true;
+ }
+ return false;
+}
+
+/*!
+ If a cookie with the same identifier as \a cookie exists in this cookie jar
+ it will be updated. This function uses insertCookie().
+
+ Returns true if \a cookie was updated, false if no cookie in the jar matches
+ the identifier of \a cookie.
+
+ \sa QNetworkCookie::hasSameIdentifier()
+*/
+bool QNetworkCookieJar::updateCookie(const QNetworkCookie &cookie)
+{
+ if (deleteCookie(cookie))
+ return insertCookie(cookie);
+ return false;
+}
+
+/*!
+ Deletes from cookie jar the cookie found to have the same identifier as \a cookie.
+
+ Returns true if a cookie was deleted, false otherwise.
+
+ \sa QNetworkCookie::hasSameIdentifier()
+*/
+bool QNetworkCookieJar::deleteCookie(const QNetworkCookie &cookie)
+{
+ Q_D(QNetworkCookieJar);
+ QList<QNetworkCookie>::Iterator it;
+ for (it = d->allCookies.begin(); it != d->allCookies.end(); it++)
+ if (it->hasSameIdentifier(cookie)) {
+ d->allCookies.erase(it);
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Returns true if the domain and path of \a cookie are valid, false otherwise.
+*/
+bool QNetworkCookieJar::validateCookie(const QNetworkCookie &cookie, const QUrl &url) const
+{
+ QString domain = cookie.domain();
+ if (!(isParentDomain(domain, url.host()) || isParentDomain(url.host(), domain)))
+ return false; // not accepted
+
+ // the check for effective TLDs makes the "embedded dot" rule from RFC 2109 section 4.3.2
+ // redundant; the "leading dot" rule has been relaxed anyway, see QNetworkCookie::normalize()
+ // we remove the leading dot for this check if it's present
+ if (qIsEffectiveTLD(domain.startsWith('.') ? domain.remove(0, 1) : domain))
+ return false; // not accepted
+
+ return true;
+}
+
QT_END_NAMESPACE
diff --git a/src/network/access/qnetworkcookiejar.h b/src/network/access/qnetworkcookiejar.h
index 5f30f62179..3ae906c978 100644
--- a/src/network/access/qnetworkcookiejar.h
+++ b/src/network/access/qnetworkcookiejar.h
@@ -63,9 +63,14 @@ public:
virtual QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const;
virtual bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url);
+ virtual bool insertCookie(const QNetworkCookie &cookie);
+ virtual bool updateCookie(const QNetworkCookie &cookie);
+ virtual bool deleteCookie(const QNetworkCookie &cookie);
+
protected:
QList<QNetworkCookie> allCookies() const;
void setAllCookies(const QList<QNetworkCookie> &cookieList);
+ virtual bool validateCookie(const QNetworkCookie &cookie, const QUrl &url) const;
private:
Q_DECLARE_PRIVATE(QNetworkCookieJar)