#ifndef FILESERVER_BOOST_HXX #define FILESERVER_BOOST_HXX #include #include #include #include #include #include #include namespace beast = boost::beast; namespace http = beast::http; namespace net = boost::asio; using tcp_stream = typename beast::tcp_stream::rebind_executor::executor_with_default>::other; using tcp_buffer = beast::flat_static_buffer<65535>; template http::response create_response(const http::request &req) { http::response res{Status, req.version()}; res.keep_alive(req.keep_alive()); return std::move(res); } template net::awaitable send_error(tcp_stream &s, const http::request &req, std::string &&body) { auto res = create_response(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 logger; template 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