From 0ac37c6ab3317e9c2832019de332d632d6f56205 Mon Sep 17 00:00:00 2001 From: Sky Johnson Date: Sat, 14 Jun 2025 14:53:13 -0500 Subject: [PATCH] streamline session mgmt, add session refresh --- server.hpp | 61 +++++++++++++++++---------------------- session_store.hpp | 73 +++++++++++++++++++++++++++++++---------------- 2 files changed, 75 insertions(+), 59 deletions(-) diff --git a/server.hpp b/server.hpp index 7ac8a35..0b2afde 100644 --- a/server.hpp +++ b/server.hpp @@ -142,44 +142,35 @@ private: // Client disconnected } - void process_request(int client_fd, std::string_view request_data) { - Request req = Parser::parse(request_data); + void process_request(int client_fd, std::string_view request_data) { + Request req = Parser::parse(request_data); - if (!req.valid) { - send_error_response(client_fd, "Bad Request", 400, req.version); - return; - } - - // Handle session - std::string session_id; - bool needs_session = sessions.needs_session(req); - - if (needs_session) { - std::string_view existing_id = sessions.extract_session_id(req); - session_id = existing_id.empty() ? sessions.create() : std::string(existing_id); - } - - Response response; - - // Try router first - if (router.handle(req, response)) { - if (needs_session) set_session_cookie(response, session_id); - send_response(client_fd, response, req.version); - return; - } - - // Then try static files - if (static_handler && static_handler->handle(req, response)) { - set_session_cookie(response, session_id); - send_response(client_fd, response, req.version); - } else { - response.status = 404; - response.set_text("Not Found"); - if (needs_session) set_session_cookie(response, session_id); - send_response(client_fd, response, req.version); - } + if (!req.valid) { + send_error_response(client_fd, "Bad Request", 400, req.version); + return; } + Response response; + + if (static_handler && static_handler->handle(req, response)) { + send_response(client_fd, response, req.version); + return; + } + + if (router.handle(req, response)) { + std::string_view existing_id = sessions.extract_session_id(req); + std::string session_id = existing_id.empty() ? + sessions.create() : std::string(existing_id); + + set_session_cookie(response, session_id); + send_response(client_fd, response, req.version); + } else { + response.status = 404; + response.set_text("Not Found"); + send_response(client_fd, response, req.version); + } + } + void set_session_cookie(Response& response, const std::string& session_id) { response.cookies.push_back("session_id=" + session_id + "; HttpOnly; Path=/; SameSite=Strict"); } diff --git a/session_store.hpp b/session_store.hpp index b0fe25b..c16f29d 100644 --- a/session_store.hpp +++ b/session_store.hpp @@ -123,30 +123,6 @@ public: store_.set_file("sessions.txt"); } - bool needs_session(const Request& req) const { - if (req.path.starts_with("/static") || - req.path.starts_with("/assets") || - req.path.ends_with(".css") || - req.path.ends_with(".js") || - req.path.ends_with(".png") || - req.path.ends_with(".jpg") || - req.path.ends_with(".jpeg") || - req.path.ends_with(".gif") || - req.path.ends_with(".ico") || - req.path.ends_with(".svg") || - req.path.ends_with(".woff") || - req.path.ends_with(".woff2") || - req.path.ends_with(".ttf")) { - return false; - } - - return req.path.starts_with("/api") || - req.path.starts_with("/admin") || - req.method == HttpMethod::POST || - req.method == HttpMethod::PUT || - req.method == HttpMethod::DELETE; - } - std::string create() { std::string id = generate_id(); size_t shard = get_shard(id); @@ -226,6 +202,55 @@ public: return true; } + std::string refresh(const std::string& old_id) { + size_t old_shard = get_shard(old_id); + std::lock_guard lock(mutexes_[old_shard]); + + auto it = shards_[old_shard].find(old_id); + if (it == shards_[old_shard].end()) return old_id; + + // Generate new ID + std::string new_id = generate_id(); + size_t new_shard = get_shard(new_id); + + // Handle cross-shard case + if (new_shard != old_shard) { + std::lock_guard new_lock(mutexes_[new_shard]); + + // Check session limit on new shard + if (shards_[new_shard].size() >= MAX_SESSIONS_PER_SHARD) { + evict_lru_session(new_shard); + } + + // Move session data + SessionData session = std::move(it->second); + lru_lists_[old_shard].erase(session.lru_iter); + + // Add to new shard + lru_lists_[new_shard].push_front(new_id); + session.lru_iter = lru_lists_[new_shard].begin(); + session.last_access = std::chrono::steady_clock::now(); + session.dirty = true; + + shards_[new_shard][new_id] = std::move(session); + shards_[old_shard].erase(it); + } else { + // Same shard - just update the key + SessionData session = std::move(it->second); + lru_lists_[old_shard].erase(session.lru_iter); + + lru_lists_[old_shard].push_front(new_id); + session.lru_iter = lru_lists_[old_shard].begin(); + session.last_access = std::chrono::steady_clock::now(); + session.dirty = true; + + shards_[old_shard][new_id] = std::move(session); + shards_[old_shard].erase(it); + } + + return new_id; + } + size_t size() { size_t total = 0; for (size_t i = 0; i < SHARD_COUNT; ++i) {