CNetWork.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  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::GetloginByUrl(LPCSTR key,std::string & data)
  18. {
  19. std::vector<cpr::Pair> p;
  20. p.push_back({ "redirect", "dashboard"});
  21. p.push_back({ "token", CApp::getSingletonPtr()->GetLoginInfo()->token.c_str() });
  22. p.push_back({ "auth_data", CApp::getSingletonPtr()->GetLoginInfo()->auth_data.c_str() });
  23. std::string text = PostUrl("/api/v1/manage/auth/getQuickLoginUrl", p, "");
  24. if (text.empty()) {
  25. return HTTPRET::http_f;
  26. }
  27. data = text.c_str();
  28. return HTTPRET::http_yes;
  29. }
  30. HTTPRET CNetWork::GetMySub(std::string& data)
  31. {
  32. std::vector<cpr::Parameter> p;
  33. p.push_back({ "token", CApp::getSingletonPtr()->GetLoginInfo()->token.c_str() });
  34. p.push_back({ "auth_data", CApp::getSingletonPtr()->GetLoginInfo()->auth_data.c_str() });
  35. std::string text = GetUrl("/api/v1/manager/getSubscribe", p, "");
  36. if (text.empty()) {
  37. return HTTPRET::http_f;
  38. }
  39. data = text.c_str();
  40. return HTTPRET::http_yes;
  41. return HTTPRET();
  42. }
  43. void CNetWork::SetUrlArray(std::vector<ServerListUrl> data) {
  44. m_url_list = data;
  45. }
  46. HTTPRET CNetWork::Version(std::string& data) {
  47. std::vector<cpr::Pair> p;
  48. p.push_back({ "from","win" });
  49. p.push_back({ "version",S_CW2A(VERSION).GetBuffer(0) });
  50. p.push_back({ "token", CApp::getSingletonPtr()->GetLoginInfo()->token.c_str() });
  51. p.push_back({ "auth_data", CApp::getSingletonPtr()->GetLoginInfo()->auth_data.c_str() });
  52. std::string text = PostUrl("/api/v1/manage/app/getVersion", p, "");
  53. if (text.empty()) {
  54. return HTTPRET::http_f;
  55. }
  56. data = text.c_str();
  57. return HTTPRET::http_yes;
  58. }
  59. HTTPRET CNetWork::Refresh(std::string& data) {
  60. std::vector<cpr::Parameter> p;
  61. std::string text = GetUrl("/api/client/v3/refresh", p, CApp::getSingletonPtr()->GetLoginInfo()->token);
  62. if (text.empty()) {
  63. return HTTPRET::http_f;
  64. }
  65. data = text.c_str();
  66. return HTTPRET::http_yes;
  67. }
  68. HTTPRET CNetWork::Auth(std::string& data){
  69. std::vector<cpr::Parameter> p;
  70. std::string text = GetUrl("/api/client/v3/authUser",p,CApp::getSingletonPtr()->GetLoginInfo()->token);
  71. if (text.empty()) {
  72. return HTTPRET::http_f;
  73. }
  74. data = text.c_str();
  75. return HTTPRET::http_yes;
  76. }
  77. HTTPRET CNetWork::GetServerNode(std::string& data) {
  78. std::vector<cpr::Parameter> p;
  79. p.push_back({ "token", CApp::getSingletonPtr()->GetLoginInfo()->token.c_str() });
  80. p.push_back({ "auth_data", CApp::getSingletonPtr()->GetLoginInfo()->auth_data.c_str() });
  81. std::string text = GetUrl("/api/v1/manager/server/fetch",p,"");
  82. if (text.empty()) {
  83. return HTTPRET::http_f;
  84. }
  85. data = text.c_str();
  86. return HTTPRET::http_yes;
  87. }
  88. HTTPRET CNetWork::GetSysConfig(std::string& data)
  89. {
  90. AutoToggleNode();
  91. std::vector<cpr::Parameter> p;
  92. std::string text = GetUrl("/api/v1/manage/getUrl", p);
  93. if (text.empty()) {
  94. if (m_http_status == 445)
  95. {
  96. return HTTPRET::http_user_expired_at;
  97. }
  98. else if (m_http_status == 446)
  99. {
  100. return HTTPRET::http_user_transfer_enable;
  101. }
  102. else {
  103. return HTTPRET::http_f;
  104. }
  105. }
  106. data = text.c_str();
  107. return HTTPRET::http_yes;
  108. }
  109. HTTPRET CNetWork::PostReg(LPCSTR username, LPCSTR password, std::string& data) {
  110. std::vector<cpr::Pair> p;
  111. p.push_back({ "username",""});
  112. p.push_back({ "email",username });
  113. p.push_back({ "password",password });
  114. std::string text = PostUrl("/api/client/v2/register", p);
  115. if (text.empty()) {
  116. if (m_http_status == 445)
  117. {
  118. return HTTPRET::http_user_expired_at;
  119. }
  120. else if (m_http_status == 446)
  121. {
  122. return HTTPRET::http_user_transfer_enable;
  123. }
  124. else if (m_http_status == 447) {
  125. return HTTPRET::http_user_enable;
  126. }
  127. else {
  128. return HTTPRET::http_f;
  129. }
  130. }
  131. data = text.c_str();
  132. return HTTPRET::http_yes;
  133. }
  134. HTTPRET CNetWork::PostLogin(LPCSTR username, LPCSTR password, std::string& data)
  135. {
  136. std::vector<cpr::Pair> p;
  137. p.push_back({ "email",username });
  138. p.push_back({ "password",password });
  139. std::string text = PostUrl("/api/v1/manage/auth/login/", p);
  140. if (text.empty()) {
  141. if (m_http_status == 445)
  142. {
  143. return HTTPRET::http_user_expired_at;
  144. } else if (m_http_status == 446)
  145. {
  146. return HTTPRET::http_user_transfer_enable;
  147. }
  148. else if (m_http_status == 447) {
  149. return HTTPRET::http_user_enable;
  150. }
  151. else {
  152. return HTTPRET::http_f;
  153. }
  154. }
  155. data = text.c_str();
  156. return HTTPRET::http_yes;
  157. }
  158. HTTPRET CNetWork::GetSysConfigFromUser(LPCSTR username, LPCSTR password, std::string& data) {
  159. std::vector<cpr::Parameter> p;
  160. p.push_back({ "email",username });
  161. p.push_back({ "password",password });
  162. std::string text = GetUrl("/api/client/v3/getconfig", p);
  163. if (text.empty()) {
  164. if (m_http_status == 445)
  165. {
  166. return HTTPRET::http_user_expired_at;
  167. }
  168. else if (m_http_status == 446)
  169. {
  170. return HTTPRET::http_user_transfer_enable;
  171. }
  172. else {
  173. return HTTPRET::http_f;
  174. }
  175. }
  176. data = text.c_str();
  177. return HTTPRET::http_yes;
  178. }
  179. void CNetWork::SetUrl(LPCSTR url)
  180. {
  181. m_url = url;
  182. }
  183. void CNetWork::initSessionPool(int szie) {
  184. for (int i = 0 ; i < szie ; i++)
  185. {
  186. std::shared_ptr<cpr::Session> pp = std::make_shared<cpr::Session>();
  187. m_session_vect.push_back(std::move(pp));
  188. }
  189. }
  190. void CNetWork::DestoryOneConnSessionPool() {
  191. for (auto &conn : m_session_vect)
  192. {
  193. std::move(m_session_vect.front());
  194. }
  195. }
  196. std::shared_ptr<cpr::Session> CNetWork::GetSession() {
  197. std::shared_ptr<cpr::Session> pp = nullptr;
  198. m_mutx.lock();
  199. if (m_session_vect.size() > 0)
  200. {
  201. pp = m_session_vect.front();
  202. m_session_vect.pop_back();
  203. }
  204. m_mutx.unlock();
  205. /*if (pp == nullptr)
  206. {
  207. pp = std::make_shared<cpr::Session>();
  208. }*/
  209. return pp;
  210. }
  211. void CNetWork::pullSession(std::shared_ptr<cpr::Session> &p) {
  212. m_mutx.lock();
  213. m_session_vect.push_back(p);
  214. m_mutx.unlock();
  215. }
  216. SStringA CNetWork::GetLastErrorA()
  217. {
  218. return SStringA().Format("%s", m_error_msg.c_str()).GetBuffer(0);
  219. }
  220. SStringW CNetWork::GetLastErrorW()
  221. {
  222. return S_CA2W(m_error_msg.c_str(),CP_UTF8).GetBuffer(0);
  223. }
  224. std::string CNetWork::GetUrl(std::string path, std::vector<cpr::Parameter> parame,std::string token)
  225. {
  226. cpr::Parameters ps;
  227. std::vector<cpr::Parameter>::iterator it_i;
  228. for (it_i = parame.begin(); it_i != parame.end(); ++it_i)
  229. {
  230. ps.Add(*it_i);
  231. //ps(cpr::Parameter({ it->first, it->second }));
  232. }
  233. cpr::Header hander;
  234. if (!token.empty())
  235. {
  236. hander = cpr::Header{ {"accept", "application/json"} , {"Authorization", "bearer " + token} };
  237. }
  238. else {
  239. hander = cpr::Header{ {"accept", "application/json"} };
  240. }
  241. cpr::Response r;
  242. std::string res_test = "";
  243. //auto session = GetSession();
  244. int count = 3;
  245. /*int serverurlid = 0;*/
  246. do
  247. {
  248. if (count <= 0)
  249. {
  250. break;
  251. }
  252. auto s = fmt::format("{0}{1}", m_url, path.c_str());
  253. if (parame.empty())
  254. {
  255. m_session.SetHeader(hander);
  256. m_session.SetVerifySsl(false);
  257. m_session.SetTimeout(cpr::Timeout{TIMEOUTE});
  258. m_session.SetUrl(s.c_str());
  259. //session->SetDebugCallback()
  260. r = m_session.Get();
  261. //r = cpr::Get(cpr::Url{ s.c_str() }, cpr::VerifySsl{ false }, hander, cpr::Timeout{ 60 * 1000 });
  262. }
  263. else {
  264. m_session.SetHeader(hander);
  265. m_session.SetVerifySsl(false);
  266. m_session.SetTimeout(cpr::Timeout{ TIMEOUTE });
  267. m_session.SetUrl(s.c_str());
  268. m_session.SetParameters(ps);
  269. r = m_session.Get();
  270. //r = cpr::Get(cpr::Url{ s.c_str() }, cpr::VerifySsl{ false }, ps, hander, cpr::Timeout{ 60 * 1000 });
  271. }
  272. if (r.status_code == 200 || r.status_code == 201)
  273. {
  274. res_test = r.text;
  275. break;
  276. }
  277. else {
  278. m_http_status = r.status_code;
  279. if (r.error.message.empty())
  280. {
  281. m_error_msg = r.status_line;
  282. }
  283. else {
  284. m_error_msg = UpdateError(r.error.code, r.error.message);
  285. }
  286. }
  287. if (!res_test.empty())
  288. {
  289. break;
  290. }
  291. Sleep(3000);
  292. count--;
  293. Logger::getSingletonPtr()->INFO("get 重试" + std::to_string(count) + "次数");
  294. } while (res_test.empty());
  295. //pullSession(session);
  296. return res_test;
  297. }
  298. std::string CNetWork::PostUrl(std::string path, std::vector<cpr::Pair> parame, std::string token)
  299. {
  300. auto s = fmt::format("{0}{1}", m_url, path.c_str());
  301. cpr::Header hander;
  302. if (!token.empty())
  303. {
  304. hander = cpr::Header{ {"accept", "application/json"} , {"Authorization", "bearer " + token} };
  305. }
  306. else {
  307. hander = cpr::Header{ {"accept", "application/json"} };
  308. }
  309. cpr::Response r;
  310. std::string res_test = "";
  311. /**
  312. * \brief
  313. * \param
  314. * \param
  315. * \param
  316. * \return
  317. */
  318. int count = 3;
  319. do
  320. {
  321. if (count <= 0)
  322. {
  323. break;
  324. }
  325. if (parame.empty())
  326. {
  327. //r = cpr::Get(cpr::Url{ s.c_str() }, hander, cpr::VerifySsl{false}, cpr::Timeout{ 60 * 1000 });
  328. m_session.SetHeader(hander);
  329. m_session.SetVerifySsl(false);
  330. m_session.SetTimeout(cpr::Timeout{ TIMEOUTE });
  331. m_session.SetUrl(s.c_str());
  332. r = m_session.Get();
  333. }
  334. else {
  335. m_session.SetHeader(hander);
  336. m_session.SetVerifySsl(false);
  337. m_session.SetTimeout(cpr::Timeout{ TIMEOUTE });
  338. m_session.SetUrl(s.c_str());
  339. m_session.SetPayload(cpr::Payload{ parame.begin(),parame.end() });
  340. r = m_session.Post();
  341. //r = cpr::Post(cpr::Url{ s.c_str() }, cpr::VerifySsl{ false }, cpr::Payload{ parame.begin(),parame.end() }, hander, cpr::Timeout{ 60 * 1000 });
  342. }
  343. //Logger::getSingletonPtr()->DEBUG(r.url.c_str());
  344. if (r.status_code == 200 || r.status_code == 201)
  345. {
  346. res_test = std::move(r.text);
  347. break;
  348. }
  349. else {
  350. m_http_status = r.status_code;
  351. if (r.error.message.empty())
  352. {
  353. m_error_msg = r.status_line;
  354. }
  355. else {
  356. m_error_msg = UpdateError(r.error.code, r.error.message);
  357. }
  358. }
  359. if (!res_test.empty())
  360. {
  361. break;
  362. }
  363. Logger::getSingletonPtr()->INFO("重试" + std::to_string(count) + "次数");
  364. count--;
  365. } while (res_test.empty());
  366. //pullSession(session);
  367. return res_test;
  368. }
  369. void CNetWork::AutoToggleNode() {
  370. cpr::Header hander;
  371. hander = cpr::Header{ {"accept", "application/json"} };
  372. std::vector<cpr::Parameter> p;
  373. p.push_back({ "tag","win" });
  374. p.push_back({ "appverion",S_CW2A(VERSION).GetBuffer(0) });
  375. cpr::Parameters ps;
  376. std::vector<cpr::Parameter>::iterator it_i;
  377. for (it_i = p.begin(); it_i != p.end(); ++it_i)
  378. {
  379. ps.Add(*it_i);
  380. //ps(cpr::Parameter({ it->first, it->second }));
  381. }
  382. //m_url_list.reserve(m_url.size());
  383. //切换节点,
  384. for each (ServerListUrl itme in m_url_list)
  385. {
  386. cpr::Session m_session;
  387. auto s = fmt::format("{0}{1}", itme.url, "/api/v1/manage/getUrl");
  388. m_session.SetHeader(hander);
  389. m_session.SetVerifySsl(false);
  390. m_session.SetTimeout(cpr::Timeout{ TIMEOUTE });
  391. m_session.SetUrl(s.c_str());
  392. m_session.SetParameters(ps);
  393. auto r = m_session.Get();
  394. if (r.status_code != 200) {
  395. continue;
  396. }
  397. else
  398. {
  399. if (m_url != itme.url)
  400. {
  401. m_url = itme.url;
  402. Logger::getSingletonPtr()->INFO(S_CW2A(itme.name).GetBuffer(0));
  403. }
  404. break;
  405. }
  406. }
  407. }
  408. std::string CNetWork::Retrying(std::string path, std::vector<cpr::Parameter> parame, std::string token)
  409. {
  410. std::string res_test = "";
  411. int count = 3;
  412. do
  413. {
  414. if (count <= 0)
  415. {
  416. break;
  417. }
  418. res_test = GetUrl(path, parame, token);
  419. if (!res_test.empty())
  420. {
  421. break;
  422. }
  423. count--;
  424. } while (res_test.empty());
  425. return res_test;
  426. }
  427. bool write_data(std::string /*data*/, intptr_t /*userdata*/)
  428. {
  429. return true;
  430. }
  431. bool CNetWork::Download(std::string path)
  432. {
  433. //return false;
  434. std::string configdir = std::filesystem::current_path().string() + "\\" + S_CW2A(CLASH_ASSETS_DIR_NAME).GetBuffer(0);
  435. std::filesystem::path p(configdir);
  436. if (!std::filesystem::exists(p)) {
  437. std::filesystem::create_directory(p);
  438. }
  439. std::string configname = configdir + "\\" + CLASHCONFIGDIR;
  440. std::ofstream ofs(configname);
  441. cpr::Url url{ path };
  442. cpr::Session session;
  443. session.SetUrl(url);
  444. cpr::Response response = session.Download(ofs);
  445. return response.status_code == 200;
  446. }
  447. void CNetWork::Init()
  448. {
  449. }
  450. void CNetWork::UnInit()
  451. {
  452. }
  453. std::string CNetWork::UpdateError(cpr::ErrorCode code, std::string msg)
  454. {
  455. if (code == cpr::ErrorCode::HOST_RESOLUTION_FAILURE)
  456. {
  457. m_error_msg = "解析域名失败";
  458. }
  459. else if (code == cpr::ErrorCode::OPERATION_TIMEDOUT)
  460. {
  461. m_error_msg = "请求数据超时,请重新请求";
  462. }
  463. else if (code == cpr::ErrorCode::CONNECTION_FAILURE) {
  464. m_error_msg = "发送服务器失败";
  465. }
  466. else if (code == cpr::ErrorCode::INVALID_URL_FORMAT) {
  467. m_error_msg = "未知URL错误";
  468. } else if (code == cpr::ErrorCode::SSL_CONNECT_ERROR)
  469. {
  470. m_error_msg = "SSL连接错误";
  471. }
  472. else {
  473. m_error_msg = msg;
  474. }
  475. return m_error_msg;
  476. }