#include "StringUtils.h" #include "VWeb.h" #include #include namespace VWeb { #pragma region AUTH PreMiddleWareReturn AuthWare::PreHandle(Request &request) { if (m_AuthFunction) return m_AuthFunction(request); return {}; } #pragma endregion AUTH #pragma region SESSION static std::string GenerateSID() { static std::random_device dev; static std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, 15); const char *v = "0123456789abcdef"; const bool dashArray[] = {false, false, false, false, true, false, true, false, true, false, true, false, false, false, false, false}; std::stringstream res; for (bool dash : dashArray) { if (dash) res << "-"; res << v[dist(rng)]; res << v[dist(rng)]; } return res.str(); } SessionManager::SessionManager() { m_GCThread = CreateRef([this]() { while (m_IsRunning) { if (m_Counter == 59) { GC(); m_Counter = -1; } m_Counter++; } std::this_thread::sleep_for(std::chrono::milliseconds(1000)); }); } SessionManager::~SessionManager() { m_IsRunning = false; m_GCThread->join(); } PreMiddleWareReturn SessionManager::PreHandle(Request &request) { auto &cookies = request.CookieData; if (!cookies->Has("sid")) return {}; auto &cookie = cookies->Get("sid"); std::lock_guard lck(m_Mutex); if (!m_Sessions.contains(cookie.Value)) return {}; auto &session = m_Sessions[cookie.Value]; session->Update(); request.SessionData = session; return {}; } bool SessionManager::PostHandle(const Request &request, Response &response) { if (response.SessionData->Id.empty() && response.SessionData->ContainsData()) { response.SessionData->Update(); { std::lock_guard lck(m_Mutex); response.SessionData->Id = GenerateSID(); while (m_Sessions.contains(response.SessionData->Id)) response.SessionData->Id = GenerateSID(); } m_Sessions[response.SessionData->Id] = response.SessionData; auto &sidCookie = response.CookieData->Get("sid"); sidCookie.HttpOnly = true; sidCookie.Secure = true; sidCookie.Value = response.SessionData->Id; } return true; } void SessionManager::GC() { std::lock_guard lck(m_Mutex); std::vector mark_as_delete; for (auto &itemToCollect : m_Sessions) { if (!itemToCollect.second->IsValid()) mark_as_delete.push_back(itemToCollect.first); } for (auto &i : mark_as_delete) m_Sessions.erase(i.data()); } #pragma endregion SESSION #pragma region COOKIES PreMiddleWareReturn CookieManager::PreHandle(Request &request) { auto &cookieHeaders = request.Header("Cookie"); auto &cookies = request.CookieData; if (cookieHeaders.Size() > 0) { auto &values = cookieHeaders.Values(); for (auto &rawCookie : cookieHeaders.Values()) { auto splitCookies = String::Split(rawCookie, ";"); for (auto &cookie : splitCookies) { auto split = String::Split(cookie, "="); String::Trim(split[0]); String::Trim(split[1]); cookies->CreateOld(split[0], split[1]); } } } return {}; } #pragma endregion COOKIES } // namespace VWeb