HTTP.cpp 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110
  1. #include "StdAfx.h"
  2. #include "HTTP.h"
  3. #include "CodePageConvert.h"
  4. CDNSMap CHTTP::m_mapDNS; //DNS缓存表
  5. CHTTP::CHTTP(void)
  6. {
  7. m_pchRecvData = NULL;
  8. m_nDataSize = 0;
  9. }
  10. CHTTP::~CHTTP(void)
  11. {
  12. //释放接收的数据
  13. if (m_pchRecvData != NULL)
  14. {
  15. free(m_pchRecvData);
  16. m_pchRecvData = NULL;
  17. }
  18. m_nDataSize = 0;
  19. }
  20. int CHTTP::Init(void)
  21. {
  22. m_strURL = "";
  23. m_strHeader = "";
  24. m_bPost = false;
  25. m_strPostData = "";
  26. m_strWait = "";
  27. m_bNeedHeader = "";
  28. m_uiCodePage = CP_ACP;
  29. m_strPtl = "";
  30. m_strDomain = "";
  31. m_strPath = "";
  32. m_nPort = 8000;
  33. m_nPtlTailPos = string::npos;
  34. m_nDomainTailPos = string::npos;
  35. m_nConnTimeoutBak = m_nConnTimeout = HTTP::CONN_TIMEOUT_DEFAULT;
  36. m_nSendTimeoutBak = m_nSendTimeout = 100000;
  37. m_nRecvTimeoutBak = m_nRecvTimeout = 100000;
  38. m_listCookies.clear();
  39. m_strRecvData = "";
  40. m_nHeaderLen = -1;
  41. m_nBodyLen = -1;
  42. m_inputs = nullptr;
  43. m_bStartup = false;
  44. m_socket = INVALID_SOCKET;
  45. return 0;
  46. }
  47. /******************************************************************************
  48. HTTP的GET操作
  49. ******************************************************************************/
  50. int CHTTP::Get(string & strHTML, string strURL
  51. , string strHeader
  52. , string strWait, bool bNeedHeader)
  53. {
  54. m_strURL = strURL;
  55. m_strHeader = strHeader;
  56. m_bPost = false;
  57. m_strPostData = "";
  58. m_strWait = strWait;
  59. m_bNeedHeader = bNeedHeader;
  60. //获取HTML字符串
  61. int nGetHTMLStr = _GetHTMLStr(strHTML);
  62. if (nGetHTMLStr != 0)
  63. {
  64. return nGetHTMLStr;
  65. }
  66. return 0;
  67. }
  68. /******************************************************************************
  69. HTTP的POST操作
  70. ******************************************************************************/
  71. int CHTTP::Post(string & strHTML, string strURL, string strPostData
  72. , string strHeader
  73. , string strWait, bool bNeedHeader)
  74. {
  75. m_strURL = strURL;
  76. m_strHeader = strHeader;
  77. m_bPost = true;
  78. m_strPostData = strPostData;
  79. m_inputs = nullptr;
  80. m_strWait = strWait;
  81. m_bNeedHeader = bNeedHeader;
  82. //获取HTML字符串
  83. int nGetHTMLStr = _GetHTMLStr(strHTML);
  84. if (nGetHTMLStr != 0)
  85. {
  86. return nGetHTMLStr;
  87. }
  88. return 0;
  89. }
  90. /******************************************************************************
  91. HTTP的POST操作
  92. ******************************************************************************/
  93. int CHTTP::PostFile(string & strHTML, string strURL, std::vector<CInputFiled*>& inputs
  94. , string strHeader
  95. , string strWait , bool bNeedHeader )
  96. {
  97. m_strURL = strURL;
  98. m_strHeader = strHeader;
  99. m_bPost = true;
  100. m_strPostData = "";
  101. m_inputs = &inputs;
  102. m_strWait = strWait;
  103. m_bNeedHeader = bNeedHeader;
  104. //获取HTML字符串
  105. int nGetHTMLStr = _GetHTMLStr(strHTML);
  106. if (nGetHTMLStr != 0)
  107. {
  108. return nGetHTMLStr;
  109. }
  110. }
  111. /******************************************************************************
  112. GET图片数据
  113. ******************************************************************************/
  114. int CHTTP::GetImg(char * & pchImgData, int & nImgSize
  115. , string strURL, string strHeader)
  116. {
  117. m_strURL = strURL;
  118. m_strHeader = strHeader;
  119. m_bPost = false;
  120. m_strPostData = "";
  121. m_strWait = "";
  122. m_bNeedHeader = false;
  123. //执行HTTP操作
  124. int nExecute = _Execute();
  125. if (nExecute != 0)
  126. {
  127. return nExecute;
  128. }
  129. //返回图片数据
  130. if (m_pchRecvData == NULL)
  131. {
  132. return HTTP::GET_IMG_DATA_NULL;
  133. }
  134. if (m_nDataSize <= 0)
  135. {
  136. return HTTP::GET_IMG_SIZE_INVALID;
  137. }
  138. pchImgData = m_pchRecvData;
  139. nImgSize = m_nDataSize;
  140. return 0;
  141. }
  142. /******************************************************************************
  143. 设置超时时间
  144. ******************************************************************************/
  145. void CHTTP::SetTimeout(int nConnTimeout, int nSendTimeout, int nRecvTimeout)
  146. {
  147. //先备份值
  148. m_nConnTimeoutBak = m_nConnTimeout;
  149. m_nSendTimeoutBak = m_nSendTimeout;
  150. m_nRecvTimeoutBak = m_nRecvTimeout;
  151. //修改值
  152. m_nConnTimeout = nConnTimeout;
  153. m_nSendTimeout = nSendTimeout;
  154. m_nRecvTimeout = nRecvTimeout;
  155. }
  156. /******************************************************************************
  157. 恢复上次设置的超时时间
  158. ******************************************************************************/
  159. void CHTTP::SetTimeoutBack(void)
  160. {
  161. m_nConnTimeout = m_nConnTimeoutBak;
  162. m_nSendTimeout = m_nSendTimeoutBak;
  163. m_nRecvTimeout = m_nRecvTimeoutBak;
  164. }
  165. /******************************************************************************
  166. 添加一个Cookie项
  167. ******************************************************************************/
  168. int CHTTP::AddCookie(string strCookie)
  169. {
  170. if (strCookie == "")
  171. {
  172. return HTTP::ADD_COOKIE_STRING_COOKIE_NULL;
  173. }
  174. //分解此Cookie
  175. HTTP::SCookie sCookie;
  176. int nParseCookie = _ParseCookieStr(sCookie, strCookie);
  177. if (nParseCookie != 0)
  178. {
  179. return nParseCookie;
  180. }
  181. if (sCookie.strName == "")
  182. {
  183. return HTTP::ADD_COOKIE_STRING_NAME_NULL;
  184. }
  185. //添加到Cookie列表
  186. int nAddCookie = _AddCookie(sCookie);
  187. if (nAddCookie != 0)
  188. {
  189. return nAddCookie;
  190. }
  191. return 0;
  192. }
  193. /******************************************************************************
  194. 获取Cookies字符串
  195. ******************************************************************************/
  196. string CHTTP::GetCookies(bool bOnlyNameValue)
  197. {
  198. string strCookies = "";
  199. //分隔符,默认为;;,如果只需要Cookie名和值,则为;
  200. string strSplit = ";; ";
  201. if (bOnlyNameValue)
  202. {
  203. strSplit = "; ";
  204. }
  205. //遍历Cookies表
  206. int nListSize = m_listCookies.size();
  207. for (int i = 0; i < nListSize; i++)
  208. {
  209. //提取一条Cookie
  210. HTTP::SCookie const & sCookie = m_listCookies[i];
  211. string strCookie = "";
  212. strCookie += sCookie.strName + "=" + sCookie.strValue;
  213. if (!bOnlyNameValue)
  214. {
  215. if (sCookie.strPath != "")
  216. {
  217. strCookie += "; path=" + sCookie.strPath;
  218. }
  219. if (sCookie.strDomain != "")
  220. {
  221. strCookie += "; domain=" + sCookie.strDomain;
  222. }
  223. }
  224. //添加到Cookies字符串中
  225. strCookies += (strCookies == "") ? "" : strSplit;
  226. strCookies += strCookie;
  227. }
  228. return strCookies;
  229. }
  230. /******************************************************************************
  231. 设置Cookies
  232. ******************************************************************************/
  233. int CHTTP::SetCookies(string strCookies)
  234. {
  235. //清空Cookies表
  236. m_listCookies.clear();
  237. if (strCookies == "")
  238. {
  239. return 0;
  240. }
  241. //默认用 ;; 分割
  242. string strSplit = ";;";
  243. //如果找不到分割字符串,则用 ; 分割
  244. if (strCookies.find(strSplit) == string::npos)
  245. {
  246. strSplit = ";";
  247. }
  248. //分割字符串
  249. vector<string> listCookies;
  250. _SplitStr(listCookies, strCookies, strSplit);
  251. //添加每一个Cookies
  252. int nListLen = listCookies.size();
  253. for (int i = 0; i < nListLen; i++)
  254. {
  255. string strCookie = listCookies[i];
  256. if (strCookie != "")
  257. {
  258. int nAddCookie = AddCookie(strCookie);
  259. if (nAddCookie != 0)
  260. {
  261. return nAddCookie;
  262. }
  263. }
  264. }
  265. return 0;
  266. }
  267. /******************************************************************************
  268. 设置编码方式
  269. ******************************************************************************/
  270. void CHTTP::SetCodePage(UINT uiCodePage)
  271. {
  272. m_uiCodePage = uiCodePage;
  273. }
  274. /******************************************************************************
  275. 清除DNS缓存
  276. ******************************************************************************/
  277. int CHTTP::ClearDNS(void)
  278. {
  279. //清空DNS缓存表
  280. int nClearDNS = m_mapDNS.ClearDNS();
  281. if (nClearDNS != 0)
  282. {
  283. return nClearDNS;
  284. }
  285. return 0;
  286. }
  287. /******************************************************************************
  288. 执行HTTP操作
  289. ******************************************************************************/
  290. int CHTTP::_Execute(void)
  291. {
  292. //分解URL
  293. int nParseURL = _ParseURL();
  294. if (nParseURL != 0)
  295. {
  296. return nParseURL;
  297. }
  298. //开始访问
  299. int nStartVisit = _StartVisitFile();
  300. //结束访问,保证句柄释放,所以放到这里执行
  301. int nEndVisit = _EndVisit();
  302. if (nStartVisit != 0)
  303. {
  304. return nStartVisit;
  305. }
  306. if (nEndVisit != 0)
  307. {
  308. return nEndVisit;
  309. }
  310. return 0;
  311. }
  312. /******************************************************************************
  313. 获取HTML字符串
  314. ******************************************************************************/
  315. int CHTTP::_GetHTMLStr(string & strHTML)
  316. {
  317. //执行HTTP操作
  318. int nExecute = _Execute();
  319. if (nExecute != 0)
  320. {
  321. return nExecute;
  322. }
  323. //编码转换
  324. int nEncodeRecvStr = _EncodeRecvStr();
  325. if (nEncodeRecvStr != 0)
  326. {
  327. return nEncodeRecvStr;
  328. }
  329. //返回值
  330. strHTML = m_strRecvData;
  331. return 0;
  332. }
  333. /******************************************************************************
  334. 分解URL
  335. ******************************************************************************/
  336. int CHTTP::_ParseURL(void)
  337. {
  338. //获取协议
  339. int nCutURLPtl = _CutURLPtl();
  340. if (nCutURLPtl != 0)
  341. {
  342. return nCutURLPtl;
  343. }
  344. //获取域名
  345. int nCutURLDomain = _CutURLDomain();
  346. if (nCutURLDomain != 0)
  347. {
  348. return nCutURLDomain;
  349. }
  350. //提取路径
  351. int nCutURLPath = _CutURLPath();
  352. if (nCutURLPath != 0)
  353. {
  354. return nCutURLPath;
  355. }
  356. return 0;
  357. }
  358. /******************************************************************************
  359. 连接服务器
  360. ******************************************************************************/
  361. int CHTTP::_ConnServer(void)
  362. {
  363. //启动并创建套接字
  364. int nStartupCreateSocket = _StartupCreateSocket();
  365. if (nStartupCreateSocket != 0)
  366. {
  367. return nStartupCreateSocket;
  368. }
  369. //填写地址信息
  370. sockaddr_in addr = {0};
  371. int nFillAddrInfo = _FillAddrInfo(addr);
  372. if (nFillAddrInfo != 0)
  373. {
  374. return nFillAddrInfo;
  375. }
  376. //带超时的连接
  377. int nConnWithTimeout = _ConnWithTimeout(addr);
  378. if (nConnWithTimeout != 0)
  379. {
  380. return nConnWithTimeout;
  381. }
  382. //设置套接字的超时
  383. int nSetSocketTimeout = _SetSocketTimeout();
  384. if (nSetSocketTimeout != 0)
  385. {
  386. return nSetSocketTimeout;
  387. }
  388. return 0;
  389. }
  390. /******************************************************************************
  391. 发送数据
  392. ******************************************************************************/
  393. int CHTTP::_SendData(void)
  394. {
  395. string strSendData = "";
  396. //构造请求头
  397. string strHeader = _MakeHeader();
  398. //添加请求头,添加头和尾
  399. if (m_strPath == "")
  400. {
  401. return HTTP::SEND_DATA_PATH_NULL;
  402. }
  403. strSendData += (m_bPost ? "POST " : "GET ") + m_strPath + " HTTP/1.1\r\n";
  404. strSendData += strHeader;
  405. strSendData += "\r\n\r\n";
  406. //编码POST数据
  407. if (m_bPost)
  408. {
  409. int nEncodePostData = _EncodePostData();
  410. if (nEncodePostData != 0)
  411. {
  412. return nEncodePostData;
  413. }
  414. strSendData += m_strPostData;
  415. }
  416. //发送数据
  417. if (m_socket == INVALID_SOCKET)
  418. {
  419. return HTTP::SEND_DATA_INVALID_SOCKET;
  420. }
  421. if (send(m_socket, strSendData.c_str(), strSendData.length(), 0)
  422. == SOCKET_ERROR)
  423. {
  424. return HTTP::SEND_DATA_SEND_FAIL;
  425. }
  426. return 0;
  427. }
  428. /******************************************************************************
  429. 接收数据
  430. ******************************************************************************/
  431. int CHTTP::_RecvData(void)
  432. {
  433. //接收响应数据
  434. int nRecvResponseData = _RecvResponseData();
  435. if (nRecvResponseData != 0)
  436. {
  437. return nRecvResponseData;
  438. }
  439. //提取Cookies
  440. int nGetResponseCookies = _GetResponseCookies();
  441. if (nGetResponseCookies != 0)
  442. {
  443. return nGetResponseCookies;
  444. }
  445. //剔除响应数据的头部
  446. int nRejectHeader = _RejectHeader();
  447. if (nRejectHeader != 0)
  448. {
  449. return nRejectHeader;
  450. }
  451. return 0;
  452. }
  453. /******************************************************************************
  454. 剔除响应数据的头部
  455. ******************************************************************************/
  456. int CHTTP::_RejectHeader(void)
  457. {
  458. //如果需要响应头,则不剔除
  459. if (m_bNeedHeader)
  460. {
  461. return 0;
  462. }
  463. //剔除接收数据的响应头
  464. if (m_nDataSize <= 0)
  465. {
  466. return HTTP::REJECT_HEADER_DATA_SIZE_INVALID;
  467. }
  468. if (m_nHeaderLen <= 0)
  469. {
  470. return HTTP::REJECT_HEADER_HEADER_LEN_INVALID;
  471. }
  472. if (m_pchRecvData == NULL)
  473. {
  474. return HTTP::REJECT_HEADER_RECV_DATA_NULL;
  475. }
  476. m_nDataSize -= m_nHeaderLen;
  477. memmove(m_pchRecvData, m_pchRecvData + m_nHeaderLen, m_nDataSize);
  478. //重新转换字符串
  479. int nTransDataToStr = _TransDataToStr();
  480. if (nTransDataToStr != 0)
  481. {
  482. return nTransDataToStr;
  483. }
  484. return 0;
  485. }
  486. /******************************************************************************
  487. 提取响应数据的Cookies
  488. ******************************************************************************/
  489. int CHTTP::_GetResponseCookies(void)
  490. {
  491. //提取响应头
  492. if (m_strRecvData == "")
  493. {
  494. return HTTP::GET_RESPONSE_COOKIES_RECV_DATA_NULL;
  495. }
  496. if (m_nHeaderLen <= 0)
  497. {
  498. return HTTP::GET_RESPONSE_COOKIES_HEADER_LEN_INVALID;
  499. }
  500. string strHeader = m_strRecvData.substr(0, m_nHeaderLen);
  501. if (strHeader == "")
  502. {
  503. return HTTP::GET_RESPONSE_COOKIES_HEADER_NULL;
  504. }
  505. //提取Cookies
  506. vector<string> listCookies;
  507. _SplitStr(listCookies, strHeader, "\r\n");
  508. int nListLen = listCookies.size();
  509. for (int i = 0; i < nListLen; i++)
  510. {
  511. string strCookie = listCookies[i];
  512. if (strCookie == ""
  513. || strCookie.find("Set-Cookie:") == string::npos)
  514. {
  515. continue;
  516. }
  517. _ReplaceString(strCookie, "Set-Cookie:", "");
  518. if (strCookie != "")
  519. {
  520. int nAddCookie = AddCookie(strCookie);
  521. if (nAddCookie != 0)
  522. {
  523. return nAddCookie;
  524. }
  525. }
  526. }
  527. return 0;
  528. }
  529. /******************************************************************************
  530. 接收响应数据
  531. ******************************************************************************/
  532. int CHTTP::_RecvResponseData(void)
  533. {
  534. //接收数据初始化
  535. m_nDataSize = 0;
  536. m_strRecvData = "";
  537. m_nHeaderLen = -1;
  538. m_nBodyLen = -1;
  539. //当接收没有结束时,循环接收数据
  540. while (!_IsEndRecv())
  541. {
  542. //接收一次数据
  543. int nRecvEachData = _RecvEachData();
  544. if (nRecvEachData != 0)
  545. {
  546. return nRecvEachData;
  547. }
  548. //把收到的数据转换成字符串
  549. int nTransDataToStr = _TransDataToStr();
  550. if (nTransDataToStr != 0)
  551. {
  552. return nTransDataToStr;
  553. }
  554. }
  555. return 0;
  556. }
  557. /******************************************************************************
  558. 一次一次接收数据
  559. ******************************************************************************/
  560. int CHTTP::_RecvEachData(void)
  561. {
  562. //申请内存
  563. if (m_nDataSize < 0)
  564. {
  565. return HTTP::RECV_EACH_DATA_SIZE_INVALID;
  566. }
  567. m_nDataSize += HTTP::RECV_BUF_SIZE;
  568. char * pchRecvData = (char *)realloc(m_pchRecvData, m_nDataSize);
  569. if (pchRecvData == NULL)
  570. {
  571. return HTTP::RECV_EACH_DATA_MALLOC_FAIL;
  572. }
  573. m_pchRecvData = pchRecvData;
  574. //接收数据
  575. if (m_socket == INVALID_SOCKET)
  576. {
  577. return HTTP::RECV_EACH_DATA_INVALID_SOCKET;
  578. }
  579. int nRecv = recv(m_socket
  580. , m_pchRecvData + m_nDataSize - HTTP::RECV_BUF_SIZE
  581. , HTTP::RECV_BUF_SIZE, 0);
  582. if (nRecv == 0)
  583. {
  584. return HTTP::RECV_EACH_DATA_CONN_CLOSE;
  585. }
  586. if (nRecv < 0
  587. || nRecv == SOCKET_ERROR)
  588. {
  589. return HTTP::RECV_EACH_DATA_RECV_FAIL;
  590. }
  591. //修改接收到的数据大小
  592. m_nDataSize -= HTTP::RECV_BUF_SIZE - nRecv;
  593. return 0;
  594. }
  595. /******************************************************************************
  596. 是否结束接收
  597. ******************************************************************************/
  598. bool CHTTP::_IsEndRecv(void)
  599. {
  600. //获取正文长度
  601. _GetBodyLen();
  602. //如果指定了等待字符串,则是否结束接收由这个决定
  603. if (m_strWait != "")
  604. {
  605. return _CheckWaitStr();
  606. }
  607. //如果响应头还没接收完,则继续接收
  608. if (m_nHeaderLen == -1)
  609. {
  610. return false;
  611. }
  612. //如果没有指定正文长度,则结束接收
  613. if (m_nBodyLen == -1)
  614. {
  615. return true;
  616. }
  617. //指定了正文长度,则检测长度,长度达到则结束接收
  618. else if (m_nDataSize - m_nHeaderLen
  619. >= m_nBodyLen)
  620. {
  621. return true;
  622. }
  623. return false;
  624. }
  625. /******************************************************************************
  626. 获取响应数据正文长度
  627. ******************************************************************************/
  628. void CHTTP::_GetBodyLen(void)
  629. {
  630. //如果响应头已经接收完毕,则直接返回
  631. if (m_nHeaderLen != -1)
  632. {
  633. return;
  634. }
  635. //查找响应头结束符
  636. if (m_strRecvData == "")
  637. {
  638. return;
  639. }
  640. string::size_type nHeaderEndPos = m_strRecvData.find("\r\n\r\n");
  641. if (nHeaderEndPos == string::npos)
  642. {
  643. return;
  644. }
  645. m_nHeaderLen = nHeaderEndPos + strlen("\r\n\r\n");
  646. //截取响应头
  647. string strHeader = m_strRecvData.substr(0, m_nHeaderLen);
  648. if (strHeader == "")
  649. {
  650. return;
  651. }
  652. //获取HTTP响应包正文的长度
  653. string strLength = _CutStr(strHeader, "Content-Length:", "\r\n");
  654. if (strLength == "")
  655. {
  656. return;
  657. }
  658. m_nBodyLen = atoi(strLength.c_str());
  659. }
  660. /******************************************************************************
  661. 开始访问
  662. ******************************************************************************/
  663. int CHTTP::_StartVisit(void)
  664. {
  665. //连接服务器
  666. int nConnServer = _ConnServer();
  667. if (nConnServer != 0)
  668. {
  669. return nConnServer;
  670. }
  671. //发送数据
  672. int nSendData = _SendData();
  673. if (nSendData != 0)
  674. {
  675. return nSendData;
  676. }
  677. //接收数据
  678. int nRecvData = _RecvData();
  679. if (nRecvData != 0)
  680. {
  681. return nRecvData;
  682. }
  683. return 0;
  684. }
  685. /******************************************************************************
  686. 开始访问
  687. ******************************************************************************/
  688. int CHTTP::_StartVisitFile(void)
  689. {
  690. //连接服务器
  691. int nConnServer = _ConnServer();
  692. if (nConnServer != 0)
  693. {
  694. return nConnServer;
  695. }
  696. //发送数据
  697. if (m_socket == INVALID_SOCKET)
  698. {
  699. return HTTP::SEND_DATA_INVALID_SOCKET;
  700. }
  701. //发送数据
  702. {
  703. //发送数据差别较大比较
  704. string strSendData = "";
  705. //构造请求头
  706. string strHeader = "POST ";
  707. strHeader += m_strPath;
  708. strHeader += " HTTP/1.1\r\n";
  709. string boundary_value = ("---------------------------7b4a6d158c9");
  710. string boundary = ("--") + boundary_value;
  711. string end_boundary = boundary + ("--");
  712. string end_filed = ("--");
  713. //添加基本请求头
  714. strHeader +=
  715. "Host: " + m_strDomain +
  716. "\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)";
  717. strHeader += "User-Agent: Mozilla/4.0\r\n";
  718. strHeader += "Accept-Language: zh-cn\r\n";
  719. strHeader += "Connection: Keep-Alive\r\n";
  720. strHeader += "Accept: */*\r\n";
  721. strHeader += "Content-Type: multipart/form-data; charset=\"utf-8\"; boundary=---------------------------7b4a6d158c9\r\n";
  722. //指定请求头
  723. if (m_strHeader != "")
  724. {
  725. strHeader += "\r\n";
  726. strHeader += m_strHeader;
  727. }
  728. vector<char*> ff;
  729. vector<int> ff_len;
  730. //编码POST数据
  731. DWORD dwTotalRequestLength = 0;
  732. for (int i = 0; i<(*m_inputs).size(); i++)
  733. {
  734. CString field;
  735. char * filed_str = NULL;
  736. int filedLength = 0;
  737. if ((*m_inputs)[i]->GetType() == INPUT_FILED_VALUE){
  738. field.Format(_T("%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n"), _T("-----------------------------7b4a6d158c9"), (*m_inputs)[i]->GetFiledName(), (*m_inputs)[i]->GetFiledValue());
  739. filedLength = WideCharToMultiByte(CP_UTF8, 0, field, -1, NULL, 0, NULL, NULL);
  740. filed_str = new char[filedLength];
  741. WideCharToMultiByte(CP_UTF8, 0, field, -1, filed_str, filedLength, NULL, NULL);
  742. dwTotalRequestLength += (filedLength - 1);
  743. }
  744. else{
  745. field.Format(_T("%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: image/jpeg\r\n\r\n"), _T("-----------------------------7b4a6d158c9"), (*m_inputs)[i]->GetFiledName(), (*m_inputs)[i]->GetFiledValue());
  746. filedLength = WideCharToMultiByte(CP_UTF8, 0, field, -1, NULL, 0, NULL, NULL);
  747. filed_str = new char[filedLength];
  748. WideCharToMultiByte(CP_UTF8, 0, field, -1, filed_str, filedLength, NULL, NULL);
  749. dwTotalRequestLength += (filedLength - 1);
  750. dwTotalRequestLength +=(*m_inputs)[i]->DataSize();
  751. dwTotalRequestLength += 2;
  752. }
  753. ff.push_back(filed_str);
  754. ff_len.push_back(filedLength);
  755. }
  756. char * filed_str = NULL;
  757. CString field = _T("-----------------------------7b4a6d158c9--");
  758. int endLength = WideCharToMultiByte(CP_UTF8, 0, field, -1, NULL, 0, NULL, NULL);
  759. filed_str = new char[endLength];
  760. WideCharToMultiByte(CP_UTF8, 0, field, -1, filed_str, endLength, NULL, NULL);
  761. dwTotalRequestLength += (endLength - 1);
  762. //strHeader += "Content-Length: 2951835 ";
  763. //strHeader += ("\r\nContent-Type: multipart/form-data; boundary=" + boundary_value);
  764. char temp[64] = { 0 };
  765. //注意下面这个参数Content-Length,这个参数值是:http请求头长度+请求尾长度+文件总长度
  766. sprintf(temp, "Content-Length: %d\r\n\r\n", dwTotalRequestLength);
  767. strHeader += temp;
  768. if (send(m_socket, strHeader.c_str(), strHeader.length(), 0)
  769. == SOCKET_ERROR)
  770. {
  771. return HTTP::SEND_DATA_SEND_FAIL;
  772. }
  773. for (int i = 0; i<(*m_inputs).size(); i++)
  774. {
  775. if ((*m_inputs)[i]->GetType() == INPUT_FILED_VALUE){
  776. if (send(m_socket, ff[i], ff_len[i] - 1, 0) == SOCKET_ERROR)
  777. {
  778. return HTTP::SEND_DATA_SEND_FAIL;
  779. }
  780. }
  781. else{
  782. if (send(m_socket, ff[i], ff_len[i] - 1, 0) == SOCKET_ERROR)
  783. {
  784. return HTTP::SEND_DATA_SEND_FAIL;
  785. }
  786. CInputFiled* input = (*m_inputs)[i];
  787. const int buffer_size = 4 * 1024;
  788. char buffer[buffer_size];
  789. int len;
  790. input->Open();
  791. while ((len = input->Read(buffer, buffer_size))>0){
  792. if (send(m_socket, buffer, len, 0) == SOCKET_ERROR)
  793. {
  794. int fff = WSAGetLastError();
  795. input->Close();
  796. return HTTP::SEND_DATA_SEND_FAIL;
  797. }
  798. }
  799. input->Close();
  800. if (send(m_socket, "\r\n", 2, 0) == SOCKET_ERROR)
  801. {
  802. input->Close();
  803. return HTTP::SEND_DATA_SEND_FAIL;
  804. }
  805. }
  806. }
  807. if (send(m_socket, filed_str, endLength, 0) == SOCKET_ERROR)
  808. {
  809. return HTTP::SEND_DATA_SEND_FAIL;
  810. }
  811. }
  812. //接收数据
  813. int nRecvData = _RecvData();
  814. if (nRecvData != 0)
  815. {
  816. return nRecvData;
  817. }
  818. return 0;
  819. }
  820. /******************************************************************************
  821. 结束访问
  822. ******************************************************************************/
  823. int CHTTP::_EndVisit(void)
  824. {
  825. //关闭套接字
  826. if (m_socket != INVALID_SOCKET)
  827. {
  828. if (closesocket(m_socket) != 0)
  829. {
  830. return HTTP::END_VISIT_CLOSE_FAIL;
  831. }
  832. m_socket = INVALID_SOCKET;
  833. }
  834. //清空套接字
  835. if (m_bStartup)
  836. {
  837. if (WSACleanup() != 0)
  838. {
  839. return HTTP::END_VISIT_CLEAN_FAIL;
  840. }
  841. }
  842. return 0;
  843. }
  844. /******************************************************************************
  845. 把数据转换成字符串
  846. ******************************************************************************/
  847. int CHTTP::_TransDataToStr(void)
  848. {
  849. //没有数据
  850. if (m_nDataSize == 0)
  851. {
  852. m_strRecvData = "";
  853. return 0;
  854. }
  855. //申请多一个字节的内存,存放结束符
  856. if (m_nDataSize < 0)
  857. {
  858. return HTTP::TRANS_DATA_TO_STR_SIZE_INVALID;
  859. }
  860. if (m_pchRecvData == NULL)
  861. {
  862. return HTTP::TRANS_DATA_TO_STR_DATA_NULL;
  863. }
  864. char * pchRecvData = (char *)realloc(m_pchRecvData, m_nDataSize + 1);
  865. if (pchRecvData == NULL)
  866. {
  867. return HTTP::TRANS_DATA_TO_STR_REBUF_FAIL;
  868. }
  869. m_pchRecvData = pchRecvData;
  870. //添加字符串结束符,变成字符串
  871. m_pchRecvData[m_nDataSize] = '\0';
  872. m_strRecvData = m_pchRecvData;
  873. if (m_strRecvData == "")
  874. {
  875. return HTTP::TRANS_DATA_TO_STR_STR_NULL;
  876. }
  877. return 0;
  878. }
  879. /******************************************************************************
  880. 把接收到的字符串编码转换
  881. ******************************************************************************/
  882. int CHTTP::_EncodeRecvStr(void)
  883. {
  884. if (m_strRecvData == "")
  885. {
  886. return 0;
  887. }
  888. //对UTF8编码
  889. if (m_uiCodePage == CP_UTF8)
  890. {
  891. int nTransCodePage = _TransCodePage(
  892. m_strRecvData, CP_ACP, m_uiCodePage);
  893. if (nTransCodePage != 0)
  894. {
  895. return nTransCodePage;
  896. }
  897. if (m_strRecvData == "")
  898. {
  899. return HTTP::ENCODE_RECV_STR_FAIL;
  900. }
  901. }
  902. return 0;
  903. }
  904. /******************************************************************************
  905. 检测等待字符串是否出现
  906. ******************************************************************************/
  907. bool CHTTP::_CheckWaitStr(void)
  908. {
  909. if (m_strWait == "")
  910. {
  911. return false;
  912. }
  913. if (m_strRecvData == "")
  914. {
  915. return false;
  916. }
  917. if (m_strRecvData.find(m_strWait) == string::npos)
  918. {
  919. return false;
  920. }
  921. return true;
  922. }
  923. /******************************************************************************
  924. 编码POST数据
  925. ******************************************************************************/
  926. int CHTTP::_EncodePostData(void)
  927. {
  928. //对UTF8编码
  929. if (m_uiCodePage == CP_UTF8)
  930. {
  931. if (m_strPostData == "")
  932. {
  933. return 0;
  934. }
  935. int nTransCodePage = _TransCodePage(
  936. m_strPostData, m_uiCodePage, CP_ACP);
  937. if (nTransCodePage != 0)
  938. {
  939. return nTransCodePage;
  940. }
  941. if (m_strPostData == "")
  942. {
  943. return HTTP::ENCODE_POST_DATA_FAIL;
  944. }
  945. }
  946. return 0;
  947. }
  948. /******************************************************************************
  949. 获取IP地址
  950. ******************************************************************************/
  951. int CHTTP::_GetIPStr(wstring & strIP)
  952. {
  953. //获取IP字符串
  954. if (m_strDomain == "")
  955. {
  956. return HTTP::GET_IP_STR_DOMAIN_NULL;
  957. }
  958. string strGetIP = "";
  959. int nGetIPStr = m_mapDNS.GetIPStr(strGetIP, m_strDomain);
  960. if (nGetIPStr != 0)
  961. {
  962. return nGetIPStr;
  963. }
  964. if (strGetIP == "")
  965. {
  966. return HTTP::GET_IP_STR_IP_NULL;
  967. }
  968. //转换成宽字符
  969. if (!MBToWC(strIP, strGetIP, CP_ACP))
  970. {
  971. return HTTP::GET_IP_STR_IPW_FAIL;
  972. }
  973. if (strIP == L"")
  974. {
  975. return HTTP::GET_IP_STR_IPW_NULL;
  976. }
  977. return 0;
  978. }
  979. /******************************************************************************
  980. 编码转换
  981. ******************************************************************************/
  982. int CHTTP::_TransCodePage(string & strTrans
  983. , UINT uiDstCodePage, UINT uiSrcCodePage)
  984. {
  985. //先把源串转换为宽字符串
  986. if (strTrans == "")
  987. {
  988. return 0;
  989. }
  990. wstring strWC = L"";
  991. if (!MBToWC(strWC, strTrans, uiSrcCodePage))
  992. {
  993. return HTTP::TRANS_CODE_PAGE_WC_FAIL;
  994. }
  995. if (strWC == L"")
  996. {
  997. return HTTP::TRANS_CODE_PAGE_WC_NULL;
  998. }
  999. //再把宽字符串转换为目标串
  1000. if (!WCToMB(strTrans, strWC, uiDstCodePage))
  1001. {
  1002. return HTTP::TRANS_CODE_PAGE_DST_FAIL;
  1003. }
  1004. if (strTrans == "")
  1005. {
  1006. return HTTP::TRANS_CODE_PAGE_DST_NULL;
  1007. }
  1008. return 0;
  1009. }
  1010. /******************************************************************************
  1011. 构造请求头
  1012. ******************************************************************************/
  1013. string CHTTP::_MakeHeader(void)
  1014. {
  1015. string strHeader = "";
  1016. //添加基本请求头
  1017. strHeader +=
  1018. "Host: " + m_strDomain +
  1019. "\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)";
  1020. //指定请求头
  1021. if (m_strHeader != "")
  1022. {
  1023. strHeader += "\r\n";
  1024. strHeader += m_strHeader;
  1025. }
  1026. //POST请求头
  1027. if (m_bPost)
  1028. {
  1029. strHeader += "\r\n";
  1030. strHeader += "Content-Type: application/x-www-form-urlencoded";
  1031. strHeader += "\r\n";
  1032. strHeader += "Content-Length: ";
  1033. char achBuf[12] = {0};
  1034. _itoa_s(m_strPostData.length(), achBuf, sizeof(achBuf), 10);
  1035. strHeader += achBuf;
  1036. }
  1037. //Cookies
  1038. string strCookies = _MakeCookiesString();
  1039. if (strCookies != "")
  1040. {
  1041. strHeader += "\r\n";
  1042. strHeader += strCookies;
  1043. }
  1044. return strHeader;
  1045. }
  1046. /******************************************************************************
  1047. 截取URL的协议部分
  1048. ******************************************************************************/
  1049. int CHTTP::_CutURLPtl()
  1050. {
  1051. //定位协议冒号和反斜杠
  1052. if (m_strURL == "")
  1053. {
  1054. return HTTP::CUT_URL_PTL_URL_NULL;
  1055. }
  1056. m_nPtlTailPos = m_strURL.find("://");
  1057. if (m_nPtlTailPos == string::npos)
  1058. {
  1059. return HTTP::CUT_URL_PTL_PTL_TAIL_POS;
  1060. }
  1061. //截取协议
  1062. m_strPtl = m_strURL.substr(0, m_nPtlTailPos);
  1063. if (m_strPtl == "")
  1064. {
  1065. return HTTP::CUT_URL_PTL_PTL_NULL;
  1066. }
  1067. //把协议转换成小写
  1068. _ToLower(m_strPtl);
  1069. //协议默认的端口
  1070. if (m_strPtl == "http")
  1071. {
  1072. m_nPort = 80;
  1073. }
  1074. else
  1075. {
  1076. return HTTP::CUT_URL_PTL_PTL_UNKNOW;
  1077. }
  1078. return 0;
  1079. }
  1080. /******************************************************************************
  1081. 截取URL的域名部分
  1082. ******************************************************************************/
  1083. int CHTTP::_CutURLDomain()
  1084. {
  1085. //定位域名后面的反斜杠
  1086. if (m_nPtlTailPos == string::npos)
  1087. {
  1088. return HTTP::CUT_URL_DOMAIN_PTL_TAIL_POS;
  1089. }
  1090. string::size_type nDomainHeadPos = m_nPtlTailPos + strlen("://");
  1091. if (m_strURL == "")
  1092. {
  1093. return HTTP::CUT_URL_DOMAIN_URL_NULL;
  1094. }
  1095. if (nDomainHeadPos >= m_strURL.length())
  1096. {
  1097. return HTTP::CUT_URL_DOMAIN_DOMAIN_HEAD_POS;
  1098. }
  1099. m_nDomainTailPos = m_strURL.find("/", nDomainHeadPos);
  1100. if (m_nDomainTailPos == string::npos)
  1101. {
  1102. return HTTP::CUT_URL_DOMAIN_DOMAIN_TAIL_POS;
  1103. }
  1104. //截取域名
  1105. m_strDomain = m_strURL.substr(nDomainHeadPos
  1106. , m_nDomainTailPos - nDomainHeadPos);
  1107. if (m_strDomain == "")
  1108. {
  1109. return HTTP::CUT_URL_DOMAIN_DOMAIN_NULL;
  1110. }
  1111. //处理域名中包含端口号的情况
  1112. int nProcessDomainPort = _ProcessDomainPort();
  1113. if (nProcessDomainPort != 0)
  1114. {
  1115. return nProcessDomainPort;
  1116. }
  1117. return 0;
  1118. }
  1119. /******************************************************************************
  1120. 处理域名中包含端口号的情况
  1121. ******************************************************************************/
  1122. int CHTTP::_ProcessDomainPort()
  1123. {
  1124. if (m_strDomain == "")
  1125. {
  1126. return HTTP::PROCESS_DOMAIN_PORT_DOMAIN_NULL;
  1127. }
  1128. //检测域名中是否指定了端口
  1129. string::size_type nPortColonPos = m_strDomain.find(":");
  1130. if (nPortColonPos != string::npos)
  1131. {
  1132. //截取端口号
  1133. string::size_type nPortHeadPos = nPortColonPos + strlen(":");
  1134. if (nPortHeadPos >= m_strDomain.length())
  1135. {
  1136. return HTTP::PROCESS_DOMAIN_PORT_PORT_POS;
  1137. }
  1138. string strPort = m_strDomain.substr(nPortHeadPos
  1139. , m_strDomain.length() - nPortHeadPos);
  1140. if (strPort == "")
  1141. {
  1142. return HTTP::PROCESS_DOMAIN_PORT_PORT_NULL;
  1143. }
  1144. //把端口号转换成整型
  1145. m_nPort = (unsigned short)atol(strPort.c_str());
  1146. if (m_nPort == 0)
  1147. {
  1148. return HTTP::PROCESS_DOMAIN_PORT_PORT_ZERO;
  1149. }
  1150. //重新截取域名
  1151. m_strDomain = m_strDomain.substr(0, nPortColonPos);
  1152. if (m_strDomain == "")
  1153. {
  1154. return HTTP::PROCESS_DOMAIN_PORT_DOMAIN_RECUT;
  1155. }
  1156. }
  1157. return 0;
  1158. }
  1159. /******************************************************************************
  1160. 截取URL的路径部分
  1161. ******************************************************************************/
  1162. int CHTTP::_CutURLPath(void)
  1163. {
  1164. if (m_strURL == "")
  1165. {
  1166. return HTTP::CUT_URL_PATH_URL_NULL;
  1167. }
  1168. if (m_nDomainTailPos == string::npos
  1169. || m_nDomainTailPos >= m_strURL.length())
  1170. {
  1171. return HTTP::CUT_URL_PATH_DOMAIN_TAIL_POS;
  1172. }
  1173. m_strPath = m_strURL.substr(m_nDomainTailPos
  1174. , m_strURL.length() - m_nDomainTailPos);
  1175. if (m_strPath == "")
  1176. {
  1177. return HTTP::CUT_URL_PATH_PATH_NULL;
  1178. }
  1179. return 0;
  1180. }
  1181. /******************************************************************************
  1182. 生成Cookies串
  1183. ******************************************************************************/
  1184. string CHTTP::_MakeCookiesString(void)
  1185. {
  1186. string strCookies = "";
  1187. //遍历Cookies列表
  1188. int nListLen = (int)m_listCookies.size();
  1189. for (int i = 0; i < nListLen; i++)
  1190. {
  1191. //提取一条Cookie
  1192. HTTP::SCookie const & sCookie = m_listCookies[i];
  1193. if (sCookie.strName == ""
  1194. || sCookie.strValue == "")
  1195. {
  1196. continue;
  1197. }
  1198. //判断这条Cookie是否匹配域名和路径属性
  1199. if (_IsCookieMatch(sCookie))
  1200. {
  1201. //加入分隔符
  1202. strCookies += (strCookies == "") ? "Cookie: " : "; ";
  1203. //加入键值
  1204. strCookies += sCookie.strName + "=" + sCookie.strValue;
  1205. }
  1206. }
  1207. return strCookies;
  1208. }
  1209. /******************************************************************************
  1210. 判断这条Cookie是否匹配域名和路径属性
  1211. ******************************************************************************/
  1212. bool CHTTP::_IsCookieMatch(HTTP::SCookie const & sCookie)
  1213. {
  1214. //判断是否匹配路径
  1215. if (!_IsCookiePathMatch(sCookie.strPath))
  1216. {
  1217. return false;
  1218. }
  1219. //判断是否匹配域名
  1220. if (!_IsCookieDomainMatch(sCookie.strDomain))
  1221. {
  1222. return false;
  1223. }
  1224. return true;
  1225. }
  1226. /******************************************************************************
  1227. 截取字符串
  1228. ******************************************************************************/
  1229. string CHTTP::_CutStr(string strSource, string strHead, string strTail)
  1230. {
  1231. if (strSource == "")
  1232. {
  1233. return "";
  1234. }
  1235. //便于定位,剔除所有空格
  1236. _ReplaceString(strSource, " ", "");
  1237. if (strSource == "")
  1238. {
  1239. return "";
  1240. }
  1241. //便于定位,转换成小写
  1242. string strSourceLow = strSource;
  1243. string strHeadLow = strHead;
  1244. string strTailLow = strTail;
  1245. _ToLower(strSourceLow);
  1246. _ToLower(strHeadLow);
  1247. _ToLower(strTailLow);
  1248. //定位字符串
  1249. string::size_type nPos = 0;
  1250. string::size_type nLen = 0;
  1251. if (strSourceLow == "")
  1252. {
  1253. return "";
  1254. }
  1255. if (!_PosStr(nPos, nLen, strSourceLow, strHeadLow, strTailLow))
  1256. {
  1257. return "";
  1258. }
  1259. if (nPos < 0
  1260. || nPos >= strSource.length()
  1261. || nLen < 0)
  1262. {
  1263. return "";
  1264. }
  1265. //截取字符串
  1266. return strSource.substr(nPos, nLen);
  1267. }
  1268. /******************************************************************************
  1269. 定位字符串
  1270. ******************************************************************************/
  1271. bool CHTTP::_PosStr(string::size_type & nPos, string::size_type & nLen,
  1272. string strSourceLow, string strHeadLow, string strTailLow)
  1273. {
  1274. if (strSourceLow == "")
  1275. {
  1276. return false;
  1277. }
  1278. //头定位
  1279. string::size_type nHeadPos = strSourceLow.find(strHeadLow);
  1280. if (nHeadPos == string::npos)
  1281. {
  1282. return false;
  1283. }
  1284. //内容定位
  1285. string::size_type nValuePos = nHeadPos + strlen(strHeadLow.c_str());
  1286. if (nValuePos >= strSourceLow.length())
  1287. {
  1288. return false;
  1289. }
  1290. //尾定位
  1291. string::size_type nTailPos = strSourceLow.find(strTailLow, nValuePos);
  1292. if (nTailPos == string::npos)
  1293. {
  1294. return false;
  1295. }
  1296. //如果尾定位字符串为空,则认为定位到源字符串最后
  1297. if (strTailLow == "")
  1298. {
  1299. nTailPos = strSourceLow.length();
  1300. }
  1301. //返回定位结果
  1302. nPos = nValuePos;
  1303. if (nTailPos < nValuePos)
  1304. {
  1305. return false;
  1306. }
  1307. nLen = nTailPos - nValuePos;
  1308. return true;
  1309. }
  1310. /******************************************************************************
  1311. 判断这条Cookie路径是否匹配
  1312. ******************************************************************************/
  1313. bool CHTTP::_IsCookiePathMatch(string strCookiePath)
  1314. {
  1315. if (m_strPath == "")
  1316. {
  1317. return false;
  1318. }
  1319. //为空则默认匹配
  1320. if (strCookiePath == "")
  1321. {
  1322. return true;
  1323. }
  1324. if (m_strPath.find(strCookiePath) != 0)
  1325. {
  1326. //找不到,肯定不匹配
  1327. return false;
  1328. }
  1329. //获取Cookie路径最后一个字符
  1330. int nCookiePathEndPos = (int)strCookiePath.length() - 1;
  1331. if (nCookiePathEndPos < 0)
  1332. {
  1333. return false;
  1334. }
  1335. char chCookiePathEnd = strCookiePath[nCookiePathEndPos];
  1336. //如果以 / 结尾,则匹配没问题了
  1337. if (chCookiePathEnd == '/')
  1338. {
  1339. return true;
  1340. }
  1341. //检测后面还没匹配完的情况。比如:/ab和/abc,只匹配前面,但其实不匹配
  1342. if (!_IsCookiePathMatchNext(strCookiePath))
  1343. {
  1344. return false;
  1345. }
  1346. return true;
  1347. }
  1348. /******************************************************************************
  1349. 判断这条Cookie域名是否匹配
  1350. ******************************************************************************/
  1351. bool CHTTP::_IsCookieDomainMatch(string strCookieDomain)
  1352. {
  1353. if (m_strDomain == "")
  1354. {
  1355. return false;
  1356. }
  1357. //为空则默认匹配
  1358. if (strCookieDomain == "")
  1359. {
  1360. return true;
  1361. }
  1362. string::size_type nDomainPos = m_strDomain.rfind(strCookieDomain);
  1363. if (nDomainPos == string::npos)
  1364. {
  1365. //找不到,肯定不匹配
  1366. return false;
  1367. }
  1368. //判断是否正好匹配到了最后面
  1369. if (nDomainPos + strlen(strCookieDomain.c_str())
  1370. == m_strDomain.size())
  1371. {
  1372. return true;
  1373. }
  1374. return false;
  1375. }
  1376. /******************************************************************************
  1377. 判断这条Cookie路径的后面是否匹配,防止/ab与/abc匹配的情况。
  1378. ******************************************************************************/
  1379. bool CHTTP::_IsCookiePathMatchNext(string strCookiePath)
  1380. {
  1381. if (m_strPath == "")
  1382. {
  1383. return false;
  1384. }
  1385. //为空则默认匹配
  1386. if (strCookiePath == "")
  1387. {
  1388. return true;
  1389. }
  1390. string::size_type nPathLen = m_strPath.size();
  1391. string::size_type nCookiePathLen = strCookiePath.size();
  1392. //后面还有东西,则需要检测
  1393. if (nPathLen > nCookiePathLen)
  1394. {
  1395. //获取匹配后的下一个字符
  1396. char chMatchNext = m_strPath[nCookiePathLen];
  1397. //检测下一个字符
  1398. if (chMatchNext != '/'
  1399. && chMatchNext != '?'
  1400. && chMatchNext != '#')
  1401. {
  1402. //后面并不匹配
  1403. return false;
  1404. }
  1405. }
  1406. return true;
  1407. }
  1408. /******************************************************************************
  1409. 字符串替换
  1410. ******************************************************************************/
  1411. void CHTTP::_ReplaceString(string & strReplace, string strOld, string strNew)
  1412. {
  1413. string::size_type nFindStartPos = 0;
  1414. string::size_type nFoundPos = string::npos;
  1415. string::size_type nOldLen = strOld.length();
  1416. string::size_type nNewLen = strNew.length();
  1417. //要替换的字符串为空,没法替换
  1418. if (strOld == ""
  1419. || nOldLen == 0)
  1420. {
  1421. return;
  1422. }
  1423. //源串为空,没法替换
  1424. if (strReplace == "")
  1425. {
  1426. return;
  1427. }
  1428. //替换每一处
  1429. while (true)
  1430. {
  1431. //寻找要替换的字符串位置
  1432. nFoundPos = strReplace.find(strOld, nFindStartPos);
  1433. if (nFoundPos == string::npos)
  1434. {
  1435. break;
  1436. }
  1437. //替换掉
  1438. strReplace.replace(nFoundPos, nOldLen, strNew);
  1439. //搜索起始位置下移
  1440. nFindStartPos = nFoundPos + nNewLen;
  1441. if (nFindStartPos >= strReplace.length())
  1442. {
  1443. break;
  1444. }
  1445. }
  1446. }
  1447. /******************************************************************************
  1448. 分解Cookie字符串
  1449. ******************************************************************************/
  1450. int CHTTP::_ParseCookieStr(HTTP::SCookie & sCookie, string strCookie)
  1451. {
  1452. if (strCookie == "")
  1453. {
  1454. return HTTP::PARSE_COOKIE_STR_COOKIE_NULL;
  1455. }
  1456. strCookie += ";";
  1457. //提取Cookie名
  1458. sCookie.strName = _CutStr(strCookie, "", "=");
  1459. sCookie.strValue = _CutStr(strCookie, "=", ";");
  1460. sCookie.strPath = _CutStr(strCookie, ";path=", ";");
  1461. sCookie.strDomain = _CutStr(strCookie, ";domain=", ";");
  1462. if (sCookie.strName == "")
  1463. {
  1464. return HTTP::PARSE_COOKIE_STR_NAME_NULL;
  1465. }
  1466. return 0;
  1467. }
  1468. /******************************************************************************
  1469. 查找Cookie项是否已经存在Cookies表中
  1470. ******************************************************************************/
  1471. int CHTTP::_FindCookie(HTTP::SCookie const & sCookie)
  1472. {
  1473. int nListLen = (int)m_listCookies.size();
  1474. int nFindList = 0;
  1475. for (nFindList = 0; nFindList < nListLen; nFindList++)
  1476. {
  1477. HTTP::SCookie const & sFindCookie = m_listCookies[nFindList];
  1478. if (sCookie.strName == sFindCookie.strName)
  1479. {
  1480. break;
  1481. }
  1482. }
  1483. if (nFindList < nListLen)
  1484. {
  1485. return nFindList;
  1486. }
  1487. return -1;
  1488. }
  1489. /******************************************************************************
  1490. 添加一个Cookie项
  1491. ******************************************************************************/
  1492. int CHTTP::_AddCookie(HTTP::SCookie const & sCookie)
  1493. {
  1494. if (sCookie.strName == "")
  1495. {
  1496. return HTTP::ADD_COOKIE_SCOOKIE_NAME_NULL;
  1497. }
  1498. int nFindCookie = _FindCookie(sCookie);
  1499. //找到,替换掉
  1500. if (nFindCookie > -1)
  1501. {
  1502. if (nFindCookie >= (int)m_listCookies.size())
  1503. {
  1504. return HTTP::ADD_COOKIE_SOCKET_FIND_INVALID;
  1505. }
  1506. HTTP::SCookie & sFindCookie = m_listCookies[nFindCookie];
  1507. sFindCookie.strName = sCookie.strName;
  1508. if (sCookie.strValue != "")
  1509. {
  1510. sFindCookie.strValue = sCookie.strValue;
  1511. }
  1512. if (sCookie.strPath != "")
  1513. {
  1514. sFindCookie.strPath = sCookie.strPath;
  1515. }
  1516. if (sCookie.strDomain != "")
  1517. {
  1518. sFindCookie.strDomain = sCookie.strDomain;
  1519. }
  1520. }
  1521. //找不到,直接添加
  1522. else
  1523. {
  1524. m_listCookies.push_back(sCookie);
  1525. }
  1526. return 0;
  1527. }
  1528. /******************************************************************************
  1529. 分割字符串
  1530. ******************************************************************************/
  1531. void CHTTP::_SplitStr(vector<string> & listStr, string strSrc, string strSplit)
  1532. {
  1533. listStr.clear();
  1534. if (strSrc == "")
  1535. {
  1536. return;
  1537. }
  1538. if (strSplit == "")
  1539. {
  1540. return;
  1541. }
  1542. string::size_type nStartPos = 0;
  1543. while (true)
  1544. {
  1545. //寻找分割字符串
  1546. if (nStartPos >= strSrc.length())
  1547. {
  1548. break;
  1549. }
  1550. string::size_type nSplitPos = strSrc.find(strSplit, nStartPos);
  1551. if (nSplitPos == string::npos)
  1552. {
  1553. //找不到,则定位到字符串最后去
  1554. nSplitPos = strSrc.length();
  1555. }
  1556. //截取字符串
  1557. string strCut = strSrc.substr(nStartPos, nSplitPos - nStartPos);
  1558. nStartPos = nSplitPos + strlen(strSplit.c_str());
  1559. //添加到列表
  1560. if (strCut != "")
  1561. {
  1562. listStr.push_back(strCut);
  1563. }
  1564. }
  1565. }
  1566. /******************************************************************************
  1567. 小写字符串
  1568. ******************************************************************************/
  1569. void CHTTP::_ToLower(string & strLower)
  1570. {
  1571. if (strLower == "")
  1572. {
  1573. return;
  1574. }
  1575. transform(strLower.begin(), strLower.end()
  1576. , strLower.begin(), tolower);
  1577. }
  1578. /******************************************************************************
  1579. 启动并创建套接字
  1580. ******************************************************************************/
  1581. int CHTTP::_StartupCreateSocket(void)
  1582. {
  1583. m_bStartup = true;
  1584. m_socket = INVALID_SOCKET;
  1585. //启动套接字
  1586. WSADATA wsaData;
  1587. if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
  1588. {
  1589. m_bStartup = false;
  1590. return HTTP::STARTUP_CREATE_SOCKET_STARTUP;
  1591. }
  1592. //创建套接字
  1593. m_socket = socket(AF_INET, SOCK_STREAM, 0);
  1594. if (m_socket == INVALID_SOCKET)
  1595. {
  1596. return HTTP::STARTUP_CREATE_SOCKET_SOCKET;
  1597. }
  1598. return 0;
  1599. }
  1600. /**************************************************************************
  1601. 填写地址信息
  1602. **************************************************************************/
  1603. int CHTTP::_FillAddrInfo(sockaddr_in & addr)
  1604. {
  1605. //获得域名的IP数据
  1606. if (m_strDomain == "")
  1607. {
  1608. return HTTP::FILL_ADDR_INFO_DOMAIN_NULL;
  1609. }
  1610. ULONG ulIPData = 0;
  1611. int nGetIPData = m_mapDNS.GetIPData(ulIPData, m_strDomain);
  1612. if (nGetIPData != 0)
  1613. {
  1614. return nGetIPData;
  1615. }
  1616. if (ulIPData == 0)
  1617. {
  1618. return HTTP::FILL_ADDR_INFO_IP_ZERO;
  1619. }
  1620. //填写SOCKET地址信息
  1621. if (m_nPort <= 0)
  1622. {
  1623. return HTTP::FILL_ADDR_INFO_PORT_INVALID;
  1624. }
  1625. addr.sin_family = AF_INET;
  1626. addr.sin_addr.S_un.S_addr = ulIPData;
  1627. addr.sin_port = htons(m_nPort);
  1628. return 0;
  1629. }
  1630. /******************************************************************************
  1631. 带超时的连接
  1632. ******************************************************************************/
  1633. int CHTTP::_ConnWithTimeout(sockaddr_in const & addr)
  1634. {
  1635. //以非阻塞模式,设置连接超时
  1636. if (m_socket == INVALID_SOCKET)
  1637. {
  1638. return HTTP::CONN_WITH_TIMEOUT_INVALID_SOCKET;
  1639. }
  1640. ULONG arg = !0;
  1641. if (ioctlsocket(m_socket, FIONBIO, &arg) != 0)
  1642. {
  1643. return HTTP::CONN_WITH_TIMEOUT_SETNB_FAIL;
  1644. }
  1645. //连接服务器
  1646. if (addr.sin_addr.S_un.S_addr == 0
  1647. || addr.sin_port <= 0)
  1648. {
  1649. return HTTP::CONN_WITH_TIMEOUT_ADDR_INVALID;
  1650. }
  1651. if (connect(m_socket, (sockaddr *)&addr, sizeof(addr)) != SOCKET_ERROR)
  1652. {
  1653. return HTTP::CONN_WITH_TIMEOUT_CONN_FAIL;
  1654. }
  1655. //实现连接超时
  1656. int nSelectTimeout = _SelectTimeout();
  1657. if (nSelectTimeout != 0)
  1658. {
  1659. return nSelectTimeout;
  1660. }
  1661. //恢复阻塞模式
  1662. arg = 0;
  1663. if (ioctlsocket(m_socket, FIONBIO, &arg) != 0)
  1664. {
  1665. return HTTP::CONN_WITH_TIMEOUT_SETB_FAIL;
  1666. }
  1667. return 0;
  1668. }
  1669. /******************************************************************************
  1670. 使用select实现超时
  1671. ******************************************************************************/
  1672. int CHTTP::_SelectTimeout(void)
  1673. {
  1674. //用select实现连接超时
  1675. if (m_nConnTimeout <= 0)
  1676. {
  1677. return HTTP::SELECT_TIMEOUT_TIMEOUT_INVALID;
  1678. }
  1679. if (m_socket == INVALID_SOCKET)
  1680. {
  1681. return HTTP::SELECT_TIMEOUT_INVALID_SOCKET;
  1682. }
  1683. fd_set fds;
  1684. FD_ZERO(&fds);
  1685. FD_SET(m_socket, &fds);
  1686. timeval timeout;
  1687. timeout.tv_sec = m_nConnTimeout / 1000;
  1688. timeout.tv_usec = m_nConnTimeout % 1000;
  1689. if (select(0, 0, &fds, 0, &timeout) <= 0)
  1690. {
  1691. //连接不上,重新从DNS获取IP,因为可能是因为DNS更新IP导致连接不上的
  1692. int nClearDNS = m_mapDNS.ClearDNS();
  1693. if (nClearDNS != 0)
  1694. {
  1695. return nClearDNS;
  1696. }
  1697. return HTTP::SELECT_TIMEOUT_CONN_TIMEOUT;
  1698. }
  1699. return 0;
  1700. }
  1701. /******************************************************************************
  1702. 设置套接字的超时
  1703. ******************************************************************************/
  1704. int CHTTP::_SetSocketTimeout(void)
  1705. {
  1706. if (m_socket == INVALID_SOCKET)
  1707. {
  1708. return HTTP::SET_SOCKET_TIMEOUT_INVALID_SOCKET;
  1709. }
  1710. if (m_nSendTimeout <= 0
  1711. || m_nRecvTimeout <= 0)
  1712. {
  1713. return HTTP::SET_SOCKET_TIMEOUT_VALUE_INVALID;
  1714. }
  1715. //设置发送超时
  1716. DWORD dwSendTimeout = (DWORD)m_nSendTimeout;
  1717. if (setsockopt(m_socket, SOL_SOCKET, SO_SNDTIMEO
  1718. , (char *)&dwSendTimeout, sizeof(dwSendTimeout)) != 0)
  1719. {
  1720. return HTTP::SET_SOCKET_TIMEOUT_SET_SND_TIMEOUT;
  1721. }
  1722. //设置接收超时
  1723. DWORD dwRecvTimeout = (DWORD)m_nRecvTimeout;
  1724. if (setsockopt(m_socket, SOL_SOCKET, SO_RCVTIMEO
  1725. , (char *)&dwRecvTimeout, sizeof(dwRecvTimeout)) != 0)
  1726. {
  1727. return HTTP::SET_SOCKET_TIMEOUT_SET_RCV_TIMEOUT;
  1728. }
  1729. return 0;
  1730. }