diff --git a/modules/web/http/web_server_cookie.cpp b/modules/web/http/web_server_cookie.cpp index 46deff10a..e62dabd61 100644 --- a/modules/web/http/web_server_cookie.cpp +++ b/modules/web/http/web_server_cookie.cpp @@ -1,5 +1,7 @@ #include "web_server_cookie.h" +#include "core/class_db.h" +#include "core/object.h" String WebServerCookie::get_domain() { return _domain; @@ -50,11 +52,32 @@ void WebServerCookie::set_delete(const bool val) { _delete = val; } -bool WebServerCookie::get_should_expire() { - return _should_expire; +WebServerCookie::SameSiteValues WebServerCookie::get_same_site() { + return _same_site; } -void WebServerCookie::set_should_expire(const bool val) { - _should_expire = val; +void WebServerCookie::set_same_site(const WebServerCookie::SameSiteValues val) { + _same_site = val; +} + +bool WebServerCookie::get_use_max_age() { + return _use_max_age; +} +void WebServerCookie::set_use_max_age(const bool val) { + _use_max_age = val; +} + +int WebServerCookie::get_max_age() { + return _max_age; +} +void WebServerCookie::set_max_age(const int val) { + _max_age = val; +} + +bool WebServerCookie::get_use_expiry_date() { + return _use_expiry_date; +} +void WebServerCookie::set_use_expiry_date(const bool val) { + _use_expiry_date = val; } uint64_t WebServerCookie::get_expiry_date_unix_time() { @@ -63,7 +86,7 @@ uint64_t WebServerCookie::get_expiry_date_unix_time() { void WebServerCookie::set_expiry_date_unix_time(const uint64_t unix_time) { _expiry_date = OS::get_singleton()->get_datetime_from_unix_time(unix_time); - _should_expire = true; + _use_expiry_date = true; } OS::DateTime WebServerCookie::get_expiry_date() { @@ -72,13 +95,13 @@ OS::DateTime WebServerCookie::get_expiry_date() { void WebServerCookie::set_expiry_date(OS::DateTime date_time) { _expiry_date = date_time; - _should_expire = true; + _use_expiry_date = true; } void WebServerCookie::set_expiry_date(OS::Date date, OS::Time time) { _expiry_date.date = date; _expiry_date.time = time; - _should_expire = true; + _use_expiry_date = true; } Dictionary WebServerCookie::get_expiry_date_dict() { @@ -108,7 +131,7 @@ void WebServerCookie::set_expiry_date_dict(const Dictionary &date, const Diction _expiry_date.time.min = time["minute"]; _expiry_date.time.sec = time["second"]; - _should_expire = true; + _use_expiry_date = true; } void WebServerCookie::set_expiry_date_dt_dict(const Dictionary &date_time) { @@ -124,7 +147,7 @@ void WebServerCookie::set_expiry_date_dt_dict(const Dictionary &date_time) { _expiry_date.time.min = date_time["minute"]; _expiry_date.time.sec = date_time["second"]; - _should_expire = true; + _use_expiry_date = true; } void WebServerCookie::set_data(const String &p_key, const String &p_value) { @@ -133,14 +156,170 @@ void WebServerCookie::set_data(const String &p_key, const String &p_value) { } String WebServerCookie::get_response_header_string() { - return ""; + if (_delete) { + String l; + + l += "Set-Cookie: "; + l += _key; + l += "=; expires=Thu, 01 Jan 1970 00:00:00 GMT"; + + if (_domain != "") { + l += "; Domain="; + l += _domain; + } + + if (_path != "") { + l += "; Path="; + l += _path; + } + + l += "\r\n"; + + return l; + } + + String l; + + l += "Set-Cookie: "; + l += _key; + l += "="; + l += _value; + + if (_use_expiry_date) { + l += "; Expires="; + + switch (_expiry_date.date.weekday) { + case OS::DAY_SUNDAY: + l += "Sun, "; + break; + case OS::DAY_MONDAY: + l += "Mon, "; + break; + case OS::DAY_TUESDAY: + l += "Tue, "; + break; + case OS::DAY_WEDNESDAY: + l += "Wed, "; + break; + case OS::DAY_THURSDAY: + l += "Thu, "; + break; + case OS::DAY_FRIDAY: + l += "Fri, "; + break; + case OS::DAY_SATURDAY: + l += "Sun, "; + break; + default: + break; + } + + l += itos(_expiry_date.date.day).pad_zeros(2); + l += " "; + + switch (_expiry_date.date.month) { + case OS::MONTH_JANUARY: + l += "Jan "; + break; + case OS::MONTH_FEBRUARY: + l += "Feb "; + break; + case OS::MONTH_MARCH: + l += "Mar "; + break; + case OS::MONTH_APRIL: + l += "Apr "; + break; + case OS::MONTH_MAY: + l += "May "; + break; + case OS::MONTH_JUNE: + l += "Jun "; + break; + case OS::MONTH_JULY: + l += "Jul "; + break; + case OS::MONTH_AUGUST: + l += "Aug "; + break; + case OS::MONTH_SEPTEMBER: + l += "Sep "; + break; + case OS::MONTH_OCTOBER: + l += "Oct "; + break; + case OS::MONTH_NOVEMBER: + l += "Nov "; + break; + case OS::MONTH_DECEMBER: + l += "Dec "; + break; + default: + break; + } + + l += itos(_expiry_date.date.year); + l += " "; + l += itos(_expiry_date.time.hour).pad_zeros(2); + l += ":"; + l += itos(_expiry_date.time.min).pad_zeros(2); + l += ":"; + l += itos(_expiry_date.time.sec).pad_zeros(2); + + l += " GMT"; + } + + if (_use_max_age) { + l += "; Max-Age="; + l += itos(_max_age); + } + + if (_secure) { + l += "; Secure"; + } + + if (_http_only) { + l += "; HttpOnly"; + } + + if (_domain != "") { + l += "; Domain="; + l += _domain; + } + + if (_path != "") { + l += "; Path="; + l += _path; + } + + switch (_same_site) { + case SAME_SITE_NONE: + l += "; SameSite=None"; + break; + case SAME_SITE_LAX: + l += "; SameSite=Lax"; + break; + case SAME_SITE_STRICT: + l += "; SameSite=Strict"; + break; + case SAME_SITE_UNSET: + default: + break; + } + + l += "\r\n"; + + return l; } WebServerCookie::WebServerCookie() { - _should_expire = false; + _use_max_age = false; + _max_age = 0; + _use_expiry_date = false; _http_only = true; _secure = false; _delete = false; + _same_site = SAME_SITE_UNSET; } WebServerCookie::~WebServerCookie() { @@ -175,9 +354,21 @@ void WebServerCookie::_bind_methods() { ClassDB::bind_method(D_METHOD("set_delete", "val"), &WebServerCookie::set_delete); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "delete"), "set_delete", "get_delete"); - ClassDB::bind_method(D_METHOD("get_should_expire"), &WebServerCookie::get_should_expire); - ClassDB::bind_method(D_METHOD("set_should_expire", "val"), &WebServerCookie::set_should_expire); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "should_expire"), "set_should_expire", "get_should_expire"); + ClassDB::bind_method(D_METHOD("get_same_site"), &WebServerCookie::get_same_site); + ClassDB::bind_method(D_METHOD("set_same_site", "val"), &WebServerCookie::set_same_site); + ADD_PROPERTY(PropertyInfo(Variant::INT, "same_site", PROPERTY_HINT_ENUM, "Unset,None,Lax,Strict"), "set_same_site", "get_same_site"); + + ClassDB::bind_method(D_METHOD("get_use_max_age"), &WebServerCookie::get_use_max_age); + ClassDB::bind_method(D_METHOD("set_use_max_age", "val"), &WebServerCookie::set_use_max_age); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_max_age"), "set_use_max_age", "get_use_max_age"); + + ClassDB::bind_method(D_METHOD("get_max_age"), &WebServerCookie::get_max_age); + ClassDB::bind_method(D_METHOD("set_max_age", "val"), &WebServerCookie::set_max_age); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_age"), "set_max_age", "get_max_age"); + + ClassDB::bind_method(D_METHOD("get_use_expiry_date"), &WebServerCookie::get_use_expiry_date); + ClassDB::bind_method(D_METHOD("set_use_expiry_date", "val"), &WebServerCookie::set_use_expiry_date); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_expiry_date"), "set_use_expiry_date", "get_use_expiry_date"); ClassDB::bind_method(D_METHOD("get_expiry_date_unix_time"), &WebServerCookie::get_expiry_date_unix_time); ClassDB::bind_method(D_METHOD("set_expiry_date_unix_time", "unix_time"), &WebServerCookie::set_expiry_date_unix_time); @@ -188,4 +379,9 @@ void WebServerCookie::_bind_methods() { ClassDB::bind_method(D_METHOD("set_data", "key", "value"), &WebServerCookie::set_data); ClassDB::bind_method(D_METHOD("get_response_header_string"), &WebServerCookie::get_response_header_string); + + BIND_ENUM_CONSTANT(SAME_SITE_UNSET); + BIND_ENUM_CONSTANT(SAME_SITE_NONE); + BIND_ENUM_CONSTANT(SAME_SITE_LAX); + BIND_ENUM_CONSTANT(SAME_SITE_STRICT); } diff --git a/modules/web/http/web_server_cookie.h b/modules/web/http/web_server_cookie.h index 41bae91f1..36a83fef0 100644 --- a/modules/web/http/web_server_cookie.h +++ b/modules/web/http/web_server_cookie.h @@ -10,6 +10,13 @@ class WebServerCookie : public Reference { GDCLASS(WebServerCookie, Reference); public: + enum SameSiteValues { + SAME_SITE_UNSET = 0, + SAME_SITE_NONE, + SAME_SITE_LAX, + SAME_SITE_STRICT, + }; + String get_domain(); void set_domain(const String &val); @@ -31,8 +38,17 @@ public: bool get_delete(); void set_delete(const bool val); - bool get_should_expire(); - void set_should_expire(const bool val); + SameSiteValues get_same_site(); + void set_same_site(const SameSiteValues val); + + bool get_use_max_age(); + void set_use_max_age(const bool val); + + int get_max_age(); + void set_max_age(const int val); + + bool get_use_expiry_date(); + void set_use_expiry_date(const bool val); uint64_t get_expiry_date_unix_time(); void set_expiry_date_unix_time(const uint64_t unix_time); @@ -55,7 +71,9 @@ public: protected: static void _bind_methods(); - bool _should_expire; + bool _use_max_age; + int _max_age; + bool _use_expiry_date; OS::DateTime _expiry_date; String _domain; String _path; @@ -64,6 +82,9 @@ protected: bool _http_only; bool _secure; bool _delete; + SameSiteValues _same_site; }; +VARIANT_ENUM_CAST(WebServerCookie::SameSiteValues); + #endif