mirror of
https://github.com/CrowCpp/Crow.git
synced 2024-06-07 21:10:44 +00:00
Add session id preset, remove boost filesystem, small fixes
This commit is contained in:
parent
b939dd4f1d
commit
29c657df8f
@ -1,7 +1,8 @@
|
||||
#include "crow.h"
|
||||
#include "crow/middlewares/session.h"
|
||||
|
||||
crow::response redirect() {
|
||||
crow::response redirect()
|
||||
{
|
||||
crow::response rsp;
|
||||
rsp.redirect("/");
|
||||
return rsp;
|
||||
@ -10,7 +11,7 @@ crow::response redirect() {
|
||||
int main()
|
||||
{
|
||||
// Choose a storage kind for:
|
||||
// - InMemoryStore stores all entries in memory
|
||||
// - InMemoryStore stores all entries in memory
|
||||
// - FileStore stores all entries in json files
|
||||
using Session = crow::SessionMiddleware<crow::InMemoryStore>;
|
||||
|
||||
@ -18,16 +19,15 @@ int main()
|
||||
// Check out the existing ones for guidelines
|
||||
|
||||
// Make sure the CookieParser is registered before the Session
|
||||
crow::App<crow::CookieParser, Session> app {Session{
|
||||
// choose a secret key for sigining cookies
|
||||
"MY_SECRET_KEY",
|
||||
// customize cookies
|
||||
crow::CookieParser::Cookie("session").max_age(/*one day*/24 * 60 * 60).path("/"),
|
||||
// set session_id length (small value only for demonstration purposes)
|
||||
4,
|
||||
// init the store
|
||||
crow::InMemoryStore{}
|
||||
}};
|
||||
crow::App<crow::CookieParser, Session> app{Session{
|
||||
// choose a secret key for sigining sessions ids
|
||||
"MY_SECRET_KEY",
|
||||
// customize cookies
|
||||
crow::CookieParser::Cookie("session").max_age(/*one day*/ 24 * 60 * 60).path("/"),
|
||||
// set session id length (small value only for demonstration purposes)
|
||||
4,
|
||||
// init the store
|
||||
crow::InMemoryStore{}}};
|
||||
|
||||
// List all values
|
||||
CROW_ROUTE(app, "/")
|
||||
@ -37,13 +37,16 @@ int main()
|
||||
|
||||
// atomically increase number of views
|
||||
// if "views" doesn't exist, it'll be default initialized
|
||||
session.apply("views", [](int v){ return v + 1; });
|
||||
session.apply("views", [](int v) {
|
||||
return v + 1;
|
||||
});
|
||||
|
||||
// get all currently present keys
|
||||
auto keys = session.keys();
|
||||
|
||||
std::string out;
|
||||
for (const auto& key: keys) out += "<p> " + key + " = " + session.string(key) + "</p>";
|
||||
for (const auto& key : keys)
|
||||
out += "<p> " + key + " = " + session.string(key) + "</p>";
|
||||
return out;
|
||||
});
|
||||
|
||||
@ -96,18 +99,34 @@ int main()
|
||||
|
||||
std::lock_guard<std::recursive_mutex> l(session.mutex());
|
||||
|
||||
if (session.get("views", 0) % 2 == 0) {
|
||||
if (session.get("views", 0) % 2 == 0)
|
||||
{
|
||||
session.set("even", true);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
session.evict("even");
|
||||
}
|
||||
|
||||
return redirect();
|
||||
});
|
||||
|
||||
// Manually hand out session ids
|
||||
// This allows sharing sessions between devices or binding them to users, etc.
|
||||
// Session ids are signed so they don't have to be random tokens
|
||||
CROW_ROUTE(app, "/login")
|
||||
([&](const crow::request& req) {
|
||||
auto& session = app.get_context<Session>(req);
|
||||
|
||||
if (!session.exists())
|
||||
{
|
||||
session.preset_id("user_email@email.com");
|
||||
}
|
||||
});
|
||||
|
||||
app.port(18080)
|
||||
//.multithreaded()
|
||||
.run();
|
||||
//.multithreaded()
|
||||
.run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -21,10 +21,8 @@
|
||||
// fallback to boost otherwise
|
||||
#ifdef CROW_CAN_USE_CPP17
|
||||
#include <variant>
|
||||
#include <filesystem>
|
||||
#else
|
||||
#include "boost/variant.hpp"
|
||||
#include "boost/filesystem.hpp"
|
||||
#endif
|
||||
|
||||
namespace crow
|
||||
@ -34,7 +32,7 @@ namespace crow
|
||||
{
|
||||
using multi_value_types = black_magic::S<bool, int32_t, int64_t, uint64_t, double, std::string>;
|
||||
|
||||
/// A multi_value is a safe variant wrapper with json support
|
||||
/// A multi_value is a safe variant wrapper with json conversion support
|
||||
#ifdef CROW_CAN_USE_CPP17
|
||||
struct multi_value
|
||||
{
|
||||
@ -156,6 +154,8 @@ namespace crow
|
||||
{
|
||||
if (rv.nt() == num_type::Floating_point)
|
||||
return multi_value{rv.d()};
|
||||
else if (rv.nt() == num_type::Unsigned_integer)
|
||||
return multi_value{rv.u()};
|
||||
else
|
||||
return multi_value{rv.i()};
|
||||
}
|
||||
@ -170,6 +170,7 @@ namespace crow
|
||||
struct CachedSession
|
||||
{
|
||||
std::string session_id;
|
||||
std::string requested_session_id;
|
||||
std::unordered_map<std::string, multi_value> entries;
|
||||
|
||||
// values that were changed after last load
|
||||
@ -206,7 +207,7 @@ namespace crow
|
||||
}
|
||||
|
||||
// Check wheter this session is already present
|
||||
bool valid() { return bool(node); }
|
||||
bool exists() { return bool(node); }
|
||||
|
||||
// Get a value by key or fallback if it doesn't exist or is of another type
|
||||
template<typename T>
|
||||
@ -220,6 +221,14 @@ namespace crow
|
||||
return fallback;
|
||||
}
|
||||
|
||||
// Request a special session id for the store
|
||||
// WARNING: it does not check for collisions!
|
||||
void preset_id(std::string id)
|
||||
{
|
||||
check_node();
|
||||
node->requested_session_id = std::move(id);
|
||||
}
|
||||
|
||||
// Set a value by key
|
||||
template<typename T>
|
||||
void set(const std::string& key, T value)
|
||||
@ -348,7 +357,12 @@ namespace crow
|
||||
// generate new id
|
||||
if (ctx.node->session_id == "")
|
||||
{
|
||||
ctx.node->session_id = next_id();
|
||||
// check for requested id
|
||||
ctx.node->session_id = std::move(ctx.node->requested_session_id);
|
||||
if (ctx.node->session_id == "")
|
||||
{
|
||||
ctx.node->session_id = utility::random_alphanum(id_length_);
|
||||
}
|
||||
auto& cookies = all_ctx.template get<CookieParser>();
|
||||
store_id(cookies, ctx.node->session_id);
|
||||
}
|
||||
@ -452,12 +466,7 @@ namespace crow
|
||||
// FileStore stores all data as json files in a folder
|
||||
struct FileStore
|
||||
{
|
||||
#ifdef CROW_CAN_USE_CPP17
|
||||
using path_t = std::filesystem::path;
|
||||
#else
|
||||
using path_t = std::string;
|
||||
#endif
|
||||
FileStore(const path_t& folder):
|
||||
FileStore(const std::string& folder):
|
||||
path(folder)
|
||||
{}
|
||||
|
||||
@ -485,12 +494,7 @@ namespace crow
|
||||
|
||||
std::string get_filename(const std::string& key)
|
||||
{
|
||||
#ifdef CROW_CAN_USE_CPP17
|
||||
return path / (key + ".json");
|
||||
#else
|
||||
using namespace boost::filesystem;
|
||||
return (path / (key + ".json")).string();
|
||||
#endif
|
||||
return utility::join_path(path, key + ".json");
|
||||
}
|
||||
|
||||
bool contains(const std::string& key)
|
||||
@ -499,7 +503,7 @@ namespace crow
|
||||
return file.good();
|
||||
}
|
||||
|
||||
path_t path;
|
||||
std::string path;
|
||||
};
|
||||
|
||||
} // namespace crow
|
||||
|
@ -643,10 +643,7 @@ namespace crow
|
||||
inline std::string default_loader(const std::string& filename)
|
||||
{
|
||||
std::string path = detail::get_template_base_directory_ref();
|
||||
if (!(path.back() == '/' || path.back() == '\\'))
|
||||
path += '/';
|
||||
path += filename;
|
||||
std::ifstream inf(path);
|
||||
std::ifstream inf(utility::join_path(path, filename));
|
||||
if (!inf)
|
||||
{
|
||||
CROW_LOG_WARNING << "Template \"" << filename << "\" not found.";
|
||||
|
@ -12,6 +12,10 @@
|
||||
|
||||
#include "crow/settings.h"
|
||||
|
||||
#ifdef CROW_CAN_USE_CPP17
|
||||
#include <filesystem>
|
||||
#endif
|
||||
|
||||
// TODO(EDev): Adding C++20's [[likely]] and [[unlikely]] attributes might be useful
|
||||
#if defined(__GNUG__) || defined(__clang__)
|
||||
#define CROW_LIKELY(X) __builtin_expect(!!(X), 1)
|
||||
@ -780,17 +784,31 @@ namespace crow
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string random_alphanum(std::size_t size) {
|
||||
static const char alphabet[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
inline std::string random_alphanum(std::size_t size)
|
||||
{
|
||||
static const char alphabet[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
std::random_device dev;
|
||||
std::mt19937 rng(dev());
|
||||
std::uniform_int_distribution<std::mt19937::result_type> dist(0, sizeof(alphabet)-2);
|
||||
std::uniform_int_distribution<std::mt19937::result_type> dist(0, sizeof(alphabet) - 2);
|
||||
std::string out;
|
||||
out.reserve(size);
|
||||
for (std::size_t i = 0; i < size; i++) out.push_back(alphabet[dist(rng)]);
|
||||
for (std::size_t i = 0; i < size; i++)
|
||||
out.push_back(alphabet[dist(rng)]);
|
||||
return out;
|
||||
}
|
||||
|
||||
inline std::string join_path(std::string path, const std::string& fname)
|
||||
{
|
||||
#ifdef CROW_CAN_USE_CPP17
|
||||
return std::filesystem::path(path) / fname;
|
||||
#else
|
||||
if (!(path.back() == '/' || path.back() == '\\'))
|
||||
path += '/';
|
||||
path += fname;
|
||||
return path;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace utility
|
||||
} // namespace crow
|
||||
|
Loading…
Reference in New Issue
Block a user