diff --git a/core/http/http_session.cpp b/core/http/http_session.cpp index 51e161c..197ab90 100644 --- a/core/http/http_session.cpp +++ b/core/http/http_session.cpp @@ -1,58 +1,48 @@ #include "http_session.h" -void HTTPSession::add_object(const String &key, Object *obj) { - std::lock_guard lock(_mutex); +void HTTPSession::add(const String &key, const Variant &value) { + _mutex.lock(); - _data[key] = obj; + _data[key] = value; + + _mutex.unlock(); } -void HTTPSession::remove_object(const String &key) { - std::lock_guard lock(_mutex); +void HTTPSession::remove(const String &key) { + _mutex.lock(); - _data.erase(key); + _data[key] = Variant(); + + _mutex.unlock(); +} +bool HTTPSession::has(const String &key) { + return _data[key].is_null(); } -Object *HTTPSession::get_object(const String &key) { - //don't lock here +Variant HTTPSession::get(const String &key) { return _data[key]; } -void HTTPSession::add_reference(const String &key, const Ref &ref) { - std::lock_guard lock(_mutex); +Object *HTTPSession::get_object(const String &key) { + // don't lock here - _reference_data[key] = ref; + return _data[key].to_object(); } -void HTTPSession::remove_reference(const String &key) { - std::lock_guard lock(_mutex); - _reference_data.erase(key); -} Ref HTTPSession::get_reference(const String &key) { - //don't lock here + // don't lock here - return _reference_data[key]; + return _data[key].to_reference(); } -void HTTPSession::add_int(const String &key, const int val) { - std::lock_guard lock(_mutex); - - _int_data[key] = val; -} -void HTTPSession::remove_int(const String &key) { - std::lock_guard lock(_mutex); - - _int_data.erase(key); -} int HTTPSession::get_int(const String &key) { - //don't lock here + // don't lock here - return _int_data[key]; + return _data[key].to_int(); } void HTTPSession::clear() { _data.clear(); - _int_data.clear(); - _reference_data.clear(); } void HTTPSession::reset() { @@ -60,8 +50,8 @@ void HTTPSession::reset() { session_id = ""; } -std::map HTTPSession::get_int_data() { - return _int_data; +std::map *HTTPSession::get_data() { + return &_data; } HTTPSession::HTTPSession() { diff --git a/core/http/http_session.h b/core/http/http_session.h index c74d234..84e8058 100644 --- a/core/http/http_session.h +++ b/core/http/http_session.h @@ -1,27 +1,26 @@ #ifndef HTTP_SESSION_H #define HTTP_SESSION_H -#include "core/string.h" - -#include "core/object.h" -#include "core/reference.h" #include -#include -class HTTPSession : public Object { - RCPP_OBJECT(HTTPSession, Object); +#include "core/reference.h" + +#include "core/string.h" +#include "core/variant.h" +#include "core/threading/mutex.h" + + +class HTTPSession : public Reference { + RCPP_OBJECT(HTTPSession, Reference); public: - void add_object(const String &key, Object *obj); - void remove_object(const String &key); + void add(const String &key, const Variant &value); + void remove(const String &key); + bool has(const String &key); + + Variant get(const String &key); Object *get_object(const String &key); - - void add_reference(const String &key, const Ref &ref); - void remove_reference(const String &key); Ref get_reference(const String &key); - - void add_int(const String &key, const int val); - void remove_int(const String &key); int get_int(const String &key); String session_id; @@ -30,18 +29,15 @@ public: void clear(); void reset(); - std::map get_int_data(); + std::map *get_data(); HTTPSession(); ~HTTPSession(); protected: - std::mutex _mutex; + Mutex _mutex; - //todo make something similar to godot's variant. (Or get godot's variant lol) - std::map _data; - std::map > _reference_data; - std::map _int_data; + std::map _data; }; #endif \ No newline at end of file diff --git a/core/http/request.cpp b/core/http/request.cpp index 678466d..28e224b 100644 --- a/core/http/request.cpp +++ b/core/http/request.cpp @@ -8,8 +8,8 @@ #include "core/http/web_root.h" #include "session_manager.h" -HTTPSession *Request::get_or_create_session() { - if (session) { +Ref Request::get_or_create_session() { + if (session.is_valid()) { return session; } diff --git a/core/http/request.h b/core/http/request.h index f61622a..6097044 100644 --- a/core/http/request.h +++ b/core/http/request.h @@ -34,11 +34,11 @@ public: bool connection_closed; - HTTPSession *session; + Ref session; std::map data; std::map > reference_data; - HTTPSession *get_or_create_session(); + Ref get_or_create_session(); virtual const String get_cookie(const String &key); virtual void add_cookie(const ::Cookie &cookie); diff --git a/core/http/session_manager.cpp b/core/http/session_manager.cpp index aaa6598..31d3f92 100644 --- a/core/http/session_manager.cpp +++ b/core/http/session_manager.cpp @@ -15,25 +15,27 @@ #include "cookie.h" -void SessionManager::add_session(HTTPSession *session) { - if (!session) { +void SessionManager::add_session(Ref &session) { + if (!session.is_valid()) { printf("SessionManager::add_session: ERROR, session is null!\n"); return; } - std::lock_guard lock(_mutex); + _mutex.lock(); _sessions_vec.push_back(session); _sessions[session->session_id] = session; + + _mutex.unlock(); } -void SessionManager::remove_session(HTTPSession *session) { - if (!session) { +void SessionManager::remove_session(Ref &session) { + if (!session.is_valid()) { printf("SessionManager::remove_session: ERROR, session is null!\n"); return; } - std::lock_guard lock(_mutex); + _mutex.lock(); _sessions.erase(session->session_id); @@ -41,20 +43,23 @@ void SessionManager::remove_session(HTTPSession *session) { if (_sessions_vec[i] == session) { _sessions_vec[i] = _sessions_vec[_sessions_vec.size() - 1]; _sessions_vec.pop_back(); + _mutex.unlock(); return; } } + + _mutex.unlock(); } void SessionManager::delete_session(const String &session_id) { _mutex.lock(); - HTTPSession *s = _sessions[session_id]; + Ref s = _sessions[session_id]; _sessions.erase(session_id); for (int i = 0; i < _sessions_vec.size(); ++i) { - HTTPSession *sess = _sessions_vec[i]; + Ref sess = _sessions_vec[i]; if (sess->session_id == session_id) { @@ -67,13 +72,11 @@ void SessionManager::delete_session(const String &session_id) { _mutex.unlock(); - if (!s) { + if (!s.is_valid()) { return; } if (!s->id) { - delete s; - return; } @@ -82,11 +85,9 @@ void SessionManager::delete_session(const String &session_id) { b->del(_data_table_name)->where()->wp("session_db_id", s->id)->end_command(); b->del(_table_name)->where()->wp("id", s->id)->end_command(); b->run_query(); - - delete s; } -void SessionManager::save_session(HTTPSession *session) { +void SessionManager::save_session(Ref &session) { Ref b = DatabaseManager::get_singleton()->ddb->get_query_builder(); if (!session->id) { @@ -105,39 +106,41 @@ void SessionManager::save_session(HTTPSession *session) { b->del(_data_table_name)->where()->wp("session_db_id", session->id)->end_command(); int id = session->id; - std::map m = session->get_int_data(); - for (std::map::iterator it = m.begin(); it != m.end(); it++) { - b->insert(_data_table_name, "session_db_id, key, value")->values()->val(id)->val(it->first)->val(it->second)->cvalues()->end_command(); + std::map *m = session->get_data(); + for (std::map::iterator it = m->begin(); it != m->end(); it++) { + const Variant &val = it->second; + + if (val.is_simple_type()) { + b->insert(_data_table_name, "session_db_id,key,value")->values()->val(id)->val(it->first)->val(val.to_string())->cvalues()->end_command(); + } } b->run_query(); } -HTTPSession *SessionManager::get_session(const String &session_id) { +Ref SessionManager::get_session(const String &session_id) { return _sessions[session_id]; } -HTTPSession *SessionManager::create_session() { - HTTPSession *session = new HTTPSession(); - - std::unique_lock lock(_mutex, std::defer_lock); +Ref SessionManager::create_session() { + Ref session = new HTTPSession(); while (true) { session->session_id = generate_session_id(session->session_id); - lock.lock(); + _mutex.lock(); if (_sessions[session->session_id] == nullptr) { _sessions_vec.push_back(session); _sessions[session->session_id] = session; - lock.unlock(); + _mutex.unlock(); return session; } - lock.unlock(); + _mutex.unlock(); } save_session(session); @@ -159,7 +162,7 @@ void SessionManager::load_sessions() { int id = r->get_cell_int(0); String session_id = r->get_cell(1); - HTTPSession *s = new HTTPSession(); + Ref s = new HTTPSession(); s->id = id; s->session_id = session_id; @@ -169,7 +172,7 @@ void SessionManager::load_sessions() { b->reset(); - b->select("session_db_id, key, value"); + b->select("session_db_id,key,value"); b->from(_data_table_name); // b->print(); r = b->run(); @@ -177,39 +180,37 @@ void SessionManager::load_sessions() { while (r->next_row()) { int session_db_id = r->get_cell_int(0); - HTTPSession *s = nullptr; + Ref s; for (int i = 0; i < _sessions_vec.size(); ++i) { - HTTPSession *ss = _sessions_vec[i]; + Ref ss = _sessions_vec[i]; - if (ss && session_db_id == ss->id) { + if (ss.is_valid() && session_db_id == ss->id) { s = ss; break; } } - if (!s) { + if (!s.is_valid()) { printf("Error: SessionManager::load_sessions(): %d sid doesn't exists!\n", session_db_id); continue; } String key = r->get_cell(1); - int value = r->get_cell_int(2); + String value = r->get_cell(2); - s->add_int(key, value); + s->add(key, Variant::parse_string(value)); } } void SessionManager::clear() { - std::lock_guard lock(_mutex); - - for (int i = 0; i < _sessions_vec.size(); ++i) { - delete _sessions_vec[i]; - } + _mutex.lock(); _sessions.clear(); _sessions_vec.clear(); + + _mutex.unlock(); } String SessionManager::generate_session_id(const String &base) { @@ -250,7 +251,7 @@ void SessionManager::create_table() { tb->create_table(_data_table_name); tb->integer("session_db_id")->not_null()->next_row(); tb->varchar("key", 100)->next_row(); - tb->integer("value")->not_null()->next_row(); + tb->text("value")->not_null()->next_row(); tb->foreign_key("session_db_id"); tb->references(_table_name, "id"); tb->ccreate_table(); diff --git a/core/http/session_manager.h b/core/http/session_manager.h index e6e458a..a0da9a9 100644 --- a/core/http/session_manager.h +++ b/core/http/session_manager.h @@ -3,7 +3,7 @@ #include "core/string.h" #include "core/containers/vector.h" -#include +#include "core/threading/mutex.h" #include #include "core/object.h" @@ -17,12 +17,12 @@ class SessionManager : public Object { RCPP_OBJECT(SessionManager, Object); public: - void add_session(HTTPSession *session); - void remove_session(HTTPSession *session); + void add_session(Ref &session); + void remove_session(Ref &session); void delete_session(const String &session_id); - void save_session(HTTPSession *session); - HTTPSession *get_session(const String &session_id); - HTTPSession *create_session(); + void save_session(Ref &session); + Ref get_session(const String &session_id); + Ref create_session(); void load_sessions(); @@ -39,9 +39,9 @@ public: SessionManager(); ~SessionManager(); - std::map _sessions; - Vector _sessions_vec; - std::mutex _mutex; + std::map> _sessions; + Vector> _sessions_vec; + Mutex _mutex; protected: static SessionManager *_self; diff --git a/modules/rbac_users/rbac_user_controller.cpp b/modules/rbac_users/rbac_user_controller.cpp index d032323..b06e506 100644 --- a/modules/rbac_users/rbac_user_controller.cpp +++ b/modules/rbac_users/rbac_user_controller.cpp @@ -59,7 +59,7 @@ RBACUserController::~RBACUserController() { // returnring true means handled, false means continue bool RBACUserSessionSetupMiddleware::on_before_handle_request_main(Request *request) { - if (request->session) { + if (request->session.is_valid()) { int user_id = request->session->get_int("user_id"); if (user_id != 0) { @@ -70,7 +70,7 @@ bool RBACUserSessionSetupMiddleware::on_before_handle_request_main(Request *requ request->reference_data["user"] = u; } else { // log - request->session->remove_int("user_id"); + request->session->remove("user_id"); } } } @@ -89,7 +89,7 @@ bool RBACDefaultUserSessionSetupMiddleware::on_before_handle_request_main(Reques Ref rank; - if (request->session) { + if (request->session.is_valid()) { int user_id = request->session->get_int("user_id"); if (user_id != 0) { @@ -102,7 +102,7 @@ bool RBACDefaultUserSessionSetupMiddleware::on_before_handle_request_main(Reques request->reference_data["user"] = u; } else { // log - request->session->remove_int("user_id"); + request->session->remove("user_id"); } } } diff --git a/modules/users/user_controller.cpp b/modules/users/user_controller.cpp index 95c6b9a..71fb8a2 100644 --- a/modules/users/user_controller.cpp +++ b/modules/users/user_controller.cpp @@ -16,7 +16,7 @@ #include "core/hash/sha256.h" void UserController::handle_request_main(Request *request) { - if (request->session) { + if (request->session.is_valid()) { Ref u = request->reference_data["user"]; if (u.is_valid()) { @@ -68,9 +68,9 @@ void UserController::handle_login_request_default(Request *request) { if (!check_password(user, data.pass_val)) { data.error_str += "Invalid username or password!"; } else { - HTTPSession *session = request->get_or_create_session(); + Ref session = request->get_or_create_session(); - session->add_int("user_id", user->id); + session->add("user_id", user->id); SessionManager::get_singleton()->save_session(session); ::Cookie c = ::Cookie("session_id", session->session_id); @@ -794,7 +794,7 @@ String UserController::_table_name = "users"; // returnring true means handled, false means continue bool UserSessionSetupMiddleware::on_before_handle_request_main(Request *request) { - if (request->session) { + if (request->session.is_valid()) { int user_id = request->session->get_int("user_id"); if (user_id != 0) { @@ -805,7 +805,7 @@ bool UserSessionSetupMiddleware::on_before_handle_request_main(Request *request) request->reference_data["user"] = u; } else { // log - request->session->remove_int("user_id"); + request->session->remove("user_id"); } } }