mirror of
https://github.com/SantaSpeen/BeamMP-Server.git
synced 2026-02-16 08:20:40 +00:00
Add preliminary work for HTTP health endpoint (#68)
* Add preliminary work for HTTP health endpoint * Http: Fix infinite loop bug in Tx509KeypairGenerator::generateKey() * update commandline * Add TLS Support class for use with http server * Add preliminary HTTP Server; TLS still broken; fix in later commit * Fix TLS handshake, due to server being unable to serve key/certfile in 'Http.h/Http.cpp'; Cause was httlib not being threadsafe due to being a blocking http library * Run clang format * Add option to configure http server port via ServerConfig * TConfig: add HTTPServerPort to config parsing step * Fix SSL Cert / Key path not auto generating when not existing * Add health endpoint; Fix SSL Cert serial no. not refreshing when regenerating * Switch arround status codes in /health route * Run clang format Co-authored-by: Lion Kortlepel <development@kortlepel.com>
This commit is contained in:
@@ -40,6 +40,9 @@ public:
|
||||
, ServerDesc("BeamMP Default Description")
|
||||
, Resource("Resources")
|
||||
, MapName("/levels/gridmap_v2/info.json")
|
||||
, SSLKeyPath("./.ssl/HttpServer/key.pem")
|
||||
, SSLCertPath("./.ssl/HttpServer/cert.pem")
|
||||
, HTTPServerPort(8080)
|
||||
, MaxPlayers(10)
|
||||
, Private(true)
|
||||
, MaxCars(1)
|
||||
@@ -52,6 +55,8 @@ public:
|
||||
std::string Resource;
|
||||
std::string MapName;
|
||||
std::string Key;
|
||||
std::string SSLKeyPath;
|
||||
std::string SSLCertPath;
|
||||
int MaxPlayers;
|
||||
bool Private;
|
||||
int MaxCars;
|
||||
@@ -61,6 +66,7 @@ public:
|
||||
bool SendErrors;
|
||||
bool SendErrorsMessageEnabled;
|
||||
[[nodiscard]] bool HasCustomIP() const { return !CustomIP.empty(); }
|
||||
int HTTPServerPort;
|
||||
};
|
||||
|
||||
using TShutdownHandler = std::function<void()>;
|
||||
@@ -162,6 +168,12 @@ void RegisterThread(const std::string& str);
|
||||
Application::Console().Write(_this_location + std::string("[DEBUG] ") + (x)); \
|
||||
} \
|
||||
} while (false)
|
||||
#define beammp_event(x) \
|
||||
do { \
|
||||
if (Application::Settings.DebugModeEnabled) { \
|
||||
Application::Console().Write(_this_location + std::string("[EVENT] ") + (x)); \
|
||||
} \
|
||||
}while(false)
|
||||
// for those times when you just need to ignore something :^)
|
||||
// explicity disables a [[nodiscard]] warning
|
||||
#define beammp_ignore(x) (void)x
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <Common.h>
|
||||
#include <IThreaded.h>
|
||||
#include <filesystem>
|
||||
#include <httplib.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace Crypto {
|
||||
constexpr size_t RSA_DEFAULT_KEYLENGTH { 2048 };
|
||||
}
|
||||
|
||||
namespace Http {
|
||||
std::string GET(const std::string& host, int port, const std::string& target, unsigned int* status = nullptr);
|
||||
std::string POST(const std::string& host, int port, const std::string& target, const std::string& body, const std::string& ContentType, unsigned int* status = nullptr);
|
||||
@@ -10,4 +22,36 @@ namespace Status {
|
||||
std::string ToString(int code);
|
||||
}
|
||||
const std::string ErrorString = "-1";
|
||||
|
||||
namespace Server {
|
||||
void SetupEnvironment();
|
||||
// todo: Add non TLS Server Instance, this one is TLS only
|
||||
class THttpServerInstance : IThreaded {
|
||||
public:
|
||||
THttpServerInstance();
|
||||
static fs::path KeyFilePath;
|
||||
static fs::path CertFilePath;
|
||||
|
||||
protected:
|
||||
void operator()();
|
||||
|
||||
private:
|
||||
/**
|
||||
* the shared pointer is necessary because httplib is a blocking library and due lacking thread-safety
|
||||
* will "forget" about its environment, when configured across multiple threads.
|
||||
* So we need to able to start the server (make it "listen()") in a single Thread.
|
||||
*/
|
||||
std::shared_ptr<httplib::SSLServer> mHttpLibServerInstancePtr;
|
||||
};
|
||||
// todo: all of these functions are likely unsafe,
|
||||
// todo: replace with something that's managed by a domain specific crypto library
|
||||
class Tx509KeypairGenerator {
|
||||
public:
|
||||
static long GenerateRandomId();
|
||||
static bool EnsureTLSConfigExists();
|
||||
static X509* GenerateCertificate(EVP_PKEY& pkey);
|
||||
static EVP_PKEY* GenerateKey();
|
||||
static void GenerateAndWriteToDisk(const fs::path& KeyFilePath, const fs::path& CertFilePath);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ private:
|
||||
void PrintDebug();
|
||||
|
||||
void ParseOldFormat();
|
||||
|
||||
bool IsDefault();
|
||||
bool mFailed { false };
|
||||
std::string mConfigFileName;
|
||||
};
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
|
||||
using TLuaStateId = std::string;
|
||||
namespace fs = std::filesystem;
|
||||
/**
|
||||
* std::variant means, that TLuaArgTypes may be one of the Types listed as template args
|
||||
*/
|
||||
using TLuaArgTypes = std::variant<std::string, int, sol::variadic_args, bool>;
|
||||
static constexpr size_t TLuaArgTypes_String = 0;
|
||||
static constexpr size_t TLuaArgTypes_Int = 1;
|
||||
@@ -114,11 +117,21 @@ public:
|
||||
void EnsureStateExists(TLuaStateId StateId, const std::string& Name, bool DontCallOnInit = false);
|
||||
void RegisterEvent(const std::string& EventName, TLuaStateId StateId, const std::string& FunctionName);
|
||||
template <typename... ArgsT>
|
||||
/**
|
||||
*
|
||||
* @tparam ArgsT Template Arguments for the event (Metadata) todo: figure out what this means
|
||||
* @param EventName Name of the event
|
||||
* @param IgnoreId
|
||||
* @param Args
|
||||
* @return
|
||||
*/
|
||||
[[nodiscard]] std::vector<std::shared_ptr<TLuaResult>> TriggerEvent(const std::string& EventName, TLuaStateId IgnoreId, ArgsT&&... Args) {
|
||||
std::unique_lock Lock(mLuaEventsMutex);
|
||||
if (mLuaEvents.find(EventName) == mLuaEvents.end()) {
|
||||
beammp_event(EventName);
|
||||
if (mLuaEvents.find(EventName) == mLuaEvents.end()) { // if no event handler is defined for 'EventName', return immediately
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<TLuaResult>> Results;
|
||||
for (const auto& Event : mLuaEvents.at(EventName)) {
|
||||
for (const auto& Function : Event.second) {
|
||||
@@ -127,7 +140,7 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
return Results;
|
||||
return Results; //
|
||||
}
|
||||
std::set<std::string> GetEventHandlersForState(const std::string& EventName, TLuaStateId StateId);
|
||||
void CreateEventTimer(const std::string& EventName, TLuaStateId StateId, size_t IntervalMS);
|
||||
|
||||
Reference in New Issue
Block a user