VWeb/Source/InbuildMiddleWare.cpp
Maurice Grönwoldt 5bb68a7d02 Split VWeb into smaller headers
We have no make install support... so we don't need to have everything as a single-header and lib file.
2023-09-16 16:29:03 +02:00

123 lines
3.3 KiB
C++

#include "Includes/PreMiddleWare.h"
#include "StringUtils.h"
#include <random>
#include <sstream>
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<int> 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<std::thread>([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<std::mutex> 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(Request &request, Response &response) {
if (response.SessionData->Id.empty() &&
response.SessionData->ContainsData()) {
response.SessionData->Update();
{
std::lock_guard<std::mutex> 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.Name = "sid";
sidCookie.HttpOnly = true;
sidCookie.SameSite = CookieSameSite::Strict;
sidCookie.Value = response.SessionData->Id;
}
return true;
}
void SessionManager::GC() {
std::lock_guard<std::mutex> lck(m_Mutex);
std::vector<std::string_view> 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 : 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