From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- .../cpr/test/abstractServer.cpp | 143 +++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 Src/external_dependencies/cpr/test/abstractServer.cpp (limited to 'Src/external_dependencies/cpr/test/abstractServer.cpp') diff --git a/Src/external_dependencies/cpr/test/abstractServer.cpp b/Src/external_dependencies/cpr/test/abstractServer.cpp new file mode 100644 index 00000000..bb8eaeb0 --- /dev/null +++ b/Src/external_dependencies/cpr/test/abstractServer.cpp @@ -0,0 +1,143 @@ +#include "abstractServer.hpp" + +namespace cpr { +void AbstractServer::SetUp() { + Start(); +} + +void AbstractServer::TearDown() { + Stop(); +} + +void AbstractServer::Start() { + should_run = true; + serverThread = std::make_shared(&AbstractServer::Run, this); + serverThread->detach(); + std::unique_lock server_lock(server_mutex); + server_start_cv.wait(server_lock); +} + +void AbstractServer::Stop() { + should_run = false; + std::unique_lock server_lock(server_mutex); + server_stop_cv.wait(server_lock); +} + +static void EventHandler(mg_connection* conn, int event, void* event_data, void* context) { + switch (event) { + case MG_EV_READ: + case MG_EV_WRITE: + /** Do nothing. Just for housekeeping. **/ + break; + case MG_EV_POLL: + /** Do nothing. Just for housekeeping. **/ + break; + case MG_EV_CLOSE: + /** Do nothing. Just for housekeeping. **/ + break; + case MG_EV_ACCEPT: + /* Initialize HTTPS connection if Server is an HTTPS Server */ + static_cast(context)->acceptConnection(conn); + break; + case MG_EV_CONNECT: + /** Do nothing. Just for housekeeping. **/ + break; + + case MG_EV_HTTP_CHUNK: { + /** Do nothing. Just for housekeeping. **/ + } break; + + case MG_EV_HTTP_MSG: { + AbstractServer* server = static_cast(context); + server->OnRequest(conn, static_cast(event_data)); + } break; + + default: + break; + } +} + +void AbstractServer::Run() { + // Setup a new mongoose http server. + memset(&mgr, 0, sizeof(mg_mgr)); + initServer(&mgr, EventHandler); + + // Notify the main thread that the server is up and runing: + server_start_cv.notify_all(); + + // Main server loop: + while (should_run) { + // NOLINTNEXTLINE (cppcoreguidelines-avoid-magic-numbers) + mg_mgr_poll(&mgr, 100); + } + + // Shutdown and cleanup: + timer_args.clear(); + mg_mgr_free(&mgr); + + // Notify the main thread that we have shut down everything: + server_stop_cv.notify_all(); +} + +static const std::string base64_chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; +/** + * Decodes the given BASE64 string to a normal string. + * Source: https://gist.github.com/williamdes/308b95ac9ef1ee89ae0143529c361d37 + **/ +std::string AbstractServer::Base64Decode(const std::string& in) { + std::string out; + + std::vector T(256, -1); + for (size_t i = 0; i < 64; i++) + T[base64_chars[i]] = static_cast(i); + + int val = 0; + int valb = -8; + for (unsigned char c : in) { + if (T[c] == -1) { + break; + } + val = (val << 6) + T[c]; + valb += 6; + if (valb >= 0) { + out.push_back(char((val >> valb) & 0xFF)); + valb -= 8; + } + } + return out; +} + +// Sends error similar like in mongoose 6 method mg_http_send_error +// https://github.com/cesanta/mongoose/blob/6.18/mongoose.c#L7081-L7089 +void AbstractServer::SendError(mg_connection* conn, int code, std::string& reason) { + std::string headers{"Content-Type: text/plain\r\nConnection: close\r\n"}; + mg_http_reply(conn, code, headers.c_str(), reason.c_str()); +} + +// Checks whether a pointer to a connection is still managed by a mg_mgr. +// This check tells whether it is still possible to send a message via the given connection +// Note that it is still possible that the pointer of an old connection object may be reused by mongoose. +// In this case, the active connection might refer to a different connection than the one the caller refers to +bool AbstractServer::IsConnectionActive(mg_mgr* mgr, mg_connection* conn) { + mg_connection* c{mgr->conns}; + while (c) { + if (c == conn) { + return true; + } + c = c->next; + } + return false; +} + +uint16_t AbstractServer::GetRemotePort(const mg_connection* conn) { + return (conn->rem.port >> 8) | (conn->rem.port << 8); +} + +uint16_t AbstractServer::GetLocalPort(const mg_connection* conn) { + return (conn->loc.port >> 8) | (conn->loc.port << 8); +} + +} // namespace cpr -- cgit