diff --git a/main.cpp b/main.cpp index 8dbcddd..81f2691 100644 --- a/main.cpp +++ b/main.cpp @@ -26,12 +26,14 @@ struct ContentType { ContentType() = delete; constexpr static std::string_view - TEXT_HTML = "text/html"sv; + TEXT_HTML = "text/html"sv; // При необходимости внутрь ContentType можно добавить и другие типы контента }; // Создаёт StringResponse с заданными параметрами -StringResponse MakeStringResponse(http::status status, std::string_view body, unsigned http_version, +StringResponse MakeStringResponse(http::status status, + std::string_view body, + unsigned http_version, bool keep_alive, std::string_view content_type = ContentType::TEXT_HTML) { @@ -46,7 +48,10 @@ StringResponse MakeStringResponse(http::status status, std::string_view body, un StringResponse HandleRequest(StringRequest&& req) { // Подставьте сюда код из синхронной версии HTTP-сервера - return MakeStringResponse(http::status::ok, "OK"sv, req.version(), req.keep_alive()); + return MakeStringResponse(http::status::ok, + "OK"sv, + req.version(), + req.keep_alive()); } // Запускает функцию fn на n потоках, включая текущий @@ -71,21 +76,24 @@ int main() const unsigned num_threads = std::thread::hardware_concurrency(); net::io_context ioc(num_threads); - tcp::acceptor acceptor(net::make_strand(ioc)); + tcp::acceptor acceptor(net::make_strand(ioc)); // Подписываемся на сигналы и при их получении завершаем работу сервера net::signal_set signals(ioc, SIGINT, SIGTERM); - signals.async_wait([&ioc](const sys::error_code& ec, [[maybe_unused]] int signal_number) + signals.async_wait([&ioc](const sys::error_code& ec, + [[maybe_unused]] int signal_number) { if (!ec) { - cout << "Signal "sv << signal_number << " received"sv << endl; + cout << "Signal "sv << signal_number << " received"sv + << endl; ioc.stop(); } }); const auto address = net::ip::make_address("0.0.0.0"); - constexpr net::ip::port_type port = 8080; + constexpr + net::ip::port_type port = 8080; http_server::ServeHttp(ioc, {address, port}, [](auto&& req, auto&& sender) { sender(HandleRequest(std::forward(req))); diff --git a/src/http_server.h b/src/http_server.h index 72ed644..089cca9 100644 --- a/src/http_server.h +++ b/src/http_server.h @@ -14,10 +14,14 @@ namespace http_server { template -void ServeHttp(net::io_context& ioc, const tcp::endpoint& endpoint, RequestHandler&& handler) +void ServeHttp(net::io_context& ioc, + const tcp::endpoint& endpoint, + RequestHandler&& handler) { - using MyListener = Listener>; + using MyListener = Listener>; - std::make_shared(ioc, endpoint, std::forward(handler))->Run(); + std::make_shared(ioc, + endpoint, + std::forward(handler))->Run(); } } diff --git a/src/session.h b/src/session.h index 4d378df..4f8c613 100644 --- a/src/session.h +++ b/src/session.h @@ -10,22 +10,25 @@ #include "session_base.h" -namespace http_server { +namespace http_server +{ namespace net = boost::asio; using tcp = net::ip::tcp; namespace beast = boost::beast; namespace http = beast::http; -template -class Session : public SessionBase, public std::enable_shared_from_this> { +template +class Session + : public SessionBase, + public std::enable_shared_from_this> +{ RequestHandler request_handler_; public: template Session(tcp::socket&& socket, Handler&& request_handler) - : SessionBase(std::move(socket)), request_handler_(request_handler) - {} + : SessionBase(std::move(socket)), request_handler_(request_handler) {} std::shared_ptr GetSharedThis() override { @@ -33,13 +36,16 @@ class Session : public SessionBase, public std::enable_shared_from_thisshared_from_this()](auto&& response) { - self->Write(std::move(response)); - }); + request_handler_(std::move(request), + [self = this->shared_from_this()](auto&& response) + { + self->Write(std::move(response)); + }); } }; } // namespace http_server \ No newline at end of file diff --git a/src/session_base.cpp b/src/session_base.cpp index 6db3fce..01a264b 100644 --- a/src/session_base.cpp +++ b/src/session_base.cpp @@ -27,7 +27,8 @@ void SessionBase::Read() request_ = {}; stream_.expires_after(30s); http::async_read(stream_, buffer_, request_, - beast::bind_front_handler(&SessionBase::OnRead, GetSharedThis())); + beast::bind_front_handler(&SessionBase::OnRead, + GetSharedThis())); } void SessionBase::OnRead(beast::error_code ec, size_t bytes_read) { @@ -54,11 +55,13 @@ void SessionBase::OnWrite(bool close, boost::beast::error_code ec, std::size_t bytes_written) { - if (ec) { + if (ec) + { return ReportError(ec, "write"sv); } - if (close) { + if (close) + { // Семантика ответа требует закрыть соединение return Close(); } diff --git a/src/session_base.h b/src/session_base.h index 7441d69..0103bcd 100644 --- a/src/session_base.h +++ b/src/session_base.h @@ -11,8 +11,8 @@ #include #include -namespace http_server { - +namespace http_server +{ namespace net = boost::asio; using tcp = net::ip::tcp; namespace beast = boost::beast; @@ -22,7 +22,8 @@ using namespace std::literals; void ReportError(beast::error_code ec, std::string_view what); -class SessionBase { +class SessionBase +{ protected: using HttpRequest = http::request; @@ -40,22 +41,28 @@ class SessionBase { protected: explicit SessionBase(tcp::socket&& socket); - template - void Write(http::response&& response) { + template + void Write(http::response&& response) + { // Запись выполняется асинхронно, поэтому response перемещаем в область кучи - auto safe_response = std::make_shared>(std::move(response)); + auto safe_response = std::make_shared < http::response + < Body, Fields>>(std::move(response)); auto self = GetSharedThis(); http::async_write(stream_, *safe_response, - [safe_response, self](beast::error_code ec, std::size_t bytes_written) { - self->OnWrite(safe_response->need_eof(), ec, bytes_written); + [safe_response, self](beast::error_code ec, + std::size_t bytes_written) + { + self->OnWrite(safe_response->need_eof(), + ec, + bytes_written); }); } private: - beast::tcp_stream stream_; + beast::tcp_stream stream_; beast::flat_buffer buffer_; - HttpRequest request_; + HttpRequest request_; void OnRead(beast::error_code ec, [[maybe_unused]] size_t bytes_read); @@ -63,6 +70,8 @@ class SessionBase { virtual void HandleRequest(HttpRequest&& request) = 0; - void OnWrite(bool close, beast::error_code ec, [[maybe_unused]] std::size_t bytes_written); + void OnWrite(bool close, + beast::error_code ec, + [[maybe_unused]] std::size_t bytes_written); }; } // namespace http_server \ No newline at end of file