mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2025-07-04 00:36:14 +00:00
add MP.HttpsGET, MP.HttpsPOST
This commit is contained in:
parent
549517c518
commit
853b078124
23
src/Http.cpp
23
src/Http.cpp
@ -17,11 +17,14 @@ using tcp = net::ip::tcp; // from <boost/asio/ip/tcp.hpp>
|
|||||||
|
|
||||||
std::string Http::GET(const std::string& host, int port, const std::string& target, unsigned int* status) {
|
std::string Http::GET(const std::string& host, int port, const std::string& target, unsigned int* status) {
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Check command line arguments.
|
// Check command line arguments.
|
||||||
int version = 11;
|
int version = 11;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// The io_context is required for all I/O
|
// The io_context is required for all I/O
|
||||||
net::io_context ioc;
|
net::io_context ioc;
|
||||||
|
|
||||||
@ -67,6 +70,8 @@ std::string Http::GET(const std::string& host, int port, const std::string& targ
|
|||||||
beast::flat_buffer buffer;
|
beast::flat_buffer buffer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Declare a container to hold the response
|
// Declare a container to hold the response
|
||||||
http::response<http::string_body> res;
|
http::response<http::string_body> res;
|
||||||
|
|
||||||
@ -86,17 +91,18 @@ std::string Http::GET(const std::string& host, int port, const std::string& targ
|
|||||||
*status = res.base().result_int();
|
*status = res.base().result_int();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore ec
|
if (ec)
|
||||||
|
throw beast::system_error { ec };
|
||||||
|
|
||||||
// If we get here then the connection is closed gracefully
|
// If we get here then the connection is closed gracefully
|
||||||
return std::string(res.body());
|
return std::string(res.body());
|
||||||
} catch (std::exception const& e) {
|
} catch (std::exception const& e) {
|
||||||
Application::Console().Write(__func__ + std::string(": ") + e.what());
|
Application::Console().Write(__func__ + std::string(": ") + e.what());
|
||||||
return "-1";
|
return ErrorString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Http::POST(const std::string& host, const std::string& target, const std::unordered_map<std::string, std::string>& fields, const std::string& body, bool json, int* status) {
|
std::string Http::POST(const std::string& host, int port, const std::string& target, const std::unordered_map<std::string, std::string>& fields, const std::string& body, const std::string& ContentType, unsigned int* status) {
|
||||||
try {
|
try {
|
||||||
net::io_context io;
|
net::io_context io;
|
||||||
|
|
||||||
@ -110,7 +116,7 @@ std::string Http::POST(const std::string& host, const std::string& target, const
|
|||||||
decltype(resolver)::results_type results;
|
decltype(resolver)::results_type results;
|
||||||
auto try_connect_with_protocol = [&](tcp protocol) {
|
auto try_connect_with_protocol = [&](tcp protocol) {
|
||||||
try {
|
try {
|
||||||
results = resolver.resolve(protocol, host, std::to_string(443));
|
results = resolver.resolve(protocol, host, std::to_string(port));
|
||||||
if (!SSL_set_tlsext_host_name(stream.native_handle(), host.c_str())) {
|
if (!SSL_set_tlsext_host_name(stream.native_handle(), host.c_str())) {
|
||||||
boost::system::error_code ec { static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category() };
|
boost::system::error_code ec { static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category() };
|
||||||
// FIXME: we could throw and crash, if we like
|
// FIXME: we could throw and crash, if we like
|
||||||
@ -189,6 +195,10 @@ std::string Http::POST(const std::string& host, const std::string& target, const
|
|||||||
}
|
}
|
||||||
Sentry.SetContext("https-post-response-data", response_data);
|
Sentry.SetContext("https-post-response-data", response_data);
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
*status = response.base().result_int();
|
||||||
|
}
|
||||||
|
|
||||||
std::stringstream result;
|
std::stringstream result;
|
||||||
result << response;
|
result << response;
|
||||||
|
|
||||||
@ -199,12 +209,13 @@ std::string Http::POST(const std::string& host, const std::string& target, const
|
|||||||
// info(result.str());
|
// info(result.str());
|
||||||
std::string debug_response_str;
|
std::string debug_response_str;
|
||||||
std::getline(result, debug_response_str);
|
std::getline(result, debug_response_str);
|
||||||
|
|
||||||
//debug("POST " + host + target + ": " + debug_response_str);
|
//debug("POST " + host + target + ": " + debug_response_str);
|
||||||
return std::string(response.body());
|
return std::string(response.body());
|
||||||
|
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
Application::Console().Write(e.what());
|
Application::Console().Write(__func__ + std::string(": ") + e.what());
|
||||||
return "-1";
|
return ErrorString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
112
src/TLuaFile.cpp
112
src/TLuaFile.cpp
@ -676,7 +676,7 @@ int lua_Registered(lua_State* L) {
|
|||||||
lua_getstack(L, 0, &info);
|
lua_getstack(L, 0, &info);
|
||||||
lua_getinfo(L, "n", &info);
|
lua_getinfo(L, "n", &info);
|
||||||
|
|
||||||
if(auto it = TLuaEngine::mGlobals.find(info.name); it != TLuaEngine::mGlobals.end()){
|
if (auto it = TLuaEngine::mGlobals.find(info.name); it != TLuaEngine::mGlobals.end()) {
|
||||||
lua_getglobal(it->second, info.name);
|
lua_getglobal(it->second, info.name);
|
||||||
if (lua_isfunction(it->second, -1)) {
|
if (lua_isfunction(it->second, -1)) {
|
||||||
lua_pcall(it->second, 0, 0, 0); //TODO revisit to allow arguments and return also we need to mutex this
|
lua_pcall(it->second, 0, 0, 0); //TODO revisit to allow arguments and return also we need to mutex this
|
||||||
@ -689,13 +689,13 @@ int lua_Registered(lua_State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int lua_Register(lua_State* L) {
|
int lua_Register(lua_State* L) {
|
||||||
if(lua_isstring(L, 1)){
|
if (lua_isstring(L, 1)) {
|
||||||
std::string Name(lua_tolstring(L, 1, nullptr));
|
std::string Name(lua_tolstring(L, 1, nullptr));
|
||||||
lua_getglobal(L, Name.c_str());
|
lua_getglobal(L, Name.c_str());
|
||||||
if (lua_isfunction(L, -1)) {
|
if (lua_isfunction(L, -1)) {
|
||||||
TLuaEngine::mGlobals.emplace(Name, L);
|
TLuaEngine::mGlobals.emplace(Name, L);
|
||||||
for (auto& Script : Engine().LuaFiles()) {
|
for (auto& Script : Engine().LuaFiles()) {
|
||||||
if(Script->GetState() != L){
|
if (Script->GetState() != L) {
|
||||||
lua_register(Script->GetState(), Name.c_str(), lua_Registered);
|
lua_register(Script->GetState(), Name.c_str(), lua_Registered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -705,7 +705,7 @@ int lua_Register(lua_State* L) {
|
|||||||
ClearStack(L);
|
ClearStack(L);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SendError(Engine(), L, "Register wrong arguments expected string");
|
SendError(Engine(), L, "Wrong arguments to `Register`, expected string");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -799,6 +799,106 @@ int lua_GetOSName(lua_State* L) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// status, body = HttpGET(host, port, target)
|
||||||
|
// example usage:
|
||||||
|
// send a GET https://example.com:443/index.html:
|
||||||
|
// status, body = MP.HttpGET("example.com", 443, "/index.html")
|
||||||
|
int lua_HttpsGET(lua_State* L) {
|
||||||
|
if (!lua_isstring(L, 1)) {
|
||||||
|
SendError(Engine(), L, "`HttpsGET` expects host (type string) as first argument.");
|
||||||
|
ClearStack(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!lua_isnumber(L, 2)) {
|
||||||
|
SendError(Engine(), L, "`HttpsGET` expects port (type number) as second argument.");
|
||||||
|
ClearStack(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!lua_isstring(L, 3)) {
|
||||||
|
SendError(Engine(), L, "`HttpsGET` expects target (type string) as third argument.");
|
||||||
|
ClearStack(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Host = lua_tostring(L, 1);
|
||||||
|
auto Port = int(lua_tointeger(L, 2));
|
||||||
|
auto Target = lua_tostring(L, 3);
|
||||||
|
|
||||||
|
ClearStack(L);
|
||||||
|
|
||||||
|
unsigned int Status;
|
||||||
|
auto Body = Http::GET(Host, Port, Target, &Status);
|
||||||
|
lua_pushinteger(L, Status);
|
||||||
|
|
||||||
|
auto PrettyRemote = "https://" + std::string(Host) + ":" + std::to_string(Port) + std::string(Target);
|
||||||
|
if (Body == Http::ErrorString) {
|
||||||
|
SendError(Engine(), L, "HTTPS GET " + PrettyRemote + " failed status " + std::to_string(Status) + ". Check the console or log for more info.");
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
debug("GET " + PrettyRemote + " completed status " + std::to_string(Status));
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushstring(L, Body.c_str());
|
||||||
|
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// status, body = HttpsPOST(host, port, target, body, content_type)
|
||||||
|
int lua_HttpsPOST(lua_State* L) {
|
||||||
|
if (!lua_isstring(L, 1)) {
|
||||||
|
SendError(Engine(), L, "`HttpsPOST` expects host (type string) as 1. argument.");
|
||||||
|
ClearStack(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!lua_isnumber(L, 2)) {
|
||||||
|
SendError(Engine(), L, "`HttpsPOST` expects port (type number) as 2. argument.");
|
||||||
|
ClearStack(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!lua_isstring(L, 3)) {
|
||||||
|
SendError(Engine(), L, "`HttpsPOST` expects target (type string) as 3. argument.");
|
||||||
|
ClearStack(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!lua_isstring(L, 4)) {
|
||||||
|
SendError(Engine(), L, "`HttpsPOST` expects body (type string) as 4. argument.");
|
||||||
|
ClearStack(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!lua_isstring(L, 5)) {
|
||||||
|
SendError(Engine(), L, "`HttpsPOST` expects content_type (type string) as 5. argument.");
|
||||||
|
ClearStack(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Host = lua_tostring(L, 1);
|
||||||
|
auto Port = int(lua_tointeger(L, 2));
|
||||||
|
auto Target = lua_tostring(L, 3);
|
||||||
|
auto RequestBody = lua_tostring(L, 4);
|
||||||
|
auto ContentType = lua_tostring(L, 5);
|
||||||
|
|
||||||
|
ClearStack(L);
|
||||||
|
|
||||||
|
// build fields
|
||||||
|
std::unordered_map<std::string, std::string> Fields;
|
||||||
|
|
||||||
|
unsigned int Status;
|
||||||
|
auto ResponseBody = Http::POST(Host, Port, Target, {}, RequestBody, ContentType, &Status);
|
||||||
|
|
||||||
|
lua_pushinteger(L, Status);
|
||||||
|
|
||||||
|
auto PrettyRemote = "https://" + std::string(Host) + ":" + std::to_string(Port) + std::string(Target);
|
||||||
|
if (ResponseBody == Http::ErrorString) {
|
||||||
|
SendError(Engine(), L, "HTTPS POST " + PrettyRemote + " failed status " + std::to_string(Status) + ". Check the console or log for more info.");
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
debug("POST " + PrettyRemote + " completed status " + std::to_string(Status));
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushstring(L, ResponseBody.c_str());
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
void TLuaFile::Load() {
|
void TLuaFile::Load() {
|
||||||
Assert(mLuaState);
|
Assert(mLuaState);
|
||||||
luaL_openlibs(mLuaState);
|
luaL_openlibs(mLuaState);
|
||||||
@ -826,6 +926,8 @@ void TLuaFile::Load() {
|
|||||||
LuaTable::InsertFunction(mLuaState, "Sleep", lua_Sleep);
|
LuaTable::InsertFunction(mLuaState, "Sleep", lua_Sleep);
|
||||||
LuaTable::InsertFunction(mLuaState, "Set", lua_Set);
|
LuaTable::InsertFunction(mLuaState, "Set", lua_Set);
|
||||||
LuaTable::InsertFunction(mLuaState, "GetOSName", lua_GetOSName);
|
LuaTable::InsertFunction(mLuaState, "GetOSName", lua_GetOSName);
|
||||||
|
LuaTable::InsertFunction(mLuaState, "HttpsGET", lua_HttpsGET);
|
||||||
|
LuaTable::InsertFunction(mLuaState, "HttpsPOST", lua_HttpsPOST);
|
||||||
LuaTable::End(mLuaState, "MP");
|
LuaTable::End(mLuaState, "MP");
|
||||||
|
|
||||||
lua_register(mLuaState, "print", lua_Print);
|
lua_register(mLuaState, "print", lua_Print);
|
||||||
@ -901,7 +1003,7 @@ void SendError(TLuaEngine& Engine, lua_State* L, const std::string& msg) {
|
|||||||
TLuaFile& S = MaybeS.value();
|
TLuaFile& S = MaybeS.value();
|
||||||
a = fs::path(S.GetFileName()).filename().string();
|
a = fs::path(S.GetFileName()).filename().string();
|
||||||
}
|
}
|
||||||
warn(a + (" | Incorrect Call of ") + msg);
|
warn(a + (" | Error in MP Lua call: ") + msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TLuaArg::PushArgs(lua_State* State) {
|
void TLuaArg::PushArgs(lua_State* State) {
|
||||||
|
@ -290,7 +290,7 @@ void TNetwork::Authentication(SOCKET TCPSock) {
|
|||||||
|
|
||||||
json::Document AuthResponse;
|
json::Document AuthResponse;
|
||||||
AuthResponse.Parse(Rc.c_str());
|
AuthResponse.Parse(Rc.c_str());
|
||||||
if (Rc == "-1" || AuthResponse.HasParseError()) {
|
if (Rc == Http::ErrorString || AuthResponse.HasParseError()) {
|
||||||
ClientKick(*Client, "Invalid key! Please restart your game.");
|
ClientKick(*Client, "Invalid key! Please restart your game.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user