summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-14 13:18:32 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-12-07 22:38:37 +0100
commit37bd7b5733c7f1a4eb6ac5458fdc46f94a91194a (patch)
tree6dff87bc15f8a38b7aad071f1c8f36caa392c23e /src
parentc0a17ecfaf101715fd758f48c81141ddf2836975 (diff)
Add SameSite API to QNetworkCookie
Change-Id: I3f8b25418154f74bb55fa978b03465f75771d015 Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/network/access/qnetworkcookie.cpp72
-rw-r--r--src/network/access/qnetworkcookie.h10
-rw-r--r--src/network/access/qnetworkcookie_p.h9
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)