add http debug error logging

This commit is contained in:
Lion Kortlepel 2024-03-22 12:19:18 +01:00
parent cc42a5e0ab
commit adba66afb9
No known key found for this signature in database
GPG Key ID: 4322FF2B4C71259B
3 changed files with 146 additions and 85 deletions

View File

@ -15,3 +15,4 @@ void debug(const std::string& toPrint);
void error(const std::string& toPrint); void error(const std::string& toPrint);
void info(const std::string& toPrint); void info(const std::string& toPrint);
void warn(const std::string& toPrint); void warn(const std::string& toPrint);
std::string getDate();

View File

@ -13,112 +13,169 @@
#include "Http.h" #include "Http.h"
#include <mutex> #include <mutex>
#include <cmath> #include <cmath>
#include <filesystem>
#include <httplib.h> #include <httplib.h>
#include <nlohmann/json.hpp>
void WriteHttpDebug(const httplib::Client& client, const std::string& method, const std::string& target, const httplib::Result& result) try {
const std::filesystem::path folder = ".https_debug";
std::filesystem::create_directories(folder);
if (!std::filesystem::exists(folder / "WHAT IS THIS FOLDER.txt")) {
std::ofstream ignore { folder / "WHAT IS THIS FOLDER.txt" };
ignore << "This folder exists to help debug current issues with the backend. Do not share this folder with anyone but BeamMP staff. It contains detailed logs of any failed http requests." << std::endl;
}
const auto file = folder / (method + ".json");
// 1 MB limit
if (std::filesystem::exists(file) && std::filesystem::file_size(file) > 1'000'000) {
std::filesystem::rename(file, file.generic_string() + ".bak");
}
std::ofstream of { file, std::ios::app };
nlohmann::json js {
{ "utc", std::chrono::system_clock::now().time_since_epoch().count() },
{ "target", target },
{ "client_info", {
{ "openssl_verify_result", client.get_openssl_verify_result() },
{ "host", client.host()},
{ "port", client.port()},
{ "socket_open", client.is_socket_open()},
{"valid", client.is_valid()},
}
},
};
if (result) {
auto value = result.value();
js["result"] = {};
js["result"]["body"] = value.body;
js["result"]["status"] = value.status;
js["result"]["headers"] = value.headers;
js["result"]["version"] = value.version;
js["result"]["location"] = value.location;
js["result"]["reason"] = value.reason;
}
of << js.dump();
}
catch (const std::exception& e) {
error(e.what());
}
bool HTTP::isDownload = false; bool HTTP::isDownload = false;
std::string HTTP::Get(const std::string &IP) { std::string HTTP::Get(const std::string& IP) {
static std::mutex Lock; static std::mutex Lock;
std::scoped_lock Guard(Lock); std::scoped_lock Guard(Lock);
auto pos = IP.find('/',10); auto pos = IP.find('/', 10);
httplib::Client cli(IP.substr(0, pos).c_str()); httplib::Client cli(IP.substr(0, pos).c_str());
cli.set_connection_timeout(std::chrono::seconds(10)); cli.set_connection_timeout(std::chrono::seconds(10));
cli.set_follow_location(true); cli.set_follow_location(true);
auto res = cli.Get(IP.substr(pos).c_str(), ProgressBar); auto res = cli.Get(IP.substr(pos).c_str(), ProgressBar);
std::string Ret; std::string Ret;
if(res){ if (res) {
if (res->status == 200) { if (res->status == 200) {
Ret = res->body; Ret = res->body;
} }
else { else {
error("Failed to GET '" + IP + "': " + res->reason + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result())); WriteHttpDebug(cli, "GET", IP, res);
} error("Failed to GET '" + IP + "': " + res->reason + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result()));
}else{
if(isDownload) {
std::cout << "\n";
}
error("HTTP Get failed on " + to_string(res.error()) + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result()));
}
return Ret; }
}
else {
if (isDownload) {
std::cout << "\n";
}
WriteHttpDebug(cli, "GET", IP, res);
error("HTTP Get failed on " + to_string(res.error()) + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result()));
}
return Ret;
} }
std::string HTTP::Post(const std::string& IP, const std::string& Fields) { std::string HTTP::Post(const std::string& IP, const std::string& Fields) {
static std::mutex Lock; static std::mutex Lock;
std::scoped_lock Guard(Lock); std::scoped_lock Guard(Lock);
auto pos = IP.find('/',10); auto pos = IP.find('/', 10);
httplib::Client cli(IP.substr(0, pos).c_str()); httplib::Client cli(IP.substr(0, pos).c_str());
cli.set_connection_timeout(std::chrono::seconds(10)); cli.set_connection_timeout(std::chrono::seconds(10));
std::string Ret; std::string Ret;
if(!Fields.empty()) { if (!Fields.empty()) {
httplib::Result res = cli.Post(IP.substr(pos).c_str(), Fields, "application/json"); httplib::Result res = cli.Post(IP.substr(pos).c_str(), Fields, "application/json");
if(res) { if (res) {
if (res->status != 200) { if (res->status != 200) {
error(res->reason); error(res->reason);
} }
Ret = res->body; Ret = res->body;
}else{ }
error("HTTP Post failed on " + to_string(res.error()) + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result())); else {
} WriteHttpDebug(cli, "POST", IP, res);
}else{ error("HTTP Post failed on " + to_string(res.error()) + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result()));
httplib::Result res = cli.Post(IP.substr(pos).c_str());
if(res) {
if (res->status != 200) {
error(res->reason);
}
Ret = res->body;
}else{
error("HTTP Post failed on " + to_string(res.error()) + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result()));
}
}
if(Ret.empty())return "-1"; }
else return Ret; }
else {
httplib::Result res = cli.Post(IP.substr(pos).c_str());
if (res) {
if (res->status != 200) {
error(res->reason);
}
Ret = res->body;
}
else {
WriteHttpDebug(cli, "POST", IP, res);
error("HTTP Post failed on " + to_string(res.error()) + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result()));
}
}
if (Ret.empty())return "-1";
else return Ret;
} }
bool HTTP::ProgressBar(size_t c, size_t t){ bool HTTP::ProgressBar(size_t c, size_t t) {
if(isDownload) { if (isDownload) {
static double last_progress, progress_bar_adv; static double last_progress, progress_bar_adv;
progress_bar_adv = round(c / double(t) * 25); progress_bar_adv = round(c / double(t) * 25);
std::cout << "\r"; std::cout << "\r";
std::cout << "Progress : [ "; std::cout << "Progress : [ ";
std::cout << round(c / double(t) * 100); std::cout << round(c / double(t) * 100);
std::cout << "% ] ["; std::cout << "% ] [";
int i; int i;
for (i = 0; i <= progress_bar_adv; i++)std::cout << "#"; for (i = 0; i <= progress_bar_adv; i++)std::cout << "#";
for (i = 0; i < 25 - progress_bar_adv; i++)std::cout << "."; for (i = 0; i < 25 - progress_bar_adv; i++)std::cout << ".";
std::cout << "]"; std::cout << "]";
last_progress = round(c / double(t) * 100); last_progress = round(c / double(t) * 100);
} }
return true; return true;
} }
bool HTTP::Download(const std::string &IP, const std::string &Path) { bool HTTP::Download(const std::string& IP, const std::string& Path) {
static std::mutex Lock; static std::mutex Lock;
std::scoped_lock Guard(Lock); std::scoped_lock Guard(Lock);
isDownload = true; isDownload = true;
std::string Ret = Get(IP); std::string Ret = Get(IP);
isDownload = false; isDownload = false;
if(Ret.empty())return false; if (Ret.empty())return false;
std::ofstream File(Path, std::ios::binary); std::ofstream File(Path, std::ios::binary);
if(File.is_open()) { if (File.is_open()) {
File << Ret; File << Ret;
File.close(); File.close();
std::cout << "\n"; std::cout << "\n";
info("Download Complete!"); info("Download Complete!");
}else{ }
error("Failed to open file directory: " + Path); else {
return false; error("Failed to open file directory: " + Path);
} return false;
}
return true; return true;
} }

View File

@ -25,6 +25,9 @@ int main(int argc, char* argv[]) {
std::thread th(flush); std::thread th(flush);
th.detach(); th.detach();
#endif #endif
HTTP::Get("https://backend.beammp.com/fucker");
GetEP(argv[0]); GetEP(argv[0]);
InitLauncher(argc, argv); InitLauncher(argc, argv);