Reworked the Web Server's Cookie API.

This commit is contained in:
Relintai 2022-07-21 14:05:55 +02:00
parent 9d07a6b271
commit ca08fe3de2
7 changed files with 244 additions and 38 deletions

View File

@ -2,55 +2,145 @@
#include "web_server_cookie.h" #include "web_server_cookie.h"
String WebServerCookie::get_domain() { String WebServerCookie::get_domain() {
return domain; return _domain;
} }
void WebServerCookie::set_domain(const String &val) { void WebServerCookie::set_domain(const String &val) {
domain = val; _domain = val;
} }
String WebServerCookie::get_path() { String WebServerCookie::get_path() {
return path; return _path;
} }
void WebServerCookie::set_path(const String &val) { void WebServerCookie::set_path(const String &val) {
path = val; _path = val;
} }
String WebServerCookie::get_key() { String WebServerCookie::get_key() {
return key; return _key;
} }
void WebServerCookie::set_key(const String &val) { void WebServerCookie::set_key(const String &val) {
key = val; _key = val;
} }
String WebServerCookie::get_value() { String WebServerCookie::get_value() {
return value; return _value;
} }
void WebServerCookie::set_value(const String &val) { void WebServerCookie::set_value(const String &val) {
value = val; _value = val;
} }
bool WebServerCookie::get_http_only() { bool WebServerCookie::get_http_only() {
return http_only; return _http_only;
} }
void WebServerCookie::set_http_only(const bool val) { void WebServerCookie::set_http_only(const bool val) {
http_only = val; _http_only = val;
} }
bool WebServerCookie::get_secure() { bool WebServerCookie::get_secure() {
return secure; return _secure;
} }
void WebServerCookie::set_secure(const bool val) { void WebServerCookie::set_secure(const bool val) {
secure = val; _secure = val;
}
bool WebServerCookie::get_delete() {
return _delete;
}
void WebServerCookie::set_delete(const bool val) {
_delete = val;
}
bool WebServerCookie::get_should_expire() {
return _should_expire;
}
void WebServerCookie::set_should_expire(const bool val) {
_should_expire = val;
}
uint64_t WebServerCookie::get_expiry_date_unix_time() {
return OS::get_singleton()->get_unix_time_from_datetime(_expiry_date);
}
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;
}
OS::DateTime WebServerCookie::get_expiry_date() {
return _expiry_date;
}
void WebServerCookie::set_expiry_date(OS::DateTime date_time) {
_expiry_date = date_time;
_should_expire = true;
}
void WebServerCookie::set_expiry_date(OS::Date date, OS::Time time) {
_expiry_date.date = date;
_expiry_date.time = time;
_should_expire = true;
}
Dictionary WebServerCookie::get_expiry_date_dict() {
Dictionary date_time;
date_time["year"] = _expiry_date.date.year;
date_time["month"] = _expiry_date.date.month;
date_time["day"] = _expiry_date.date.day;
date_time["weekday"] = _expiry_date.date.weekday;
date_time["dst"] = _expiry_date.date.dst;
date_time["hour"] = _expiry_date.time.hour;
date_time["minute"] = _expiry_date.time.min;
date_time["second"] = _expiry_date.time.sec;
return date_time;
}
void WebServerCookie::set_expiry_date_dict(const Dictionary &date, const Dictionary &time) {
int month = date["month"];
int weekday = date["weekday"];
_expiry_date.date.year = date["year"];
_expiry_date.date.month = static_cast<OS::Month>(month);
_expiry_date.date.day = date["day"];
_expiry_date.date.weekday = static_cast<OS::Weekday>(weekday);
_expiry_date.date.dst = date["dst"];
_expiry_date.time.hour = time["hour"];
_expiry_date.time.min = time["minute"];
_expiry_date.time.sec = time["second"];
_should_expire = true;
}
void WebServerCookie::set_expiry_date_dt_dict(const Dictionary &date_time) {
int month = date_time["month"];
int weekday = date_time["weekday"];
_expiry_date.date.year = date_time["year"];
_expiry_date.date.month = static_cast<OS::Month>(month);
_expiry_date.date.day = date_time["day"];
_expiry_date.date.weekday = static_cast<OS::Weekday>(weekday);
_expiry_date.date.dst = date_time["dst"];
_expiry_date.time.hour = date_time["hour"];
_expiry_date.time.min = date_time["minute"];
_expiry_date.time.sec = date_time["second"];
_should_expire = true;
} }
void WebServerCookie::set_data(const String &p_key, const String &p_value) { void WebServerCookie::set_data(const String &p_key, const String &p_value) {
key = p_key; _key = p_key;
value = p_value; _value = p_value;
}
String WebServerCookie::get_response_header_string() {
return "";
} }
WebServerCookie::WebServerCookie() { WebServerCookie::WebServerCookie() {
http_only = true; _should_expire = false;
secure = false; _http_only = true;
_secure = false;
_delete = false;
} }
WebServerCookie::~WebServerCookie() { WebServerCookie::~WebServerCookie() {
@ -81,5 +171,21 @@ void WebServerCookie::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_secure", "val"), &WebServerCookie::set_secure); ClassDB::bind_method(D_METHOD("set_secure", "val"), &WebServerCookie::set_secure);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "secure"), "set_secure", "get_secure"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "secure"), "set_secure", "get_secure");
ClassDB::bind_method(D_METHOD("get_delete"), &WebServerCookie::get_delete);
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_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);
ClassDB::bind_method(D_METHOD("get_expiry_date"), &WebServerCookie::get_expiry_date_dict);
ClassDB::bind_method(D_METHOD("set_expiry_date", "date", "time"), &WebServerCookie::set_expiry_date_dict);
ClassDB::bind_method(D_METHOD("set_expiry_date_dt", "date_time"), &WebServerCookie::set_expiry_date_dt_dict);
ClassDB::bind_method(D_METHOD("set_data", "key", "value"), &WebServerCookie::set_data); 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);
} }

View File

@ -1,6 +1,7 @@
#ifndef WEB_SERVER_COOKIE_H #ifndef WEB_SERVER_COOKIE_H
#define WEB_SERVER_COOKIE_H #define WEB_SERVER_COOKIE_H
#include "core/os/os.h"
#include "core/ustring.h" #include "core/ustring.h"
#include "core/reference.h" #include "core/reference.h"
@ -27,21 +28,42 @@ public:
bool get_secure(); bool get_secure();
void set_secure(const bool val); void set_secure(const bool val);
bool get_delete();
void set_delete(const bool val);
bool get_should_expire();
void set_should_expire(const bool val);
uint64_t get_expiry_date_unix_time();
void set_expiry_date_unix_time(const uint64_t unix_time);
OS::DateTime get_expiry_date();
void set_expiry_date(OS::DateTime date_time);
void set_expiry_date(OS::Date date, OS::Time time);
Dictionary get_expiry_date_dict();
void set_expiry_date_dict(const Dictionary &date, const Dictionary &time);
void set_expiry_date_dt_dict(const Dictionary &date_time);
void set_data(const String &p_key, const String &p_value); void set_data(const String &p_key, const String &p_value);
String get_response_header_string();
WebServerCookie(); WebServerCookie();
~WebServerCookie(); ~WebServerCookie();
//todo date
String domain;
String path;
String key;
String value;
bool http_only;
bool secure;
protected: protected:
static void _bind_methods(); static void _bind_methods();
bool _should_expire;
OS::DateTime _expiry_date;
String _domain;
String _path;
String _key;
String _value;
bool _http_only;
bool _secure;
bool _delete;
}; };
#endif #endif

View File

@ -153,10 +153,34 @@ String WebServerRequest::get_cookie(const String &key) {
return ""; return "";
} }
void WebServerRequest::add_cookie(const Ref<WebServerCookie> &cookie) { void WebServerRequest::response_add_cookie(const Ref<WebServerCookie> &cookie) {
_cookies.push_back(cookie);
} }
void WebServerRequest::remove_cookie(const String &key) { int WebServerRequest::response_get_cookie_count() {
return _cookies.size();
}
Ref<WebServerCookie> WebServerRequest::response_get_cookie(const int index) {
ERR_FAIL_INDEX_V(index, _cookies.size(), Ref<WebServerCookie>());
return _cookies[index];
}
void WebServerRequest::response_remove_cookie(const int index) {
ERR_FAIL_INDEX(index, _cookies.size());
_cookies.remove(index);
}
void WebServerRequest::response_remove_cookie_simple(const String &key) {
Ref<WebServerCookie> cookie;
cookie.instance();
cookie->set_data(key, "");
cookie->set_delete(true);
_cookies.push_back(cookie);
} }
HTTPServerEnums::HTTPMethod WebServerRequest::get_method() const { HTTPServerEnums::HTTPMethod WebServerRequest::get_method() const {
@ -500,8 +524,12 @@ void WebServerRequest::_bind_methods() {
ClassDB::bind_method(D_METHOD("validate_csrf_token"), &WebServerRequest::validate_csrf_token); ClassDB::bind_method(D_METHOD("validate_csrf_token"), &WebServerRequest::validate_csrf_token);
ClassDB::bind_method(D_METHOD("get_cookie", "key"), &WebServerRequest::get_cookie); ClassDB::bind_method(D_METHOD("get_cookie", "key"), &WebServerRequest::get_cookie);
ClassDB::bind_method(D_METHOD("add_cookie", "cookie"), &WebServerRequest::add_cookie);
ClassDB::bind_method(D_METHOD("remove_cookie", "key"), &WebServerRequest::remove_cookie); ClassDB::bind_method(D_METHOD("response_add_cookie", "cookie"), &WebServerRequest::response_add_cookie);
ClassDB::bind_method(D_METHOD("response_get_cookie_count"), &WebServerRequest::response_get_cookie_count);
ClassDB::bind_method(D_METHOD("response_get_cookie", "index"), &WebServerRequest::response_get_cookie);
ClassDB::bind_method(D_METHOD("response_remove_cookie", "index"), &WebServerRequest::response_remove_cookie);
ClassDB::bind_method(D_METHOD("response_remove_cookie_simple", "key"), &WebServerRequest::response_remove_cookie_simple);
ClassDB::bind_method(D_METHOD("get_method"), &WebServerRequest::get_method); ClassDB::bind_method(D_METHOD("get_method"), &WebServerRequest::get_method);

View File

@ -60,8 +60,12 @@ public:
bool validate_csrf_token(); bool validate_csrf_token();
virtual String get_cookie(const String &key); virtual String get_cookie(const String &key);
virtual void add_cookie(const Ref<WebServerCookie> &cookie);
virtual void remove_cookie(const String &key); void response_add_cookie(const Ref<WebServerCookie> &cookie);
int response_get_cookie_count();
Ref<WebServerCookie> response_get_cookie(const int index);
void response_remove_cookie(const int index);
void response_remove_cookie_simple(const String &key);
virtual HTTPServerEnums::HTTPMethod get_method() const; virtual HTTPServerEnums::HTTPMethod get_method() const;
@ -141,6 +145,7 @@ protected:
String _full_path; String _full_path;
Vector<String> _path_stack; Vector<String> _path_stack;
int _path_stack_pointer; int _path_stack_pointer;
Vector<Ref<WebServerCookie>> _cookies;
}; };
#endif #endif

View File

@ -30,6 +30,7 @@
#include "http_server_simple.h" #include "http_server_simple.h"
#include "../http/web_server_cookie.h"
#include "http_parser.h" #include "http_parser.h"
#include "simple_web_server_request.h" #include "simple_web_server_request.h"
#include "web_server_simple.h" #include "web_server_simple.h"
@ -218,6 +219,19 @@ void HTTPServerSimple::send_redirect(Ref<WebServerRequest> request, const String
String s = "HTTP/1.1 " + HTTPServerEnums::get_status_code_header_string(status_code) + "\r\n"; String s = "HTTP/1.1 " + HTTPServerEnums::get_status_code_header_string(status_code) + "\r\n";
s += "Location: " + location + "\r\n"; s += "Location: " + location + "\r\n";
s += "Connection: Close\r\n"; s += "Connection: Close\r\n";
for (int i = 0; i < request->response_get_cookie_count(); ++i) {
Ref<WebServerCookie> cookie = request->response_get_cookie(i);
ERR_CONTINUE(!cookie.is_valid());
String cookie_str = cookie->get_response_header_string();
if (cookie_str != "") {
s += cookie_str;
}
}
s += "\r\n"; s += "\r\n";
CharString cs = s.utf8(); CharString cs = s.utf8();
peer->put_data((const uint8_t *)cs.get_data(), cs.size() - 1); peer->put_data((const uint8_t *)cs.get_data(), cs.size() - 1);
@ -229,6 +243,19 @@ void HTTPServerSimple::send(Ref<WebServerRequest> request) {
s += "Content-Length: " + itos(body.size()) + "\r\n"; s += "Content-Length: " + itos(body.size()) + "\r\n";
s += "Content-type: text/html\r\n"; s += "Content-type: text/html\r\n";
s += "Connection: Close\r\n"; s += "Connection: Close\r\n";
for (int i = 0; i < request->response_get_cookie_count(); ++i) {
Ref<WebServerCookie> cookie = request->response_get_cookie(i);
ERR_CONTINUE(!cookie.is_valid());
String cookie_str = cookie->get_response_header_string();
if (cookie_str != "") {
s += cookie_str;
}
}
s += "\r\n"; s += "\r\n";
s += body; s += body;
@ -239,6 +266,19 @@ void HTTPServerSimple::send_file(Ref<WebServerRequest> request, const String &p_
if (!FileAccess::exists(p_file_path)) { if (!FileAccess::exists(p_file_path)) {
String s = "HTTP/1.1 404 Not Found\r\n"; String s = "HTTP/1.1 404 Not Found\r\n";
s += "Connection: Close\r\n"; s += "Connection: Close\r\n";
for (int i = 0; i < request->response_get_cookie_count(); ++i) {
Ref<WebServerCookie> cookie = request->response_get_cookie(i);
ERR_CONTINUE(!cookie.is_valid());
String cookie_str = cookie->get_response_header_string();
if (cookie_str != "") {
s += cookie_str;
}
}
s += "\r\n"; s += "\r\n";
CharString cs = s.utf8(); CharString cs = s.utf8();
peer->put_data((const uint8_t *)cs.get_data(), cs.size() - 1); peer->put_data((const uint8_t *)cs.get_data(), cs.size() - 1);
@ -259,6 +299,19 @@ void HTTPServerSimple::send_file(Ref<WebServerRequest> request, const String &p_
String s = "HTTP/1.1 200 OK\r\n"; String s = "HTTP/1.1 200 OK\r\n";
s += "Connection: Close\r\n"; s += "Connection: Close\r\n";
s += "Content-Type: " + ctype + "\r\n"; s += "Content-Type: " + ctype + "\r\n";
for (int i = 0; i < request->response_get_cookie_count(); ++i) {
Ref<WebServerCookie> cookie = request->response_get_cookie(i);
ERR_CONTINUE(!cookie.is_valid());
String cookie_str = cookie->get_response_header_string();
if (cookie_str != "") {
s += cookie_str;
}
}
s += "Access-Control-Allow-Origin: *\r\n"; s += "Access-Control-Allow-Origin: *\r\n";
s += "Cross-Origin-Opener-Policy: same-origin\r\n"; s += "Cross-Origin-Opener-Policy: same-origin\r\n";
s += "Cross-Origin-Embedder-Policy: require-corp\r\n"; s += "Cross-Origin-Embedder-Policy: require-corp\r\n";

View File

@ -16,12 +16,6 @@ String SimpleWebServerRequest::get_cookie(const String &key) {
return ""; return "";
} }
void SimpleWebServerRequest::add_cookie(const Ref<WebServerCookie> &cookie) {
}
void SimpleWebServerRequest::remove_cookie(const String &key) {
}
HTTPServerEnums::HTTPMethod SimpleWebServerRequest::get_method() const { HTTPServerEnums::HTTPMethod SimpleWebServerRequest::get_method() const {
return HTTPServerEnums::HTTP_METHOD_GET; return HTTPServerEnums::HTTP_METHOD_GET;
} }

View File

@ -22,8 +22,6 @@ class SimpleWebServerRequest : public WebServerRequest {
public: public:
virtual String get_cookie(const String &key); virtual String get_cookie(const String &key);
virtual void add_cookie(const Ref<WebServerCookie> &cookie);
virtual void remove_cookie(const String &key);
virtual HTTPServerEnums::HTTPMethod get_method() const; virtual HTTPServerEnums::HTTPMethod get_method() const;