#include "pch.h" #include "tunnel.h" #include "protocol.h" #include "globalcfg.h" #include "httplib.h" #include "usrerr.h" #include #define HTTP_JSON_CONTENT TEXT("application/json") static httplib::Client *g_httpCtx = nullptr; static httplib::Client *g_tunnelHttpCtx = nullptr; int InitControlServer(const TCHAR *pUserSvrUrl) { if (g_tunnelHttpCtx) { delete g_tunnelHttpCtx; g_tunnelHttpCtx = nullptr; } if (GetGlobalCfgInfo()->scgProxy.scgGwPort > 0) { TCHAR scgProxyUrl[MAX_PATH]; StringCbPrintf(scgProxyUrl, MAX_PATH, TEXT("http://127.0.0.1:%d"), GetGlobalCfgInfo()->scgProxy.scgGwPort); g_tunnelHttpCtx = new httplib::Client(pUserSvrUrl); } else { g_tunnelHttpCtx = new httplib::Client(pUserSvrUrl); } if (g_tunnelHttpCtx) { g_tunnelHttpCtx->set_connection_timeout(0, 1000000); // 1 second g_tunnelHttpCtx->set_read_timeout(5, 0); // 5 seconds g_tunnelHttpCtx->set_write_timeout(5, 0); // 5 seconds g_tunnelHttpCtx->set_post_connect_cb([](socket_t sock) { if (UsedSCGProxy()) { int ret; unsigned char vmid[4]; unsigned char *p; const unsigned int id = htonl(GetGlobalCfgInfo()->curConnVmId); const auto svrId = static_cast(GetGlobalCfgInfo()->userCfg.cliConfig.scgCtrlAppId); unsigned char scgProxy[] = {0x01, // VERSION 0x09, // Length 0xF0, // ++++++ INFO[0] TYPE 0x04, // INFO[0] LENGTH 0, // INFO[0] VMID[0] 0, // INFO[0] VMID[1] 0, // INFO[0] VMID[2] 0, // INFO[0] VMID[3] 0xF1, // INFO[1] TYPE 0x01, // INFO[1] LENGTH svrId}; // ------ INFO[1] SCG Service ID p = scgProxy; memcpy(vmid, &id, 4); scgProxy[4] = vmid[0]; scgProxy[5] = vmid[1]; scgProxy[6] = vmid[2]; scgProxy[7] = vmid[3]; ret = send(sock, reinterpret_cast(p), sizeof(scgProxy), 0); while (ret < static_cast(sizeof(scgProxy))) { p += ret; ret += send(sock, reinterpret_cast(p), sizeof(scgProxy), 0); } SPDLOG_DEBUG(TEXT("Service Connected To SCG Server: {0}"), sock); } }); } SPDLOG_DEBUG(TEXT("Connect to Tunnel Control Service: {0}"), pUserSvrUrl); return ERR_SUCCESS; } template int CreateProtocolRequest(T *pReqParams, TCHAR **pOutJson) { std::string json; if (!g_httpCtx && lstrlen(GetGlobalCfgInfo()->platformServerUrl) > 0) { g_httpCtx = new httplib::Client(GetGlobalCfgInfo()->platformServerUrl); if (g_httpCtx) { g_httpCtx->set_connection_timeout(0, 300000); // 300 milliseconds g_httpCtx->set_read_timeout(5, 0); // 5 seconds g_httpCtx->set_write_timeout(5, 0); // 5 seconds } } if (aigc::JsonHelper::ObjectToJson(*pReqParams, json)) { *pOutJson = _strdup(json.c_str()); return ERR_SUCCESS; } return -ERR_JSON_CREATE; } template int DecodeProtocolResponse(T *pResponse, const TCHAR *pJson) { if (aigc::JsonHelper::JsonToObject(*pResponse, pJson)) { return ERR_SUCCESS; } return -ERR_JSON_DECODE; } template int ProtolPostMessage(const TCHAR *pUrlPath, ProtocolRequest *pReq, ProtocolResponse *pRsp, bool platformServer) { int ret; httplib::Result res; TCHAR *pJson = nullptr; if (lstrlen(GetGlobalCfgInfo()->platformServerUrl) == 0) { SPDLOG_ERROR(TEXT("Platform Server URL uninitialize.")); return -ERR_SYSTEM_UNINITIALIZE; } if (pReq == nullptr) { SPDLOG_ERROR(TEXT("Input pToken params error")); SPDLOG_ERROR(TEXT("Input ProtocolRequest *pReq params error")); return -ERR_INPUT_PARAMS; } if (pRsp == nullptr) { SPDLOG_ERROR(TEXT("Input ProtocolResponse *pRsp params error")); return -ERR_INPUT_PARAMS; } ret = CreateProtocolRequest(pReq, &pJson); if (ret != ERR_SUCCESS) { if (pJson) { free(pJson); } return ret; } if (platformServer) { res = g_httpCtx->Post(pUrlPath, pJson, HTTP_JSON_CONTENT); } else { if (g_tunnelHttpCtx == nullptr) { free(pJson); SPDLOG_ERROR(TEXT("Server Control Service don't connected(g_tunnelHttpCtx is not initialize).")); return -ERR_SYSTEM_UNINITIALIZE; } res = g_tunnelHttpCtx->Post(pUrlPath, pJson, HTTP_JSON_CONTENT); } if (res.error() != httplib::Error::Success) { SPDLOG_ERROR(TEXT("[{0}]:Post Data {1} error: {2}"), pUrlPath, pJson, httplib::to_string(res.error())); free(pJson); return -ERR_HTTP_POST_DATA; } if (res->status != 200) { SPDLOG_ERROR(TEXT("[{0}]:Post Data {1} server return HTTP error: {2}"), pUrlPath, pJson, res->status); free(pJson); return -ERR_HTTP_SERVER_RSP; } SPDLOG_DEBUG(TEXT("+++++ Http Request {0}\n---- Http Response {1}"), pJson, res->body.c_str()); free(pJson); if (lstrlen(res->body.c_str()) == 0) { SPDLOG_ERROR(TEXT("Server response empty message")); return -ERR_READ_FILE; } if (DecodeProtocolResponse(pRsp, res->body.c_str()) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Decode JSON {0} to ProtocolResponse<{1}> error"), res->body, typeid(T2).name()); return -ERR_JSON_DECODE; } return ERR_SUCCESS; } int ProtoGetUserConfigure(const TCHAR *pUser, const TCHAR *pToken) { int ret; ProtocolRequest req; ProtocolResponse rsp; ret = ProtolPostMessage(GET_SERVERCFG_PATH, &req, &rsp); return ret; } template int ProtolPostMessage(const TCHAR *pUrlPath, ProtocolRequest *pReq, ProtocolResponse *pRsp, bool platformServer); template int ProtolPostMessage(const TCHAR *pUrlPath, ProtocolRequest *pReq, ProtocolResponse *pRsp, bool platformServer); template int ProtolPostMessage(const TCHAR *pUrlPath, ProtocolRequest *pReq, ProtocolResponse *pRsp, bool platformServer); template int ProtolPostMessage(const TCHAR *pUrlPath, ProtocolRequest *pReq, ProtocolResponse *pRsp, bool platformServer); template int ProtolPostMessage(const TCHAR *pUrlPath, ProtocolRequest *pReq, ProtocolResponse *pRsp, bool platformServer);