streamline session mgmt, add session refresh
This commit is contained in:
parent
7e4c8d12cc
commit
0ac37c6ab3
61
server.hpp
61
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");
|
||||
}
|
||||
|
@ -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<std::mutex> 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<std::mutex> 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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user