diff --git a/panda/src/downloader/httpCookie.I b/panda/src/downloader/httpCookie.I index 6116f6722c..95e9d4a5f6 100644 --- a/panda/src/downloader/httpCookie.I +++ b/panda/src/downloader/httpCookie.I @@ -11,15 +11,6 @@ * @date 2004-08-26 */ -/** - * Constructs an empty cookie. - */ -INLINE HTTPCookie:: -HTTPCookie() : - _secure(false) -{ -} - /** * Constructs a cookie according to the indicated string, presumably the tag * of a Set-Cookie header. There is no way to detect a formatting error in @@ -40,7 +31,8 @@ HTTPCookie(const std::string &name, const std::string &path, const std::string & _name(name), _path(path), _domain(domain), - _secure(false) + _secure(false), + _samesite(SS_unspecified) { } @@ -168,6 +160,22 @@ get_secure() const { return _secure; } +/** + * + */ +INLINE void HTTPCookie:: +set_samesite(SameSite samesite) { + _samesite = samesite; +} + +/** + * + */ +INLINE HTTPCookie::SameSite HTTPCookie:: +get_samesite() const { + return _samesite; +} + /** * Returns true if the cookie's expiration date is before the indicated date, * false otherwise. diff --git a/panda/src/downloader/httpCookie.cxx b/panda/src/downloader/httpCookie.cxx index 6ba75d1abd..7c7dff1b0e 100644 --- a/panda/src/downloader/httpCookie.cxx +++ b/panda/src/downloader/httpCookie.cxx @@ -16,6 +16,7 @@ #ifdef HAVE_OPENSSL #include "httpChannel.h" +#include "string_utils.h" #include @@ -59,6 +60,7 @@ update_from(const HTTPCookie &other) { _value = other._value; _expires = other._expires; _secure = other._secure; + _samesite = other._samesite; } /** @@ -74,6 +76,7 @@ parse_set_cookie(const string &format, const URLSpec &url) { _path = url.get_path(); _expires = HTTPDate(); _secure = false; + _samesite = SS_unspecified; bool okflag = true; bool first_param = true; @@ -147,12 +150,16 @@ output(std::ostream &out) const { << "; path=" << _path << "; domain=" << _domain; if (has_expires()) { - out << "; expires=" << _expires; + out << "; expires=" << _expires.get_string(); } if (_secure) { out << "; secure"; } + + if (_samesite != SS_unspecified) { + out << "; samesite=" << _samesite; + } } /** @@ -178,7 +185,7 @@ parse_cookie_param(const string ¶m, bool first_param) { _value = value; } else { - key = HTTPChannel::downcase(key); + key = downcase(key); if (key == "expires") { _expires = HTTPDate(value); if (!_expires.is_valid()) { @@ -189,7 +196,7 @@ parse_cookie_param(const string ¶m, bool first_param) { _path = value; } else if (key == "domain") { - _domain = HTTPChannel::downcase(value); + _domain = downcase(value); // From RFC 2965: If an explicitly specified value does not start with a // dot, the user agent supplies a leading dot. @@ -200,6 +207,18 @@ parse_cookie_param(const string ¶m, bool first_param) { } else if (key == "secure") { _secure = true; + } else if (key == "samesite") { + value = downcase(value); + if (value == "lax") { + _samesite = SS_lax; + } + else if (value == "strict") { + _samesite = SS_strict; + } + else if (value == "none") { + _samesite = SS_none; + } + } else { return false; } @@ -208,4 +227,21 @@ parse_cookie_param(const string ¶m, bool first_param) { return true; } +std::ostream &operator << (std::ostream &out, HTTPCookie::SameSite samesite) { + switch (samesite) { + case HTTPCookie::SS_unspecified: + return out; + + case HTTPCookie::SS_lax: + return out << "lax"; + + case HTTPCookie::SS_strict: + return out << "strict"; + + case HTTPCookie::SS_none: + return out << "none"; + } + return out; +} + #endif // HAVE_OPENSSL diff --git a/panda/src/downloader/httpCookie.h b/panda/src/downloader/httpCookie.h index dfbc507215..7c7ea85f09 100644 --- a/panda/src/downloader/httpCookie.h +++ b/panda/src/downloader/httpCookie.h @@ -31,7 +31,7 @@ */ class EXPCL_PANDA_DOWNLOADER HTTPCookie { PUBLISHED: - INLINE HTTPCookie(); + INLINE HTTPCookie() = default; INLINE explicit HTTPCookie(const std::string &format, const URLSpec &url); INLINE explicit HTTPCookie(const std::string &name, const std::string &path, const std::string &domain); @@ -57,6 +57,16 @@ PUBLISHED: INLINE void set_secure(bool flag); INLINE bool get_secure() const; + enum SameSite { + SS_unspecified, + SS_lax, + SS_strict, + SS_none, + }; + + INLINE void set_samesite(SameSite samesite); + INLINE SameSite get_samesite() const; + bool operator < (const HTTPCookie &other) const; void update_from(const HTTPCookie &other); @@ -74,9 +84,11 @@ private: std::string _path; std::string _domain; HTTPDate _expires; - bool _secure; + bool _secure = false; + SameSite _samesite = SS_unspecified; }; +std::ostream &operator << (std::ostream &out, HTTPCookie::SameSite samesite); INLINE std::ostream &operator << (std::ostream &out, const HTTPCookie &cookie); #include "httpCookie.I"