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>
bb10
parent
1166ad8603
commit
ed429ebfc9
|
|
@ -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
|
||||
{
|
||||
|
|
@ -171,6 +171,17 @@ bool QNetworkCookie::operator==(const QNetworkCookie &other) const
|
|||
d->comment == other.d->comment;
|
||||
}
|
||||
|
||||
/*!
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue