diff options
Diffstat (limited to 'src/web_service/web_backend.cpp')
-rw-r--r-- | src/web_service/web_backend.cpp | 85 |
1 files changed, 34 insertions, 51 deletions
diff --git a/src/web_service/web_backend.cpp b/src/web_service/web_backend.cpp index 737ffe409b..67183e64c5 100644 --- a/src/web_service/web_backend.cpp +++ b/src/web_service/web_backend.cpp @@ -6,21 +6,18 @@ #include <cstdlib> #include <mutex> #include <string> -#include <LUrlParser.h> + #include <fmt/format.h> #include <httplib.h> -#include "common/common_types.h" + #include "common/logging/log.h" -#include "common/web_result.h" #include "web_service/web_backend.h" +#include "web_service/web_result.h" namespace WebService { constexpr std::array<const char, 1> API_VERSION{'1'}; -constexpr int HTTP_PORT = 80; -constexpr int HTTPS_PORT = 443; - constexpr std::size_t TIMEOUT_SECONDS = 30; struct Client::Impl { @@ -33,17 +30,16 @@ struct Client::Impl { } /// A generic function handles POST, GET and DELETE request together - Common::WebResult GenericRequest(const std::string& method, const std::string& path, - const std::string& data, bool allow_anonymous, - const std::string& accept) { + WebResult GenericRequest(const std::string& method, const std::string& path, + const std::string& data, bool allow_anonymous, + const std::string& accept) { if (jwt.empty()) { UpdateJWT(); } if (jwt.empty() && !allow_anonymous) { LOG_ERROR(WebService, "Credentials must be provided for authenticated requests"); - return Common::WebResult{Common::WebResult::Code::CredentialsMissing, - "Credentials needed"}; + return WebResult{WebResult::Code::CredentialsMissing, "Credentials needed", ""}; } auto result = GenericRequest(method, path, data, accept, jwt); @@ -62,33 +58,22 @@ struct Client::Impl { * username + token is used if jwt is empty but username and token are * not empty anonymous if all of jwt, username and token are empty */ - Common::WebResult GenericRequest(const std::string& method, const std::string& path, - const std::string& data, const std::string& accept, - const std::string& jwt = "", const std::string& username = "", - const std::string& token = "") { + WebResult GenericRequest(const std::string& method, const std::string& path, + const std::string& data, const std::string& accept, + const std::string& jwt = "", const std::string& username = "", + const std::string& token = "") { if (cli == nullptr) { - auto parsedUrl = LUrlParser::clParseURL::ParseURL(host); - int port; - if (parsedUrl.m_Scheme == "http") { - if (!parsedUrl.GetPort(&port)) { - port = HTTP_PORT; - } - cli = std::make_unique<httplib::Client>(parsedUrl.m_Host.c_str(), port); - } else if (parsedUrl.m_Scheme == "https") { - if (!parsedUrl.GetPort(&port)) { - port = HTTPS_PORT; - } - cli = std::make_unique<httplib::SSLClient>(parsedUrl.m_Host.c_str(), port); - } else { - LOG_ERROR(WebService, "Bad URL scheme {}", parsedUrl.m_Scheme); - return Common::WebResult{Common::WebResult::Code::InvalidURL, "Bad URL scheme"}; - } + cli = std::make_unique<httplib::Client>(host.c_str()); } - if (cli == nullptr) { - LOG_ERROR(WebService, "Invalid URL {}", host + path); - return Common::WebResult{Common::WebResult::Code::InvalidURL, "Invalid URL"}; + + if (!cli->is_valid()) { + LOG_ERROR(WebService, "Client is invalid, skipping request!"); + return {}; } - cli->set_timeout_sec(TIMEOUT_SECONDS); + + cli->set_connection_timeout(TIMEOUT_SECONDS); + cli->set_read_timeout(TIMEOUT_SECONDS); + cli->set_write_timeout(TIMEOUT_SECONDS); httplib::Headers params; if (!jwt.empty()) { @@ -106,7 +91,7 @@ struct Client::Impl { std::string(API_VERSION.begin(), API_VERSION.end())); if (method != "GET") { params.emplace(std::string("Content-Type"), std::string("application/json")); - }; + } httplib::Request request; request.method = method; @@ -118,29 +103,28 @@ struct Client::Impl { if (!cli->send(request, response)) { LOG_ERROR(WebService, "{} to {} returned null", method, host + path); - return Common::WebResult{Common::WebResult::Code::LibError, "Null response"}; + return WebResult{WebResult::Code::LibError, "Null response", ""}; } if (response.status >= 400) { LOG_ERROR(WebService, "{} to {} returned error status code: {}", method, host + path, response.status); - return Common::WebResult{Common::WebResult::Code::HttpError, - std::to_string(response.status)}; + return WebResult{WebResult::Code::HttpError, std::to_string(response.status), ""}; } auto content_type = response.headers.find("content-type"); if (content_type == response.headers.end()) { LOG_ERROR(WebService, "{} to {} returned no content", method, host + path); - return Common::WebResult{Common::WebResult::Code::WrongContent, ""}; + return WebResult{WebResult::Code::WrongContent, "", ""}; } if (content_type->second.find(accept) == std::string::npos) { LOG_ERROR(WebService, "{} to {} returned wrong content: {}", method, host + path, content_type->second); - return Common::WebResult{Common::WebResult::Code::WrongContent, "Wrong content"}; + return WebResult{WebResult::Code::WrongContent, "Wrong content", ""}; } - return Common::WebResult{Common::WebResult::Code::Success, "", response.body}; + return WebResult{WebResult::Code::Success, "", response.body}; } // Retrieve a new JWT from given username and token @@ -150,7 +134,7 @@ struct Client::Impl { } auto result = GenericRequest("POST", "/jwt/internal", "", "text/html", "", username, token); - if (result.result_code != Common::WebResult::Code::Success) { + if (result.result_code != WebResult::Code::Success) { LOG_ERROR(WebService, "UpdateJWT failed"); } else { std::lock_guard lock{jwt_cache.mutex}; @@ -180,29 +164,28 @@ Client::Client(std::string host, std::string username, std::string token) Client::~Client() = default; -Common::WebResult Client::PostJson(const std::string& path, const std::string& data, - bool allow_anonymous) { +WebResult Client::PostJson(const std::string& path, const std::string& data, bool allow_anonymous) { return impl->GenericRequest("POST", path, data, allow_anonymous, "application/json"); } -Common::WebResult Client::GetJson(const std::string& path, bool allow_anonymous) { +WebResult Client::GetJson(const std::string& path, bool allow_anonymous) { return impl->GenericRequest("GET", path, "", allow_anonymous, "application/json"); } -Common::WebResult Client::DeleteJson(const std::string& path, const std::string& data, - bool allow_anonymous) { +WebResult Client::DeleteJson(const std::string& path, const std::string& data, + bool allow_anonymous) { return impl->GenericRequest("DELETE", path, data, allow_anonymous, "application/json"); } -Common::WebResult Client::GetPlain(const std::string& path, bool allow_anonymous) { +WebResult Client::GetPlain(const std::string& path, bool allow_anonymous) { return impl->GenericRequest("GET", path, "", allow_anonymous, "text/plain"); } -Common::WebResult Client::GetImage(const std::string& path, bool allow_anonymous) { +WebResult Client::GetImage(const std::string& path, bool allow_anonymous) { return impl->GenericRequest("GET", path, "", allow_anonymous, "image/png"); } -Common::WebResult Client::GetExternalJWT(const std::string& audience) { +WebResult Client::GetExternalJWT(const std::string& audience) { return impl->GenericRequest("POST", fmt::format("/jwt/external/{}", audience), "", false, "text/html"); } |