67 lines
2.2 KiB
C++
67 lines
2.2 KiB
C++
#ifndef FILESERVER_BOOST_HXX
|
|
#define FILESERVER_BOOST_HXX
|
|
|
|
#include <spdlog/spdlog.h>
|
|
#include <boost/beast/core.hpp>
|
|
#include <boost/beast/http.hpp>
|
|
#include <boost/asio/write.hpp>
|
|
#include <boost/asio/awaitable.hpp>
|
|
#include <boost/asio/use_awaitable.hpp>
|
|
#include <boost/asio/experimental/concurrent_channel.hpp>
|
|
|
|
namespace beast = boost::beast;
|
|
namespace http = beast::http;
|
|
namespace net = boost::asio;
|
|
|
|
using tcp_stream = typename beast::tcp_stream::rebind_executor<net::use_awaitable_t<>::executor_with_default<net::any_io_executor>>::other;
|
|
using tcp_buffer = beast::flat_static_buffer<65535>;
|
|
|
|
template<http::status Status, typename BodyType, typename ReqBody>
|
|
http::response<BodyType> create_response(const http::request<ReqBody> &req) {
|
|
http::response<BodyType> res{Status, req.version()};
|
|
res.keep_alive(req.keep_alive());
|
|
return std::move(res);
|
|
}
|
|
|
|
template<typename ReqBody>
|
|
net::awaitable<void> send_error(tcp_stream &s, const http::request<ReqBody> &req, std::string &&body) {
|
|
auto res = create_response<http::status::bad_request, http::string_body, ReqBody>(req);
|
|
res.body() = body;
|
|
co_await http::async_write(s, res, net::use_awaitable);
|
|
}
|
|
|
|
struct err_handler {
|
|
std::source_location loc;
|
|
|
|
explicit err_handler(std::source_location loc = std::source_location::current()) : loc(loc) {}
|
|
|
|
void operator()(const std::exception_ptr& e) const {
|
|
if (!e) return;
|
|
try {
|
|
std::rethrow_exception(e);
|
|
} catch (beast::system_error &se) {
|
|
log(se.what());
|
|
} catch (std::exception &e1) {
|
|
log(e1.what());
|
|
//std::cerr << "Error in " << loc.file_name() << ":" << loc.line() << " `" << loc.function_name() << "`\n" << e1.what() << "\n";
|
|
}
|
|
}
|
|
|
|
private:
|
|
static std::shared_ptr<spdlog::logger> logger;
|
|
|
|
template<typename MsgType>
|
|
void log(MsgType msg) const {
|
|
if (!logger)
|
|
logger = spdlog::default_logger()->clone("err_handler");
|
|
spdlog::source_loc spd_loc;
|
|
spd_loc.filename = loc.file_name();
|
|
spd_loc.line = (int)loc.line();
|
|
spd_loc.funcname = loc.function_name();
|
|
spdlog::log(spd_loc, spdlog::level::err, msg);
|
|
}
|
|
};
|
|
|
|
|
|
#endif //FILESERVER_BOOST_HXX
|