/** * * Session.h * An Tao * * Copyright 2018, An Tao. All rights reserved. * https://github.com/an-tao/drogon * Use of this source code is governed by a MIT license * that can be found in the License file. * * Drogon * */ #pragma once #include #include #include #include #include #include namespace drogon { /** * @brief This class represents a session stored in the framework. * One can get or set any type of data to a session object. */ class Session { public: /** * @brief Get the data identified by the key parameter. * @note if the data is not found, a default value is returned. * For example: * @code auto &userName = sessionPtr->get("user name"); @endcode */ template const T &get(const std::string &key) const { const static T nullVal = T(); std::lock_guard lck(mutex_); auto it = sessionMap_.find(key); if (it != sessionMap_.end()) { if (typeid(T) == it->second.type()) { return *(any_cast(&(it->second))); } else { LOG_ERROR << "Bad type"; } } return nullVal; } /** * @brief Get the 'any' object identified by the given key */ any &operator[](const std::string &key) { std::lock_guard lck(mutex_); return sessionMap_[key]; } /** * @brief Insert a key-value pair * @note here the any object can be created implicitly. for example * @code sessionPtr->insert("user name", userNameString); @endcode */ void insert(const std::string &key, const any &obj) { std::lock_guard lck(mutex_); sessionMap_[key] = obj; } /** * @brief Insert a key-value pair * @note here the any object can be created implicitly. for example * @code sessionPtr->insert("user name", userNameString); @endcode */ void insert(const std::string &key, any &&obj) { std::lock_guard lck(mutex_); sessionMap_[key] = std::move(obj); } /** * @brief Erase the data identified by the given key. */ void erase(const std::string &key) { std::lock_guard lck(mutex_); sessionMap_.erase(key); } /** * @brief Retrun true if the data identified by the key exists. */ bool find(const std::string &key) { std::lock_guard lck(mutex_); if (sessionMap_.find(key) == sessionMap_.end()) { return false; } return true; } /** * @brief Clear all data in the session. */ void clear() { std::lock_guard lck(mutex_); sessionMap_.clear(); } /** * @brief Get the session ID of the current session. */ std::string sessionId() const { std::lock_guard lck(mutex_); return sessionId_; } /** * @brief Let the framework create a new session ID for this session and set * it to the client. * @note This method does not change the session ID now. */ void changeSessionIdToClient() { needToChange_ = true; needToSet_ = true; } Session() = delete; private: using SessionMap = std::map; SessionMap sessionMap_; mutable std::mutex mutex_; std::string sessionId_; bool needToSet_{false}; bool needToChange_{false}; friend class SessionManager; friend class HttpAppFrameworkImpl; /** * @brief Constructor, usually called by the framework */ Session(const std::string &id, bool needToSet) : sessionId_(id), needToSet_(needToSet) { } /** * @brief Change the state of the session, usually called by the framework */ void hasSet() { needToSet_ = false; } /** * @brief If the session ID needs to be changed. * */ bool needToChangeSessionId() const { return needToChange_; } /** * @brief If the session ID needs to be set to the client through cookie, * return true */ bool needSetToClient() const { return needToSet_; } void setSessionId(const std::string &id) { std::lock_guard lck(mutex_); sessionId_ = id; needToChange_ = false; } }; using SessionPtr = std::shared_ptr; } // namespace drogon