remove global vars
This commit is contained in:
parent
11c681acf3
commit
41e0fe4c11
105
bserv/client.hpp
105
bserv/client.hpp
|
@ -13,7 +13,6 @@
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
#include "router.hpp"
|
|
||||||
#include "logging.hpp"
|
#include "logging.hpp"
|
||||||
|
|
||||||
namespace bserv {
|
namespace bserv {
|
||||||
|
@ -24,6 +23,9 @@ namespace asio = boost::asio;
|
||||||
namespace json = boost::json;
|
namespace json = boost::json;
|
||||||
using asio::ip::tcp;
|
using asio::ip::tcp;
|
||||||
|
|
||||||
|
using request_type = http::request<http::string_body>;
|
||||||
|
using response_type = http::response<http::string_body>;
|
||||||
|
|
||||||
class request_failed_exception
|
class request_failed_exception
|
||||||
: public std::exception {
|
: public std::exception {
|
||||||
private:
|
private:
|
||||||
|
@ -37,9 +39,9 @@ public:
|
||||||
|
|
||||||
// sends one async request to a remote server
|
// sends one async request to a remote server
|
||||||
template <typename ResponseType>
|
template <typename ResponseType>
|
||||||
class client_session
|
class http_client_session
|
||||||
: public std::enable_shared_from_this<
|
: public std::enable_shared_from_this<
|
||||||
client_session<ResponseType>> {
|
http_client_session<ResponseType>> {
|
||||||
private:
|
private:
|
||||||
tcp::resolver resolver_;
|
tcp::resolver resolver_;
|
||||||
beast::tcp_stream stream_;
|
beast::tcp_stream stream_;
|
||||||
|
@ -54,7 +56,7 @@ private:
|
||||||
request_failed_exception{what + ": " + ec.message()}));
|
request_failed_exception{what + ": " + ec.message()}));
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
client_session(
|
http_client_session(
|
||||||
asio::io_context& ioc,
|
asio::io_context& ioc,
|
||||||
const http::request<http::string_body>& req)
|
const http::request<http::string_body>& req)
|
||||||
: resolver_{asio::make_strand(ioc)},
|
: resolver_{asio::make_strand(ioc)},
|
||||||
|
@ -65,15 +67,15 @@ public:
|
||||||
resolver_.async_resolve(
|
resolver_.async_resolve(
|
||||||
host, port,
|
host, port,
|
||||||
beast::bind_front_handler(
|
beast::bind_front_handler(
|
||||||
&client_session::on_resolve,
|
&http_client_session::on_resolve,
|
||||||
client_session<ResponseType>::shared_from_this()));
|
http_client_session<ResponseType>::shared_from_this()));
|
||||||
return promise_.get_future();
|
return promise_.get_future();
|
||||||
}
|
}
|
||||||
void on_resolve(
|
void on_resolve(
|
||||||
beast::error_code ec,
|
beast::error_code ec,
|
||||||
tcp::resolver::results_type results) {
|
tcp::resolver::results_type results) {
|
||||||
if (ec) {
|
if (ec) {
|
||||||
failed(ec, "client_session::resolver resolve");
|
failed(ec, "http_client_session::resolver resolve");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// sets a timeout on the operation
|
// sets a timeout on the operation
|
||||||
|
@ -82,14 +84,14 @@ public:
|
||||||
stream_.async_connect(
|
stream_.async_connect(
|
||||||
results,
|
results,
|
||||||
beast::bind_front_handler(
|
beast::bind_front_handler(
|
||||||
&client_session::on_connect,
|
&http_client_session::on_connect,
|
||||||
client_session<ResponseType>::shared_from_this()));
|
http_client_session<ResponseType>::shared_from_this()));
|
||||||
}
|
}
|
||||||
void on_connect(
|
void on_connect(
|
||||||
beast::error_code ec,
|
beast::error_code ec,
|
||||||
tcp::resolver::results_type::endpoint_type) {
|
tcp::resolver::results_type::endpoint_type) {
|
||||||
if (ec) {
|
if (ec) {
|
||||||
failed(ec, "client_session::stream connect");
|
failed(ec, "http_client_session::stream connect");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// sets a timeout on the operation
|
// sets a timeout on the operation
|
||||||
|
@ -98,23 +100,23 @@ public:
|
||||||
http::async_write(
|
http::async_write(
|
||||||
stream_, req_,
|
stream_, req_,
|
||||||
beast::bind_front_handler(
|
beast::bind_front_handler(
|
||||||
&client_session::on_write,
|
&http_client_session::on_write,
|
||||||
client_session<ResponseType>::shared_from_this()));
|
http_client_session<ResponseType>::shared_from_this()));
|
||||||
}
|
}
|
||||||
void on_write(
|
void on_write(
|
||||||
beast::error_code ec,
|
beast::error_code ec,
|
||||||
std::size_t bytes_transferred) {
|
std::size_t bytes_transferred) {
|
||||||
boost::ignore_unused(bytes_transferred);
|
boost::ignore_unused(bytes_transferred);
|
||||||
if (ec) {
|
if (ec) {
|
||||||
failed(ec, "client_session::stream write");
|
failed(ec, "http_client_session::stream write");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// receives the HTTP response
|
// receives the HTTP response
|
||||||
http::async_read(
|
http::async_read(
|
||||||
stream_, buffer_, res_,
|
stream_, buffer_, res_,
|
||||||
beast::bind_front_handler(
|
beast::bind_front_handler(
|
||||||
&client_session::on_read,
|
&http_client_session::on_read,
|
||||||
client_session<ResponseType>::shared_from_this()));
|
http_client_session<ResponseType>::shared_from_this()));
|
||||||
}
|
}
|
||||||
static_assert(std::is_same<ResponseType, http::response<http::string_body>>::value
|
static_assert(std::is_same<ResponseType, http::response<http::string_body>>::value
|
||||||
|| std::is_same<ResponseType, boost::json::value>::value,
|
|| std::is_same<ResponseType, boost::json::value>::value,
|
||||||
|
@ -124,7 +126,7 @@ public:
|
||||||
std::size_t bytes_transferred) {
|
std::size_t bytes_transferred) {
|
||||||
boost::ignore_unused(bytes_transferred);
|
boost::ignore_unused(bytes_transferred);
|
||||||
if (ec) {
|
if (ec) {
|
||||||
failed(ec, "client_session::stream read");
|
failed(ec, "http_client_session::stream read");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if constexpr (std::is_same<ResponseType, http::response<http::string_body>>::value) {
|
if constexpr (std::is_same<ResponseType, http::response<http::string_body>>::value) {
|
||||||
|
@ -141,42 +143,14 @@ public:
|
||||||
// `not_connected` happens sometimes so don't bother reporting it
|
// `not_connected` happens sometimes so don't bother reporting it
|
||||||
if (ec && ec != beast::errc::not_connected) {
|
if (ec && ec != beast::errc::not_connected) {
|
||||||
// reports the error to the log!
|
// reports the error to the log!
|
||||||
fail(ec, "client_session::stream::socket shutdown");
|
fail(ec, "http_client_session::stream::socket shutdown");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// if we get here then the connection is closed gracefully
|
// if we get here then the connection is closed gracefully
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class client {
|
request_type get_request(
|
||||||
private:
|
|
||||||
asio::io_context& ioc_;
|
|
||||||
public:
|
|
||||||
client(asio::io_context& ioc)
|
|
||||||
: ioc_{ioc} {}
|
|
||||||
std::future<http::response<http::string_body>> request(
|
|
||||||
const std::string& host,
|
|
||||||
const std::string& port,
|
|
||||||
const http::request<http::string_body>& req) {
|
|
||||||
return std::make_shared<
|
|
||||||
client_session<http::response<http::string_body>>
|
|
||||||
>(ioc_, req)->send(host, port);
|
|
||||||
}
|
|
||||||
std::future<boost::json::value> request_for_object(
|
|
||||||
const std::string& host,
|
|
||||||
const std::string& port,
|
|
||||||
const http::request<http::string_body>& req) {
|
|
||||||
return std::make_shared<
|
|
||||||
client_session<boost::json::value>
|
|
||||||
>(ioc_, req)->send(host, port);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::shared_ptr<client> client_ptr;
|
|
||||||
|
|
||||||
namespace request {
|
|
||||||
|
|
||||||
request_type get_request(
|
|
||||||
const std::string& host,
|
const std::string& host,
|
||||||
const std::string& target,
|
const std::string& target,
|
||||||
const http::verb& method,
|
const http::verb& method,
|
||||||
|
@ -190,6 +164,29 @@ namespace request {
|
||||||
req.body() = boost::json::serialize(obj);
|
req.body() = boost::json::serialize(obj);
|
||||||
req.prepare_payload();
|
req.prepare_payload();
|
||||||
return req;
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
class http_client {
|
||||||
|
private:
|
||||||
|
asio::io_context& ioc_;
|
||||||
|
public:
|
||||||
|
http_client(asio::io_context& ioc)
|
||||||
|
: ioc_{ioc} {}
|
||||||
|
std::future<http::response<http::string_body>> request(
|
||||||
|
const std::string& host,
|
||||||
|
const std::string& port,
|
||||||
|
const http::request<http::string_body>& req) {
|
||||||
|
return std::make_shared<
|
||||||
|
http_client_session<http::response<http::string_body>>
|
||||||
|
>(ioc_, req)->send(host, port);
|
||||||
|
}
|
||||||
|
std::future<boost::json::value> request_for_object(
|
||||||
|
const std::string& host,
|
||||||
|
const std::string& port,
|
||||||
|
const http::request<http::string_body>& req) {
|
||||||
|
return std::make_shared<
|
||||||
|
http_client_session<boost::json::value>
|
||||||
|
>(ioc_, req)->send(host, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::future<response_type> send(
|
std::future<response_type> send(
|
||||||
|
@ -199,9 +196,8 @@ namespace request {
|
||||||
const http::verb& method,
|
const http::verb& method,
|
||||||
const boost::json::object& obj) {
|
const boost::json::object& obj) {
|
||||||
request_type req = get_request(host, target, method, obj);
|
request_type req = get_request(host, target, method, obj);
|
||||||
return client_ptr->request(host, port, req);
|
return request(host, port, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::future<boost::json::value> send_for_object(
|
std::future<boost::json::value> send_for_object(
|
||||||
const std::string& host,
|
const std::string& host,
|
||||||
const std::string& port,
|
const std::string& port,
|
||||||
|
@ -209,9 +205,8 @@ namespace request {
|
||||||
const http::verb& method,
|
const http::verb& method,
|
||||||
const boost::json::object& obj) {
|
const boost::json::object& obj) {
|
||||||
request_type req = get_request(host, target, method, obj);
|
request_type req = get_request(host, target, method, obj);
|
||||||
return client_ptr->request_for_object(host, port, req);
|
return request_for_object(host, port, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::future<response_type> get(
|
std::future<response_type> get(
|
||||||
const std::string& host,
|
const std::string& host,
|
||||||
const std::string& port,
|
const std::string& port,
|
||||||
|
@ -219,7 +214,6 @@ namespace request {
|
||||||
const boost::json::object& obj) {
|
const boost::json::object& obj) {
|
||||||
return send(host, port, target, http::verb::get, obj);
|
return send(host, port, target, http::verb::get, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::future<boost::json::value> get_for_object(
|
std::future<boost::json::value> get_for_object(
|
||||||
const std::string& host,
|
const std::string& host,
|
||||||
const std::string& port,
|
const std::string& port,
|
||||||
|
@ -227,7 +221,6 @@ namespace request {
|
||||||
const boost::json::object& obj) {
|
const boost::json::object& obj) {
|
||||||
return send_for_object(host, port, target, http::verb::get, obj);
|
return send_for_object(host, port, target, http::verb::get, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::future<response_type> put(
|
std::future<response_type> put(
|
||||||
const std::string& host,
|
const std::string& host,
|
||||||
const std::string& port,
|
const std::string& port,
|
||||||
|
@ -235,7 +228,6 @@ namespace request {
|
||||||
const boost::json::object& obj) {
|
const boost::json::object& obj) {
|
||||||
return send(host, port, target, http::verb::put, obj);
|
return send(host, port, target, http::verb::put, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::future<boost::json::value> put_for_object(
|
std::future<boost::json::value> put_for_object(
|
||||||
const std::string& host,
|
const std::string& host,
|
||||||
const std::string& port,
|
const std::string& port,
|
||||||
|
@ -243,7 +235,6 @@ namespace request {
|
||||||
const boost::json::object& obj) {
|
const boost::json::object& obj) {
|
||||||
return send_for_object(host, port, target, http::verb::put, obj);
|
return send_for_object(host, port, target, http::verb::put, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::future<response_type> post(
|
std::future<response_type> post(
|
||||||
const std::string& host,
|
const std::string& host,
|
||||||
const std::string& port,
|
const std::string& port,
|
||||||
|
@ -251,7 +242,6 @@ namespace request {
|
||||||
const boost::json::object& obj) {
|
const boost::json::object& obj) {
|
||||||
return send(host, port, target, http::verb::post, obj);
|
return send(host, port, target, http::verb::post, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::future<boost::json::value> post_for_object(
|
std::future<boost::json::value> post_for_object(
|
||||||
const std::string& host,
|
const std::string& host,
|
||||||
const std::string& port,
|
const std::string& port,
|
||||||
|
@ -259,7 +249,6 @@ namespace request {
|
||||||
const boost::json::object& obj) {
|
const boost::json::object& obj) {
|
||||||
return send_for_object(host, port, target, http::verb::post, obj);
|
return send_for_object(host, port, target, http::verb::post, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::future<response_type> delete_(
|
std::future<response_type> delete_(
|
||||||
const std::string& host,
|
const std::string& host,
|
||||||
const std::string& port,
|
const std::string& port,
|
||||||
|
@ -267,7 +256,6 @@ namespace request {
|
||||||
const boost::json::object& obj) {
|
const boost::json::object& obj) {
|
||||||
return send(host, port, target, http::verb::delete_, obj);
|
return send(host, port, target, http::verb::delete_, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::future<boost::json::value> delete_for_object(
|
std::future<boost::json::value> delete_for_object(
|
||||||
const std::string& host,
|
const std::string& host,
|
||||||
const std::string& port,
|
const std::string& port,
|
||||||
|
@ -275,8 +263,7 @@ namespace request {
|
||||||
const boost::json::object& obj) {
|
const boost::json::object& obj) {
|
||||||
return send_for_object(host, port, target, http::verb::delete_, obj);
|
return send_for_object(host, port, target, http::verb::delete_, obj);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
} // request
|
|
||||||
|
|
||||||
} // bserv
|
} // bserv
|
||||||
|
|
||||||
|
|
|
@ -88,8 +88,6 @@ db_connection::~db_connection() {
|
||||||
mgr_.counter_lock_.unlock();
|
mgr_.counter_lock_.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<db_connection_manager> db_conn_mgr;
|
|
||||||
|
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
class db_parameter {
|
class db_parameter {
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include <pqxx/pqxx>
|
#include <pqxx/pqxx>
|
||||||
|
|
||||||
|
#include "client.hpp"
|
||||||
#include "database.hpp"
|
#include "database.hpp"
|
||||||
#include "session.hpp"
|
#include "session.hpp"
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
|
@ -24,8 +25,11 @@ namespace bserv {
|
||||||
namespace beast = boost::beast;
|
namespace beast = boost::beast;
|
||||||
namespace http = beast::http;
|
namespace http = beast::http;
|
||||||
|
|
||||||
using request_type = http::request<http::string_body>;
|
struct server_resources {
|
||||||
using response_type = http::response<http::string_body>;
|
std::shared_ptr<session_manager_base> session_mgr;
|
||||||
|
std::shared_ptr<db_connection_manager> db_conn_mgr;
|
||||||
|
std::shared_ptr<http_client> http_client_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
namespace placeholders {
|
namespace placeholders {
|
||||||
|
|
||||||
|
@ -55,7 +59,9 @@ constexpr placeholder<-3> response;
|
||||||
// boost::json::object&&
|
// boost::json::object&&
|
||||||
constexpr placeholder<-4> json_params;
|
constexpr placeholder<-4> json_params;
|
||||||
// std::shared_ptr<bserv::db_connection>
|
// std::shared_ptr<bserv::db_connection>
|
||||||
constexpr placeholder<-5> transaction;
|
constexpr placeholder<-5> db_connection_ptr;
|
||||||
|
// std::shared_ptr<bserv::http_client>
|
||||||
|
constexpr placeholder<-6> http_client_ptr;
|
||||||
|
|
||||||
} // placeholders
|
} // placeholders
|
||||||
|
|
||||||
|
@ -116,6 +122,7 @@ struct get_parameter<0, Head, Tail...> {
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
Type&& get_parameter_data(
|
Type&& get_parameter_data(
|
||||||
|
server_resources&,
|
||||||
const std::vector<std::string>&,
|
const std::vector<std::string>&,
|
||||||
request_type&, response_type&, Type&& val) {
|
request_type&, response_type&, Type&& val) {
|
||||||
return static_cast<Type&&>(val);
|
return static_cast<Type&&>(val);
|
||||||
|
@ -123,6 +130,7 @@ Type&& get_parameter_data(
|
||||||
|
|
||||||
template <int N, std::enable_if_t<(N >= 0), int> = 0>
|
template <int N, std::enable_if_t<(N >= 0), int> = 0>
|
||||||
const std::string& get_parameter_data(
|
const std::string& get_parameter_data(
|
||||||
|
server_resources&,
|
||||||
const std::vector<std::string>& url_params,
|
const std::vector<std::string>& url_params,
|
||||||
request_type&, response_type&,
|
request_type&, response_type&,
|
||||||
placeholders::placeholder<N>) {
|
placeholders::placeholder<N>) {
|
||||||
|
@ -130,6 +138,7 @@ const std::string& get_parameter_data(
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<session_type> get_parameter_data(
|
std::shared_ptr<session_type> get_parameter_data(
|
||||||
|
server_resources& resources,
|
||||||
const std::vector<std::string>&,
|
const std::vector<std::string>&,
|
||||||
request_type& request, response_type& response,
|
request_type& request, response_type& response,
|
||||||
placeholders::placeholder<-1>) {
|
placeholders::placeholder<-1>) {
|
||||||
|
@ -142,13 +151,14 @@ std::shared_ptr<session_type> get_parameter_data(
|
||||||
session_id = cookie_dict[SESSION_NAME];
|
session_id = cookie_dict[SESSION_NAME];
|
||||||
}
|
}
|
||||||
std::shared_ptr<session_type> session_ptr;
|
std::shared_ptr<session_type> session_ptr;
|
||||||
if (session_mgr->get_or_create(session_id, session_ptr)) {
|
if (resources.session_mgr->get_or_create(session_id, session_ptr)) {
|
||||||
response.set(http::field::set_cookie, SESSION_NAME + "=" + session_id);
|
response.set(http::field::set_cookie, SESSION_NAME + "=" + session_id);
|
||||||
}
|
}
|
||||||
return session_ptr;
|
return session_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
request_type& get_parameter_data(
|
request_type& get_parameter_data(
|
||||||
|
server_resources&,
|
||||||
const std::vector<std::string>&,
|
const std::vector<std::string>&,
|
||||||
request_type& request, response_type&,
|
request_type& request, response_type&,
|
||||||
placeholders::placeholder<-2>) {
|
placeholders::placeholder<-2>) {
|
||||||
|
@ -156,6 +166,7 @@ request_type& get_parameter_data(
|
||||||
}
|
}
|
||||||
|
|
||||||
response_type& get_parameter_data(
|
response_type& get_parameter_data(
|
||||||
|
server_resources&,
|
||||||
const std::vector<std::string>&,
|
const std::vector<std::string>&,
|
||||||
request_type&, response_type& response,
|
request_type&, response_type& response,
|
||||||
placeholders::placeholder<-3>) {
|
placeholders::placeholder<-3>) {
|
||||||
|
@ -163,6 +174,7 @@ response_type& get_parameter_data(
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::json::object get_parameter_data(
|
boost::json::object get_parameter_data(
|
||||||
|
server_resources&,
|
||||||
const std::vector<std::string>&,
|
const std::vector<std::string>&,
|
||||||
request_type& request, response_type&,
|
request_type& request, response_type&,
|
||||||
placeholders::placeholder<-4>) {
|
placeholders::placeholder<-4>) {
|
||||||
|
@ -195,10 +207,19 @@ boost::json::object get_parameter_data(
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<db_connection> get_parameter_data(
|
std::shared_ptr<db_connection> get_parameter_data(
|
||||||
|
server_resources& resources,
|
||||||
const std::vector<std::string>&,
|
const std::vector<std::string>&,
|
||||||
request_type&, response_type&,
|
request_type&, response_type&,
|
||||||
placeholders::placeholder<-5>) {
|
placeholders::placeholder<-5>) {
|
||||||
return db_conn_mgr->get_or_block();
|
return resources.db_conn_mgr->get_or_block();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<http_client> get_parameter_data(
|
||||||
|
server_resources& resources,
|
||||||
|
const std::vector<std::string>&,
|
||||||
|
request_type&, response_type&,
|
||||||
|
placeholders::placeholder<-6>) {
|
||||||
|
return resources.http_client_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int Idx, typename Func, typename Params, typename ...Args>
|
template <int Idx, typename Func, typename Params, typename ...Args>
|
||||||
|
@ -206,15 +227,16 @@ struct path_handler;
|
||||||
|
|
||||||
template <int Idx, typename Ret, typename ...Args, typename ...Params>
|
template <int Idx, typename Ret, typename ...Args, typename ...Params>
|
||||||
struct path_handler<Idx, Ret (*)(Args ...), parameter_pack<Params...>> {
|
struct path_handler<Idx, Ret (*)(Args ...), parameter_pack<Params...>> {
|
||||||
Ret invoke(Ret (*pf)(Args ...), parameter_pack<Params...>& params,
|
Ret invoke(server_resources& resources,
|
||||||
|
Ret (*pf)(Args ...), parameter_pack<Params...>& params,
|
||||||
const std::vector<std::string>& url_params,
|
const std::vector<std::string>& url_params,
|
||||||
request_type& request, response_type& response) {
|
request_type& request, response_type& response) {
|
||||||
if constexpr (Idx == 0) return (*pf)();
|
if constexpr (Idx == 0) return (*pf)();
|
||||||
else return static_cast<path_handler<
|
else return static_cast<path_handler<
|
||||||
Idx - 1, Ret (*)(Args ...), parameter_pack<Params...>,
|
Idx - 1, Ret (*)(Args ...), parameter_pack<Params...>,
|
||||||
typename get_parameter<Idx - 1, Params...>::type>*
|
typename get_parameter<Idx - 1, Params...>::type>*
|
||||||
>(this)->invoke2(pf, params, url_params, request, response,
|
>(this)->invoke2(resources, pf, params, url_params, request, response,
|
||||||
get_parameter_data(url_params, request, response,
|
get_parameter_data(resources, url_params, request, response,
|
||||||
get_parameter_value<Idx - 1>(params)));
|
get_parameter_value<Idx - 1>(params)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -228,7 +250,8 @@ struct path_handler<Idx, Ret (*)(Args ...),
|
||||||
template <
|
template <
|
||||||
typename Head2, typename ...Tail2,
|
typename Head2, typename ...Tail2,
|
||||||
std::enable_if_t<sizeof...(Tail2) == sizeof...(Tail), int> = 0>
|
std::enable_if_t<sizeof...(Tail2) == sizeof...(Tail), int> = 0>
|
||||||
Ret invoke2(Ret (*pf)(Args ...), parameter_pack<Params...>& params,
|
Ret invoke2(server_resources& resources,
|
||||||
|
Ret (*pf)(Args ...), parameter_pack<Params...>& params,
|
||||||
const std::vector<std::string>& url_params,
|
const std::vector<std::string>& url_params,
|
||||||
request_type& request, response_type& response,
|
request_type& request, response_type& response,
|
||||||
Head2&& head2, Tail2&& ...tail2) {
|
Head2&& head2, Tail2&& ...tail2) {
|
||||||
|
@ -238,8 +261,8 @@ struct path_handler<Idx, Ret (*)(Args ...),
|
||||||
else return static_cast<path_handler<
|
else return static_cast<path_handler<
|
||||||
Idx - 1, Ret (*)(Args ...), parameter_pack<Params...>,
|
Idx - 1, Ret (*)(Args ...), parameter_pack<Params...>,
|
||||||
typename get_parameter<Idx - 1, Params...>::type, Head, Tail...>*
|
typename get_parameter<Idx - 1, Params...>::type, Head, Tail...>*
|
||||||
>(this)->invoke2(pf, params, url_params, request, response,
|
>(this)->invoke2(resources, pf, params, url_params, request, response,
|
||||||
get_parameter_data(url_params, request, response,
|
get_parameter_data(resources, url_params, request, response,
|
||||||
get_parameter_value<Idx - 1>(params)),
|
get_parameter_value<Idx - 1>(params)),
|
||||||
static_cast<Head2&&>(head2), static_cast<Tail2&&>(tail2)...);
|
static_cast<Head2&&>(head2), static_cast<Tail2&&>(tail2)...);
|
||||||
}
|
}
|
||||||
|
@ -265,6 +288,7 @@ struct path_holder : std::enable_shared_from_this<path_holder> {
|
||||||
const std::string&,
|
const std::string&,
|
||||||
std::vector<std::string>&) const = 0;
|
std::vector<std::string>&) const = 0;
|
||||||
virtual std::optional<boost::json::value> invoke(
|
virtual std::optional<boost::json::value> invoke(
|
||||||
|
server_resources&,
|
||||||
const std::vector<std::string>&,
|
const std::vector<std::string>&,
|
||||||
request_type&, response_type&) = 0;
|
request_type&, response_type&) = 0;
|
||||||
};
|
};
|
||||||
|
@ -295,9 +319,11 @@ public:
|
||||||
return matched;
|
return matched;
|
||||||
}
|
}
|
||||||
std::optional<boost::json::value> invoke(
|
std::optional<boost::json::value> invoke(
|
||||||
|
server_resources& resources,
|
||||||
const std::vector<std::string>& url_params,
|
const std::vector<std::string>& url_params,
|
||||||
request_type& request, response_type& response) {
|
request_type& request, response_type& response) {
|
||||||
return handler_.invoke(
|
return handler_.invoke(
|
||||||
|
resources,
|
||||||
pf_, params_, url_params,
|
pf_, params_, url_params,
|
||||||
request, response);
|
request, response);
|
||||||
}
|
}
|
||||||
|
@ -335,15 +361,19 @@ class router {
|
||||||
private:
|
private:
|
||||||
using path_holder_type = std::shared_ptr<router_internal::path_holder>;
|
using path_holder_type = std::shared_ptr<router_internal::path_holder>;
|
||||||
std::vector<path_holder_type> paths_;
|
std::vector<path_holder_type> paths_;
|
||||||
|
std::shared_ptr<server_resources> resources_;
|
||||||
public:
|
public:
|
||||||
router(const std::initializer_list<path_holder_type>& paths)
|
router(const std::initializer_list<path_holder_type>& paths)
|
||||||
: paths_{paths} {}
|
: paths_{paths} {}
|
||||||
|
void set_resources(std::shared_ptr<server_resources> resources) {
|
||||||
|
resources_ = resources;
|
||||||
|
}
|
||||||
std::optional<boost::json::value> operator()(
|
std::optional<boost::json::value> operator()(
|
||||||
const std::string& url, request_type& request, response_type& response) {
|
const std::string& url, request_type& request, response_type& response) {
|
||||||
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))
|
||||||
return ptr->invoke(url_params, request, response);
|
return ptr->invoke(*resources_, url_params, request, response);
|
||||||
}
|
}
|
||||||
throw url_not_found_exception{};
|
throw url_not_found_exception{};
|
||||||
}
|
}
|
||||||
|
|
|
@ -320,22 +320,32 @@ private:
|
||||||
// io_context for all I/O
|
// io_context for all I/O
|
||||||
asio::io_context ioc_;
|
asio::io_context ioc_;
|
||||||
router routes_;
|
router routes_;
|
||||||
|
std::shared_ptr<session_manager_base> session_mgr_;
|
||||||
|
std::shared_ptr<db_connection_manager> db_conn_mgr_;
|
||||||
|
std::shared_ptr<http_client> http_client_ptr_;
|
||||||
public:
|
public:
|
||||||
server(const server_config& config, router&& routes)
|
server(const server_config& config, router&& routes)
|
||||||
: ioc_{config.get_num_threads()}, routes_{routes} {
|
: ioc_{config.get_num_threads()},
|
||||||
|
routes_{std::move(routes)} {
|
||||||
init_logging(config);
|
init_logging(config);
|
||||||
|
|
||||||
// database connection
|
// database connection
|
||||||
try {
|
try {
|
||||||
db_conn_mgr = std::make_shared<
|
db_conn_mgr_ = std::make_shared<
|
||||||
db_connection_manager>(config.get_db_conn_str(), config.get_num_db_conn());
|
db_connection_manager>(config.get_db_conn_str(), config.get_num_db_conn());
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
lgfatal << "db connection initialization failed: " << e.what() << std::endl;
|
lgfatal << "db connection initialization failed: " << e.what() << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
session_mgr = std::make_shared<memory_session>();
|
session_mgr_ = std::make_shared<memory_session_manager>();
|
||||||
|
http_client_ptr_ = std::make_shared<http_client>(ioc_);
|
||||||
|
|
||||||
client_ptr = std::make_shared<client>(ioc_);
|
std::shared_ptr<server_resources> resources_ptr = std::make_shared<server_resources>();
|
||||||
|
resources_ptr->session_mgr = session_mgr_;
|
||||||
|
resources_ptr->db_conn_mgr = db_conn_mgr_;
|
||||||
|
resources_ptr->http_client_ptr = http_client_ptr_;
|
||||||
|
|
||||||
|
routes_.set_resources(resources_ptr);
|
||||||
|
|
||||||
// creates and launches a listening port
|
// creates and launches a listening port
|
||||||
std::make_shared<listener>(
|
std::make_shared<listener>(
|
||||||
|
|
|
@ -23,9 +23,9 @@ const std::string SESSION_NAME = "bsessionid";
|
||||||
// using session_type = std::map<std::string, boost::json::value>;
|
// using session_type = std::map<std::string, boost::json::value>;
|
||||||
using session_type = boost::json::object;
|
using session_type = boost::json::object;
|
||||||
|
|
||||||
struct session_base
|
struct session_manager_base
|
||||||
: std::enable_shared_from_this<session_base> {
|
: std::enable_shared_from_this<session_manager_base> {
|
||||||
virtual ~session_base() = default;
|
virtual ~session_manager_base() = default;
|
||||||
// if `key` refers to an existing session, that session will be placed in
|
// if `key` refers to an existing session, that session will be placed in
|
||||||
// `session_ptr` and this function will return `false`.
|
// `session_ptr` and this function will return `false`.
|
||||||
// otherwise, this function will create a new session, place the created
|
// otherwise, this function will create a new session, place the created
|
||||||
|
@ -39,9 +39,7 @@ struct session_base
|
||||||
std::shared_ptr<session_type>& session_ptr) = 0;
|
std::shared_ptr<session_type>& session_ptr) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<session_base> session_mgr;
|
class memory_session_manager : public session_manager_base {
|
||||||
|
|
||||||
class memory_session : public session_base {
|
|
||||||
private:
|
private:
|
||||||
using time_point = std::chrono::steady_clock::time_point;
|
using time_point = std::chrono::steady_clock::time_point;
|
||||||
std::mt19937 rng_;
|
std::mt19937 rng_;
|
||||||
|
@ -58,7 +56,7 @@ private:
|
||||||
std::set<std::pair<time_point, std::size_t>> queue_;
|
std::set<std::pair<time_point, std::size_t>> queue_;
|
||||||
mutable std::mutex lock_;
|
mutable std::mutex lock_;
|
||||||
public:
|
public:
|
||||||
memory_session()
|
memory_session_manager()
|
||||||
: rng_{utils::internal::get_rd_value()},
|
: rng_{utils::internal::get_rd_value()},
|
||||||
dist_{0, std::numeric_limits<std::size_t>::max()} {}
|
dist_{0, std::numeric_limits<std::size_t>::max()} {}
|
||||||
bool get_or_create(
|
bool get_or_create(
|
||||||
|
|
15
handlers.hpp
15
handlers.hpp
|
@ -209,10 +209,10 @@ boost::json::object user_logout(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::json::object send_request() {
|
boost::json::object send_request(std::shared_ptr<bserv::http_client> client_ptr) {
|
||||||
// post for response:
|
// post for response:
|
||||||
// auto res = bserv::request::post(
|
// auto res = client_ptr->post(
|
||||||
// "localhost", "8081", "/test", {{"msg", "request"}}
|
// "localhost", "8080", "/echo", {{"msg", "request"}}
|
||||||
// ).get();
|
// ).get();
|
||||||
// return {{"response", boost::json::parse(res.body())}};
|
// return {{"response", boost::json::parse(res.body())}};
|
||||||
// -------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
|
@ -221,10 +221,15 @@ boost::json::object send_request() {
|
||||||
// -------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
// post for json response (json value, rather than json
|
// post for json response (json value, rather than json
|
||||||
// object, is returned):
|
// object, is returned):
|
||||||
auto obj = bserv::request::post_for_object(
|
auto obj = client_ptr->post_for_object(
|
||||||
"localhost", "8081", "/test", {{"msg", "request"}}
|
"localhost", "8080", "/echo", {{"msg", "request"}}
|
||||||
).get();
|
).get();
|
||||||
return {{"response", obj}};
|
return {{"response", obj}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::json::object echo(
|
||||||
|
boost::json::object&& params) {
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // _HANDLERS_HPP
|
#endif // _HANDLERS_HPP
|
11
main.cpp
11
main.cpp
|
@ -108,18 +108,21 @@ int main(int argc, char* argv[]) {
|
||||||
bserv::make_path("/register", &user_register,
|
bserv::make_path("/register", &user_register,
|
||||||
bserv::placeholders::request,
|
bserv::placeholders::request,
|
||||||
bserv::placeholders::json_params,
|
bserv::placeholders::json_params,
|
||||||
bserv::placeholders::transaction),
|
bserv::placeholders::db_connection_ptr),
|
||||||
bserv::make_path("/login", &user_login,
|
bserv::make_path("/login", &user_login,
|
||||||
bserv::placeholders::request,
|
bserv::placeholders::request,
|
||||||
bserv::placeholders::json_params,
|
bserv::placeholders::json_params,
|
||||||
bserv::placeholders::transaction,
|
bserv::placeholders::db_connection_ptr,
|
||||||
bserv::placeholders::session),
|
bserv::placeholders::session),
|
||||||
bserv::make_path("/logout", &user_logout,
|
bserv::make_path("/logout", &user_logout,
|
||||||
bserv::placeholders::session),
|
bserv::placeholders::session),
|
||||||
bserv::make_path("/find/<str>", &find_user,
|
bserv::make_path("/find/<str>", &find_user,
|
||||||
bserv::placeholders::transaction,
|
bserv::placeholders::db_connection_ptr,
|
||||||
bserv::placeholders::_1),
|
bserv::placeholders::_1),
|
||||||
bserv::make_path("/send", &send_request)
|
bserv::make_path("/send", &send_request,
|
||||||
|
bserv::placeholders::http_client_ptr),
|
||||||
|
bserv::make_path("/echo", &echo,
|
||||||
|
bserv::placeholders::json_params)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
Loading…
Reference in New Issue