diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-14 13:18:32 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-12-07 22:38:37 +0100 |
commit | 37bd7b5733c7f1a4eb6ac5458fdc46f94a91194a (patch) | |
tree | 6dff87bc15f8a38b7aad071f1c8f36caa392c23e /src/network/access | |
parent | c0a17ecfaf101715fd758f48c81141ddf2836975 (diff) |
Add SameSite API to QNetworkCookie
Change-Id: I3f8b25418154f74bb55fa978b03465f75771d015
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/network/access')
-rw-r--r-- | src/network/access/qnetworkcookie.cpp | 72 | ||||
-rw-r--r-- | src/network/access/qnetworkcookie.h | 10 | ||||
-rw-r--r-- | src/network/access/qnetworkcookie_p.h | 9 |
3 files changed, 84 insertions, 7 deletions
diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index cf1232e37f..cfc3b14c9e 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -223,6 +223,29 @@ void QNetworkCookie::setSecure(bool enable) } /*! + Returns the "SameSite" option if specified in the cookie + string, \c SameSite::Default if not present. + + \since 6.1 + \sa setSameSite() +*/ +QNetworkCookie::SameSite QNetworkCookie::sameSite() const +{ + return d->sameSite; +} + +/*! + Sets the "SameSite" option of this cookie to \a sameSite. + + \since 6.1 + \sa sameSite() +*/ +void QNetworkCookie::setSameSite(QNetworkCookie::SameSite sameSite) +{ + d->sameSite = sameSite; +} + +/*! \since 4.5 Returns \c true if the "HttpOnly" flag is enabled for this cookie. @@ -436,6 +459,49 @@ static QPair<QByteArray, QByteArray> nextField(const QByteArray &text, int &posi */ /*! + \enum QNetworkCookie::SameSite + \since 6.1 + + \value Default SameSite is not set. Can be interpreted as None or Lax by the browser. + \value None Cookies can be sent in all contexts. This used to be default, but + recent browsers made Lax default, and will now require the cookie to be both secure and to set SameSite=None. + \value Lax Cookies are sent on first party requests and GET requests initiated by third party website. + This is the default in modern browsers (since mid 2020). + \value Strict Cookies will only be sent in a first-party context. + + \sa setSameSite(), sameSite() +*/ + +namespace { +QByteArray sameSiteToRawString(QNetworkCookie::SameSite samesite) +{ + switch (samesite) { + case QNetworkCookie::SameSite::None: + return QByteArrayLiteral("None"); + case QNetworkCookie::SameSite::Lax: + return QByteArrayLiteral("Lax"); + case QNetworkCookie::SameSite::Strict: + return QByteArrayLiteral("Strict"); + case QNetworkCookie::SameSite::Default: + break; + } + return QByteArray(); +} + +QNetworkCookie::SameSite sameSiteFromRawString(QByteArray str) +{ + str = str.toLower(); + if (str == QByteArrayLiteral("none")) + return QNetworkCookie::SameSite::None; + if (str == QByteArrayLiteral("lax")) + return QNetworkCookie::SameSite::Lax; + if (str == QByteArrayLiteral("strict")) + return QNetworkCookie::SameSite::Strict; + return QNetworkCookie::SameSite::Default; +} +} // namespace + +/*! Returns the raw form of this QNetworkCookie. The QByteArray returned by this function is suitable for an HTTP header, either in a server response (the Set-Cookie header) or the client request @@ -460,9 +526,9 @@ QByteArray QNetworkCookie::toRawForm(RawForm form) const result += "; secure"; if (isHttpOnly()) result += "; HttpOnly"; - if (!d->sameSite.isEmpty()) { + if (d->sameSite != SameSite::Default) { result += "; SameSite="; - result += d->sameSite; + result += sameSiteToRawString(d->sameSite); } if (!isSessionCookie()) { result += "; expires="; @@ -999,7 +1065,7 @@ QList<QNetworkCookie> QNetworkCookiePrivate::parseSetCookieHeaderLine(const QByt } else if (field.first == "httponly") { cookie.setHttpOnly(true); } else if (field.first == "samesite") { - cookie.d->sameSite = field.second; + cookie.setSameSite(sameSiteFromRawString(field.second)); } else { // ignore unknown fields in the cookie (RFC6265 section 5.2, rule 6) } diff --git a/src/network/access/qnetworkcookie.h b/src/network/access/qnetworkcookie.h index b712b63849..736a9d7149 100644 --- a/src/network/access/qnetworkcookie.h +++ b/src/network/access/qnetworkcookie.h @@ -57,11 +57,19 @@ class QUrl; class QNetworkCookiePrivate; class Q_NETWORK_EXPORT QNetworkCookie { + Q_GADGET public: enum RawForm { NameAndValueOnly, Full }; + enum class SameSite { + Default, + None, + Lax, + Strict + }; + Q_ENUM(SameSite) explicit QNetworkCookie(const QByteArray &name = QByteArray(), const QByteArray &value = QByteArray()); QNetworkCookie(const QNetworkCookie &other); @@ -79,6 +87,8 @@ public: void setSecure(bool enable); bool isHttpOnly() const; void setHttpOnly(bool enable); + SameSite sameSite() const; + void setSameSite(SameSite sameSite); bool isSessionCookie() const; QDateTime expirationDate() const; diff --git a/src/network/access/qnetworkcookie_p.h b/src/network/access/qnetworkcookie_p.h index e30e611cf5..0cf3442fee 100644 --- a/src/network/access/qnetworkcookie_p.h +++ b/src/network/access/qnetworkcookie_p.h @@ -53,24 +53,25 @@ #include <QtNetwork/private/qtnetworkglobal_p.h> #include "QtCore/qdatetime.h" +#include "QtNetwork/qnetworkcookie.h" QT_BEGIN_NAMESPACE class QNetworkCookiePrivate: public QSharedData { public: - inline QNetworkCookiePrivate() : secure(false), httpOnly(false) { } + QNetworkCookiePrivate() = default; static QList<QNetworkCookie> parseSetCookieHeaderLine(const QByteArray &cookieString); QDateTime expirationDate; QString domain; QString path; QString comment; - QByteArray sameSite; QByteArray name; QByteArray value; - bool secure; - bool httpOnly; + QNetworkCookie::SameSite sameSite = QNetworkCookie::SameSite::Default; + bool secure = false; + bool httpOnly = false; }; static inline bool isLWS(char c) |