aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/cpr/test/abstractServer.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/cpr/test/abstractServer.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/external_dependencies/cpr/test/abstractServer.cpp')
-rw-r--r--Src/external_dependencies/cpr/test/abstractServer.cpp143
1 files changed, 143 insertions, 0 deletions
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<std::thread>(&AbstractServer::Run, this);
+ serverThread->detach();
+ std::unique_lock<std::mutex> server_lock(server_mutex);
+ server_start_cv.wait(server_lock);
+}
+
+void AbstractServer::Stop() {
+ should_run = false;
+ std::unique_lock<std::mutex> 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<AbstractServer*>(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<AbstractServer*>(context);
+ server->OnRequest(conn, static_cast<mg_http_message*>(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<int> T(256, -1);
+ for (size_t i = 0; i < 64; i++)
+ T[base64_chars[i]] = static_cast<int>(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