HttpClientSyn.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. #include "stdafx.h"
  2. #include "HttpClientSyn.h"
  3. #include <atlbase.h>
  4. #include <atlconv.h>
  5. #pragma comment(lib,"Winhttp.lib")
  6. #define MAXSTATICPARAMCOUNT 32
  7. CHttpClientSyn::CHttpClientSyn()
  8. {
  9. m_hSession = NULL;
  10. m_hConnect = NULL;
  11. m_hRequest = NULL;
  12. m_dwTimeout = 0;
  13. m_lpReceiveData = NULL;
  14. m_dwReceiveDataLength = 0;
  15. }
  16. CHttpClientSyn::~CHttpClientSyn(void)
  17. {
  18. ClearEvn();
  19. }
  20. BOOL CHttpClientSyn::InitializeHttp(const std::wstring& wstrUrl, DWORD dwTimeout)
  21. {
  22. static URL_COMPONENTS urlCom;
  23. memset(&urlCom, 0, sizeof(urlCom));
  24. urlCom.dwStructSize = sizeof(urlCom);
  25. static WCHAR wchScheme[64] = { 0 };
  26. memset(wchScheme, 0, 64 * sizeof(WCHAR));
  27. urlCom.lpszScheme = wchScheme;
  28. urlCom.dwSchemeLength = ARRAYSIZE(wchScheme);
  29. static WCHAR wchHostName[1024] = { 0 };
  30. memset(wchHostName, 0, 1024 * sizeof(WCHAR));
  31. urlCom.lpszHostName = wchHostName;
  32. urlCom.dwHostNameLength = ARRAYSIZE(wchHostName);
  33. static WCHAR wchUrlPath[1024] = { 0 };
  34. memset(wchUrlPath, 0, 1024 * sizeof(WCHAR));
  35. urlCom.lpszUrlPath = wchUrlPath;
  36. urlCom.dwUrlPathLength = ARRAYSIZE(wchUrlPath);
  37. static WCHAR wchExtraInfo[4096] = { 0 };
  38. memset(wchExtraInfo, 0, 4096 * sizeof(WCHAR));
  39. urlCom.lpszExtraInfo = wchExtraInfo;
  40. urlCom.dwExtraInfoLength = ARRAYSIZE(wchExtraInfo);
  41. if (FALSE == WinHttpCrackUrl(wstrUrl.c_str(), wstrUrl.length(), ICU_ESCAPE, &urlCom))
  42. {
  43. m_strErrorDescriptor = GetLastErrorInfo(GetLastError());
  44. return FALSE;
  45. }
  46. static std::wstring wstrExtraInfo;
  47. wstrExtraInfo = urlCom.lpszExtraInfo;
  48. ParseParams(wstrExtraInfo);
  49. AddExtInfo(m_VecExtInfo);
  50. if (m_hSession == NULL)
  51. m_hSession = WinHttpOpen(NULL, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
  52. if (NULL == m_hSession)
  53. {
  54. m_strErrorDescriptor = GetLastErrorInfo(GetLastError());
  55. return FALSE;
  56. }
  57. if (FALSE == WinHttpSetTimeouts(m_hSession, dwTimeout, dwTimeout, dwTimeout, dwTimeout))
  58. {
  59. m_strErrorDescriptor = GetLastErrorInfo(GetLastError());
  60. return FALSE;
  61. }
  62. if (m_hConnect == NULL)
  63. m_hConnect = WinHttpConnect(m_hSession, urlCom.lpszHostName, urlCom.nPort, 0);
  64. if (NULL == m_hConnect)
  65. {
  66. m_strErrorDescriptor = GetLastErrorInfo(GetLastError());
  67. return FALSE;
  68. }
  69. m_wstrUrlPath = urlCom.lpszUrlPath;
  70. return TRUE;
  71. }
  72. VOID CHttpClientSyn::UninitializeHttp()
  73. {
  74. if (NULL != m_hConnect)
  75. {
  76. WinHttpCloseHandle(m_hConnect);
  77. m_hConnect = NULL;
  78. }
  79. if (NULL != m_hRequest)
  80. {
  81. WinHttpCloseHandle(m_hRequest);
  82. m_hRequest = NULL;
  83. }
  84. if (NULL != m_hSession)
  85. {
  86. WinHttpCloseHandle(m_hSession);
  87. m_hSession = NULL;
  88. }
  89. m_VecExtInfo.clear();
  90. }
  91. BOOL CHttpClientSyn::ReceiveData()
  92. {
  93. BOOL bSuc = FALSE;
  94. DWORD dwReceivedBufferLength = 0;
  95. LPBYTE lpReceivedBuffer = NULL;
  96. if (FALSE == WinHttpReceiveResponse(m_hRequest, NULL))
  97. {
  98. m_strErrorDescriptor = GetLastErrorInfo(GetLastError());
  99. return FALSE;
  100. }
  101. DWORD dwRetLength = 0;
  102. do {
  103. bSuc = FALSE;
  104. if (FALSE == WinHttpQueryDataAvailable(m_hRequest, &dwRetLength))
  105. {
  106. m_strErrorDescriptor = GetLastErrorInfo(GetLastError());
  107. break;
  108. }
  109. if (0 == dwRetLength)
  110. {
  111. bSuc = TRUE;
  112. break;
  113. }
  114. LPBYTE lpReceivedData = new BYTE[dwRetLength];
  115. if (NULL == lpReceivedData)
  116. {
  117. break;
  118. }
  119. memset(lpReceivedData, 0, dwRetLength);
  120. DWORD dwRead = 0;
  121. if (FALSE == WinHttpReadData(m_hRequest, lpReceivedData, dwRetLength, &dwRead))
  122. {
  123. m_strErrorDescriptor = GetLastErrorInfo(GetLastError());
  124. break;
  125. }
  126. if (0 == dwRead)
  127. {
  128. break;
  129. }
  130. DWORD dwReceivedBufferLengthNew = dwReceivedBufferLength + dwRetLength;
  131. LPBYTE lpReceivedBufferNew = new BYTE[dwReceivedBufferLengthNew];
  132. if (NULL == lpReceivedBufferNew)
  133. {
  134. break;
  135. }
  136. memset(lpReceivedBufferNew, 0, dwReceivedBufferLengthNew);
  137. if (NULL != lpReceivedBuffer)
  138. {
  139. memcpy_s(lpReceivedBufferNew, dwReceivedBufferLengthNew, lpReceivedBuffer, dwReceivedBufferLength);
  140. delete[] lpReceivedBuffer;
  141. lpReceivedBuffer = NULL;
  142. }
  143. if (NULL != lpReceivedData)
  144. {
  145. memcpy_s(lpReceivedBufferNew + dwReceivedBufferLength, dwReceivedBufferLengthNew - dwReceivedBufferLength, lpReceivedData, dwRetLength);
  146. delete[] lpReceivedData;
  147. lpReceivedData = NULL;
  148. }
  149. lpReceivedBuffer = lpReceivedBufferNew;
  150. dwReceivedBufferLength = dwReceivedBufferLengthNew;
  151. bSuc = TRUE;
  152. } while (dwRetLength > 0);
  153. if (bSuc)
  154. {
  155. m_lpReceiveData = lpReceivedBuffer;
  156. m_dwReceiveDataLength = dwReceivedBufferLength;
  157. m_strErrorDescriptor = _T("");
  158. }
  159. return TRUE;
  160. }
  161. BOOL CHttpClientSyn::ReceiveData(LPBYTE lpBuffer, DWORD& dwBufferSize)
  162. {
  163. if (NULL == m_lpReceiveData)
  164. {
  165. ::SetLastError(ERROR_WINHTTP_NOT_INITIALIZED);
  166. return FALSE;
  167. }
  168. if (NULL == lpBuffer)
  169. {
  170. ::SetLastError(ERROR_INVALID_ADDRESS);
  171. return FALSE;
  172. }
  173. if (m_dwReceiveDataLength > dwBufferSize)
  174. {
  175. dwBufferSize = m_dwReceiveDataLength;
  176. ::SetLastError(ERROR_INSUFFICIENT_BUFFER);
  177. return FALSE;
  178. }
  179. errno_t e = memcpy_s(lpBuffer, dwBufferSize, m_lpReceiveData, m_dwReceiveDataLength);
  180. if (0 != e)
  181. {
  182. return FALSE;
  183. }
  184. ClearEvn();
  185. return TRUE;
  186. }
  187. VOID CHttpClientSyn::ClearEvn()
  188. {
  189. UninitializeHttp();
  190. m_dwTimeout = 0;
  191. if (NULL != m_lpReceiveData)
  192. {
  193. delete[] m_lpReceiveData;
  194. m_lpReceiveData = NULL;
  195. }
  196. m_dwReceiveDataLength = 0;
  197. }
  198. BOOL CHttpClientSyn::TransmiteData(const std::wstring& wstrUrl, EType eType, DWORD dwTimeout)
  199. {
  200. if (FALSE == InitializeHttp(wstrUrl, dwTimeout))
  201. {
  202. UninitializeHttp();
  203. return FALSE;
  204. }
  205. if (FALSE == TransmiteData(eType))
  206. {
  207. UninitializeHttp();
  208. return FALSE;
  209. }
  210. ReceiveData();
  211. UninitializeHttp();
  212. return TRUE;
  213. }
  214. BOOL CHttpClientSyn::TransmiteData(EType eType)
  215. {
  216. BOOL bSuc = FALSE;
  217. switch (eType)
  218. {
  219. case eGet:
  220. {
  221. bSuc = TransmiteDataToServerByGet();
  222. }
  223. break;
  224. case ePost:
  225. {
  226. bSuc = TransmiteDataToServerByPost();
  227. }
  228. break;
  229. case eUpload:
  230. {
  231. bSuc = TransmiteDataToServerByUpload();
  232. }
  233. break;
  234. default: break;
  235. }
  236. return bSuc;
  237. }
  238. BOOL CHttpClientSyn::GetData(LPVOID lpBuffer, DWORD dwBufferSize, DWORD& dwWrite)
  239. {
  240. return FALSE;
  241. }
  242. BOOL CHttpClientSyn::ModifyRequestHeader(HINTERNET hRequest)
  243. {
  244. return TRUE;
  245. }
  246. VOID CHttpClientSyn::ParseParams(const std::wstring& wstrExtraInfo)
  247. {
  248. static int nPos = 0;
  249. nPos = wstrExtraInfo.find('?');
  250. if (-1 == nPos)
  251. {
  252. return;
  253. }
  254. static std::wstring wstrParam;// = wstrExtraInfo;
  255. wstrParam = wstrExtraInfo;
  256. int nStaticMaxParamCount = MAXSTATICPARAMCOUNT;
  257. do{
  258. wstrParam = wstrParam.substr(nPos + 1, wstrExtraInfo.length() - nPos - 1);
  259. nPos = wstrParam.find('&', nPos);
  260. static std::wstring wstrKeyValuePair;
  261. if (-1 == nPos)
  262. {
  263. wstrKeyValuePair = wstrParam;
  264. }
  265. else
  266. {
  267. wstrKeyValuePair = wstrParam.substr(0, nPos);
  268. }
  269. int nSp = wstrKeyValuePair.find('=');
  270. if (-1 != nSp)
  271. {
  272. StParam stParam;
  273. stParam.wstrKey = wstrKeyValuePair.substr(0, nSp);
  274. stParam.wstrValue = wstrKeyValuePair.substr(nSp + 1, wstrKeyValuePair.length() - nSp - 1);
  275. m_VecExtInfo.push_back(stParam);
  276. }
  277. } while (-1 != nPos && nStaticMaxParamCount > 0);
  278. }
  279. BOOL CHttpClientSyn::TransmiteDataToServerByGet()
  280. {
  281. static std::wstring wstrUrlPathAppend;// = m_wstrUrlPath;
  282. wstrUrlPathAppend = m_wstrUrlPath;
  283. // 采用Get方式时,要将参数放在OpenRequest中
  284. if (false == wstrUrlPathAppend.empty())
  285. {
  286. wstrUrlPathAppend += L"?";
  287. }
  288. wstrUrlPathAppend += GenerateExtInfo(m_VecExtInfo);
  289. m_hRequest = WinHttpOpenRequest(m_hConnect, L"GET", wstrUrlPathAppend.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
  290. if (NULL == m_hRequest)
  291. {
  292. m_strErrorDescriptor = GetLastErrorInfo(GetLastError());
  293. return FALSE;
  294. }
  295. ModifyRequestHeader(m_hRequest);
  296. if (FALSE == WinHttpSendRequest(m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0))
  297. {
  298. m_strErrorDescriptor = GetLastErrorInfo(GetLastError());
  299. return FALSE;
  300. }
  301. return TRUE;
  302. }
  303. BOOL CHttpClientSyn::TransmiteDataToServerByPost()
  304. {
  305. m_hRequest = WinHttpOpenRequest(m_hConnect, L"POST", m_wstrUrlPath.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
  306. if (NULL == m_hRequest)
  307. {
  308. m_strErrorDescriptor = GetLastErrorInfo(GetLastError());
  309. return FALSE;
  310. }
  311. ModifyRequestHeader(m_hRequest);
  312. std::wstring wstrExtInfo = GenerateExtInfo(m_VecExtInfo);
  313. std::string strExtInfo = CW2A(wstrExtInfo.c_str(), CP_UTF8);
  314. DWORD dwTotal = strExtInfo.length();
  315. dwTotal += GetDataSize();
  316. if (FALSE == WinHttpSendRequest(m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, dwTotal, 0))
  317. {
  318. m_strErrorDescriptor = GetLastErrorInfo(GetLastError());
  319. return FALSE;
  320. }
  321. if (0 != strExtInfo.length())
  322. {
  323. // 默认可以一次全部写完
  324. if (FALSE == WinHttpWriteData(m_hRequest, strExtInfo.c_str(), strExtInfo.length(), NULL))
  325. {
  326. m_strErrorDescriptor = GetLastErrorInfo(GetLastError());
  327. return FALSE;
  328. }
  329. }
  330. // 静态分配一个数组
  331. BYTE buffer[1024] = { 0 };
  332. BOOL bContinue = FALSE;
  333. BOOL bSendOK = FALSE;
  334. do {
  335. DWORD dwBufferLength = sizeof(buffer);
  336. SecureZeroMemory(buffer, dwBufferLength);
  337. DWORD dwWriteSize = 0;
  338. bContinue = GetData(buffer, dwBufferLength, dwWriteSize);
  339. if (0 != dwWriteSize)
  340. {
  341. bSendOK = WinHttpWriteData(m_hRequest, buffer, dwWriteSize, NULL);
  342. }
  343. else
  344. {
  345. bSendOK = TRUE;
  346. }
  347. } while (bContinue && bSendOK);
  348. return bSendOK;
  349. }
  350. BOOL CHttpClientSyn::TransmiteDataToServerByUpload()
  351. {
  352. m_hRequest = WinHttpOpenRequest(m_hConnect, L"POST", m_wstrUrlPath.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
  353. if (NULL == m_hRequest)
  354. {
  355. m_strErrorDescriptor = GetLastErrorInfo(GetLastError());
  356. return FALSE;
  357. }
  358. ModifyRequestHeader(m_hRequest);
  359. std::wstring wstrExtInfo = GenerateExtInfo(m_VecExtInfo);
  360. std::string strExtInfo = CW2A(wstrExtInfo.c_str(), CP_UTF8);
  361. DWORD dwTotal = strExtInfo.length();
  362. dwTotal += GetDataSize();
  363. if (FALSE == WinHttpSendRequest(m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, dwTotal, 0))
  364. {
  365. m_strErrorDescriptor = GetLastErrorInfo(GetLastError());
  366. return FALSE;
  367. }
  368. // 静态分配一个数组
  369. BYTE buffer[1024] = { 0 };
  370. BOOL bContinue = FALSE;
  371. BOOL bSendOK = FALSE;
  372. do {
  373. DWORD dwBufferLength = sizeof(buffer);
  374. SecureZeroMemory(buffer, dwBufferLength);
  375. DWORD dwWriteSize = 0;
  376. bContinue = GetData(buffer, dwBufferLength, dwWriteSize);
  377. if (0 != dwWriteSize)
  378. {
  379. bSendOK = WinHttpWriteData(m_hRequest, buffer, dwWriteSize, NULL);
  380. }
  381. else
  382. {
  383. bSendOK = TRUE;
  384. }
  385. } while (bContinue && bSendOK);
  386. if (0 != strExtInfo.length())
  387. {
  388. if (FALSE == WinHttpWriteData(m_hRequest, strExtInfo.c_str(), strExtInfo.length(), NULL))
  389. {
  390. m_strErrorDescriptor = GetLastErrorInfo(GetLastError());
  391. return FALSE;
  392. }
  393. }
  394. return bSendOK;
  395. }