mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2025-07-03 08:15:35 +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) {
|
||||
|
||||
|
||||
try {
|
||||
// Check command line arguments.
|
||||
int version = 11;
|
||||
|
||||
|
||||
|
||||
|
||||
// The io_context is required for all I/O
|
||||
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;
|
||||
|
||||
|
||||
|
||||
|
||||
// Declare a container to hold the response
|
||||
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();
|
||||
}
|
||||
|
||||
// ignore ec
|
||||
if (ec)
|
||||
throw beast::system_error { ec };
|
||||
|
||||
// If we get here then the connection is closed gracefully
|
||||
return std::string(res.body());
|
||||
} catch (std::exception const& e) {
|
||||
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 {
|
||||
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;
|
||||
auto try_connect_with_protocol = [&](tcp protocol) {
|
||||
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())) {
|
||||
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
|
||||
@ -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);
|
||||
|
||||
if (status) {
|
||||
*status = response.base().result_int();
|
||||
}
|
||||
|
||||
std::stringstream result;
|
||||
result << response;
|
||||
|
||||
@ -199,12 +209,13 @@ std::string Http::POST(const std::string& host, const std::string& target, const
|
||||
// info(result.str());
|
||||
std::string debug_response_str;
|
||||
std::getline(result, debug_response_str);
|
||||
|
||||
//debug("POST " + host + target + ": " + debug_response_str);
|
||||
return std::string(response.body());
|
||||
|
||||
} catch (const std::exception& e) {
|
||||
Application::Console().Write(e.what());
|
||||
return "-1";
|
||||
Application::Console().Write(__func__ + std::string(": ") + e.what());
|
||||
return ErrorString;
|
||||
}
|
||||
}
|
||||
|
||||
|
106
src/TLuaFile.cpp
106
src/TLuaFile.cpp
@ -705,7 +705,7 @@ int lua_Register(lua_State* L) {
|
||||
ClearStack(L);
|
||||
}
|
||||
} else {
|
||||
SendError(Engine(), L, "Register wrong arguments expected string");
|
||||
SendError(Engine(), L, "Wrong arguments to `Register`, expected string");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -799,6 +799,106 @@ int lua_GetOSName(lua_State* L) {
|
||||
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() {
|
||||
Assert(mLuaState);
|
||||
luaL_openlibs(mLuaState);
|
||||
@ -826,6 +926,8 @@ void TLuaFile::Load() {
|
||||
LuaTable::InsertFunction(mLuaState, "Sleep", lua_Sleep);
|
||||
LuaTable::InsertFunction(mLuaState, "Set", lua_Set);
|
||||
LuaTable::InsertFunction(mLuaState, "GetOSName", lua_GetOSName);
|
||||
LuaTable::InsertFunction(mLuaState, "HttpsGET", lua_HttpsGET);
|
||||
LuaTable::InsertFunction(mLuaState, "HttpsPOST", lua_HttpsPOST);
|
||||
LuaTable::End(mLuaState, "MP");
|
||||
|
||||
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();
|
||||
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) {
|
||||
|
@ -290,7 +290,7 @@ void TNetwork::Authentication(SOCKET TCPSock) {
|
||||
|
||||
json::Document AuthResponse;
|
||||
AuthResponse.Parse(Rc.c_str());
|
||||
if (Rc == "-1" || AuthResponse.HasParseError()) {
|
||||
if (Rc == Http::ErrorString || AuthResponse.HasParseError()) {
|
||||
ClientKick(*Client, "Invalid key! Please restart your game.");
|
||||
return;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user