From aca5c81168ed5d17376e36e3e4f6f749bcdd9d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D1=82=D0=BE=D0=BD?= Date: Thu, 21 Nov 2024 22:04:07 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A1=D1=82=D0=B0=D0=BD=D0=B4=D0=B0=D1=80?= =?UTF-8?q?=D1=82=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20req=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=8A=D0=B5=D0=BA=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 1 + src/RequestHandlers/BasicRequestHandler.cpp | 96 +++++++++++++++++++++ src/RequestHandlers/BasicRequestHandler.h | 86 +----------------- 3 files changed, 99 insertions(+), 84 deletions(-) create mode 100644 src/RequestHandlers/BasicRequestHandler.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f67e14..0cfe699 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,5 +22,6 @@ add_executable(application src/main.cpp src/Session.cpp src/Listener.h src/Listener.cpp + src/RequestHandlers/BasicRequestHandler.cpp src/RequestHandlers/BasicRequestHandler.h) target_link_libraries(application PRIVATE Threads::Threads) \ No newline at end of file diff --git a/src/RequestHandlers/BasicRequestHandler.cpp b/src/RequestHandlers/BasicRequestHandler.cpp new file mode 100644 index 0000000..9aa7349 --- /dev/null +++ b/src/RequestHandlers/BasicRequestHandler.cpp @@ -0,0 +1,96 @@ +#include "BasicRequestHandler.h" + +#include + +namespace uad +{ +namespace beast = boost::beast; +namespace http = beast::http; +namespace net = boost::asio; + +http::message_generator HandleRequest( + beast::string_view doc_root, + http::request&& req) +{ + auto const bad_request = + [&req](beast::string_view why) + { + http::response res {http::status::bad_request, req.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, "text/html"); + res.keep_alive(req.keep_alive()); + res.body() = std::string(why); + res.prepare_payload(); + return res; + }; + + auto const not_found = + [&req](beast::string_view target) + { + http::response res {http::status::not_found, req.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, "text/html"); + res.keep_alive(req.keep_alive()); + res.body() = "The resource '" + std::string(target) + "' was not found."; + res.prepare_payload(); + return res; + }; + + auto const server_error = + [&req](beast::string_view what) + { + http::response res {http::status::internal_server_error, req.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, "text/html"); + res.keep_alive(req.keep_alive()); + res.body() = "An error occurred: '" + std::string(what) + "'"; + res.prepare_payload(); + return res; + }; + + if (req.method() != http::verb::get && + req.method() != http::verb::head) + return bad_request("Unknown HTTP-method"); + + if (req.target().empty() || + req.target()[0] != '/' || + req.target().find("..") != beast::string_view::npos) + return bad_request("Illegal request-target"); + + std::string path = PathCat(doc_root, req.target()); + if (req.target().back() == '/') + path.append("index.html"); + + beast::error_code ec; + http::file_body::value_type body; + body.open(path.c_str(), beast::file_mode::scan, ec); + + if (ec == beast::errc::no_such_file_or_directory) + return not_found(req.target()); + + if (ec) + return server_error(ec.message()); + + auto const size = body.size(); + + if (req.method() == http::verb::head) + { + http::response res {http::status::ok, req.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, MimeType(path)); + res.content_length(size); + res.keep_alive(req.keep_alive()); + return res; + } + + http::response res { + std::piecewise_construct, + std::make_tuple(std::move(body)), + std::make_tuple(http::status::ok, req.version())}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, MimeType(path)); + res.content_length(size); + res.keep_alive(req.keep_alive()); + return res; +} +} diff --git a/src/RequestHandlers/BasicRequestHandler.h b/src/RequestHandlers/BasicRequestHandler.h index 97e8287..0d6b263 100644 --- a/src/RequestHandlers/BasicRequestHandler.h +++ b/src/RequestHandlers/BasicRequestHandler.h @@ -14,6 +14,7 @@ #include #include #include +#include #include "./../helpers.h" @@ -23,90 +24,7 @@ namespace beast = boost::beast; namespace http = beast::http; namespace net = boost::asio; -template http::message_generator HandleRequest( beast::string_view doc_root, - http::request>&& req) -{ - auto const bad_request = - [&req](beast::string_view why) - { - http::response res {http::status::bad_request, req.version()}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, "text/html"); - res.keep_alive(req.keep_alive()); - res.body() = std::string(why); - res.prepare_payload(); - return res; - }; - - auto const not_found = - [&req](beast::string_view target) - { - http::response res {http::status::not_found, req.version()}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, "text/html"); - res.keep_alive(req.keep_alive()); - res.body() = "The resource '" + std::string(target) + "' was not found."; - res.prepare_payload(); - return res; - }; - - auto const server_error = - [&req](beast::string_view what) - { - http::response res {http::status::internal_server_error, req.version()}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, "text/html"); - res.keep_alive(req.keep_alive()); - res.body() = "An error occurred: '" + std::string(what) + "'"; - res.prepare_payload(); - return res; - }; - - if (req.method() != http::verb::get && - req.method() != http::verb::head) - return bad_request("Unknown HTTP-method"); - - if (req.target().empty() || - req.target()[0] != '/' || - req.target().find("..") != beast::string_view::npos) - return bad_request("Illegal request-target"); - - std::string path = PathCat(doc_root, req.target()); - if (req.target().back() == '/') - path.append("index.html"); - - beast::error_code ec; - http::file_body::value_type body; - body.open(path.c_str(), beast::file_mode::scan, ec); - - if (ec == beast::errc::no_such_file_or_directory) - return not_found(req.target()); - - if (ec) - return server_error(ec.message()); - - auto const size = body.size(); - - if (req.method() == http::verb::head) - { - http::response res {http::status::ok, req.version()}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, MimeType(path)); - res.content_length(size); - res.keep_alive(req.keep_alive()); - return res; - } - - http::response res { - std::piecewise_construct, - std::make_tuple(std::move(body)), - std::make_tuple(http::status::ok, req.version())}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, MimeType(path)); - res.content_length(size); - res.keep_alive(req.keep_alive()); - return res; -} + http::request&& req); }