switch to curl for Get and Post

This commit is contained in:
Lion Kortlepel 2024-10-04 22:20:22 +02:00
parent 7600372ca1
commit c74455e0fe
No known key found for this signature in database
GPG Key ID: 4322FF2B4C71259B
4 changed files with 301 additions and 324 deletions

View File

@ -17,6 +17,7 @@ add_compile_definitions(CPPHTTPLIB_OPENSSL_SUPPORT)
file(GLOB source_files "src/*.cpp" "src/*/*.cpp" "src/*/*.hpp" "include/*.h" "include/*/*.h" "include/*/*/*.h" "include/*.hpp" "include/*/*.hpp" "include/*/*/*.hpp") file(GLOB source_files "src/*.cpp" "src/*/*.cpp" "src/*/*.hpp" "include/*.h" "include/*/*.h" "include/*/*/*.h" "include/*.hpp" "include/*/*.hpp" "include/*/*/*.hpp")
find_package(httplib CONFIG REQUIRED) find_package(httplib CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED) find_package(nlohmann_json CONFIG REQUIRED)
find_package(CURL REQUIRED)
add_executable(${PROJECT_NAME} ${source_files}) add_executable(${PROJECT_NAME} ${source_files})
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "BeamMP-Launcher") set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "BeamMP-Launcher")
@ -25,15 +26,15 @@ if (WIN32)
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
find_package(OpenSSL REQUIRED) find_package(OpenSSL REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE target_link_libraries(${PROJECT_NAME} PRIVATE
ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto ws2_32 httplib::httplib nlohmann_json::nlohmann_json) ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto ws2_32 httplib::httplib nlohmann_json::nlohmann_json CURL::libcurl)
elseif (LINUX) elseif (LINUX)
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
find_package(OpenSSL REQUIRED) find_package(OpenSSL REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE target_link_libraries(${PROJECT_NAME} PRIVATE
ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto) ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto CURL::libcurl)
else(WIN32) #MINGW else(WIN32) #MINGW
add_definitions("-D_WIN32_WINNT=0x0600") add_definitions("-D_WIN32_WINNT=0x0600")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Os -s --static") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Os -s --static")
target_link_libraries(${PROJECT_NAME} ssl crypto ws2_32 ssp crypt32 z) target_link_libraries(${PROJECT_NAME} ssl crypto ws2_32 ssp crypt32 z CURL::libcurl)
endif(WIN32) endif(WIN32)
target_include_directories(${PROJECT_NAME} PRIVATE "include") target_include_directories(${PROJECT_NAME} PRIVATE "include")

View File

@ -8,16 +8,18 @@
#include "Http.h" #include "Http.h"
#include <Logger.h> #include <Logger.h>
#include <Network/network.hpp>
#include <Startup.h>
#include <Utils.h>
#include <cmath> #include <cmath>
#include <curl/curl.h>
#include <curl/easy.h>
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#include <httplib.h> #include <httplib.h>
#include <iostream> #include <iostream>
#include <mutex> #include <mutex>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <Startup.h>
#include <Network/network.hpp>
#include <Utils.h>
void WriteHttpDebug(const httplib::Client& client, const std::string& method, const std::string& target, const httplib::Result& result) try { 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"; const std::filesystem::path folder = ".https_debug";
@ -59,33 +61,31 @@ void WriteHttpDebug(const httplib::Client& client, const std::string& method, co
error(e.what()); error(e.what());
} }
static size_t CurlWriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
std::string* Result = reinterpret_cast<std::string*>(userp);
std::string NewContents(reinterpret_cast<char*>(contents), size * nmemb);
*Result += NewContents;
return size * nmemb;
}
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;
std::scoped_lock Guard(Lock);
auto pos = IP.find('/', 10);
httplib::Client cli(IP.substr(0, pos).c_str());
cli.set_connection_timeout(std::chrono::seconds(10));
cli.set_follow_location(true);
if (SkipSslVerify) {
debug("Skipping SSL server validation via --skip-ssl-verify");
cli.enable_server_certificate_verification(false);
}
auto res = cli.Get(IP.substr(pos).c_str(), ProgressBar);
std::string Ret; std::string Ret;
static thread_local CURL* curl = curl_easy_init();
if (res) { if (curl) {
if (res->status == 200) { CURLcode res;
Ret = res->body; curl_easy_setopt(curl, CURLOPT_URL, IP.c_str());
} else { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteCallback);
WriteHttpDebug(cli, "GET", IP, res); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&Ret);
error("Failed to GET (status " + std::to_string(res->status) + ") '" + IP + "': " + res->reason + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result())); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); // seconds
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
error("GET to " + IP + " failed: " + std::string(curl_easy_strerror(res)));
return "";
} }
} else { } else {
if (isDownload) { error("Curl easy init failed");
std::cout << "\n"; return "";
} }
auto result = cli.get_openssl_verify_result(); auto result = cli.get_openssl_verify_result();
std::string verify_error; std::string verify_error;
@ -93,60 +93,34 @@ std::string HTTP::Get(const std::string& IP) {
verify_error = X509_verify_cert_error_string(result); verify_error = X509_verify_cert_error_string(result);
} }
WriteHttpDebug(cli, "GET", IP, res);
error("HTTP Get failed on " + to_string(res.error()) + ", ssl verify = " + verify_error);
}
return Ret; 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;
std::scoped_lock Guard(Lock);
auto pos = IP.find('/', 10);
httplib::Client cli(IP.substr(0, pos).c_str());
cli.set_connection_timeout(std::chrono::seconds(10));
if (SkipSslVerify) {
debug("Skipping SSL server validation via --skip-ssl-verify");
cli.enable_server_certificate_verification(false);
}
std::string Ret; std::string Ret;
static thread_local CURL* curl = curl_easy_init();
if (!Fields.empty()) { if (curl) {
httplib::Result res = cli.Post(IP.substr(pos).c_str(), Fields, "application/json"); CURLcode res;
curl_easy_setopt(curl, CURLOPT_URL, IP.c_str());
if (res) { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteCallback);
if (res->status != 200) { curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&Ret);
error(res->reason); curl_easy_setopt(curl, CURLOPT_POST, 1);
} curl_easy_setopt(curl, CURLOPT_POSTFIELDS, Fields.c_str());
Ret = res->body; curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, Fields.size());
} else { struct curl_slist* list = nullptr;
WriteHttpDebug(cli, "POST", IP, res); list = curl_slist_append(list, "Content-Type: application/json");
error("HTTP Post failed on " + to_string(res.error()) + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result())); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); // seconds
res = curl_easy_perform(curl);
curl_slist_free_all(list);
if (res != CURLE_OK) {
error("POST to " + IP + " failed: " + std::string(curl_easy_strerror(res)));
return "";
} }
} else { } else {
httplib::Result res = cli.Post(IP.substr(pos).c_str()); error("Curl easy init failed");
if (res) { return "";
if (res->status != 200) {
error(res->reason);
} }
Ret = res->body;
} else {
auto result = cli.get_openssl_verify_result();
std::string verify_error;
if (result) {
verify_error = X509_verify_cert_error_string(result);
}
WriteHttpDebug(cli, "POST", IP, res);
error("HTTP Post failed on " + to_string(res.error()) + ", ssl verify = " + verify_error);
}
}
if (Ret.empty())
return "-1";
else
return Ret; return Ret;
} }
@ -200,7 +174,6 @@ void set_headers(httplib::Response& res) {
res.set_header("Access-Control-Request-Headers", "X-API-Version"); res.set_header("Access-Control-Request-Headers", "X-API-Version");
} }
void HTTP::StartProxy() { void HTTP::StartProxy() {
std::thread proxy([&]() { std::thread proxy([&]() {
httplib::Server HTTPProxy; httplib::Server HTTPProxy;
@ -255,7 +228,7 @@ void HTTP::StartProxy() {
if (std::stoi(path[2]) > 0) if (std::stoi(path[2]) > 0)
avatar_size = path[2]; avatar_size = path[2];
} catch (std::exception&) {} } catch (std::exception&) { }
} }
httplib::Result summary_res; httplib::Result summary_res;

View File

@ -10,6 +10,7 @@
#include "Network/network.hpp" #include "Network/network.hpp"
#include "Security/Init.h" #include "Security/Init.h"
#include "Startup.h" #include "Startup.h"
#include <curl/curl.h>
#include <iostream> #include <iostream>
#include <thread> #include <thread>
@ -26,6 +27,7 @@ int main(int argc, char** argv) try {
th.detach(); th.detach();
#endif #endif
curl_global_init(CURL_GLOBAL_ALL);
#if defined(_WIN32) #if defined(_WIN32)
system("cls"); system("cls");

View File

@ -3,6 +3,7 @@
"cpp-httplib", "cpp-httplib",
"nlohmann-json", "nlohmann-json",
"zlib", "zlib",
"openssl" "openssl",
"curl"
] ]
} }