diff options
| -rw-r--r-- | src/common/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/web_service/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/web_service/telemetry_json.cpp | 4 | ||||
| -rw-r--r-- | src/web_service/verify_login.cpp | 2 | ||||
| -rw-r--r-- | src/web_service/web_backend.cpp | 56 | ||||
| -rw-r--r-- | src/web_service/web_backend.h | 20 | ||||
| -rw-r--r-- | src/web_service/web_result.h (renamed from src/common/web_result.h) | 4 |
7 files changed, 41 insertions, 47 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 78c3bfb3b..5d54516eb 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -172,7 +172,6 @@ add_library(common STATIC | |||
| 172 | virtual_buffer.h | 172 | virtual_buffer.h |
| 173 | wall_clock.cpp | 173 | wall_clock.cpp |
| 174 | wall_clock.h | 174 | wall_clock.h |
| 175 | web_result.h | ||
| 176 | zstd_compression.cpp | 175 | zstd_compression.cpp |
| 177 | zstd_compression.h | 176 | zstd_compression.h |
| 178 | ) | 177 | ) |
diff --git a/src/web_service/CMakeLists.txt b/src/web_service/CMakeLists.txt index 06ab7c59d..7e484b906 100644 --- a/src/web_service/CMakeLists.txt +++ b/src/web_service/CMakeLists.txt | |||
| @@ -5,6 +5,7 @@ add_library(web_service STATIC | |||
| 5 | verify_login.h | 5 | verify_login.h |
| 6 | web_backend.cpp | 6 | web_backend.cpp |
| 7 | web_backend.h | 7 | web_backend.h |
| 8 | web_result.h | ||
| 8 | ) | 9 | ) |
| 9 | 10 | ||
| 10 | create_target_directory_groups(web_service) | 11 | create_target_directory_groups(web_service) |
diff --git a/src/web_service/telemetry_json.cpp b/src/web_service/telemetry_json.cpp index c89a3a0db..6215c914f 100644 --- a/src/web_service/telemetry_json.cpp +++ b/src/web_service/telemetry_json.cpp | |||
| @@ -4,9 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | #include <nlohmann/json.hpp> | 5 | #include <nlohmann/json.hpp> |
| 6 | #include "common/detached_tasks.h" | 6 | #include "common/detached_tasks.h" |
| 7 | #include "common/web_result.h" | ||
| 8 | #include "web_service/telemetry_json.h" | 7 | #include "web_service/telemetry_json.h" |
| 9 | #include "web_service/web_backend.h" | 8 | #include "web_service/web_backend.h" |
| 9 | #include "web_service/web_result.h" | ||
| 10 | 10 | ||
| 11 | namespace WebService { | 11 | namespace WebService { |
| 12 | 12 | ||
| @@ -125,7 +125,7 @@ bool TelemetryJson::SubmitTestcase() { | |||
| 125 | Client client(impl->host, impl->username, impl->token); | 125 | Client client(impl->host, impl->username, impl->token); |
| 126 | auto value = client.PostJson("/gamedb/testcase", content, false); | 126 | auto value = client.PostJson("/gamedb/testcase", content, false); |
| 127 | 127 | ||
| 128 | return value.result_code == Common::WebResult::Code::Success; | 128 | return value.result_code == WebResult::Code::Success; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | } // namespace WebService | 131 | } // namespace WebService |
diff --git a/src/web_service/verify_login.cpp b/src/web_service/verify_login.cpp index bfaa5b70a..ceb55ca6b 100644 --- a/src/web_service/verify_login.cpp +++ b/src/web_service/verify_login.cpp | |||
| @@ -3,9 +3,9 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <nlohmann/json.hpp> | 5 | #include <nlohmann/json.hpp> |
| 6 | #include "common/web_result.h" | ||
| 7 | #include "web_service/verify_login.h" | 6 | #include "web_service/verify_login.h" |
| 8 | #include "web_service/web_backend.h" | 7 | #include "web_service/web_backend.h" |
| 8 | #include "web_service/web_result.h" | ||
| 9 | 9 | ||
| 10 | namespace WebService { | 10 | namespace WebService { |
| 11 | 11 | ||
diff --git a/src/web_service/web_backend.cpp b/src/web_service/web_backend.cpp index 09d1651ac..74e287045 100644 --- a/src/web_service/web_backend.cpp +++ b/src/web_service/web_backend.cpp | |||
| @@ -6,13 +6,14 @@ | |||
| 6 | #include <cstdlib> | 6 | #include <cstdlib> |
| 7 | #include <mutex> | 7 | #include <mutex> |
| 8 | #include <string> | 8 | #include <string> |
| 9 | |||
| 9 | #include <LUrlParser.h> | 10 | #include <LUrlParser.h> |
| 10 | #include <fmt/format.h> | 11 | #include <fmt/format.h> |
| 11 | #include <httplib.h> | 12 | #include <httplib.h> |
| 12 | #include "common/common_types.h" | 13 | |
| 13 | #include "common/logging/log.h" | 14 | #include "common/logging/log.h" |
| 14 | #include "common/web_result.h" | ||
| 15 | #include "web_service/web_backend.h" | 15 | #include "web_service/web_backend.h" |
| 16 | #include "web_service/web_result.h" | ||
| 16 | 17 | ||
| 17 | namespace WebService { | 18 | namespace WebService { |
| 18 | 19 | ||
| @@ -33,17 +34,16 @@ struct Client::Impl { | |||
| 33 | } | 34 | } |
| 34 | 35 | ||
| 35 | /// A generic function handles POST, GET and DELETE request together | 36 | /// A generic function handles POST, GET and DELETE request together |
| 36 | Common::WebResult GenericRequest(const std::string& method, const std::string& path, | 37 | WebResult GenericRequest(const std::string& method, const std::string& path, |
| 37 | const std::string& data, bool allow_anonymous, | 38 | const std::string& data, bool allow_anonymous, |
| 38 | const std::string& accept) { | 39 | const std::string& accept) { |
| 39 | if (jwt.empty()) { | 40 | if (jwt.empty()) { |
| 40 | UpdateJWT(); | 41 | UpdateJWT(); |
| 41 | } | 42 | } |
| 42 | 43 | ||
| 43 | if (jwt.empty() && !allow_anonymous) { | 44 | if (jwt.empty() && !allow_anonymous) { |
| 44 | LOG_ERROR(WebService, "Credentials must be provided for authenticated requests"); | 45 | LOG_ERROR(WebService, "Credentials must be provided for authenticated requests"); |
| 45 | return Common::WebResult{Common::WebResult::Code::CredentialsMissing, | 46 | return WebResult{WebResult::Code::CredentialsMissing, "Credentials needed", ""}; |
| 46 | "Credentials needed", ""}; | ||
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | auto result = GenericRequest(method, path, data, accept, jwt); | 49 | auto result = GenericRequest(method, path, data, accept, jwt); |
| @@ -62,10 +62,10 @@ struct Client::Impl { | |||
| 62 | * username + token is used if jwt is empty but username and token are | 62 | * username + token is used if jwt is empty but username and token are |
| 63 | * not empty anonymous if all of jwt, username and token are empty | 63 | * not empty anonymous if all of jwt, username and token are empty |
| 64 | */ | 64 | */ |
| 65 | Common::WebResult GenericRequest(const std::string& method, const std::string& path, | 65 | WebResult GenericRequest(const std::string& method, const std::string& path, |
| 66 | const std::string& data, const std::string& accept, | 66 | const std::string& data, const std::string& accept, |
| 67 | const std::string& jwt = "", const std::string& username = "", | 67 | const std::string& jwt = "", const std::string& username = "", |
| 68 | const std::string& token = "") { | 68 | const std::string& token = "") { |
| 69 | if (cli == nullptr) { | 69 | if (cli == nullptr) { |
| 70 | auto parsedUrl = LUrlParser::clParseURL::ParseURL(host); | 70 | auto parsedUrl = LUrlParser::clParseURL::ParseURL(host); |
| 71 | int port; | 71 | int port; |
| @@ -81,12 +81,12 @@ struct Client::Impl { | |||
| 81 | cli = std::make_unique<httplib::SSLClient>(parsedUrl.m_Host.c_str(), port); | 81 | cli = std::make_unique<httplib::SSLClient>(parsedUrl.m_Host.c_str(), port); |
| 82 | } else { | 82 | } else { |
| 83 | LOG_ERROR(WebService, "Bad URL scheme {}", parsedUrl.m_Scheme); | 83 | LOG_ERROR(WebService, "Bad URL scheme {}", parsedUrl.m_Scheme); |
| 84 | return Common::WebResult{Common::WebResult::Code::InvalidURL, "Bad URL scheme", ""}; | 84 | return WebResult{WebResult::Code::InvalidURL, "Bad URL scheme", ""}; |
| 85 | } | 85 | } |
| 86 | } | 86 | } |
| 87 | if (cli == nullptr) { | 87 | if (cli == nullptr) { |
| 88 | LOG_ERROR(WebService, "Invalid URL {}", host + path); | 88 | LOG_ERROR(WebService, "Invalid URL {}", host + path); |
| 89 | return Common::WebResult{Common::WebResult::Code::InvalidURL, "Invalid URL", ""}; | 89 | return WebResult{WebResult::Code::InvalidURL, "Invalid URL", ""}; |
| 90 | } | 90 | } |
| 91 | cli->set_timeout_sec(TIMEOUT_SECONDS); | 91 | cli->set_timeout_sec(TIMEOUT_SECONDS); |
| 92 | 92 | ||
| @@ -106,7 +106,7 @@ struct Client::Impl { | |||
| 106 | std::string(API_VERSION.begin(), API_VERSION.end())); | 106 | std::string(API_VERSION.begin(), API_VERSION.end())); |
| 107 | if (method != "GET") { | 107 | if (method != "GET") { |
| 108 | params.emplace(std::string("Content-Type"), std::string("application/json")); | 108 | params.emplace(std::string("Content-Type"), std::string("application/json")); |
| 109 | }; | 109 | } |
| 110 | 110 | ||
| 111 | httplib::Request request; | 111 | httplib::Request request; |
| 112 | request.method = method; | 112 | request.method = method; |
| @@ -118,29 +118,28 @@ struct Client::Impl { | |||
| 118 | 118 | ||
| 119 | if (!cli->send(request, response)) { | 119 | if (!cli->send(request, response)) { |
| 120 | LOG_ERROR(WebService, "{} to {} returned null", method, host + path); | 120 | LOG_ERROR(WebService, "{} to {} returned null", method, host + path); |
| 121 | return Common::WebResult{Common::WebResult::Code::LibError, "Null response", ""}; | 121 | return WebResult{WebResult::Code::LibError, "Null response", ""}; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | if (response.status >= 400) { | 124 | if (response.status >= 400) { |
| 125 | LOG_ERROR(WebService, "{} to {} returned error status code: {}", method, host + path, | 125 | LOG_ERROR(WebService, "{} to {} returned error status code: {}", method, host + path, |
| 126 | response.status); | 126 | response.status); |
| 127 | return Common::WebResult{Common::WebResult::Code::HttpError, | 127 | return WebResult{WebResult::Code::HttpError, std::to_string(response.status), ""}; |
| 128 | std::to_string(response.status), ""}; | ||
| 129 | } | 128 | } |
| 130 | 129 | ||
| 131 | auto content_type = response.headers.find("content-type"); | 130 | auto content_type = response.headers.find("content-type"); |
| 132 | 131 | ||
| 133 | if (content_type == response.headers.end()) { | 132 | if (content_type == response.headers.end()) { |
| 134 | LOG_ERROR(WebService, "{} to {} returned no content", method, host + path); | 133 | LOG_ERROR(WebService, "{} to {} returned no content", method, host + path); |
| 135 | return Common::WebResult{Common::WebResult::Code::WrongContent, "", ""}; | 134 | return WebResult{WebResult::Code::WrongContent, "", ""}; |
| 136 | } | 135 | } |
| 137 | 136 | ||
| 138 | if (content_type->second.find(accept) == std::string::npos) { | 137 | if (content_type->second.find(accept) == std::string::npos) { |
| 139 | LOG_ERROR(WebService, "{} to {} returned wrong content: {}", method, host + path, | 138 | LOG_ERROR(WebService, "{} to {} returned wrong content: {}", method, host + path, |
| 140 | content_type->second); | 139 | content_type->second); |
| 141 | return Common::WebResult{Common::WebResult::Code::WrongContent, "Wrong content", ""}; | 140 | return WebResult{WebResult::Code::WrongContent, "Wrong content", ""}; |
| 142 | } | 141 | } |
| 143 | return Common::WebResult{Common::WebResult::Code::Success, "", response.body}; | 142 | return WebResult{WebResult::Code::Success, "", response.body}; |
| 144 | } | 143 | } |
| 145 | 144 | ||
| 146 | // Retrieve a new JWT from given username and token | 145 | // Retrieve a new JWT from given username and token |
| @@ -150,7 +149,7 @@ struct Client::Impl { | |||
| 150 | } | 149 | } |
| 151 | 150 | ||
| 152 | auto result = GenericRequest("POST", "/jwt/internal", "", "text/html", "", username, token); | 151 | auto result = GenericRequest("POST", "/jwt/internal", "", "text/html", "", username, token); |
| 153 | if (result.result_code != Common::WebResult::Code::Success) { | 152 | if (result.result_code != WebResult::Code::Success) { |
| 154 | LOG_ERROR(WebService, "UpdateJWT failed"); | 153 | LOG_ERROR(WebService, "UpdateJWT failed"); |
| 155 | } else { | 154 | } else { |
| 156 | std::lock_guard lock{jwt_cache.mutex}; | 155 | std::lock_guard lock{jwt_cache.mutex}; |
| @@ -180,29 +179,28 @@ Client::Client(std::string host, std::string username, std::string token) | |||
| 180 | 179 | ||
| 181 | Client::~Client() = default; | 180 | Client::~Client() = default; |
| 182 | 181 | ||
| 183 | Common::WebResult Client::PostJson(const std::string& path, const std::string& data, | 182 | WebResult Client::PostJson(const std::string& path, const std::string& data, bool allow_anonymous) { |
| 184 | bool allow_anonymous) { | ||
| 185 | return impl->GenericRequest("POST", path, data, allow_anonymous, "application/json"); | 183 | return impl->GenericRequest("POST", path, data, allow_anonymous, "application/json"); |
| 186 | } | 184 | } |
| 187 | 185 | ||
| 188 | Common::WebResult Client::GetJson(const std::string& path, bool allow_anonymous) { | 186 | WebResult Client::GetJson(const std::string& path, bool allow_anonymous) { |
| 189 | return impl->GenericRequest("GET", path, "", allow_anonymous, "application/json"); | 187 | return impl->GenericRequest("GET", path, "", allow_anonymous, "application/json"); |
| 190 | } | 188 | } |
| 191 | 189 | ||
| 192 | Common::WebResult Client::DeleteJson(const std::string& path, const std::string& data, | 190 | WebResult Client::DeleteJson(const std::string& path, const std::string& data, |
| 193 | bool allow_anonymous) { | 191 | bool allow_anonymous) { |
| 194 | return impl->GenericRequest("DELETE", path, data, allow_anonymous, "application/json"); | 192 | return impl->GenericRequest("DELETE", path, data, allow_anonymous, "application/json"); |
| 195 | } | 193 | } |
| 196 | 194 | ||
| 197 | Common::WebResult Client::GetPlain(const std::string& path, bool allow_anonymous) { | 195 | WebResult Client::GetPlain(const std::string& path, bool allow_anonymous) { |
| 198 | return impl->GenericRequest("GET", path, "", allow_anonymous, "text/plain"); | 196 | return impl->GenericRequest("GET", path, "", allow_anonymous, "text/plain"); |
| 199 | } | 197 | } |
| 200 | 198 | ||
| 201 | Common::WebResult Client::GetImage(const std::string& path, bool allow_anonymous) { | 199 | WebResult Client::GetImage(const std::string& path, bool allow_anonymous) { |
| 202 | return impl->GenericRequest("GET", path, "", allow_anonymous, "image/png"); | 200 | return impl->GenericRequest("GET", path, "", allow_anonymous, "image/png"); |
| 203 | } | 201 | } |
| 204 | 202 | ||
| 205 | Common::WebResult Client::GetExternalJWT(const std::string& audience) { | 203 | WebResult Client::GetExternalJWT(const std::string& audience) { |
| 206 | return impl->GenericRequest("POST", fmt::format("/jwt/external/{}", audience), "", false, | 204 | return impl->GenericRequest("POST", fmt::format("/jwt/external/{}", audience), "", false, |
| 207 | "text/html"); | 205 | "text/html"); |
| 208 | } | 206 | } |
diff --git a/src/web_service/web_backend.h b/src/web_service/web_backend.h index 04121f17e..81f58583c 100644 --- a/src/web_service/web_backend.h +++ b/src/web_service/web_backend.h | |||
| @@ -7,12 +7,10 @@ | |||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <string> | 8 | #include <string> |
| 9 | 9 | ||
| 10 | namespace Common { | ||
| 11 | struct WebResult; | ||
| 12 | } | ||
| 13 | |||
| 14 | namespace WebService { | 10 | namespace WebService { |
| 15 | 11 | ||
| 12 | struct WebResult; | ||
| 13 | |||
| 16 | class Client { | 14 | class Client { |
| 17 | public: | 15 | public: |
| 18 | Client(std::string host, std::string username, std::string token); | 16 | Client(std::string host, std::string username, std::string token); |
| @@ -25,8 +23,7 @@ public: | |||
| 25 | * @param allow_anonymous If true, allow anonymous unauthenticated requests. | 23 | * @param allow_anonymous If true, allow anonymous unauthenticated requests. |
| 26 | * @return the result of the request. | 24 | * @return the result of the request. |
| 27 | */ | 25 | */ |
| 28 | Common::WebResult PostJson(const std::string& path, const std::string& data, | 26 | WebResult PostJson(const std::string& path, const std::string& data, bool allow_anonymous); |
| 29 | bool allow_anonymous); | ||
| 30 | 27 | ||
| 31 | /** | 28 | /** |
| 32 | * Gets JSON from the specified path. | 29 | * Gets JSON from the specified path. |
| @@ -34,7 +31,7 @@ public: | |||
| 34 | * @param allow_anonymous If true, allow anonymous unauthenticated requests. | 31 | * @param allow_anonymous If true, allow anonymous unauthenticated requests. |
| 35 | * @return the result of the request. | 32 | * @return the result of the request. |
| 36 | */ | 33 | */ |
| 37 | Common::WebResult GetJson(const std::string& path, bool allow_anonymous); | 34 | WebResult GetJson(const std::string& path, bool allow_anonymous); |
| 38 | 35 | ||
| 39 | /** | 36 | /** |
| 40 | * Deletes JSON to the specified path. | 37 | * Deletes JSON to the specified path. |
| @@ -43,8 +40,7 @@ public: | |||
| 43 | * @param allow_anonymous If true, allow anonymous unauthenticated requests. | 40 | * @param allow_anonymous If true, allow anonymous unauthenticated requests. |
| 44 | * @return the result of the request. | 41 | * @return the result of the request. |
| 45 | */ | 42 | */ |
| 46 | Common::WebResult DeleteJson(const std::string& path, const std::string& data, | 43 | WebResult DeleteJson(const std::string& path, const std::string& data, bool allow_anonymous); |
| 47 | bool allow_anonymous); | ||
| 48 | 44 | ||
| 49 | /** | 45 | /** |
| 50 | * Gets a plain string from the specified path. | 46 | * Gets a plain string from the specified path. |
| @@ -52,7 +48,7 @@ public: | |||
| 52 | * @param allow_anonymous If true, allow anonymous unauthenticated requests. | 48 | * @param allow_anonymous If true, allow anonymous unauthenticated requests. |
| 53 | * @return the result of the request. | 49 | * @return the result of the request. |
| 54 | */ | 50 | */ |
| 55 | Common::WebResult GetPlain(const std::string& path, bool allow_anonymous); | 51 | WebResult GetPlain(const std::string& path, bool allow_anonymous); |
| 56 | 52 | ||
| 57 | /** | 53 | /** |
| 58 | * Gets an PNG image from the specified path. | 54 | * Gets an PNG image from the specified path. |
| @@ -60,14 +56,14 @@ public: | |||
| 60 | * @param allow_anonymous If true, allow anonymous unauthenticated requests. | 56 | * @param allow_anonymous If true, allow anonymous unauthenticated requests. |
| 61 | * @return the result of the request. | 57 | * @return the result of the request. |
| 62 | */ | 58 | */ |
| 63 | Common::WebResult GetImage(const std::string& path, bool allow_anonymous); | 59 | WebResult GetImage(const std::string& path, bool allow_anonymous); |
| 64 | 60 | ||
| 65 | /** | 61 | /** |
| 66 | * Requests an external JWT for the specific audience provided. | 62 | * Requests an external JWT for the specific audience provided. |
| 67 | * @param audience the audience of the JWT requested. | 63 | * @param audience the audience of the JWT requested. |
| 68 | * @return the result of the request. | 64 | * @return the result of the request. |
| 69 | */ | 65 | */ |
| 70 | Common::WebResult GetExternalJWT(const std::string& audience); | 66 | WebResult GetExternalJWT(const std::string& audience); |
| 71 | 67 | ||
| 72 | private: | 68 | private: |
| 73 | struct Impl; | 69 | struct Impl; |
diff --git a/src/common/web_result.h b/src/web_service/web_result.h index 8bfa2141d..3aeeb5288 100644 --- a/src/common/web_result.h +++ b/src/web_service/web_result.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | #include <string> | 7 | #include <string> |
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | 9 | ||
| 10 | namespace Common { | 10 | namespace WebService { |
| 11 | struct WebResult { | 11 | struct WebResult { |
| 12 | enum class Code : u32 { | 12 | enum class Code : u32 { |
| 13 | Success, | 13 | Success, |
| @@ -22,4 +22,4 @@ struct WebResult { | |||
| 22 | std::string result_string; | 22 | std::string result_string; |
| 23 | std::string returned_data; | 23 | std::string returned_data; |
| 24 | }; | 24 | }; |
| 25 | } // namespace Common | 25 | } // namespace WebService |