http_client_plus.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. /*Software License
  2. Copyright(C) 2024[liuyingjie]
  3. License Terms
  4. Usage Rights
  5. Any individual or entity is free to use, copy, and distribute the binary form of this software without modification to the source code, without the need to disclose the source code.
  6. If the source code is modified, the modifications must be open - sourced under the same license.This means that the modifications must be disclosed and accompanied by a copy of this license.
  7. Future Versions Updates
  8. From this version onwards, all future releases will be governed by the terms of the latest version of the license.This license will automatically be nullified and replaced by the new version.
  9. Users must comply with the terms of the new license issued in future releases.
  10. Liability and Disclaimer
  11. This software is provided “as is”, without any express or implied warranties, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non - infringement.In no event shall the author or copyright holder be liable for any claims, damages, or other liabilities, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
  12. Contact Information
  13. If you have any questions, please contact us: 1585346868@qq.com Or visit our website fwlua.com.
  14. */
  15. #include "net/http_client_plus.h"
  16. #if USE_NET_HTTP_CLIENT
  17. #include "HPSocket/HPSocket.h"
  18. #include "HPSocket/HPSocket-SSL.h"
  19. #include <string.h>
  20. #include <iostream>
  21. #include <sstream>
  22. #include <string>
  23. #include <iomanip>
  24. #include "base/conversion.h"
  25. #include "util/codec.h"
  26. #include "util/strutils.h"
  27. #include "util/time.h"
  28. #include "util/system.h"
  29. #define _DEBUG_CLIENT 0
  30. #define CLIENT ((IHttpClient*)client())
  31. class http_client_listener :public IHttpClientListener
  32. {
  33. public:
  34. http_client_listener()
  35. {
  36. m_client = nullptr;
  37. m_status = 0;
  38. m_download_callback = nullptr;
  39. m_download_callback_end = nullptr;
  40. m_download_callback_failed = nullptr;
  41. m_content_length = 0;
  42. m_recv_body_length = 0;
  43. transfer_encoding_length = -1;
  44. }
  45. // 通过 IHttpClientListener 继承
  46. virtual EnHttpParseResult OnMessageBegin(IHttpClient* pSender, CONNID dwConnID) override
  47. {
  48. if (m_client->m_close == true)
  49. return HPR_ERROR;
  50. #if _DEBUG_CLIENT == 1
  51. std::cout << "[OnMessageBegin]:\t" << dwConnID << std::endl;
  52. #endif
  53. transfer_encoding_length = -1;
  54. m_response_body.clear();
  55. m_recv_body_length = 0;
  56. m_status = 0;
  57. return HPR_OK;
  58. }
  59. virtual EnHttpParseResult OnRequestLine(IHttpClient* pSender, CONNID dwConnID, LPCSTR lpszMethod, LPCSTR lpszUrl) override
  60. {
  61. #if _DEBUG_CLIENT == 1
  62. std::cout << "[OnRequestLine]:\t" << dwConnID<<"\t"<<lpszMethod<<"\t"<<lpszUrl << std::endl;
  63. #endif
  64. return HPR_OK;
  65. }
  66. virtual EnHttpParseResult OnStatusLine(IHttpClient* pSender, CONNID dwConnID, USHORT usStatusCode, LPCSTR lpszDesc) override
  67. {
  68. #if _DEBUG_CLIENT == 1
  69. std::cout << "[OnStatusLine]:\t" << dwConnID << "\t" << usStatusCode << "\t" << lpszDesc << std::endl;
  70. #endif
  71. m_status = usStatusCode;
  72. return HPR_OK;
  73. }
  74. virtual EnHttpParseResult OnHeader(IHttpClient* pSender, CONNID dwConnID, LPCSTR lpszName, LPCSTR lpszValue) override
  75. {
  76. if (m_client->m_close == true)
  77. return HPR_ERROR;
  78. #if _DEBUG_CLIENT == 1
  79. std::cout << "[OnHeader]:\t" << dwConnID << "\t" << lpszName << ": " << lpszValue << std::endl;
  80. #endif
  81. if (strcmp("Content-Length", lpszName) == 0)
  82. {
  83. m_content_length = ylib::stoull(lpszValue);
  84. }
  85. m_headers_response.set(lpszName,lpszValue);
  86. return HPR_OK;
  87. }
  88. virtual EnHttpParseResult OnHeadersComplete(IHttpClient* pSender, CONNID dwConnID) override
  89. {
  90. #if _DEBUG_CLIENT == 1
  91. std::cout << "[OnHeadersComplete]"<< std::endl;
  92. #endif
  93. //m_recv_state = 1;
  94. return HPR_OK;
  95. }
  96. std::string dec2hex(int i) //将int转成16进制字符串
  97. {
  98. std::stringstream ioss; //定义字符串流
  99. std::string s_temp; //存放转化后字符
  100. ioss << std::setiosflags(std::ios::uppercase) << std::hex << i; //以十六制(大写)形式输出
  101. //ioss << resetiosflags(ios::uppercase) << hex << i; //以十六制(小写)形式输出//取消大写的设置
  102. ioss >> s_temp;
  103. return s_temp;
  104. }
  105. virtual EnHttpParseResult OnBody(IHttpClient* pSender, CONNID dwConnID, const BYTE* pData, int iLength) override
  106. {
  107. #if _DEBUG_CLIENT == 1
  108. std::cout << "[OnBody]:\t"<< iLength << std::endl;
  109. #endif
  110. if (m_client->m_close == true)
  111. return HPR_ERROR;
  112. if (m_download_callback != nullptr)
  113. {
  114. m_recv_body_length += iLength;
  115. if (m_download_callback((void*)pData, iLength, m_recv_body_length,m_content_length, *m_client))
  116. return EnHttpParseResult::HPR_OK;
  117. else
  118. return EnHttpParseResult::HPR_ERROR;
  119. }
  120. else
  121. {
  122. //if (transfer_encoding_length != -1)
  123. //{
  124. // std::string length = dec2hex(iLength) + "\r\n";
  125. // m_response_body.append(length);
  126. //}
  127. m_response_body.append((char*)pData, iLength);
  128. #ifdef _DEBUG
  129. iLength++;
  130. #endif
  131. }
  132. return EnHttpParseResult::HPR_OK;
  133. }
  134. virtual EnHttpParseResult OnChunkHeader(IHttpClient* pSender, CONNID dwConnID, int iLength) override
  135. {
  136. if (m_client->m_close == true)
  137. return HPR_ERROR;
  138. transfer_encoding_length += iLength;
  139. #if _DEBUG_CLIENT == 1
  140. std::cout << "[OnChunkHeader]:\t" << dwConnID<<"\t"<<iLength << std::endl;
  141. #endif
  142. return EnHttpParseResult::HPR_OK;
  143. }
  144. virtual EnHttpParseResult OnChunkComplete(IHttpClient* pSender, CONNID dwConnID) override
  145. {
  146. #if _DEBUG_CLIENT == 1
  147. std::cout << "[OnChunkComplete]:\t" << dwConnID << std::endl;
  148. #endif
  149. //m_response_body.append("\r\n0\r\n\r\n\r\n",9);
  150. return EnHttpParseResult::HPR_OK;
  151. }
  152. virtual EnHttpParseResult OnMessageComplete(IHttpClient* pSender, CONNID dwConnID) override
  153. {
  154. #if _DEBUG_CLIENT == 1
  155. std::cout << "[OnMessageComplete]:\t" << dwConnID << std::endl;
  156. #endif
  157. if (m_download_callback_end!= nullptr)
  158. m_download_callback_end(*m_client);
  159. m_recv_state = 1;
  160. return EnHttpParseResult::HPR_OK;
  161. }
  162. virtual EnHttpParseResult OnUpgrade(IHttpClient* pSender, CONNID dwConnID, EnHttpUpgradeType enUpgradeType) override
  163. {
  164. #if _DEBUG_CLIENT == 1
  165. std::cout << "[OnUpgrade]:\t" << dwConnID << std::endl;
  166. #endif
  167. return EnHttpParseResult::HPR_OK;
  168. }
  169. virtual EnHttpParseResult OnParseError(IHttpClient* pSender, CONNID dwConnID, int iErrorCode, LPCSTR lpszErrorDesc) override
  170. {
  171. #if _DEBUG_CLIENT == 1
  172. std::cout << "[OnParseError]:\t" << dwConnID << std::endl;
  173. #endif
  174. if (m_download_callback_failed != nullptr)
  175. m_download_callback_failed(*m_client);
  176. m_recv_state = 2;
  177. return EnHttpParseResult::HPR_OK;
  178. }
  179. virtual EnHandleResult OnWSMessageHeader(IHttpClient* pSender, CONNID dwConnID, BOOL bFinal, BYTE iReserved, BYTE iOperationCode, const BYTE lpszMask[4], ULONGLONG ullBodyLen) override
  180. {
  181. #if _DEBUG_CLIENT == 1
  182. std::cout << "[OnWSMessageHeader]:\t" << dwConnID << std::endl;
  183. #endif
  184. return EnHandleResult::HR_OK;
  185. }
  186. virtual EnHandleResult OnWSMessageBody(IHttpClient* pSender, CONNID dwConnID, const BYTE* pData, int iLength) override
  187. {
  188. #if _DEBUG_CLIENT == 1
  189. std::cout << "[OnWSMessageBody]:\t" << dwConnID << std::endl;
  190. #endif
  191. return EnHandleResult::HR_OK;
  192. }
  193. virtual EnHandleResult OnWSMessageComplete(IHttpClient* pSender, CONNID dwConnID) override
  194. {
  195. #if _DEBUG_CLIENT == 1
  196. std::cout << "[OnWSMessageComplete]:\t" << dwConnID << std::endl;
  197. #endif
  198. return EnHandleResult::HR_OK;
  199. }
  200. virtual EnHandleResult OnHandShake(ITcpClient* pSender, CONNID dwConnID) override
  201. {
  202. #if _DEBUG_CLIENT == 1
  203. std::cout << "[OnHandShake]:\t" << dwConnID << std::endl;
  204. #endif
  205. m_connect_state = 2;
  206. return EnHandleResult::HR_OK;
  207. }
  208. virtual EnHandleResult OnSend(ITcpClient* pSender, CONNID dwConnID, const BYTE* pData, int iLength) override
  209. {
  210. #if _DEBUG_CLIENT == 1
  211. std::cout << "[OnSend]:\t Length:"<< iLength<<" dwConnID:" << dwConnID << std::endl;
  212. #endif
  213. if(m_client->m_close == true)
  214. return EnHandleResult::HR_ERROR;
  215. return EnHandleResult::HR_OK;
  216. }
  217. virtual EnHandleResult OnReceive(ITcpClient* pSender, CONNID dwConnID, const BYTE* pData, int iLength) override
  218. {
  219. #if _DEBUG_CLIENT == 1
  220. std::cout << "[OnReceive]:\t Length:" << iLength << " dwConnID:" << dwConnID << std::endl;
  221. #endif
  222. if (m_client->m_close == true)
  223. return EnHandleResult::HR_ERROR;
  224. return EnHandleResult::HR_OK;
  225. }
  226. virtual EnHandleResult OnReceive(ITcpClient* pSender, CONNID dwConnID, int iLength) override
  227. {
  228. #if _DEBUG_CLIENT == 1
  229. std::cout << "[OnReceive2]:\t Length:" << iLength << " dwConnID:" << dwConnID << std::endl;
  230. #endif
  231. if (m_client->m_close == true)
  232. return EnHandleResult::HR_ERROR;
  233. return EnHandleResult::HR_OK;
  234. }
  235. virtual EnHandleResult OnClose(ITcpClient* pSender, CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode) override
  236. {
  237. #if _DEBUG_CLIENT == 1
  238. std::cout << "[OnClose]:\t" << dwConnID << std::endl;
  239. #endif
  240. m_recv_state = 2;
  241. m_connect_state = 0;
  242. return EnHandleResult::HR_OK;
  243. }
  244. virtual EnHandleResult OnPrepareConnect(ITcpClient* pSender, CONNID dwConnID, SOCKET socket) override
  245. {
  246. #if _DEBUG_CLIENT == 1
  247. std::cout << "[OnPrepareConnect]:\t" << dwConnID << std::endl;
  248. #endif
  249. return EnHandleResult::HR_OK;
  250. }
  251. virtual EnHandleResult OnConnect(ITcpClient* pSender, CONNID dwConnID) override
  252. {
  253. #if _DEBUG_CLIENT == 1
  254. std::cout << "[OnConnect]:\t" << dwConnID << std::endl;
  255. #endif
  256. return EnHandleResult::HR_OK;
  257. }
  258. public:
  259. int32 transfer_encoding_length;
  260. // 预计接收长度
  261. uint64 m_content_length;
  262. // 已接收长度
  263. uint64 m_recv_body_length;
  264. // 客户端
  265. network::http::client_plus *m_client;
  266. // 0=已断开 1=连接中 2=已连接
  267. int m_connect_state = 0;
  268. // 0=请求中 1=接收成功 2=请求失败
  269. int m_recv_state = 0;
  270. // 返回数据
  271. ylib::buffer m_response_body;
  272. // [header] 响应
  273. network::http::header_list m_headers_response;
  274. // 状态码
  275. ushort m_status;
  276. std::function<bool(void* data, uint32 downsize, uint64 alldownsize,uint64 allsize,ylib::network::http::client_plus& client)> m_download_callback;
  277. std::function<void(ylib::network::http::client_plus& client)> m_download_callback_end;
  278. std::function<void(ylib::network::http::client_plus& client)> m_download_callback_failed;
  279. };
  280. void ylib::network::http::client_plus::close()
  281. {
  282. m_close = true;
  283. }
  284. ylib::network::http::client_plus::client_plus()
  285. {
  286. m_listener = new http_client_listener;
  287. m_client_ssl = HP_Create_HttpsClient(m_listener);
  288. m_client = HP_Create_HttpClient(m_listener);
  289. m_listener->m_client = this;
  290. m_init = false;
  291. m_port = 0;
  292. m_ssl = false;
  293. m_timeout_connect_msec = 3000;
  294. m_timeout_recv_msec = 8000;
  295. m_cache = nullptr;
  296. m_close = false;
  297. }
  298. ylib::network::http::client_plus::~client_plus()
  299. {
  300. ((IHttpClient*)m_client_ssl)->Stop();
  301. ((IHttpClient*)m_client_ssl)->Wait();
  302. HP_Destroy_HttpsClient(((IHttpClient*)m_client_ssl));
  303. ((IHttpClient*)m_client)->Stop();
  304. ((IHttpClient*)m_client)->Wait();
  305. HP_Destroy_HttpClient(((IHttpClient*)m_client));
  306. delete m_listener;
  307. }
  308. void ylib::network::http::client_plus::set_timeout(uint32 connect_msec, uint32 recv_msec)
  309. {
  310. m_timeout_connect_msec = connect_msec;
  311. m_timeout_recv_msec = recv_msec;
  312. }
  313. bool ylib::network::http::client_plus::del(const std::string& url, const std::map<std::string, std::string>& value)
  314. {
  315. m_method = "DELETE";
  316. std::string param_str;
  317. for_iter(iter, value)
  318. param_str += (param_str.length() == 0 ? "" : "&") + iter->first + "=" + iter->second;
  319. if(!init())
  320. return false;
  321. if(!parseurl(std::string(url + (param_str.length() == 0 ? "" : "?") + param_str)))
  322. return false;
  323. m_url = url;
  324. if(!connect())
  325. return false;
  326. return request();
  327. }
  328. bool ylib::network::http::client_plus::get(const std::string& url, const std::map<std::string, std::string>& value,bool wait)
  329. {
  330. m_request_wait = wait;
  331. m_method = "GET";
  332. std::string param_str;
  333. for_iter(iter, value)
  334. param_str += (param_str.length() == 0 ? "" : "&") + iter->first + "=" + iter->second;
  335. if(!init())
  336. return false;
  337. if(!parseurl(std::string(url + (param_str.length() == 0 ? "" : "?") + param_str)))
  338. return false;
  339. m_url = url;
  340. if(!connect())
  341. return false;
  342. return request();
  343. }
  344. bool ylib::network::http::client_plus::post(const std::string& url, const std::map<std::string, std::string>& value,bool to_utf8)
  345. {
  346. m_request_wait = true;
  347. std::string param_str;
  348. for_iter(iter, value)
  349. param_str += (param_str.length() == 0 ? "" : "&") + iter->first + "=" + iter->second;
  350. if (to_utf8)
  351. {
  352. param_str = codec::to_utf8(param_str);
  353. m_headers_request.set("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
  354. }
  355. else
  356. {
  357. m_headers_request.set("Content-Type", "application/x-www-form-urlencoded");
  358. }
  359. m_request_body = param_str;
  360. return post(url);
  361. }
  362. bool ylib::network::http::client_plus::post(const std::string& url, const ylib::json& value, bool to_utf8)
  363. {
  364. m_headers_request.set("Content-Type", "application/json");
  365. ylib::buffer data;
  366. if (to_utf8)
  367. data = codec::to_utf8(value.to_string());
  368. else
  369. data = value.to_string();
  370. return post(url,data);
  371. }
  372. bool ylib::network::http::client_plus::post(const std::string& url, const ylib::buffer& value)
  373. {
  374. m_request_body = value;
  375. return post(url);
  376. }
  377. //bool ylib::network::http::client_plus::post(const std::string& url, const http::make_form& value)
  378. //{
  379. // std::string boundary;
  380. // value.make(m_request_body, boundary);
  381. // m_headers_request.set("Content-Type", "boundary=" + boundary + "; multipart/form-data");
  382. // return post(url);
  383. //}
  384. bool ylib::network::http::client_plus::head(const std::string& url)
  385. {
  386. m_method = "HEAD";
  387. if (!init())
  388. return false;
  389. if (!parseurl(url))
  390. return false;
  391. m_url = url;
  392. if (!connect())
  393. return false;
  394. return request();
  395. }
  396. void ylib::network::http::client_plus::setproxy(const std::string& address, ushort port)
  397. {
  398. m_proxy.address = address;
  399. m_proxy.port = port;
  400. }
  401. network::http::header_list& ylib::network::http::client_plus::headers_request()
  402. {
  403. // TODO: 在此处插入 return 语句
  404. return m_headers_request;
  405. }
  406. network::http::header_list& ylib::network::http::client_plus::headers_response()
  407. {
  408. // TODO: 在此处插入 return 语句
  409. return m_listener->m_headers_response;
  410. }
  411. uint32 ylib::network::http::client_plus::status()
  412. {
  413. return m_listener->m_status;
  414. }
  415. ylib::buffer& ylib::network::http::client_plus::response()
  416. {
  417. return m_listener->m_response_body;
  418. }
  419. void ylib::network::http::client_plus::cache(client_cache* cache)
  420. {
  421. m_cache = cache;
  422. }
  423. bool ylib::network::http::client_plus::parseurl(std::string url)
  424. {
  425. url = strutils::trim_end(url, { '/','\\'});
  426. if (strutils::left(url,7) == "http://")
  427. m_ssl = false;
  428. else if (strutils::left(url,8) == "https://")
  429. m_ssl = true;
  430. else
  431. {
  432. m_lastErrorDesc = "Only https and http protocols are supported,Bad address:"+std::string(url);
  433. return false;
  434. }
  435. std::string pu;
  436. if (m_ssl)
  437. pu = strutils::right(url,url.length() - 8);
  438. else
  439. pu = strutils::right(url,url.length() - 7);
  440. size_t index = pu.find("/");
  441. if (index != -1)
  442. {
  443. m_path = strutils::right(pu,pu.length() - index);
  444. auto arr =strutils::split(pu,'/');
  445. if (arr.size() < 2)
  446. {
  447. m_lastErrorDesc = "parseurl failed 0x01";
  448. return false;
  449. }
  450. pu = arr[0];
  451. }
  452. else
  453. m_path = "/";
  454. // www.baidu.com:443
  455. index = pu.find(":");
  456. if (index == -1)
  457. {
  458. if (m_ssl)
  459. m_port = 443;
  460. else
  461. m_port = 80;
  462. }
  463. else
  464. {
  465. auto arr = strutils::split(pu,':');
  466. if (arr.size() != 2)
  467. {
  468. m_lastErrorDesc = "parseurl failed 0x02";
  469. return false;
  470. }
  471. pu = arr[0];
  472. m_port = (ushort)ylib::stoi(arr[1]);
  473. }
  474. m_ipaddress = pu;// network::to_ip(pu);
  475. /*if (m_proxy.address != "")
  476. m_ssl = false;*/
  477. // if (m_ssl)
  478. // {
  479. // std::cout << "The hpsocket does not support the https protocol. Please define a LIB_ HPSOCKET_ SSL Macro" << std::endl;
  480. // }
  481. return true;
  482. }
  483. bool ylib::network::http::client_plus::connect()
  484. {
  485. if (m_listener->m_connect_state == 2)
  486. return true;
  487. m_close = false;
  488. m_listener->m_connect_state = 1;
  489. bool connect_result = false;
  490. if (m_proxy.address == "")
  491. connect_result = CLIENT->Start(m_ipaddress.c_str(), m_port);
  492. else
  493. connect_result = CLIENT->Start(m_proxy.address.c_str(), m_proxy.port);
  494. if (connect_result == false)
  495. {
  496. m_lastErrorDesc = std::string("start failed," + std::to_string((uint64)SYS_GetLastError()));
  497. return false;
  498. }
  499. timestamp start_msec = time::now_msec();
  500. while (m_listener->m_connect_state == 1)
  501. {
  502. system::sleep_msec(10);
  503. if (start_msec + m_timeout_connect_msec < time::now_msec())
  504. {
  505. m_lastErrorDesc = "connection timed out";
  506. return false;
  507. }
  508. }
  509. if(m_proxy.address == "")
  510. return m_listener->m_connect_state == 2;
  511. return init_proxy();
  512. }
  513. bool ylib::network::http::client_plus::init()
  514. {
  515. ((IHttpClient*)m_client)->Stop();
  516. ((IHttpClient*)m_client)->Wait();
  517. ((IHttpClient*)m_client_ssl)->Stop();
  518. ((IHttpClient*)m_client_ssl)->Wait();
  519. ((IHttpClient*)m_client_ssl)->CleanupSSLContext();
  520. if (((IHttpClient*)m_client_ssl)->SetupSSLContext() == false)
  521. {
  522. m_lastErrorDesc = std::string("SetupSSLContext failed," + std::to_string((uint64)SYS_GetLastError())).c_str();
  523. return false;
  524. }
  525. return true;
  526. }
  527. bool ylib::network::http::client_plus::request()
  528. {
  529. // std::cout << CLIENT->GetSSLCipherList() << std::endl;
  530. m_listener->m_recv_state = 0;
  531. if (m_method == "GET")
  532. {
  533. //【缓存】置头
  534. if (m_cache != nullptr)
  535. {
  536. m_cache->set_header(this, m_url);
  537. }
  538. }
  539. //置Cookie
  540. {
  541. if (m_cookie.to_string() != "")
  542. {
  543. m_headers_request.set("Cookie", m_cookie.to_string());
  544. }
  545. }
  546. //完善协议头
  547. {
  548. if(m_headers_request.exist("User-Agent") == false)
  549. m_headers_request.set("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0");
  550. if (m_headers_request.exist("Accept") == false)
  551. m_headers_request.set("Accept", "*/*");
  552. if (m_headers_request.exist("Accept-Language") == false)
  553. m_headers_request.set("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
  554. if (m_headers_request.exist("Connection") == false)
  555. {
  556. if(m_proxy.address == "")
  557. m_headers_request.set("Connection", "keep-alive");
  558. else
  559. m_headers_request.set("Connection", "close");
  560. }
  561. if (m_headers_request.exist("Host") == false)
  562. {
  563. std::string header_host = m_ipaddress;
  564. if (m_port != 80 && m_port != 443)
  565. header_host += (":" + std::to_string(m_port));
  566. m_headers_request.set("Host", header_host);
  567. }
  568. }
  569. THeader* pHeader = nullptr;
  570. auto header_map = m_headers_request.to();
  571. size_t nHeader = header_map.size();
  572. if (nHeader != 0)
  573. pHeader = new THeader[nHeader];
  574. size_t count = 0;
  575. for_iter(iter,header_map)
  576. {
  577. pHeader[count].name = iter->first.c_str();
  578. pHeader[count].value = iter->second.c_str();
  579. count++;
  580. }
  581. bool result = CLIENT->SendRequest(
  582. m_method.c_str(),
  583. m_path.c_str(),
  584. pHeader,
  585. (int)nHeader,
  586. (const BYTE*)m_request_body.data(),
  587. (int)m_request_body.length()
  588. );
  589. delete[] pHeader;
  590. if (result == false)
  591. {
  592. uint64 error = SYS_GetLastError();
  593. m_lastErrorDesc = std::string("request failed," +std::to_string((uint64)error));
  594. return false;
  595. }
  596. if(m_request_wait == false)
  597. return true;
  598. timestamp start_msec = time::now_msec();
  599. while (m_listener->m_recv_state == 0)
  600. {
  601. system::sleep_msec(10);
  602. if (start_msec + m_timeout_recv_msec < time::now_msec())
  603. {
  604. m_lastErrorDesc = "recv timed out";
  605. return false;
  606. }
  607. }
  608. result = m_listener->m_recv_state == 1;
  609. if(!result)
  610. return false;
  611. //【缓存】判断缓存
  612. if (m_cache != nullptr && m_method == "GET")
  613. {
  614. bool cache = false;
  615. if (this->status() == 304)
  616. {
  617. cache = m_cache->read(this, m_listener->m_response_body);
  618. }
  619. if (cache == false)
  620. {
  621. m_cache->write(this);
  622. }
  623. }
  624. //合并响应cookie
  625. {
  626. if (m_listener->m_headers_response.exist("Set-Cookie") != false && m_listener->m_headers_response.get("Set-Cookie").to_string() != "")
  627. m_cookie.merge(m_listener->m_headers_response.get("Set-Cookie").to_string());
  628. }
  629. return !m_close;
  630. }
  631. bool ylib::network::http::client_plus::post(const std::string& url)
  632. {
  633. m_method = "POST";
  634. if(!init())
  635. return false;
  636. if(!parseurl(url))
  637. return false;
  638. m_url = url;
  639. if(!connect())
  640. return false;
  641. return request();
  642. }
  643. void* ylib::network::http::client_plus::client()
  644. {
  645. if (m_ssl)
  646. {
  647. return m_client_ssl;
  648. }
  649. else
  650. return m_client;
  651. }
  652. bool ylib::network::http::client_plus::init_proxy()
  653. {
  654. std::string path = m_ipaddress+":"+std::to_string(m_port);
  655. THeader header[2];
  656. header[0].name = "Host";
  657. header[0].value = path.c_str();
  658. header[1].name = "Proxy-Connection";
  659. header[1].value = "keep-alive";
  660. bool result = CLIENT->SendRequest("CONNECT",path.c_str(),header,2);
  661. if (result == false)
  662. {
  663. uint64 error = SYS_GetLastError();
  664. m_lastErrorDesc = std::string("proxy request failed," + std::to_string((uint64)error));
  665. return false;
  666. }
  667. if (m_request_wait == false)
  668. return true;
  669. timestamp start_msec = time::now_msec();
  670. while (m_listener->m_recv_state == 0)
  671. {
  672. system::sleep_msec(10);
  673. if (start_msec + m_timeout_recv_msec < time::now_msec())
  674. {
  675. m_lastErrorDesc = "recv timed out";
  676. return false;
  677. }
  678. }
  679. result = m_listener->m_recv_state == 1;
  680. if (!result)
  681. return false;
  682. return m_listener->m_status == 200;
  683. }
  684. void ylib::network::http::client_plus::on_down_ing(const std::function<bool(void* data, uint32 downsize, uint64 alldownsize, uint64 allsize, ylib::network::http::client_plus& client) > & callback)
  685. { m_listener->m_download_callback = callback; }
  686. void ylib::network::http::client_plus::on_down_end(const std::function<void(ylib::network::http::client_plus& client)>& callback)
  687. { m_listener->m_download_callback_end = callback; }
  688. void ylib::network::http::client_plus::on_down_failed(const std::function<void(ylib::network::http::client_plus& client)>& callback)
  689. { m_listener->m_download_callback_failed = callback; }
  690. void ylib::network::http::client_plus::clear_all_cookies()
  691. {
  692. HP_HttpCookie_MGR_ClearCookies();
  693. }
  694. #endif