utils: add serve file; router: log url; db: conversion between std::string & boost::json::string
This commit is contained in:
parent
774efcec0d
commit
12c906e910
|
@ -35,7 +35,7 @@ int main(int argc, char* argv[]) {
|
||||||
}
|
}
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
try {
|
try {
|
||||||
std::string config_content = read_bin(argv[1]);
|
std::string config_content = bserv::utils::file::read_bin(argv[1]);
|
||||||
//std::cout << config_content << std::endl;
|
//std::cout << config_content << std::endl;
|
||||||
boost::json::object config_obj = boost::json::parse(config_content).as_object();
|
boost::json::object config_obj = boost::json::parse(config_content).as_object();
|
||||||
if (config_obj.contains("port"))
|
if (config_obj.contains("port"))
|
||||||
|
|
|
@ -28,7 +28,7 @@ bserv::db_relation_to_object orm_user{
|
||||||
|
|
||||||
std::optional<boost::json::object> get_user(
|
std::optional<boost::json::object> get_user(
|
||||||
bserv::db_transaction& tx,
|
bserv::db_transaction& tx,
|
||||||
const std::string& username) {
|
const boost::json::string& username) {
|
||||||
bserv::db_result r = tx.exec(
|
bserv::db_result r = tx.exec(
|
||||||
"select * from auth_user where username = ?", username);
|
"select * from auth_user where username = ?", username);
|
||||||
lginfo << r.query(); // this is how you log info
|
lginfo << r.query(); // this is how you log info
|
||||||
|
@ -101,7 +101,7 @@ boost::json::object user_register(
|
||||||
}
|
}
|
||||||
auto username = params["username"].as_string();
|
auto username = params["username"].as_string();
|
||||||
bserv::db_transaction tx{ conn };
|
bserv::db_transaction tx{ conn };
|
||||||
auto opt_user = get_user(tx, username.c_str());
|
auto opt_user = get_user(tx, username);
|
||||||
if (opt_user.has_value()) {
|
if (opt_user.has_value()) {
|
||||||
return {
|
return {
|
||||||
{"success", false},
|
{"success", false},
|
||||||
|
@ -115,7 +115,7 @@ boost::json::object user_register(
|
||||||
"first_name, last_name, email, is_active) values "
|
"first_name, last_name, email, is_active) values "
|
||||||
"(?, ?, ?, ?, ?, ?, ?)", bserv::db_name("auth_user"),
|
"(?, ?, ?, ?, ?, ?, ?)", bserv::db_name("auth_user"),
|
||||||
bserv::db_name("username"),
|
bserv::db_name("username"),
|
||||||
username.c_str(),
|
username,
|
||||||
bserv::utils::security::encode_password(
|
bserv::utils::security::encode_password(
|
||||||
password.c_str()), false,
|
password.c_str()), false,
|
||||||
get_or_empty(params, "first_name"),
|
get_or_empty(params, "first_name"),
|
||||||
|
@ -151,7 +151,7 @@ boost::json::object user_login(
|
||||||
}
|
}
|
||||||
auto username = params["username"].as_string();
|
auto username = params["username"].as_string();
|
||||||
bserv::db_transaction tx{ conn };
|
bserv::db_transaction tx{ conn };
|
||||||
auto opt_user = get_user(tx, username.c_str());
|
auto opt_user = get_user(tx, username);
|
||||||
if (!opt_user.has_value()) {
|
if (!opt_user.has_value()) {
|
||||||
return {
|
return {
|
||||||
{"success", false},
|
{"success", false},
|
||||||
|
@ -186,7 +186,7 @@ boost::json::object find_user(
|
||||||
std::shared_ptr<bserv::db_connection> conn,
|
std::shared_ptr<bserv::db_connection> conn,
|
||||||
const std::string& username) {
|
const std::string& username) {
|
||||||
bserv::db_transaction tx{ conn };
|
bserv::db_transaction tx{ conn };
|
||||||
auto user = get_user(tx, username);
|
auto user = get_user(tx, username.c_str());
|
||||||
if (!user.has_value()) {
|
if (!user.has_value()) {
|
||||||
return {
|
return {
|
||||||
{"success", false},
|
{"success", false},
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
std::string template_root_;
|
std::string template_root_;
|
||||||
std::string static_root_;
|
std::string static_root_;
|
||||||
inja::Environment env;
|
|
||||||
|
|
||||||
void init_rendering(const std::string& template_root) {
|
void init_rendering(const std::string& template_root) {
|
||||||
template_root_ = template_root;
|
template_root_ = template_root;
|
||||||
|
@ -27,61 +26,13 @@ std::nullopt_t render(
|
||||||
const boost::json::object& context) {
|
const boost::json::object& context) {
|
||||||
response.set(bserv::http::field::content_type, "text/html");
|
response.set(bserv::http::field::content_type, "text/html");
|
||||||
inja::json data = inja::json::parse(boost::json::serialize(context));
|
inja::json data = inja::json::parse(boost::json::serialize(context));
|
||||||
response.body() = env.render_file(template_root_ + template_file, data);
|
response.body() = inja::Environment{}.render_file(template_root_ + template_file, data);
|
||||||
response.prepare_payload();
|
response.prepare_payload();
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a reasonable mime type based on the extension of a file.
|
|
||||||
boost::beast::string_view
|
|
||||||
mime_type(boost::beast::string_view path) {
|
|
||||||
using boost::beast::iequals;
|
|
||||||
auto const ext = [&path] {
|
|
||||||
auto const pos = path.rfind(".");
|
|
||||||
if (pos == boost::beast::string_view::npos)
|
|
||||||
return boost::beast::string_view{};
|
|
||||||
return path.substr(pos);
|
|
||||||
}();
|
|
||||||
if (iequals(ext, ".htm")) return "text/html";
|
|
||||||
if (iequals(ext, ".html")) return "text/html";
|
|
||||||
if (iequals(ext, ".php")) return "text/html";
|
|
||||||
if (iequals(ext, ".css")) return "text/css";
|
|
||||||
if (iequals(ext, ".txt")) return "text/plain";
|
|
||||||
if (iequals(ext, ".js")) return "application/javascript";
|
|
||||||
if (iequals(ext, ".json")) return "application/json";
|
|
||||||
if (iequals(ext, ".xml")) return "application/xml";
|
|
||||||
if (iequals(ext, ".swf")) return "application/x-shockwave-flash";
|
|
||||||
if (iequals(ext, ".flv")) return "video/x-flv";
|
|
||||||
if (iequals(ext, ".png")) return "image/png";
|
|
||||||
if (iequals(ext, ".jpe")) return "image/jpeg";
|
|
||||||
if (iequals(ext, ".jpeg")) return "image/jpeg";
|
|
||||||
if (iequals(ext, ".jpg")) return "image/jpeg";
|
|
||||||
if (iequals(ext, ".gif")) return "image/gif";
|
|
||||||
if (iequals(ext, ".bmp")) return "image/bmp";
|
|
||||||
if (iequals(ext, ".ico")) return "image/vnd.microsoft.icon";
|
|
||||||
if (iequals(ext, ".tiff")) return "image/tiff";
|
|
||||||
if (iequals(ext, ".tif")) return "image/tiff";
|
|
||||||
if (iequals(ext, ".svg")) return "image/svg+xml";
|
|
||||||
if (iequals(ext, ".svgz")) return "image/svg+xml";
|
|
||||||
return "application/text";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string read_bin(const std::string& file) {
|
|
||||||
std::ifstream fin(file, std::ios_base::in | std::ios_base::binary);
|
|
||||||
std::string res;
|
|
||||||
while (true) {
|
|
||||||
char c = (char)fin.get();
|
|
||||||
if (fin.eof()) break;
|
|
||||||
res += c;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::nullopt_t serve(
|
std::nullopt_t serve(
|
||||||
bserv::response_type& response,
|
bserv::response_type& response,
|
||||||
const std::string& file) {
|
const std::string& file) {
|
||||||
response.set(bserv::http::field::content_type, mime_type(file));
|
return bserv::utils::file::serve(response, static_root_ + file);
|
||||||
response.body() = read_bin(static_root_ + file);
|
|
||||||
response.prepare_payload();
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,6 @@ void init_rendering(const std::string& template_root);
|
||||||
|
|
||||||
void init_static_root(const std::string& static_root);
|
void init_static_root(const std::string& static_root);
|
||||||
|
|
||||||
std::string read_bin(const std::string& file);
|
|
||||||
|
|
||||||
std::nullopt_t render(
|
std::nullopt_t render(
|
||||||
bserv::response_type& response,
|
bserv::response_type& response,
|
||||||
const std::string& template_path,
|
const std::string& template_path,
|
||||||
|
|
|
@ -149,6 +149,18 @@ namespace bserv {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class db_value<boost::json::string> : public db_parameter {
|
||||||
|
private:
|
||||||
|
std::string value_;
|
||||||
|
public:
|
||||||
|
db_value(const boost::json::string& value)
|
||||||
|
: value_{ value } {}
|
||||||
|
std::string get_value(raw_db_transaction_type& tx) {
|
||||||
|
return tx.quote(value_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class db_value<bool> : public db_parameter {
|
class db_value<bool> : public db_parameter {
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "websocket.hpp"
|
#include "websocket.hpp"
|
||||||
|
#include "logging.hpp"
|
||||||
|
|
||||||
namespace bserv {
|
namespace bserv {
|
||||||
|
|
||||||
|
@ -421,6 +422,7 @@ namespace bserv {
|
||||||
std::vector<std::string> url_params;
|
std::vector<std::string> url_params;
|
||||||
for (auto& ptr : paths_) {
|
for (auto& ptr : paths_) {
|
||||||
if (ptr->match(url, url_params)) {
|
if (ptr->match(url, url_params)) {
|
||||||
|
lgtrace << "router: received request: " << url;
|
||||||
request_resources resources{
|
request_resources resources{
|
||||||
*resources_,
|
*resources_,
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "client.hpp"
|
||||||
|
|
||||||
namespace bserv::utils {
|
namespace bserv::utils {
|
||||||
|
|
||||||
|
@ -57,6 +60,16 @@ namespace bserv::utils {
|
||||||
std::map<std::string, std::vector<std::string>>>
|
std::map<std::string, std::vector<std::string>>>
|
||||||
parse_url(std::string& s);
|
parse_url(std::string& s);
|
||||||
|
|
||||||
|
namespace file {
|
||||||
|
|
||||||
|
std::string read_bin(const std::string& filename);
|
||||||
|
|
||||||
|
std::nullopt_t serve(
|
||||||
|
response_type& response,
|
||||||
|
const std::string& filename);
|
||||||
|
|
||||||
|
} // file
|
||||||
|
|
||||||
} // bserv::utils
|
} // bserv::utils
|
||||||
|
|
||||||
#endif // _UTILS_HPP
|
#endif // _UTILS_HPP
|
|
@ -4,6 +4,7 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#include <cryptopp/cryptlib.h>
|
#include <cryptopp/cryptlib.h>
|
||||||
#include <cryptopp/pwdbased.h>
|
#include <cryptopp/pwdbased.h>
|
||||||
|
@ -233,4 +234,62 @@ namespace bserv::utils {
|
||||||
return std::make_tuple(url, dict_params, list_params);
|
return std::make_tuple(url, dict_params, list_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace file {
|
||||||
|
|
||||||
|
std::string read_bin(const std::string& filename) {
|
||||||
|
std::ifstream fin(filename, std::ios_base::in | std::ios_base::binary);
|
||||||
|
std::string res;
|
||||||
|
while (true) {
|
||||||
|
char c = (char)fin.get();
|
||||||
|
if (fin.eof()) break;
|
||||||
|
res += c;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns a reasonable mime type based on the extension of a file.
|
||||||
|
boost::beast::string_view
|
||||||
|
mime_type(boost::beast::string_view path) {
|
||||||
|
using boost::beast::iequals;
|
||||||
|
auto const ext = [&path] {
|
||||||
|
auto const pos = path.rfind(".");
|
||||||
|
if (pos == boost::beast::string_view::npos)
|
||||||
|
return boost::beast::string_view{};
|
||||||
|
return path.substr(pos);
|
||||||
|
}();
|
||||||
|
if (iequals(ext, ".htm")) return "text/html";
|
||||||
|
if (iequals(ext, ".html")) return "text/html";
|
||||||
|
if (iequals(ext, ".php")) return "text/html";
|
||||||
|
if (iequals(ext, ".css")) return "text/css";
|
||||||
|
if (iequals(ext, ".txt")) return "text/plain";
|
||||||
|
if (iequals(ext, ".js")) return "application/javascript";
|
||||||
|
if (iequals(ext, ".json")) return "application/json";
|
||||||
|
if (iequals(ext, ".xml")) return "application/xml";
|
||||||
|
if (iequals(ext, ".swf")) return "application/x-shockwave-flash";
|
||||||
|
if (iequals(ext, ".flv")) return "video/x-flv";
|
||||||
|
if (iequals(ext, ".png")) return "image/png";
|
||||||
|
if (iequals(ext, ".jpe")) return "image/jpeg";
|
||||||
|
if (iequals(ext, ".jpeg")) return "image/jpeg";
|
||||||
|
if (iequals(ext, ".jpg")) return "image/jpeg";
|
||||||
|
if (iequals(ext, ".gif")) return "image/gif";
|
||||||
|
if (iequals(ext, ".bmp")) return "image/bmp";
|
||||||
|
if (iequals(ext, ".ico")) return "image/vnd.microsoft.icon";
|
||||||
|
if (iequals(ext, ".tiff")) return "image/tiff";
|
||||||
|
if (iequals(ext, ".tif")) return "image/tiff";
|
||||||
|
if (iequals(ext, ".svg")) return "image/svg+xml";
|
||||||
|
if (iequals(ext, ".svgz")) return "image/svg+xml";
|
||||||
|
return "application/text";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::nullopt_t serve(
|
||||||
|
response_type& response,
|
||||||
|
const std::string& filename) {
|
||||||
|
response.set(bserv::http::field::content_type, mime_type(filename));
|
||||||
|
response.body() = read_bin(filename);
|
||||||
|
response.prepare_payload();
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // file
|
||||||
|
|
||||||
} // bserv::utils
|
} // bserv::utils
|
Loading…
Reference in New Issue