streamline session mgmt, add session refresh
This commit is contained in:
parent
7e4c8d12cc
commit
0ac37c6ab3
21
server.hpp
21
server.hpp
@ -150,32 +150,23 @@ private:
|
|||||||
return;
|
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;
|
Response response;
|
||||||
|
|
||||||
// Try router first
|
if (static_handler && static_handler->handle(req, response)) {
|
||||||
if (router.handle(req, response)) {
|
|
||||||
if (needs_session) set_session_cookie(response, session_id);
|
|
||||||
send_response(client_fd, response, req.version);
|
send_response(client_fd, response, req.version);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then try static files
|
if (router.handle(req, response)) {
|
||||||
if (static_handler && static_handler->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);
|
set_session_cookie(response, session_id);
|
||||||
send_response(client_fd, response, req.version);
|
send_response(client_fd, response, req.version);
|
||||||
} else {
|
} else {
|
||||||
response.status = 404;
|
response.status = 404;
|
||||||
response.set_text("Not Found");
|
response.set_text("Not Found");
|
||||||
if (needs_session) set_session_cookie(response, session_id);
|
|
||||||
send_response(client_fd, response, req.version);
|
send_response(client_fd, response, req.version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,30 +123,6 @@ public:
|
|||||||
store_.set_file("sessions.txt");
|
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 create() {
|
||||||
std::string id = generate_id();
|
std::string id = generate_id();
|
||||||
size_t shard = get_shard(id);
|
size_t shard = get_shard(id);
|
||||||
@ -226,6 +202,55 @@ public:
|
|||||||
return true;
|
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 size() {
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
for (size_t i = 0; i < SHARD_COUNT; ++i) {
|
for (size_t i = 0; i < SHARD_COUNT; ++i) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user