Reworked HTTPSession, now it uses Variants instead of multiple classes. Also it's inherited from Reference now. Also smaller cleanups to the SessionManager.

This commit is contained in:
Relintai 2022-01-09 14:32:09 +01:00
parent bede579bf6
commit a119251e09
8 changed files with 102 additions and 115 deletions

View File

@ -1,58 +1,48 @@
#include "http_session.h"
void HTTPSession::add_object(const String &key, Object *obj) {
std::lock_guard<std::mutex> 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<std::mutex> 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<Reference> &ref) {
std::lock_guard<std::mutex> 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<std::mutex> lock(_mutex);
_reference_data.erase(key);
}
Ref<Reference> 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<std::mutex> lock(_mutex);
_int_data[key] = val;
}
void HTTPSession::remove_int(const String &key) {
std::lock_guard<std::mutex> 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<String, int> HTTPSession::get_int_data() {
return _int_data;
std::map<String, Variant> *HTTPSession::get_data() {
return &_data;
}
HTTPSession::HTTPSession() {

View File

@ -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 <map>
#include <mutex>
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<Reference> &ref);
void remove_reference(const String &key);
Ref<Reference> 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<String, int> get_int_data();
std::map<String, Variant> *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<String, Object *> _data;
std::map<String, Ref<Reference> > _reference_data;
std::map<String, int> _int_data;
std::map<String, Variant> _data;
};
#endif

View File

@ -8,8 +8,8 @@
#include "core/http/web_root.h"
#include "session_manager.h"
HTTPSession *Request::get_or_create_session() {
if (session) {
Ref<HTTPSession> Request::get_or_create_session() {
if (session.is_valid()) {
return session;
}

View File

@ -34,11 +34,11 @@ public:
bool connection_closed;
HTTPSession *session;
Ref<HTTPSession> session;
std::map<String, Object *> data;
std::map<String, Ref<Reference> > reference_data;
HTTPSession *get_or_create_session();
Ref<HTTPSession> get_or_create_session();
virtual const String get_cookie(const String &key);
virtual void add_cookie(const ::Cookie &cookie);

View File

@ -15,25 +15,27 @@
#include "cookie.h"
void SessionManager::add_session(HTTPSession *session) {
if (!session) {
void SessionManager::add_session(Ref<HTTPSession> &session) {
if (!session.is_valid()) {
printf("SessionManager::add_session: ERROR, session is null!\n");
return;
}
std::lock_guard<std::mutex> 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<HTTPSession> &session) {
if (!session.is_valid()) {
printf("SessionManager::remove_session: ERROR, session is null!\n");
return;
}
std::lock_guard<std::mutex> 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<HTTPSession> s = _sessions[session_id];
_sessions.erase(session_id);
for (int i = 0; i < _sessions_vec.size(); ++i) {
HTTPSession *sess = _sessions_vec[i];
Ref<HTTPSession> 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<HTTPSession> &session) {
Ref<QueryBuilder> 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<String, int> m = session->get_int_data();
for (std::map<String, int>::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<String, Variant> *m = session->get_data();
for (std::map<String, Variant>::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<HTTPSession> SessionManager::get_session(const String &session_id) {
return _sessions[session_id];
}
HTTPSession *SessionManager::create_session() {
HTTPSession *session = new HTTPSession();
std::unique_lock<std::mutex> lock(_mutex, std::defer_lock);
Ref<HTTPSession> SessionManager::create_session() {
Ref<HTTPSession> 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<HTTPSession> 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<HTTPSession> s;
for (int i = 0; i < _sessions_vec.size(); ++i) {
HTTPSession *ss = _sessions_vec[i];
Ref<HTTPSession> 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<std::mutex> 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();

View File

@ -3,7 +3,7 @@
#include "core/string.h"
#include "core/containers/vector.h"
#include <mutex>
#include "core/threading/mutex.h"
#include <map>
#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<HTTPSession> &session);
void remove_session(Ref<HTTPSession> &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<HTTPSession> &session);
Ref<HTTPSession> get_session(const String &session_id);
Ref<HTTPSession> create_session();
void load_sessions();
@ -39,9 +39,9 @@ public:
SessionManager();
~SessionManager();
std::map<String, HTTPSession *> _sessions;
Vector<HTTPSession *> _sessions_vec;
std::mutex _mutex;
std::map<String, Ref<HTTPSession>> _sessions;
Vector<Ref<HTTPSession>> _sessions_vec;
Mutex _mutex;
protected:
static SessionManager *_self;

View File

@ -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<RBACRank> 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");
}
}
}

View File

@ -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<User> 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<HTTPSession> 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");
}
}
}