#include "RequestHandlers/BasicRequestHandler.h" #include "Session.h" namespace uad { Session::Session( tcp::socket&& socket, std::shared_ptr const& doc_root) : stream_(std::move(socket)), doc_root_(doc_root) {} void Session::Run() { net::dispatch(stream_.get_executor(), beast::bind_front_handler( &Session::DoRead, shared_from_this())); } void Session::DoRead() { req_ = {}; stream_.expires_after(std::chrono::seconds(30)); http::async_read(stream_, buffer_, req_, beast::bind_front_handler( &Session::OnRead, shared_from_this())); } void Session::OnRead( beast::error_code ec, std::size_t bytes_transferred) { boost::ignore_unused(bytes_transferred); if (ec == http::error::end_of_stream) return DoClose(); if (ec) return Fail(ec, "read"); SendResponse( HandleRequest(*doc_root_, std::move(req_))); } void Session::SendResponse(http::message_generator&& msg) { bool keep_alive = msg.keep_alive(); beast::async_write( stream_, std::move(msg), beast::bind_front_handler( &Session::OnWrite, shared_from_this(), keep_alive)); } void Session::OnWrite( bool keep_alive, beast::error_code ec, std::size_t bytes_transferred) { boost::ignore_unused(bytes_transferred); if (ec) return uad::Fail(ec, "write"); if (!keep_alive) { return DoClose(); } DoRead(); } void Session::DoClose() { beast::error_code ec; stream_.socket().shutdown(tcp::socket::shutdown_send, ec); } }