New header only http library

This commit is contained in:
Anonymous-275 2021-04-04 19:20:25 +03:00
parent e70cf0f877
commit ec3bcffe7c
8 changed files with 7671 additions and 116 deletions

View File

@ -7,8 +7,6 @@ if (WIN32)
STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
endif(WIN32) endif(WIN32)
add_subdirectory("evpp")
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
@ -18,10 +16,6 @@ file(GLOB source_files "src/*.cpp" "src/*/*.cpp" "src/*/*.hpp" "include/*.h" "i
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")
target_include_directories(${PROJECT_NAME} PUBLIC include evpp)
add_definitions("-DEVPP_HTTP_CLIENT_SUPPORTS_SSL")
if (WIN32) if (WIN32)
find_package(glog CONFIG REQUIRED) find_package(glog CONFIG REQUIRED)
find_package(Libevent CONFIG REQUIRED) find_package(Libevent CONFIG REQUIRED)
@ -31,11 +25,11 @@ if (WIN32)
set(VcpkgRoot ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}) set(VcpkgRoot ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET})
include_directories(${VcpkgRoot}/include) include_directories(${VcpkgRoot}/include)
link_directories(${VcpkgRoot}/lib) link_directories(${VcpkgRoot}/lib)
target_link_libraries(${PROJECT_NAME} PRIVATE ${VcpkgRoot}/lib/discord-rpc.lib evpp_static target_link_libraries(${PROJECT_NAME} PRIVATE ${VcpkgRoot}/lib/discord-rpc.libb
${VcpkgRoot}/lib/event.lib libevent::core libevent::extra glog::glog ZLIB::ZLIB ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto ws2_32)
OpenSSL::SSL OpenSSL::Crypto libevent::openssl ws2_32)
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} discord-rpc evpp_static z) target_link_libraries(${PROJECT_NAME} discord-rpc ssl crypto ws2_32 ssp crypt32 z)
endif(WIN32) endif(WIN32)
target_include_directories(${PROJECT_NAME} PRIVATE "include")

View File

@ -6,21 +6,15 @@
/// Created by Anonymous275 on 7/18/2020 /// Created by Anonymous275 on 7/18/2020
/// ///
#pragma once #pragma once
#include <evpp/httpc/response.h>
#include <evpp/httpc/request.h>
#include <string> #include <string>
#include "Logger.h" #include "Logger.h"
class HTTP{ class HTTP{
public: public:
static void Response(const std::shared_ptr<evpp::httpc::Response>& response, evpp::httpc::Request* request);
static bool Download(const std::string &IP, const std::string &Path); static bool Download(const std::string &IP, const std::string &Path);
static std::string Post(const std::string& IP, const std::string& Fields); static std::string Post(const std::string& IP, const std::string& Fields);
static std::string Get(const std::string &IP); static std::string Get(const std::string &IP);
static void Init(char* argv[]){ static bool ProgressBar(size_t c, size_t t);
google::InitGoogleLogging(argv[0]); public:
google::SetStderrLogging(google::GLOG_ERROR); static bool isDownload;
evpp::httpc::SET_SSL_VERIFY_MODE(SSL_VERIFY_NONE); static std::string Codes_[];
}
private:
static std::string Res_;
}; };

7578
include/httplib.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -58,7 +58,7 @@ void Parse(std::string Data,SOCKET CSocket){
NetReset(); NetReset();
Terminate = true; Terminate = true;
TCPTerminate = true; TCPTerminate = true;
Data = Code + HTTP::Post("backend.beammp.com/servers",""); Data = Code + HTTP::Post("https://backend.beammp.com/servers","");
break; break;
case 'C': case 'C':
ListOfMods.clear(); ListOfMods.clear();

View File

@ -5,128 +5,117 @@
/// ///
/// Created by Anonymous275 on 7/18/2020 /// Created by Anonymous275 on 7/18/2020
/// ///
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include <evpp/event_loop_thread.h>
#include <evpp/httpc/conn_pool.h>
#include <iostream> #include <iostream>
#include <Logger.h> #include <Logger.h>
#include <fstream> #include <fstream>
#include "http.h" #include "http.h"
#include <mutex> #include <mutex>
#include <cmath> #include <cmath>
#include <evhttp.h> #include <httplib.h>
#include "winmain-inl.h"
static bool responded;
std::string HTTP::Res_{};
void HTTP::Response(const std::shared_ptr<evpp::httpc::Response>& response, evpp::httpc::Request* request){
if(response->http_code() == 200){
Res_ = std::move(response->body().ToString());
} else {
std::cout << "\n";
error("Failed request! http code " + std::to_string(response->http_code()));
}
responded = true;
assert(request == response->request());
delete request;
}
std::string HTTP::Codes_[] =
{
"Success","Unknown","Connection","BindIPAddress",
"Read","Write","ExceedRedirectCount","Canceled",
"SSLConnection","SSLLoadingCerts","SSLServerVerification",
"UnsupportedMultipartBoundaryChars","Compression"
};
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);
responded = false;
Res_.clear();
evpp::EventLoopThread t;
t.Start(true);
auto pos = IP.find('/'); auto pos = IP.find('/',10);
std::shared_ptr<evpp::httpc::ConnPool> pool = std::make_shared<evpp::httpc::ConnPool>(IP.substr(0, pos), 443, true,
evpp::Duration(10.0));
auto *r = new evpp::httpc::Request(pool.get(), t.loop(), IP.substr(pos), "");
r->Execute(Response);
while (!responded) { httplib::Client cli(IP.substr(0, pos).c_str());
usleep(1); cli.set_connection_timeout(std::chrono::seconds(10));
auto res = cli.Get(IP.substr(pos).c_str(), ProgressBar);
std::string Ret;
if(res.error() == 0){
if(res->status == 200){
Ret = res->body;
}else error(res->reason);
}else{
if(isDownload) {
std::cout << "\n";
}
error("HTTP Get failed on " + Codes_[res.error()]);
} }
pool->Clear(); return Ret;
pool.reset();
t.Stop(true);
return Res_;
} }
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);
responded = false;
Res_.clear();
evpp::EventLoopThread t;
t.Start(true);
auto pos = IP.find('/',10);
httplib::Client cli(IP.substr(0, pos).c_str());
cli.set_connection_timeout(std::chrono::seconds(10));
std::string Ret;
auto pos = IP.find('/');
std::shared_ptr<evpp::httpc::ConnPool> pool = std::make_shared<evpp::httpc::ConnPool>(IP.substr(0, pos), 443,
true,
evpp::Duration(10.0));
auto *r = new evpp::httpc::Request(pool.get(), t.loop(), IP.substr(pos), Fields);
if(!Fields.empty()) { if(!Fields.empty()) {
r->AddHeader("Content-Type", "application/json"); httplib::Result res = cli.Post(IP.substr(pos).c_str(), Fields, "application/json");
}
r->set_request_type(EVHTTP_REQ_POST);
r->Execute(Response);
while (!responded) { if(res.error() == 0) {
usleep(1); if (res->status != 200) {
error(res->reason);
}
Ret = res->body;
}else{
error("HTTP Post failed on " + Codes_[res.error()]);
}
}else{
httplib::Result res = cli.Post(IP.substr(pos).c_str());
if(res.error() == 0) {
if (res->status != 200) {
error(res->reason);
}
Ret = res->body;
}else{
error("HTTP Post failed on " + Codes_[res.error()]);
}
} }
pool->Clear(); if(Ret.empty())return "-1";
pool.reset(); else return Ret;
t.Stop(true);
if(Res_.empty())return "-1";
else return Res_;
} }
void ProgressBar(size_t d, size_t t){ bool HTTP::ProgressBar(size_t c, size_t t){
static double last_progress, progress_bar_adv; if(isDownload) {
progress_bar_adv = round(d/double(t)*25); static double last_progress, progress_bar_adv;
std::cout << "\r"; progress_bar_adv = round(c / double(t) * 25);
std::cout << "Progress : [ "; std::cout << "\r";
std::cout << round(d/double(t)*100); std::cout << "Progress : [ ";
std::cout << "% ] ["; std::cout << round(c / double(t) * 100);
int i; std::cout << "% ] [";
for(i = 0; i <= progress_bar_adv; i++)std::cout<<"#"; int i;
for(i = 0; i < 25 - progress_bar_adv; i++)std::cout<<"."; for (i = 0; i <= progress_bar_adv; i++)std::cout << "#";
std::cout << "]"; for (i = 0; i < 25 - progress_bar_adv; i++)std::cout << ".";
last_progress = round(d/double(t)*100); std::cout << "]";
last_progress = round(c / double(t) * 100);
}
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);
responded = false;
Res_.clear();
evpp::EventLoopThread t;
t.Start(true);
auto pos = IP.find('/');
std::shared_ptr<evpp::httpc::ConnPool> pool = std::make_shared<evpp::httpc::ConnPool>(IP.substr(0,pos), 443, true, evpp::Duration(10.0));
auto* r = new evpp::httpc::Request(pool.get(), t.loop(), IP.substr(pos), "");
r->set_progress_callback(ProgressBar);
r->Execute(Response);
while (!responded) { isDownload = true;
usleep(1); std::string Ret = Get(IP);
} isDownload = false;
pool->Clear(); if(Ret.empty())return false;
pool.reset();
t.Stop(true);
if(Res_.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 << Res_; File << Ret;
File.close(); File.close();
std::cout << "\n"; std::cout << "\n";
info("Download Complete!"); info("Download Complete!");

View File

@ -47,7 +47,7 @@ std::string Login(const std::string& fields){
return ""; return "";
} }
info("Attempting to authenticate..."); info("Attempting to authenticate...");
std::string Buffer = HTTP::Post("auth.beammp.com/userlogin", fields); std::string Buffer = HTTP::Post("https://auth.beammp.com/userlogin", fields);
json::Document d; json::Document d;
d.Parse(Buffer.c_str()); d.Parse(Buffer.c_str());
if(Buffer == "-1"){ if(Buffer == "-1"){
@ -88,7 +88,7 @@ void CheckLocalKey(){
Key.read(&Buffer[0], Size); Key.read(&Buffer[0], Size);
Key.close(); Key.close();
Buffer = HTTP::Post("auth.beammp.com/userlogin", R"({"pk":")" + Buffer + "\"}"); Buffer = HTTP::Post("https://auth.beammp.com/userlogin", R"({"pk":")" + Buffer + "\"}");
json::Document d; json::Document d;
d.Parse(Buffer.c_str()); d.Parse(Buffer.c_str());

View File

@ -5,7 +5,7 @@
/// ///
/// Created by Anonymous275 on 7/16/2020 /// Created by Anonymous275 on 7/16/2020
/// ///
#include <windows.h>
#include "Discord/discord_info.h" #include "Discord/discord_info.h"
#include "Network/network.h" #include "Network/network.h"
#include "Security/Init.h" #include "Security/Init.h"
@ -70,18 +70,18 @@ void CheckName(int argc,char* args[]){
void CheckForUpdates(int argc,char*args[],const std::string& CV){ void CheckForUpdates(int argc,char*args[],const std::string& CV){
std::string link; std::string link;
std::string HTTP = HTTP::Get("beammp.com/builds/launcher?version=true"); std::string HTTP = HTTP::Get("https://beammp.com/builds/launcher?version=true");
bool fallback = false; bool fallback = false;
if(HTTP.find_first_of("0123456789") == std::string::npos){ if(HTTP.find_first_of("0123456789") == std::string::npos){
HTTP = HTTP::Get("backup1.beammp.com/builds/launcher?version=true"); HTTP = HTTP::Get("https://backup1.beammp.com/builds/launcher?version=true");
fallback = true; fallback = true;
if(HTTP.find_first_of("0123456789") == std::string::npos) { if(HTTP.find_first_of("0123456789") == std::string::npos) {
fatal("Primary Servers Offline! sorry for the inconvenience!"); fatal("Primary Servers Offline! sorry for the inconvenience!");
} }
} }
if(fallback){ if(fallback){
link = "backup1.beammp.com/builds/launcher?download=true"; link = "https://backup1.beammp.com/builds/launcher?download=true";
}else link = "beammp.com/builds/launcher?download=true"; }else link = "https://beammp.com/builds/launcher?download=true";
std::string EP(GetEP() + GetEN()), Back(GetEP() + "BeamMP-Launcher.back"); std::string EP(GetEP() + GetEN()), Back(GetEP() + "BeamMP-Launcher.back");
@ -166,7 +166,7 @@ void PreGame(const std::string& GamePath){
CheckMP(GetGamePath() + "mods/multiplayer"); CheckMP(GetGamePath() + "mods/multiplayer");
if(!Dev) { if(!Dev) {
info("Downloading mod..."); info("Downloading mod please wait...");
try { try {
if (!fs::exists(GetGamePath() + "mods/multiplayer")) { if (!fs::exists(GetGamePath() + "mods/multiplayer")) {
fs::create_directories(GetGamePath() + "mods/multiplayer"); fs::create_directories(GetGamePath() + "mods/multiplayer");
@ -175,7 +175,7 @@ void PreGame(const std::string& GamePath){
fatal(e.what()); fatal(e.what());
} }
HTTP::Download("backend.beammp.com/builds/client?download=true" HTTP::Download("https://backend.beammp.com/builds/client?download=true"
"&pk=" + PublicKey + "&pk=" + PublicKey +
"&branch=" + Branch, GetGamePath() + R"(mods\multiplayer\BeamMP.zip)"); "&branch=" + Branch, GetGamePath() + R"(mods\multiplayer\BeamMP.zip)");

View File

@ -27,7 +27,7 @@ int main(int argc, char* argv[]) {
th.detach(); th.detach();
#endif #endif
GetEP(argv[0]); GetEP(argv[0]);
HTTP::Init(argv);
InitLauncher(argc,argv); InitLauncher(argc,argv);
try { try {