session: try fixing bug: multiple bsessionids lead to login failure
This commit is contained in:
parent
811888ba7d
commit
56ca972d19
|
@ -164,11 +164,21 @@ namespace bserv {
|
||||||
= utils::parse_params(cookie_str, 0, ';');
|
= utils::parse_params(cookie_str, 0, ';');
|
||||||
boost::ignore_unused(cookie_list);
|
boost::ignore_unused(cookie_list);
|
||||||
std::string session_id;
|
std::string session_id;
|
||||||
|
std::shared_ptr<session_type> session_ptr;
|
||||||
if (cookie_dict.count(SESSION_NAME) != 0) {
|
if (cookie_dict.count(SESSION_NAME) != 0) {
|
||||||
session_id = cookie_dict[SESSION_NAME];
|
session_id = cookie_dict[SESSION_NAME];
|
||||||
}
|
}
|
||||||
std::shared_ptr<session_type> session_ptr;
|
else if (cookie_list.count(SESSION_NAME) != 0) {
|
||||||
if (resources.resources.session_mgr->get_or_create(session_id, session_ptr)) {
|
std::vector<std::string>& session_ids = cookie_list[SESSION_NAME];
|
||||||
|
for (auto& sess_id : session_ids) {
|
||||||
|
if (resources.resources.session_mgr->try_get(sess_id, session_ptr)) {
|
||||||
|
session_id = sess_id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (session_ptr == nullptr
|
||||||
|
&& resources.resources.session_mgr->get_or_create(session_id, session_ptr)) {
|
||||||
resources.response.set(http::field::set_cookie, SESSION_NAME + "=" + session_id);
|
resources.response.set(http::field::set_cookie, SESSION_NAME + "=" + session_id);
|
||||||
}
|
}
|
||||||
resources.session_ptr = session_ptr;
|
resources.session_ptr = session_ptr;
|
||||||
|
|
|
@ -37,6 +37,12 @@ namespace bserv {
|
||||||
virtual bool get_or_create(
|
virtual bool get_or_create(
|
||||||
std::string& key,
|
std::string& key,
|
||||||
std::shared_ptr<session_type>& session_ptr) = 0;
|
std::shared_ptr<session_type>& session_ptr) = 0;
|
||||||
|
// if `key` refers to an existing session, that session will be placed in
|
||||||
|
// `session_ptr` and this function will return `true`. otherwise, `false`.
|
||||||
|
// NOTE: a `shared_ptr` is returned instead of a reference.
|
||||||
|
virtual bool try_get(
|
||||||
|
const std::string& key,
|
||||||
|
std::shared_ptr<session_type>& session_ptr) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class memory_session_manager : public session_manager_base {
|
class memory_session_manager : public session_manager_base {
|
||||||
|
@ -62,6 +68,9 @@ namespace bserv {
|
||||||
bool get_or_create(
|
bool get_or_create(
|
||||||
std::string& key,
|
std::string& key,
|
||||||
std::shared_ptr<session_type>& session_ptr);
|
std::shared_ptr<session_type>& session_ptr);
|
||||||
|
bool try_get(
|
||||||
|
const std::string& key,
|
||||||
|
std::shared_ptr<session_type>& session_ptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // bserv
|
} // bserv
|
||||||
|
|
|
@ -47,4 +47,39 @@ namespace bserv {
|
||||||
return created;
|
return created;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool memory_session_manager::try_get(
|
||||||
|
const std::string& key,
|
||||||
|
std::shared_ptr<session_type>& session_ptr) {
|
||||||
|
std::lock_guard<std::mutex> lg{ lock_ };
|
||||||
|
time_point now = std::chrono::steady_clock::now();
|
||||||
|
// removes the expired sessions
|
||||||
|
while (!queue_.empty() && queue_.begin()->first < now) {
|
||||||
|
std::size_t another_key = queue_.begin()->second;
|
||||||
|
sessions_.erase(another_key);
|
||||||
|
expiry_.erase(another_key);
|
||||||
|
str_to_int_.erase(int_to_str_[another_key]);
|
||||||
|
int_to_str_.erase(another_key);
|
||||||
|
queue_.erase(queue_.begin());
|
||||||
|
}
|
||||||
|
bool found = true;
|
||||||
|
std::size_t int_key;
|
||||||
|
if (key.empty() || str_to_int_.count(key) == 0) {
|
||||||
|
found = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int_key = str_to_int_[key];
|
||||||
|
queue_.erase(
|
||||||
|
queue_.lower_bound(
|
||||||
|
std::make_pair(expiry_[int_key], int_key)));
|
||||||
|
}
|
||||||
|
// the expiry is set to be 20 minutes from now.
|
||||||
|
// if the session is re-visited within 20 minutes,
|
||||||
|
// the expiry will be extended.
|
||||||
|
expiry_[int_key] = now + std::chrono::minutes(20);
|
||||||
|
// pushes expiry-key tuple (pair) to the queue
|
||||||
|
queue_.emplace(expiry_[int_key], int_key);
|
||||||
|
session_ptr = sessions_[int_key];
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
} // bserv
|
} // bserv
|
Loading…
Reference in New Issue