diff --git a/lib/remote/actionshandler.cpp b/lib/remote/actionshandler.cpp index 5ae5fdc80..f0fd713b1 100644 --- a/lib/remote/actionshandler.cpp +++ b/lib/remote/actionshandler.cpp @@ -18,16 +18,16 @@ REGISTER_URLHANDLER("/v1/actions", ActionsHandler); bool ActionsHandler::HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); if (url->GetPath().size() != 3) return false; diff --git a/lib/remote/actionshandler.hpp b/lib/remote/actionshandler.hpp index fbf716797..83132eeec 100644 --- a/lib/remote/actionshandler.hpp +++ b/lib/remote/actionshandler.hpp @@ -18,11 +18,8 @@ public: bool HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) override; diff --git a/lib/remote/configfileshandler.cpp b/lib/remote/configfileshandler.cpp index 6c390e804..9ef940a35 100644 --- a/lib/remote/configfileshandler.cpp +++ b/lib/remote/configfileshandler.cpp @@ -16,17 +16,18 @@ REGISTER_URLHANDLER("/v1/config/files", ConfigFilesHandler); bool ConfigFilesHandler::HandleRequest( const WaitGroup::Ptr&, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + if (request.method() != http::verb::get) return false; @@ -81,11 +82,9 @@ bool ConfigFilesHandler::HandleRequest( std::ifstream fp(path.CStr(), std::ifstream::in | std::ifstream::binary); fp.exceptions(std::ifstream::badbit); - String content((std::istreambuf_iterator(fp)), std::istreambuf_iterator()); response.result(http::status::ok); response.set(http::field::content_type, "application/octet-stream"); - response.body() = content; - response.content_length(response.body().size()); + response.body() << fp.rdbuf(); } catch (const std::exception& ex) { HttpUtility::SendJsonError(response, params, 500, "Could not read file.", DiagnosticInformation(ex)); diff --git a/lib/remote/configfileshandler.hpp b/lib/remote/configfileshandler.hpp index a8826d8c1..0bb12488d 100644 --- a/lib/remote/configfileshandler.hpp +++ b/lib/remote/configfileshandler.hpp @@ -16,11 +16,8 @@ public: bool HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) override; diff --git a/lib/remote/configpackageshandler.cpp b/lib/remote/configpackageshandler.cpp index 7987092bc..9b785ec2d 100644 --- a/lib/remote/configpackageshandler.cpp +++ b/lib/remote/configpackageshandler.cpp @@ -13,42 +13,41 @@ REGISTER_URLHANDLER("/v1/config/packages", ConfigPackagesHandler); bool ConfigPackagesHandler::HandleRequest( const WaitGroup::Ptr&, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + if (url->GetPath().size() > 4) return false; if (request.method() == http::verb::get) - HandleGet(user, request, url, response, params); + HandleGet(request, response); else if (request.method() == http::verb::post) - HandlePost(user, request, url, response, params); + HandlePost(request, response); else if (request.method() == http::verb::delete_) - HandleDelete(user, request, url, response, params); + HandleDelete(request, response); else return false; return true; } -void ConfigPackagesHandler::HandleGet( - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params -) +void ConfigPackagesHandler::HandleGet(const HttpRequest& request, HttpResponse& response) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + FilterUtility::CheckPermission(user, "config/query"); std::vector packages; @@ -89,16 +88,14 @@ void ConfigPackagesHandler::HandleGet( HttpUtility::SendJsonBody(response, params, result); } -void ConfigPackagesHandler::HandlePost( - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params -) +void ConfigPackagesHandler::HandlePost(const HttpRequest& request, HttpResponse& response) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + FilterUtility::CheckPermission(user, "config/modify"); if (url->GetPath().size() >= 4) @@ -135,16 +132,14 @@ void ConfigPackagesHandler::HandlePost( HttpUtility::SendJsonBody(response, params, result); } -void ConfigPackagesHandler::HandleDelete( - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params -) +void ConfigPackagesHandler::HandleDelete(const HttpRequest& request, HttpResponse& response) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + FilterUtility::CheckPermission(user, "config/modify"); if (url->GetPath().size() >= 4) diff --git a/lib/remote/configpackageshandler.hpp b/lib/remote/configpackageshandler.hpp index 2bae0e265..95bcfacbc 100644 --- a/lib/remote/configpackageshandler.hpp +++ b/lib/remote/configpackageshandler.hpp @@ -16,37 +16,16 @@ public: bool HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) override; private: - void HandleGet( - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params - ); - void HandlePost( - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params - ); - void HandleDelete( - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params - ); + void HandleGet(const HttpRequest& request, HttpResponse& response); + void HandlePost(const HttpRequest& request, HttpResponse& response); + void HandleDelete(const HttpRequest& request, HttpResponse& response); }; diff --git a/lib/remote/configstageshandler.cpp b/lib/remote/configstageshandler.cpp index 0dee5f25f..116c65248 100644 --- a/lib/remote/configstageshandler.cpp +++ b/lib/remote/configstageshandler.cpp @@ -17,42 +17,41 @@ std::atomic ConfigStagesHandler::m_RunningPackageUpdates (false); bool ConfigStagesHandler::HandleRequest( const WaitGroup::Ptr&, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + if (url->GetPath().size() > 5) return false; if (request.method() == http::verb::get) - HandleGet(user, request, url, response, params); + HandleGet(request, response); else if (request.method() == http::verb::post) - HandlePost(user, request, url, response, params); + HandlePost(request, response); else if (request.method() == http::verb::delete_) - HandleDelete(user, request, url, response, params); + HandleDelete(request, response); else return false; return true; } -void ConfigStagesHandler::HandleGet( - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params -) +void ConfigStagesHandler::HandleGet(const HttpRequest& request, HttpResponse& response) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + FilterUtility::CheckPermission(user, "config/query"); if (url->GetPath().size() >= 4) @@ -91,16 +90,14 @@ void ConfigStagesHandler::HandleGet( HttpUtility::SendJsonBody(response, params, result); } -void ConfigStagesHandler::HandlePost( - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params -) +void ConfigStagesHandler::HandlePost(const HttpRequest& request, HttpResponse& response) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + FilterUtility::CheckPermission(user, "config/modify"); if (url->GetPath().size() >= 4) @@ -174,16 +171,14 @@ void ConfigStagesHandler::HandlePost( HttpUtility::SendJsonBody(response, params, result); } -void ConfigStagesHandler::HandleDelete( - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params -) +void ConfigStagesHandler::HandleDelete(const HttpRequest& request, HttpResponse& response) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + FilterUtility::CheckPermission(user, "config/modify"); if (url->GetPath().size() >= 4) diff --git a/lib/remote/configstageshandler.hpp b/lib/remote/configstageshandler.hpp index a26ddc49c..6dd644f05 100644 --- a/lib/remote/configstageshandler.hpp +++ b/lib/remote/configstageshandler.hpp @@ -17,37 +17,16 @@ public: bool HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) override; private: - void HandleGet( - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params - ); - void HandlePost( - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params - ); - void HandleDelete( - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params - ); + void HandleGet(const HttpRequest& request, HttpResponse& response); + void HandlePost(const HttpRequest& request, HttpResponse& response); + void HandleDelete(const HttpRequest& request, HttpResponse& response); static std::atomic m_RunningPackageUpdates; }; diff --git a/lib/remote/consolehandler.cpp b/lib/remote/consolehandler.cpp index c48821aae..c063e5781 100644 --- a/lib/remote/consolehandler.cpp +++ b/lib/remote/consolehandler.cpp @@ -56,17 +56,18 @@ static void EnsureFrameCleanupTimer() bool ConsoleHandler::HandleRequest( const WaitGroup::Ptr&, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + if (url->GetPath().size() != 3) return false; @@ -96,17 +97,16 @@ bool ConsoleHandler::HandleRequest( } if (methodName == "execute-script") - return ExecuteScriptHelper(request, response, params, command, session, sandboxed); + return ExecuteScriptHelper(request, response, command, session, sandboxed); else if (methodName == "auto-complete-script") - return AutocompleteScriptHelper(request, response, params, command, session, sandboxed); + return AutocompleteScriptHelper(request, response, command, session, sandboxed); HttpUtility::SendJsonError(response, params, 400, "Invalid method specified: " + methodName); return true; } -bool ConsoleHandler::ExecuteScriptHelper(boost::beast::http::request& request, - boost::beast::http::response& response, - const Dictionary::Ptr& params, const String& command, const String& session, bool sandboxed) +bool ConsoleHandler::ExecuteScriptHelper(const HttpRequest& request, HttpResponse& response, + const String& command, const String& session, bool sandboxed) { namespace http = boost::beast::http; @@ -174,14 +174,13 @@ bool ConsoleHandler::ExecuteScriptHelper(boost::beast::http::request& request, - boost::beast::http::response& response, - const Dictionary::Ptr& params, const String& command, const String& session, bool sandboxed) +bool ConsoleHandler::AutocompleteScriptHelper(const HttpRequest& request, HttpResponse& response, + const String& command, const String& session, bool sandboxed) { namespace http = boost::beast::http; @@ -213,7 +212,7 @@ bool ConsoleHandler::AutocompleteScriptHelper(boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) override; @@ -37,12 +34,10 @@ public: static std::vector GetAutocompletionSuggestions(const String& word, ScriptFrame& frame); private: - static bool ExecuteScriptHelper(boost::beast::http::request& request, - boost::beast::http::response& response, - const Dictionary::Ptr& params, const String& command, const String& session, bool sandboxed); - static bool AutocompleteScriptHelper(boost::beast::http::request& request, - boost::beast::http::response& response, - const Dictionary::Ptr& params, const String& command, const String& session, bool sandboxed); + static bool ExecuteScriptHelper(const HttpRequest& request, HttpResponse& response, + const String& command, const String& session, bool sandboxed); + static bool AutocompleteScriptHelper(const HttpRequest& request, HttpResponse& response, + const String& command, const String& session, bool sandboxed); }; diff --git a/lib/remote/createobjecthandler.cpp b/lib/remote/createobjecthandler.cpp index 119be1cd9..447b74c6d 100644 --- a/lib/remote/createobjecthandler.cpp +++ b/lib/remote/createobjecthandler.cpp @@ -18,17 +18,18 @@ REGISTER_URLHANDLER("/v1/objects", CreateObjectHandler); bool CreateObjectHandler::HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + if (url->GetPath().size() != 4) return false; diff --git a/lib/remote/createobjecthandler.hpp b/lib/remote/createobjecthandler.hpp index 3f6a705c2..317cf023c 100644 --- a/lib/remote/createobjecthandler.hpp +++ b/lib/remote/createobjecthandler.hpp @@ -16,11 +16,8 @@ public: bool HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) override; diff --git a/lib/remote/deleteobjecthandler.cpp b/lib/remote/deleteobjecthandler.cpp index 54d31f13d..d0f49f83c 100644 --- a/lib/remote/deleteobjecthandler.cpp +++ b/lib/remote/deleteobjecthandler.cpp @@ -18,17 +18,18 @@ REGISTER_URLHANDLER("/v1/objects", DeleteObjectHandler); bool DeleteObjectHandler::HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + if (url->GetPath().size() < 3 || url->GetPath().size() > 4) return false; diff --git a/lib/remote/deleteobjecthandler.hpp b/lib/remote/deleteobjecthandler.hpp index 0f9643277..076f76704 100644 --- a/lib/remote/deleteobjecthandler.hpp +++ b/lib/remote/deleteobjecthandler.hpp @@ -16,11 +16,8 @@ public: bool HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) override; diff --git a/lib/remote/eventshandler.cpp b/lib/remote/eventshandler.cpp index 2cbee92f3..e90e680b5 100644 --- a/lib/remote/eventshandler.cpp +++ b/lib/remote/eventshandler.cpp @@ -42,11 +42,8 @@ const String l_ApiQuery (""); bool EventsHandler::HandleRequest( const WaitGroup::Ptr&, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) @@ -54,6 +51,10 @@ bool EventsHandler::HandleRequest( namespace asio = boost::asio; namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + if (url->GetPath().size() != 2) return false; diff --git a/lib/remote/eventshandler.hpp b/lib/remote/eventshandler.hpp index 49229733a..68a1f9844 100644 --- a/lib/remote/eventshandler.hpp +++ b/lib/remote/eventshandler.hpp @@ -17,11 +17,8 @@ public: bool HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) override; diff --git a/lib/remote/httphandler.cpp b/lib/remote/httphandler.cpp index 79571d760..5fe4f90de 100644 --- a/lib/remote/httphandler.cpp +++ b/lib/remote/httphandler.cpp @@ -49,9 +49,8 @@ void HttpHandler::Register(const Url::Ptr& url, const HttpHandler::Ptr& handler) void HttpHandler::ProcessRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - boost::beast::http::response& response, + HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) @@ -59,8 +58,8 @@ void HttpHandler::ProcessRequest( Dictionary::Ptr node = m_UrlTree; std::vector handlers; - Url::Ptr url = new Url(std::string(request.target())); - auto& path (url->GetPath()); + request.DecodeUrl(); + auto& path (request.Url()->GetPath()); for (std::vector::size_type i = 0; i <= path.size(); i++) { Array::Ptr current_handlers = node->Get("handlers"); @@ -90,12 +89,10 @@ void HttpHandler::ProcessRequest( std::reverse(handlers.begin(), handlers.end()); - Dictionary::Ptr params; - try { - params = HttpUtility::FetchRequestParameters(url, request.body()); + request.DecodeParams(); } catch (const std::exception& ex) { - HttpUtility::SendJsonError(response, params, 400, "Invalid request body: " + DiagnosticInformation(ex, false)); + HttpUtility::SendJsonError(response, request.Params(), 400, "Invalid request body: " + DiagnosticInformation(ex, false)); return; } @@ -109,12 +106,20 @@ void HttpHandler::ProcessRequest( */ try { for (const HttpHandler::Ptr& handler : handlers) { - if (handler->HandleRequest(waitGroup, stream, user, request, url, response, params, yc, server)) { + if (handler->HandleRequest(waitGroup, stream, request, response, yc, server)) { processed = true; break; } } } catch (const std::exception& ex) { + /* This means we can't send an error response because the exception was thrown + * in the middle of a streaming response. We can't send any error response, so the + * only thing we can do is propagate it up. + */ + if (response.HasSerializationStarted()) { + throw; + } + Log(LogWarning, "HttpServerConnection") << "Error while processing HTTP request: " << ex.what(); @@ -122,7 +127,7 @@ void HttpHandler::ProcessRequest( } if (!processed) { - HttpUtility::SendJsonError(response, params, 404, "The requested path '" + boost::algorithm::join(path, "/") + + HttpUtility::SendJsonError(response, request.Params(), 404, "The requested path '" + boost::algorithm::join(path, "/") + "' could not be found or the request method is not valid for this path."); return; } diff --git a/lib/remote/httphandler.hpp b/lib/remote/httphandler.hpp index ec67ae8a4..0d6bd12b8 100644 --- a/lib/remote/httphandler.hpp +++ b/lib/remote/httphandler.hpp @@ -4,8 +4,10 @@ #define HTTPHANDLER_H #include "remote/i2-remote.hpp" +#include "base/io-engine.hpp" #include "remote/url.hpp" #include "remote/httpserverconnection.hpp" +#include "remote/httpmessage.hpp" #include "remote/apiuser.hpp" #include "base/registry.hpp" #include "base/tlsstream.hpp" @@ -29,11 +31,8 @@ public: virtual bool HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) = 0; @@ -42,9 +41,8 @@ public: static void ProcessRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - boost::beast::http::response& response, + HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ); diff --git a/lib/remote/httpserverconnection.cpp b/lib/remote/httpserverconnection.cpp index 17e61f160..5bc61e458 100644 --- a/lib/remote/httpserverconnection.cpp +++ b/lib/remote/httpserverconnection.cpp @@ -129,10 +129,9 @@ bool HttpServerConnection::Disconnected() static inline bool EnsureValidHeaders( - AsioTlsStream& stream, boost::beast::flat_buffer& buf, - boost::beast::http::parser& parser, - boost::beast::http::response& response, + HttpRequest& request, + HttpResponse& response, bool& shuttingDown, boost::asio::yield_context& yc ) @@ -147,7 +146,7 @@ bool EnsureValidHeaders( boost::system::error_code ec; - http::async_read_header(stream, buf, parser, yc[ec]); + request.ParseHeader(buf, yc[ec]); if (ec) { if (ec == boost::asio::error::operation_aborted) @@ -156,7 +155,7 @@ bool EnsureValidHeaders( errorMsg = ec.message(); httpError = true; } else { - switch (parser.get().version()) { + switch (request.version()) { case 10: case 11: break; @@ -168,21 +167,16 @@ bool EnsureValidHeaders( if (!errorMsg.IsEmpty() || httpError) { response.result(http::status::bad_request); - if (!httpError && parser.get()[http::field::accept] == "application/json") { - HttpUtility::SendJsonBody(response, nullptr, new Dictionary({ - { "error", 400 }, - { "status", String("Bad Request: ") + errorMsg } - })); + if (!httpError && request[http::field::accept] == "application/json") { + HttpUtility::SendJsonError(response, nullptr, 400, "Bad Request: " + errorMsg); } else { response.set(http::field::content_type, "text/html"); - response.body() = String("

Bad Request

") + errorMsg + "

"; - response.content_length(response.body().size()); + response.body() << "

Bad Request

" << errorMsg << "

\r\n"; } response.set(http::field::connection, "close"); - http::async_write(stream, response, yc); - stream.async_flush(yc); + response.Flush(yc); return false; } @@ -192,28 +186,24 @@ bool EnsureValidHeaders( static inline void HandleExpect100( - AsioTlsStream& stream, - boost::beast::http::request& request, + const Shared::Ptr& stream, + const HttpRequest& request, boost::asio::yield_context& yc ) { namespace http = boost::beast::http; if (request[http::field::expect] == "100-continue") { - http::response response; - + HttpResponse response{stream}; response.result(http::status::continue_); - - http::async_write(stream, response, yc); - stream.async_flush(yc); + response.Flush(yc); } } static inline bool HandleAccessControl( - AsioTlsStream& stream, - boost::beast::http::request& request, - boost::beast::http::response& response, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc ) { @@ -240,12 +230,10 @@ bool HandleAccessControl( response.result(http::status::ok); response.set(http::field::access_control_allow_methods, "GET, POST, PUT, DELETE"); response.set(http::field::access_control_allow_headers, "Authorization, Content-Type, X-HTTP-Method-Override"); - response.body() = "Preflight OK"; - response.content_length(response.body().size()); + response.body() << "Preflight OK"; response.set(http::field::connection, "close"); - http::async_write(stream, response, yc); - stream.async_flush(yc); + response.Flush(yc); return false; } @@ -258,9 +246,8 @@ bool HandleAccessControl( static inline bool EnsureAcceptHeader( - AsioTlsStream& stream, - boost::beast::http::request& request, - boost::beast::http::response& response, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc ) { @@ -269,12 +256,10 @@ bool EnsureAcceptHeader( if (request.method() != http::verb::get && request[http::field::accept] != "application/json") { response.result(http::status::bad_request); response.set(http::field::content_type, "text/html"); - response.body() = "

Accept header is missing or not set to 'application/json'.

"; - response.content_length(response.body().size()); + response.body() << "

Accept header is missing or not set to 'application/json'.

\r\n"; response.set(http::field::connection, "close"); - http::async_write(stream, response, yc); - stream.async_flush(yc); + response.Flush(yc); return false; } @@ -284,16 +269,14 @@ bool EnsureAcceptHeader( static inline bool EnsureAuthenticatedUser( - AsioTlsStream& stream, - boost::beast::http::request& request, - ApiUser::Ptr& authenticatedUser, - boost::beast::http::response& response, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc ) { namespace http = boost::beast::http; - if (!authenticatedUser) { + if (!request.User()) { Log(LogWarning, "HttpServerConnection") << "Unauthorized request: " << request.method_string() << ' ' << request.target(); @@ -302,18 +285,13 @@ bool EnsureAuthenticatedUser( response.set(http::field::connection, "close"); if (request[http::field::accept] == "application/json") { - HttpUtility::SendJsonBody(response, nullptr, new Dictionary({ - { "error", 401 }, - { "status", "Unauthorized. Please check your user credentials." } - })); + HttpUtility::SendJsonError(response, nullptr, 401, "Unauthorized. Please check your user credentials."); } else { response.set(http::field::content_type, "text/html"); - response.body() = "

Unauthorized. Please check your user credentials.

"; - response.content_length(response.body().size()); + response.body() << "

Unauthorized. Please check your user credentials.

\r\n"; } - http::async_write(stream, response, yc); - stream.async_flush(yc); + response.Flush(yc); return false; } @@ -323,11 +301,9 @@ bool EnsureAuthenticatedUser( static inline bool EnsureValidBody( - AsioTlsStream& stream, boost::beast::flat_buffer& buf, - boost::beast::http::parser& parser, - ApiUser::Ptr& authenticatedUser, - boost::beast::http::response& response, + HttpRequest& request, + HttpResponse& response, bool& shuttingDown, boost::asio::yield_context& yc ) @@ -336,7 +312,7 @@ bool EnsureValidBody( { size_t maxSize = 1024 * 1024; - Array::Ptr permissions = authenticatedUser->GetPermissions(); + Array::Ptr permissions = request.User()->GetPermissions(); if (permissions) { ObjectLock olock(permissions); @@ -366,7 +342,7 @@ bool EnsureValidBody( } } - parser.body_limit(maxSize); + request.Parser().body_limit(maxSize); } if (shuttingDown) @@ -374,7 +350,7 @@ bool EnsureValidBody( boost::system::error_code ec; - http::async_read(stream, buf, parser, yc[ec]); + request.ParseBody(buf, yc[ec]); if (ec) { if (ec == boost::asio::error::operation_aborted) @@ -389,21 +365,16 @@ bool EnsureValidBody( response.result(http::status::bad_request); - if (parser.get()[http::field::accept] == "application/json") { - HttpUtility::SendJsonBody(response, nullptr, new Dictionary({ - { "error", 400 }, - { "status", String("Bad Request: ") + ec.message() } - })); + if (request[http::field::accept] == "application/json") { + HttpUtility::SendJsonError(response, nullptr, 400, "Bad Request: " + ec.message()); } else { response.set(http::field::content_type, "text/html"); - response.body() = String("

Bad Request

") + ec.message() + "

"; - response.content_length(response.body().size()); + response.body() << "

Bad Request

" << ec.message() << "

\r\n"; } response.set(http::field::connection, "close"); - http::async_write(stream, response, yc); - stream.async_flush(yc); + response.Flush(yc); return false; } @@ -414,9 +385,8 @@ bool EnsureValidBody( static inline bool ProcessRequest( AsioTlsStream& stream, - boost::beast::http::request& request, - ApiUser::Ptr& authenticatedUser, - boost::beast::http::response& response, + HttpRequest& request, + HttpResponse& response, HttpServerConnection& server, bool& hasStartedStreaming, const WaitGroup::Ptr& waitGroup, @@ -424,33 +394,27 @@ bool ProcessRequest( boost::asio::yield_context& yc ) { - namespace http = boost::beast::http; - try { // Cache the elapsed time to acquire a CPU semaphore used to detect extremely heavy workloads. auto start (std::chrono::steady_clock::now()); CpuBoundWork handlingRequest (yc); cpuBoundWorkTime = std::chrono::steady_clock::now() - start; - HttpHandler::ProcessRequest(waitGroup, stream, authenticatedUser, request, response, yc, server); + HttpHandler::ProcessRequest(waitGroup, stream, request, response, yc, server); } catch (const std::exception& ex) { if (hasStartedStreaming) { return false; } - auto sysErr (dynamic_cast(&ex)); - - if (sysErr && sysErr->code() == boost::asio::error::operation_aborted) { + /* Since we don't know the state the stream is in, we can't send an error response and + * have to just cause a disconnect here. + */ + if (response.HasSerializationStarted()) { throw; } - http::response response; - - HttpUtility::SendJsonError(response, nullptr, 500, "Unhandled exception" , DiagnosticInformation(ex)); - - http::async_write(stream, response, yc); - stream.async_flush(yc); - + HttpUtility::SendJsonError(response, request.Params(), 500, "Unhandled exception", DiagnosticInformation(ex)); + response.Flush(yc); return true; } @@ -458,8 +422,8 @@ bool ProcessRequest( return false; } - http::async_write(stream, response, yc); - stream.async_flush(yc); + response.body().Finish(); + response.Flush(yc); return true; } @@ -481,23 +445,21 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc) while (m_WaitGroup->IsLockable()) { m_Seen = Utility::GetTime(); - http::parser parser; - http::response response; + HttpRequest request(m_Stream); + HttpResponse response(m_Stream); - parser.header_limit(1024 * 1024); - parser.body_limit(-1); + request.Parser().header_limit(1024 * 1024); + request.Parser().body_limit(-1); response.set(http::field::server, l_ServerHeader); - if (!EnsureValidHeaders(*m_Stream, buf, parser, response, m_ShuttingDown, yc)) { + if (!EnsureValidHeaders(buf, request, response, m_ShuttingDown, yc)) { break; } m_Seen = Utility::GetTime(); auto start (ch::steady_clock::now()); - auto& request (parser.get()); - { auto method (http::string_to_verb(request["X-Http-Method-Override"])); @@ -506,19 +468,20 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc) } } - HandleExpect100(*m_Stream, request, yc); + HandleExpect100(m_Stream, request, yc); - auto authenticatedUser (m_ApiUser); - - if (!authenticatedUser) { - authenticatedUser = ApiUser::GetByAuthHeader(std::string(request[http::field::authorization])); + if (m_ApiUser) { + request.User(m_ApiUser); + } else { + auto user = ApiUser::GetByAuthHeader(std::string(request[http::field::authorization])); + request.User(user); } Log logMsg (LogInformation, "HttpServerConnection"); logMsg << "Request " << request.method_string() << ' ' << request.target() << " (from " << m_PeerAddress - << ", user: " << (authenticatedUser ? authenticatedUser->GetName() : "") + << ", user: " << (request.User() ? request.User()->GetName() : "") << ", agent: " << request[http::field::user_agent]; //operator[] - Returns the value for a field, or "" if it does not exist. ch::steady_clock::duration cpuBoundWorkTime(0); @@ -531,29 +494,29 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc) logMsg << " took total " << ch::duration_cast(ch::steady_clock::now() - start).count() << "ms."; }); - if (!HandleAccessControl(*m_Stream, request, response, yc)) { + if (!HandleAccessControl(request, response, yc)) { break; } - if (!EnsureAcceptHeader(*m_Stream, request, response, yc)) { + if (!EnsureAcceptHeader(request, response, yc)) { break; } - if (!EnsureAuthenticatedUser(*m_Stream, request, authenticatedUser, response, yc)) { + if (!EnsureAuthenticatedUser(request, response, yc)) { break; } - if (!EnsureValidBody(*m_Stream, buf, parser, authenticatedUser, response, m_ShuttingDown, yc)) { + if (!EnsureValidBody(buf, request, response, m_ShuttingDown, yc)) { break; } m_Seen = std::numeric_limits::max(); - if (!ProcessRequest(*m_Stream, request, authenticatedUser, response, *this, m_HasStartedStreaming, m_WaitGroup, cpuBoundWorkTime, yc)) { + if (!ProcessRequest(*m_Stream, request, response, *this, m_HasStartedStreaming, m_WaitGroup, cpuBoundWorkTime, yc)) { break; } - if (request.version() != 11 || request[http::field::connection] == "close") { + if (!request.keep_alive()) { break; } } diff --git a/lib/remote/httputility.cpp b/lib/remote/httputility.cpp index a2142e5d8..7618144e4 100644 --- a/lib/remote/httputility.cpp +++ b/lib/remote/httputility.cpp @@ -52,16 +52,15 @@ Value HttpUtility::GetLastParameter(const Dictionary::Ptr& params, const String& return arr->Get(arr->GetLength() - 1); } -void HttpUtility::SendJsonBody(boost::beast::http::response& response, const Dictionary::Ptr& params, const Value& val) +void HttpUtility::SendJsonBody(HttpResponse& response, const Dictionary::Ptr& params, const Value& val) { namespace http = boost::beast::http; response.set(http::field::content_type, "application/json"); - response.body() = JsonEncode(val, params && GetLastParameter(params, "pretty")); - response.content_length(response.body().size()); + response.GetJsonEncoder(params && GetLastParameter(params, "pretty")).Encode(val); } -void HttpUtility::SendJsonError(boost::beast::http::response& response, +void HttpUtility::SendJsonError(HttpResponse& response, const Dictionary::Ptr& params, int code, const String& info, const String& diagnosticInformation) { Dictionary::Ptr result = new Dictionary({ { "error", code } }); diff --git a/lib/remote/httputility.hpp b/lib/remote/httputility.hpp index 6465b4af9..870fe1705 100644 --- a/lib/remote/httputility.hpp +++ b/lib/remote/httputility.hpp @@ -5,7 +5,7 @@ #include "remote/url.hpp" #include "base/dictionary.hpp" -#include +#include "remote/httpmessage.hpp" #include namespace icinga @@ -23,8 +23,8 @@ public: static Dictionary::Ptr FetchRequestParameters(const Url::Ptr& url, const std::string& body); static Value GetLastParameter(const Dictionary::Ptr& params, const String& key); - static void SendJsonBody(boost::beast::http::response& response, const Dictionary::Ptr& params, const Value& val); - static void SendJsonError(boost::beast::http::response& response, const Dictionary::Ptr& params, const int code, + static void SendJsonBody(HttpResponse& response, const Dictionary::Ptr& params, const Value& val); + static void SendJsonError(HttpResponse& response, const Dictionary::Ptr& params, const int code, const String& verbose = String(), const String& diagnosticInformation = String()); }; diff --git a/lib/remote/infohandler.cpp b/lib/remote/infohandler.cpp index 5fc621cd8..243a9377c 100644 --- a/lib/remote/infohandler.cpp +++ b/lib/remote/infohandler.cpp @@ -11,17 +11,18 @@ REGISTER_URLHANDLER("/", InfoHandler); bool InfoHandler::HandleRequest( const WaitGroup::Ptr&, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + if (url->GetPath().size() > 2) return false; @@ -77,23 +78,23 @@ bool InfoHandler::HandleRequest( } else { response.set(http::field::content_type, "text/html"); - String body = "Icinga 2

Hello from Icinga 2 (Version: " + Application::GetAppVersion() + ")!

"; - body += "

You are authenticated as " + user->GetName() + ". "; + auto & body = response.body(); + body << "Icinga 2

Hello from Icinga 2 (Version: " + << Application::GetAppVersion() << ")!

" + << "

You are authenticated as " << user->GetName() << ". "; if (!permInfo.empty()) { - body += "Your user has the following permissions:

    "; + body << "Your user has the following permissions:

      "; for (const String& perm : permInfo) { - body += "
    • " + perm + "
    • "; + body << "
    • " << perm << "
    • "; } - body += "
    "; + body << "
"; } else - body += "Your user does not have any permissions.

"; + body << "Your user does not have any permissions.

"; - body += R"(

More information about API requests is available in the documentation.

)"; - response.body() = body; - response.content_length(response.body().size()); + body << R"(

More information about API requests is available in the documentation.

)"; } return true; diff --git a/lib/remote/infohandler.hpp b/lib/remote/infohandler.hpp index 7396f5ac9..f0f6499a3 100644 --- a/lib/remote/infohandler.hpp +++ b/lib/remote/infohandler.hpp @@ -16,11 +16,8 @@ public: bool HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) override; diff --git a/lib/remote/mallocinfohandler.cpp b/lib/remote/mallocinfohandler.cpp index f4c27cac4..465b47b86 100644 --- a/lib/remote/mallocinfohandler.cpp +++ b/lib/remote/mallocinfohandler.cpp @@ -20,17 +20,18 @@ REGISTER_URLHANDLER("/v1/debug/malloc_info", MallocInfoHandler); bool MallocInfoHandler::HandleRequest( const WaitGroup::Ptr&, AsioTlsStream&, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context&, HttpServerConnection& ) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + if (url->GetPath().size() != 3) { return false; } @@ -87,8 +88,7 @@ bool MallocInfoHandler::HandleRequest( response.result(200); response.set(http::field::content_type, "application/xml"); - response.body() = std::string(buf, bufSize); - response.content_length(response.body().size()); + response.body() << std::string_view(buf, bufSize); #endif /* HAVE_MALLOC_INFO */ return true; diff --git a/lib/remote/mallocinfohandler.hpp b/lib/remote/mallocinfohandler.hpp index 9648fac9f..fc32341fa 100644 --- a/lib/remote/mallocinfohandler.hpp +++ b/lib/remote/mallocinfohandler.hpp @@ -15,11 +15,8 @@ public: bool HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) override; diff --git a/lib/remote/modifyobjecthandler.cpp b/lib/remote/modifyobjecthandler.cpp index c71be6a9a..4b9157af8 100644 --- a/lib/remote/modifyobjecthandler.cpp +++ b/lib/remote/modifyobjecthandler.cpp @@ -16,17 +16,18 @@ REGISTER_URLHANDLER("/v1/objects", ModifyObjectHandler); bool ModifyObjectHandler::HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + if (url->GetPath().size() < 3 || url->GetPath().size() > 4) return false; diff --git a/lib/remote/modifyobjecthandler.hpp b/lib/remote/modifyobjecthandler.hpp index f299acd6e..32ddf176c 100644 --- a/lib/remote/modifyobjecthandler.hpp +++ b/lib/remote/modifyobjecthandler.hpp @@ -16,11 +16,8 @@ public: bool HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) override; diff --git a/lib/remote/objectqueryhandler.cpp b/lib/remote/objectqueryhandler.cpp index f6f049e4e..edc282453 100644 --- a/lib/remote/objectqueryhandler.cpp +++ b/lib/remote/objectqueryhandler.cpp @@ -91,17 +91,18 @@ Dictionary::Ptr ObjectQueryHandler::SerializeObjectAttrs(const Object::Ptr& obje bool ObjectQueryHandler::HandleRequest( const WaitGroup::Ptr&, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + if (url->GetPath().size() < 3 || url->GetPath().size() > 4) return false; diff --git a/lib/remote/objectqueryhandler.hpp b/lib/remote/objectqueryhandler.hpp index 376eb661e..d26a9e1ca 100644 --- a/lib/remote/objectqueryhandler.hpp +++ b/lib/remote/objectqueryhandler.hpp @@ -16,11 +16,8 @@ public: bool HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) override; diff --git a/lib/remote/statushandler.cpp b/lib/remote/statushandler.cpp index bf14152f8..9c597dd98 100644 --- a/lib/remote/statushandler.cpp +++ b/lib/remote/statushandler.cpp @@ -71,17 +71,18 @@ public: bool StatusHandler::HandleRequest( const WaitGroup::Ptr&, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + if (url->GetPath().size() > 3) return false; diff --git a/lib/remote/statushandler.hpp b/lib/remote/statushandler.hpp index 109fd4881..1d05347d1 100644 --- a/lib/remote/statushandler.hpp +++ b/lib/remote/statushandler.hpp @@ -16,11 +16,8 @@ public: bool HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) override; diff --git a/lib/remote/templatequeryhandler.cpp b/lib/remote/templatequeryhandler.cpp index a68ad6dad..9dceabb7b 100644 --- a/lib/remote/templatequeryhandler.cpp +++ b/lib/remote/templatequeryhandler.cpp @@ -78,17 +78,18 @@ public: bool TemplateQueryHandler::HandleRequest( const WaitGroup::Ptr&, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + if (url->GetPath().size() < 3 || url->GetPath().size() > 4) return false; diff --git a/lib/remote/templatequeryhandler.hpp b/lib/remote/templatequeryhandler.hpp index 312cf4221..c62670610 100644 --- a/lib/remote/templatequeryhandler.hpp +++ b/lib/remote/templatequeryhandler.hpp @@ -16,11 +16,8 @@ public: bool HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) override; diff --git a/lib/remote/typequeryhandler.cpp b/lib/remote/typequeryhandler.cpp index b2184344d..ce09293e0 100644 --- a/lib/remote/typequeryhandler.cpp +++ b/lib/remote/typequeryhandler.cpp @@ -49,17 +49,18 @@ public: bool TypeQueryHandler::HandleRequest( const WaitGroup::Ptr&, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + if (url->GetPath().size() > 3) return false; diff --git a/lib/remote/typequeryhandler.hpp b/lib/remote/typequeryhandler.hpp index 45cbc38ec..e0567249c 100644 --- a/lib/remote/typequeryhandler.hpp +++ b/lib/remote/typequeryhandler.hpp @@ -16,11 +16,8 @@ public: bool HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) override; diff --git a/lib/remote/variablequeryhandler.cpp b/lib/remote/variablequeryhandler.cpp index 40552dd7d..b8b62bec1 100644 --- a/lib/remote/variablequeryhandler.cpp +++ b/lib/remote/variablequeryhandler.cpp @@ -59,17 +59,18 @@ public: bool VariableQueryHandler::HandleRequest( const WaitGroup::Ptr&, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) { namespace http = boost::beast::http; + auto url = request.Url(); + auto user = request.User(); + auto params = request.Params(); + if (url->GetPath().size() > 3) return false; diff --git a/lib/remote/variablequeryhandler.hpp b/lib/remote/variablequeryhandler.hpp index d145f5b59..3b7a522ae 100644 --- a/lib/remote/variablequeryhandler.hpp +++ b/lib/remote/variablequeryhandler.hpp @@ -16,11 +16,8 @@ public: bool HandleRequest( const WaitGroup::Ptr& waitGroup, AsioTlsStream& stream, - const ApiUser::Ptr& user, - boost::beast::http::request& request, - const Url::Ptr& url, - boost::beast::http::response& response, - const Dictionary::Ptr& params, + const HttpRequest& request, + HttpResponse& response, boost::asio::yield_context& yc, HttpServerConnection& server ) override;