CNetWork.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. #include "stdafx.h"
  2. #include "CNetWork.h"
  3. #include <nlohmann/json.hpp>
  4. #include <fmt/format.h>
  5. #include "Logger.h"
  6. CNetWork::CNetWork() : m_http_ret(HTTPRET::http_f)
  7. {
  8. initSessionPool(100);
  9. }
  10. CNetWork::~CNetWork(void)
  11. {
  12. DestoryOneConnSessionPool();
  13. }
  14. int CNetWork::GetHttpStatus() {
  15. return m_http_status;
  16. }
  17. HTTPRET CNetWork::Version(std::string& data) {
  18. std::vector<cpr::Parameter> p;
  19. p.push_back({ "tag","win" });
  20. p.push_back({ "appverion",S_CW2A(VERSION).GetBuffer(0)});
  21. std::string text = GetUrl("/api/client/v3/version", p, CApp::getSingletonPtr()->GetUserinfo()->access_token);
  22. if (text.empty()) {
  23. return HTTPRET::http_f;
  24. }
  25. data = text.c_str();
  26. return HTTPRET::http_yes;
  27. }
  28. HTTPRET CNetWork::Refresh(std::string& data) {
  29. std::vector<cpr::Parameter> p;
  30. std::string text = GetUrl("/api/client/v3/refresh", p, CApp::getSingletonPtr()->GetUserinfo()->access_token);
  31. if (text.empty()) {
  32. return HTTPRET::http_f;
  33. }
  34. data = text.c_str();
  35. return HTTPRET::http_yes;
  36. }
  37. HTTPRET CNetWork::Auth(std::string& data) {
  38. return HTTPRET::http_yes;
  39. }
  40. HTTPRET CNetWork::GetServerNode(std::string& data) {
  41. std::vector<cpr::Parameter> p;
  42. std::string text = GetUrl("/api/client/v3/nodes",p,CApp::getSingletonPtr()->GetUserinfo()->access_token);
  43. if (text.empty()) {
  44. return HTTPRET::http_f;
  45. }
  46. data = text.c_str();
  47. return HTTPRET::http_yes;
  48. }
  49. HTTPRET CNetWork::GetSysConfig(std::string& data)
  50. {
  51. std::vector<cpr::Parameter> p;
  52. std::string text = GetUrl("/api/client/v3/getconfig", p);
  53. if (text.empty()) {
  54. if (m_http_status == 445)
  55. {
  56. return HTTPRET::http_user_expired_at;
  57. }
  58. else if (m_http_status == 446)
  59. {
  60. return HTTPRET::http_user_transfer_enable;
  61. }
  62. else {
  63. return HTTPRET::http_f;
  64. }
  65. }
  66. data = text.c_str();
  67. return HTTPRET::http_yes;
  68. }
  69. HTTPRET CNetWork::PostLogin(LPCSTR username, LPCSTR password, std::string& data)
  70. {
  71. std::vector<cpr::Pair> p;
  72. p.push_back({ "email",username });
  73. p.push_back({ "password",password });
  74. std::string text = PostUrl("/api/client/v3/login", p);
  75. if (text.empty()) {
  76. if (m_http_status == 445)
  77. {
  78. return HTTPRET::http_user_expired_at;
  79. } else if (m_http_status == 446)
  80. {
  81. return HTTPRET::http_user_transfer_enable;
  82. }
  83. else {
  84. return HTTPRET::http_f;
  85. }
  86. }
  87. data = text.c_str();
  88. return HTTPRET::http_yes;
  89. }
  90. HTTPRET CNetWork::GetSysConfigFromUser(LPCSTR username, LPCSTR password, std::string& data) {
  91. std::vector<cpr::Parameter> p;
  92. p.push_back({ "email",username });
  93. p.push_back({ "password",password });
  94. std::string text = GetUrl("/api/client/v3/getconfig", p);
  95. if (text.empty()) {
  96. if (m_http_status == 445)
  97. {
  98. return HTTPRET::http_user_expired_at;
  99. }
  100. else if (m_http_status == 446)
  101. {
  102. return HTTPRET::http_user_transfer_enable;
  103. }
  104. else {
  105. return HTTPRET::http_f;
  106. }
  107. }
  108. data = text.c_str();
  109. return HTTPRET::http_yes;
  110. }
  111. void CNetWork::SetUrl(LPCSTR url)
  112. {
  113. m_url = url;
  114. }
  115. void CNetWork::initSessionPool(int szie) {
  116. for (int i = 0 ; i < szie ; i++)
  117. {
  118. std::shared_ptr<cpr::Session> pp = std::make_shared<cpr::Session>();
  119. m_session_vect.push_back(std::move(pp));
  120. }
  121. }
  122. void CNetWork::DestoryOneConnSessionPool() {
  123. for (auto &conn : m_session_vect)
  124. {
  125. std::move(m_session_vect.front());
  126. }
  127. }
  128. std::shared_ptr<cpr::Session> CNetWork::GetSession() {
  129. std::shared_ptr<cpr::Session> pp = nullptr;
  130. m_mutx.lock();
  131. if (m_session_vect.size() > 0)
  132. {
  133. pp = m_session_vect.front();
  134. m_session_vect.pop_back();
  135. }
  136. m_mutx.unlock();
  137. /*if (pp == nullptr)
  138. {
  139. pp = std::make_shared<cpr::Session>();
  140. }*/
  141. return pp;
  142. }
  143. void CNetWork::pullSession(std::shared_ptr<cpr::Session> &p) {
  144. m_mutx.lock();
  145. m_session_vect.push_back(p);
  146. m_mutx.unlock();
  147. }
  148. SStringA CNetWork::GetLastErrorA()
  149. {
  150. return SStringA().Format("%s", m_error_msg.c_str()).GetBuffer(0);
  151. }
  152. SStringW CNetWork::GetLastErrorW()
  153. {
  154. return S_CA2W(m_error_msg.c_str(),CP_UTF8).GetBuffer(0);
  155. }
  156. std::string CNetWork::GetUrl(std::string path, std::vector<cpr::Parameter> parame,std::string token)
  157. {
  158. cpr::Parameters ps;
  159. std::vector<cpr::Parameter>::iterator it_i;
  160. for (it_i = parame.begin(); it_i != parame.end(); ++it_i)
  161. {
  162. ps.Add(*it_i);
  163. //ps(cpr::Parameter({ it->first, it->second }));
  164. }
  165. cpr::Header hander;
  166. if (!token.empty())
  167. {
  168. hander = cpr::Header{ {"accept", "application/json"} , {"Authorization", "bearer " + token} };
  169. }
  170. else {
  171. hander = cpr::Header{ {"accept", "application/json"} };
  172. }
  173. auto s = fmt::format("{0}{1}", m_url, path.c_str());
  174. cpr::Response r;
  175. std::string res_test = "";
  176. auto session = GetSession();
  177. int count = 3;
  178. do
  179. {
  180. if (count <= 0)
  181. {
  182. break;
  183. }
  184. if (parame.empty())
  185. {
  186. session->SetHeader(hander);
  187. session->SetVerifySsl(false);
  188. session->SetTimeout(cpr::Timeout{TIMEOUTE});
  189. session->SetUrl(s.c_str());
  190. //session->SetDebugCallback()
  191. r = session->Get();
  192. //r = cpr::Get(cpr::Url{ s.c_str() }, cpr::VerifySsl{ false }, hander, cpr::Timeout{ 60 * 1000 });
  193. }
  194. else {
  195. session->SetHeader(hander);
  196. session->SetVerifySsl(false);
  197. session->SetTimeout(cpr::Timeout{ TIMEOUTE });
  198. session->SetUrl(s.c_str());
  199. session->SetParameters(ps);
  200. r = session->Get();
  201. //r = cpr::Get(cpr::Url{ s.c_str() }, cpr::VerifySsl{ false }, ps, hander, cpr::Timeout{ 60 * 1000 });
  202. }
  203. if (r.status_code == 200 || r.status_code == 201)
  204. {
  205. res_test = r.text;
  206. break;
  207. }
  208. else {
  209. m_http_status = r.status_code;
  210. if (r.error.message.empty())
  211. {
  212. m_error_msg = r.status_line;
  213. }
  214. else {
  215. m_error_msg = UpdateError(r.error.code, r.error.message);
  216. }
  217. }
  218. if (!res_test.empty())
  219. {
  220. break;
  221. }
  222. count--;
  223. Logger::getSingletonPtr()->INFO("get 重试" + std::to_string(count) + "次数");
  224. } while (res_test.empty());
  225. pullSession(session);
  226. return res_test;
  227. }
  228. std::string CNetWork::PostUrl(std::string path, std::vector<cpr::Pair> parame, std::string token)
  229. {
  230. auto s = fmt::format("{0}{1}", m_url, path.c_str());
  231. cpr::Header hander;
  232. if (!token.empty())
  233. {
  234. hander = cpr::Header{ {"accept", "application/json"} , {"Authorization", "bearer " + token} };
  235. }
  236. else {
  237. hander = cpr::Header{ {"accept", "application/json"} };
  238. }
  239. cpr::Response r;
  240. std::string res_test = "";
  241. auto session = GetSession();
  242. int count = 3;
  243. do
  244. {
  245. if (count <= 0)
  246. {
  247. break;
  248. }
  249. if (parame.empty())
  250. {
  251. //r = cpr::Get(cpr::Url{ s.c_str() }, hander, cpr::VerifySsl{false}, cpr::Timeout{ 60 * 1000 });
  252. session->SetHeader(hander);
  253. session->SetVerifySsl(false);
  254. session->SetTimeout(cpr::Timeout{ TIMEOUTE });
  255. session->SetUrl(s.c_str());
  256. r = session->Get();
  257. }
  258. else {
  259. session->SetHeader(hander);
  260. session->SetVerifySsl(false);
  261. session->SetTimeout(cpr::Timeout{ TIMEOUTE });
  262. session->SetUrl(s.c_str());
  263. session->SetPayload(cpr::Payload{ parame.begin(),parame.end() });
  264. r = session->Post();
  265. //r = cpr::Post(cpr::Url{ s.c_str() }, cpr::VerifySsl{ false }, cpr::Payload{ parame.begin(),parame.end() }, hander, cpr::Timeout{ 60 * 1000 });
  266. }
  267. //Logger::getSingletonPtr()->DEBUG(r.url.c_str());
  268. if (r.status_code == 200 || r.status_code == 201)
  269. {
  270. res_test = std::move(r.text);
  271. break;
  272. }
  273. else {
  274. m_http_status = r.status_code;
  275. if (r.error.message.empty())
  276. {
  277. m_error_msg = r.status_line;
  278. }
  279. else {
  280. m_error_msg = UpdateError(r.error.code, r.error.message);
  281. }
  282. }
  283. if (!res_test.empty())
  284. {
  285. break;
  286. }
  287. Logger::getSingletonPtr()->INFO("重试" + std::to_string(count) + "次数");
  288. count--;
  289. } while (res_test.empty());
  290. pullSession(session);
  291. return res_test;
  292. }
  293. std::string CNetWork::Retrying(std::string path, std::vector<cpr::Parameter> parame, std::string token)
  294. {
  295. std::string res_test = "";
  296. int count = 3;
  297. do
  298. {
  299. if (count <= 0)
  300. {
  301. break;
  302. }
  303. res_test = GetUrl(path, parame, token);
  304. if (!res_test.empty())
  305. {
  306. break;
  307. }
  308. count--;
  309. } while (res_test.empty());
  310. return res_test;
  311. }
  312. bool write_data(std::string /*data*/, intptr_t /*userdata*/)
  313. {
  314. return true;
  315. }
  316. bool CNetWork::Download(std::string path)
  317. {
  318. return false;
  319. /*std::string configdir = std::filesystem::current_path().string() + "\\" + CLASHCONFIGDIR;
  320. std::filesystem::path p(configdir);
  321. if (!std::filesystem::exists(p)) {
  322. std::filesystem::create_directory(p);
  323. }
  324. std::string configname = configdir + "\\" CLASHCONFIGNAME;
  325. std::ofstream ofs(configname);
  326. cpr::Url url{ path };
  327. cpr::Session session;
  328. session.SetUrl(url);
  329. cpr::Response response = session.Download(ofs);
  330. return response.status_code == 200;*/
  331. }
  332. void CNetWork::Init()
  333. {
  334. }
  335. void CNetWork::UnInit()
  336. {
  337. }
  338. std::string CNetWork::UpdateError(cpr::ErrorCode code, std::string msg)
  339. {
  340. if (code == cpr::ErrorCode::HOST_RESOLUTION_FAILURE)
  341. {
  342. m_error_msg = "解析域名失败";
  343. }
  344. else if (code == cpr::ErrorCode::OPERATION_TIMEDOUT)
  345. {
  346. m_error_msg = "请求数据超时,请重新请求";
  347. }
  348. else if (code == cpr::ErrorCode::CONNECTION_FAILURE) {
  349. m_error_msg = "发送服务器失败";
  350. }
  351. else if (code == cpr::ErrorCode::INVALID_URL_FORMAT) {
  352. m_error_msg = "未知URL错误";
  353. } else if (code == cpr::ErrorCode::SSL_CONNECT_ERROR)
  354. {
  355. m_error_msg = "SSL连接错误";
  356. }
  357. else {
  358. m_error_msg = msg;
  359. }
  360. return m_error_msg;
  361. }