Advertisement
Guest User

Untitled

a guest
Sep 25th, 2017
720
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.53 KB | None | 0 0
  1. /**
  2. * Copyright 2008-2010 Cheng Shi. All rights reserved.
  3. * Email: shicheng107@hotmail.com
  4. */
  5.  
  6. #ifndef WINHTTPCLIENT_H
  7. #define WINHTTPCLIENT_H
  8.  
  9. #pragma comment(lib, "Winhttp.lib")
  10.  
  11. #include "RegExp.h"
  12. #include "StringProcess.h"
  13. #include <comutil.h>
  14. #include "atlrxh.h"
  15. #include <windows.h>
  16. #include <Winhttp.h>
  17. #include <string>
  18.  
  19. using namespace std;
  20.  
  21. typedef bool(*PROGRESSPROC)(double);
  22.  
  23. static const unsigned int INT_RETRYTIMES = 3;
  24. static wchar_t *SZ_AGENT = L"WinHttpClient";
  25. static const int INT_BUFFERSIZE = 10240; // Initial 10 KB temporary buffer, double if it is not enough.
  26.  
  27. class WinHttpClient
  28. {
  29. public:
  30. inline WinHttpClient(const wstring &url, PROGRESSPROC progressProc = NULL);
  31. inline ~WinHttpClient(void);
  32.  
  33. // It is a synchronized method and may take a long time to finish.
  34. inline bool SendHttpRequest(const wstring &httpVerb = L"GET", bool disableAutoRedirect = false);
  35. inline wstring GetResponseHeader(void);
  36. inline wstring GetResponseContent(void);
  37. inline wstring GetResponseCharset(void);
  38. inline wstring GetResponseStatusCode(void);
  39. inline wstring GetResponseLocation(void);
  40. inline wstring GetRequestHost(void);
  41. inline const BYTE *GetRawResponseContent(void);
  42. inline unsigned int GetRawResponseContentLength(void);
  43. inline unsigned int GetRawResponseReceivedContentLength(void);
  44. inline bool SaveResponseToFile(const wstring &filePath);
  45. inline wstring GetResponseCookies(void);
  46. inline bool SetAdditionalRequestCookies(const wstring &cookies);
  47. inline bool SetAdditionalDataToSend(BYTE *data, unsigned int dataSize);
  48. inline bool UpdateUrl(const wstring &url);
  49. inline bool ResetAdditionalDataToSend(void);
  50. inline bool SetAdditionalRequestHeaders(const wstring &additionalRequestHeaders);
  51. inline bool SetRequireValidSslCertificates(bool require);
  52. inline bool SetProxy(const wstring &proxy);
  53. inline DWORD GetLastError(void);
  54. inline bool SetUserAgent(const wstring &userAgent);
  55. inline bool SetForceCharset(const wstring &charset);
  56. inline bool SetProxyUsername(const wstring &username);
  57. inline bool SetProxyPassword(const wstring &password);
  58. inline bool SetTimeouts(unsigned int resolveTimeout = 0,
  59. unsigned int connectTimeout = 60000,
  60. unsigned int sendTimeout = 30000,
  61. unsigned int receiveTimeout = 30000);
  62.  
  63. private:
  64. inline WinHttpClient(const WinHttpClient &other);
  65. inline WinHttpClient &operator =(const WinHttpClient &other);
  66. inline bool SetProgress(unsigned int byteCountReceived);
  67.  
  68. HINTERNET m_sessionHandle;
  69. bool m_requireValidSsl;
  70. wstring m_requestURL;
  71. wstring m_requestHost;
  72. wstring m_responseHeader;
  73. wstring m_responseContent;
  74. wstring m_responseCharset;
  75. BYTE *m_pResponse;
  76. unsigned int m_responseByteCountReceived; // Up to 4GB.
  77. PROGRESSPROC m_pfProcessProc;
  78. unsigned int m_responseByteCount;
  79. wstring m_responseCookies;
  80. wstring m_additionalRequestCookies;
  81. BYTE *m_pDataToSend;
  82. unsigned int m_dataToSendSize;
  83. wstring m_additionalRequestHeaders;
  84. wstring m_proxy;
  85. DWORD m_dwLastError;
  86. wstring m_statusCode;
  87. wstring m_userAgent;
  88. bool m_bForceCharset;
  89. wstring m_proxyUsername;
  90. wstring m_proxyPassword;
  91. wstring m_location;
  92. unsigned int m_resolveTimeout;
  93. unsigned int m_connectTimeout;
  94. unsigned int m_sendTimeout;
  95. unsigned int m_receiveTimeout;
  96. };
  97.  
  98. WinHttpClient::WinHttpClient(const wstring &url, PROGRESSPROC progressProc)
  99. : m_requestURL(url),
  100. m_sessionHandle(NULL),
  101. m_requireValidSsl(false),
  102. m_responseHeader(L""),
  103. m_responseContent(L""),
  104. m_responseCharset(L""),
  105. m_requestHost(L""),
  106. m_pResponse(NULL),
  107. m_responseByteCountReceived(0),
  108. m_pfProcessProc(progressProc),
  109. m_responseByteCount(0),
  110. m_responseCookies(L""),
  111. m_additionalRequestCookies(L""),
  112. m_pDataToSend(NULL),
  113. m_dataToSendSize(0),
  114. m_proxy(L""),
  115. m_dwLastError(0),
  116. m_statusCode(L""),
  117. m_userAgent(SZ_AGENT),
  118. m_bForceCharset(false),
  119. m_proxyUsername(L""),
  120. m_proxyPassword(L""),
  121. m_location(L""),
  122. m_resolveTimeout(0),
  123. m_connectTimeout(60000),
  124. m_sendTimeout(30000),
  125. m_receiveTimeout(30000)
  126. {
  127. }
  128.  
  129. WinHttpClient::~WinHttpClient(void)
  130. {
  131. if (m_pResponse != NULL)
  132. {
  133. delete[] m_pResponse;
  134. }
  135. if (m_pDataToSend != NULL)
  136. {
  137. delete[] m_pDataToSend;
  138. }
  139.  
  140. if (m_sessionHandle != NULL)
  141. {
  142. ::WinHttpCloseHandle(m_sessionHandle);
  143. }
  144. }
  145.  
  146. bool WinHttpClient::SendHttpRequest(const wstring &httpVerb, bool disableAutoRedirect)
  147. {
  148. if (m_requestURL.size() <= 0)
  149. {
  150. m_dwLastError = ERROR_PATH_NOT_FOUND;
  151. return false;
  152. }
  153. // Make verb uppercase.
  154. wstring verb = httpVerb;
  155. if (_wcsicmp(verb.c_str(), L"GET") == 0)
  156. {
  157. verb = L"GET";
  158. }
  159. else if (_wcsicmp(verb.c_str(), L"POST") == 0)
  160. {
  161. verb = L"POST";
  162. }
  163. else
  164. {
  165. m_dwLastError = ERROR_INVALID_PARAMETER;
  166. return false;
  167. }
  168. bool bRetVal = true;
  169.  
  170. if (m_sessionHandle == NULL)
  171. {
  172. m_sessionHandle = ::WinHttpOpen(m_userAgent.c_str(),
  173. WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
  174. WINHTTP_NO_PROXY_NAME,
  175. WINHTTP_NO_PROXY_BYPASS,
  176. 0);
  177. if (m_sessionHandle == NULL)
  178. {
  179. m_dwLastError = ::GetLastError();
  180. return false;
  181. }
  182. }
  183.  
  184. ::WinHttpSetTimeouts(m_sessionHandle,
  185. m_resolveTimeout,
  186. m_connectTimeout,
  187. m_sendTimeout,
  188. m_receiveTimeout);
  189.  
  190. wchar_t szHostName[MAX_PATH] = L"";
  191. wchar_t szURLPath[MAX_PATH * 5] = L"";
  192. URL_COMPONENTS urlComp;
  193. memset(&urlComp, 0, sizeof(urlComp));
  194. urlComp.dwStructSize = sizeof(urlComp);
  195. urlComp.lpszHostName = szHostName;
  196. urlComp.dwHostNameLength = MAX_PATH;
  197. urlComp.lpszUrlPath = szURLPath;
  198. urlComp.dwUrlPathLength = MAX_PATH * 5;
  199. urlComp.dwSchemeLength = 1; // None zero
  200.  
  201. if (::WinHttpCrackUrl(m_requestURL.c_str(), m_requestURL.size(), 0, &urlComp))
  202. {
  203. m_requestHost = szHostName;
  204. HINTERNET hConnect = NULL;
  205. hConnect = ::WinHttpConnect(m_sessionHandle, szHostName, urlComp.nPort, 0);
  206. if (hConnect != NULL)
  207. {
  208. DWORD dwOpenRequestFlag = (urlComp.nScheme == INTERNET_SCHEME_HTTPS) ? WINHTTP_FLAG_SECURE : 0;
  209. HINTERNET hRequest = NULL;
  210. hRequest = ::WinHttpOpenRequest(hConnect,
  211. verb.c_str(),
  212. urlComp.lpszUrlPath,
  213. NULL,
  214. WINHTTP_NO_REFERER,
  215. WINHTTP_DEFAULT_ACCEPT_TYPES,
  216. dwOpenRequestFlag);
  217. if (hRequest != NULL)
  218. {
  219. // If HTTPS, then client is very susceptable to invalid certificates
  220. // Easiest to accept anything for now
  221. if (!m_requireValidSsl && urlComp.nScheme == INTERNET_SCHEME_HTTPS)
  222. {
  223. DWORD options = SECURITY_FLAG_IGNORE_CERT_CN_INVALID
  224. | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
  225. | SECURITY_FLAG_IGNORE_UNKNOWN_CA;
  226. ::WinHttpSetOption(hRequest,
  227. WINHTTP_OPTION_SECURITY_FLAGS,
  228. (LPVOID)&options,
  229. sizeof(DWORD));
  230. }
  231.  
  232. bool bGetReponseSucceed = false;
  233. unsigned int iRetryTimes = 0;
  234.  
  235. // Retry for several times if fails.
  236. while (!bGetReponseSucceed && iRetryTimes++ < INT_RETRYTIMES)
  237. {
  238. if (m_additionalRequestHeaders.size() > 0)
  239. {
  240. if (!::WinHttpAddRequestHeaders(hRequest, m_additionalRequestHeaders.c_str(), m_additionalRequestHeaders.size(), WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON))
  241. {
  242. m_dwLastError = ::GetLastError();
  243. }
  244. }
  245. if (m_additionalRequestCookies.size() > 0)
  246. {
  247. wstring cookies = L"Cookie: ";
  248. cookies += m_additionalRequestCookies;
  249. if (!::WinHttpAddRequestHeaders(hRequest, cookies.c_str(), cookies.size(), WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON))
  250. {
  251. m_dwLastError = ::GetLastError();
  252. }
  253. }
  254. if (m_proxy.size() > 0)
  255. {
  256. WINHTTP_PROXY_INFO proxyInfo;
  257. memset(&proxyInfo, 0, sizeof(proxyInfo));
  258. proxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
  259. wchar_t szProxy[MAX_PATH] = L"";
  260. wcscpy_s(szProxy, MAX_PATH, m_proxy.c_str());
  261. proxyInfo.lpszProxy = szProxy;
  262.  
  263. if (!::WinHttpSetOption(hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo)))
  264. {
  265. m_dwLastError = ::GetLastError();
  266. }
  267.  
  268. if (m_proxyUsername.size() > 0)
  269. {
  270. if (!::WinHttpSetOption(hRequest, WINHTTP_OPTION_PROXY_USERNAME, (LPVOID)m_proxyUsername.c_str(), m_proxyUsername.size() * sizeof(wchar_t)))
  271. {
  272. m_dwLastError = ::GetLastError();
  273. }
  274. if (m_proxyPassword.size() > 0)
  275. {
  276. if (!::WinHttpSetOption(hRequest, WINHTTP_OPTION_PROXY_PASSWORD, (LPVOID)m_proxyPassword.c_str(), m_proxyPassword.size() * sizeof(wchar_t)))
  277. {
  278. m_dwLastError = ::GetLastError();
  279. }
  280. }
  281. }
  282. }
  283.  
  284. if (disableAutoRedirect)
  285. {
  286. DWORD dwDisableFeature = WINHTTP_DISABLE_REDIRECTS;
  287. if (!::WinHttpSetOption(hRequest, WINHTTP_OPTION_DISABLE_FEATURE, &dwDisableFeature, sizeof(dwDisableFeature)))
  288. {
  289. m_dwLastError = ::GetLastError();
  290. }
  291. }
  292. bool bSendRequestSucceed = false;
  293. if (::WinHttpSendRequest(hRequest,
  294. WINHTTP_NO_ADDITIONAL_HEADERS,
  295. 0,
  296. WINHTTP_NO_REQUEST_DATA,
  297. 0,
  298. 0,
  299. NULL))
  300. {
  301. bSendRequestSucceed = true;
  302. }
  303. else
  304. {
  305. // Query the proxy information from IE setting and set the proxy if any.
  306. WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig;
  307. memset(&proxyConfig, 0, sizeof(proxyConfig));
  308. if (::WinHttpGetIEProxyConfigForCurrentUser(&proxyConfig))
  309. {
  310. if (proxyConfig.lpszAutoConfigUrl != NULL)
  311. {
  312. WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions;
  313. memset(&autoProxyOptions, 0, sizeof(autoProxyOptions));
  314. autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL;
  315. autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP;
  316. autoProxyOptions.lpszAutoConfigUrl = proxyConfig.lpszAutoConfigUrl;
  317. autoProxyOptions.fAutoLogonIfChallenged = TRUE;
  318. autoProxyOptions.dwReserved = 0;
  319. autoProxyOptions.lpvReserved = NULL;
  320.  
  321. WINHTTP_PROXY_INFO proxyInfo;
  322. memset(&proxyInfo, 0, sizeof(proxyInfo));
  323.  
  324. if (::WinHttpGetProxyForUrl(m_sessionHandle, m_requestURL.c_str(), &autoProxyOptions, &proxyInfo))
  325. {
  326. if (::WinHttpSetOption(hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo)))
  327. {
  328. if (::WinHttpSendRequest(hRequest,
  329. WINHTTP_NO_ADDITIONAL_HEADERS,
  330. 0,
  331. WINHTTP_NO_REQUEST_DATA,
  332. 0,
  333. 0,
  334. NULL))
  335. {
  336. bSendRequestSucceed = true;
  337. }
  338. }
  339. if (proxyInfo.lpszProxy != NULL)
  340. {
  341. ::GlobalFree(proxyInfo.lpszProxy);
  342. }
  343. if (proxyInfo.lpszProxyBypass != NULL)
  344. {
  345. ::GlobalFree(proxyInfo.lpszProxyBypass);
  346. }
  347. }
  348. else
  349. {
  350. m_dwLastError = ::GetLastError();
  351. }
  352. }
  353. else if (proxyConfig.lpszProxy != NULL)
  354. {
  355. WINHTTP_PROXY_INFO proxyInfo;
  356. memset(&proxyInfo, 0, sizeof(proxyInfo));
  357. proxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
  358. wchar_t szProxy[MAX_PATH] = L"";
  359. wcscpy_s(szProxy, MAX_PATH, proxyConfig.lpszProxy);
  360. proxyInfo.lpszProxy = szProxy;
  361.  
  362. if (proxyConfig.lpszProxyBypass != NULL)
  363. {
  364. wchar_t szProxyBypass[MAX_PATH] = L"";
  365. wcscpy_s(szProxyBypass, MAX_PATH, proxyConfig.lpszProxyBypass);
  366. proxyInfo.lpszProxyBypass = szProxyBypass;
  367. }
  368.  
  369. if (!::WinHttpSetOption(hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo)))
  370. {
  371. m_dwLastError = ::GetLastError();
  372. }
  373. }
  374.  
  375. if (proxyConfig.lpszAutoConfigUrl != NULL)
  376. {
  377. ::GlobalFree(proxyConfig.lpszAutoConfigUrl);
  378. }
  379. if (proxyConfig.lpszProxy != NULL)
  380. {
  381. ::GlobalFree(proxyConfig.lpszProxy);
  382. }
  383. if (proxyConfig.lpszProxyBypass != NULL)
  384. {
  385. ::GlobalFree(proxyConfig.lpszProxyBypass);
  386. }
  387. }
  388. else
  389. {
  390. m_dwLastError = ::GetLastError();
  391. }
  392. }
  393. if (bSendRequestSucceed)
  394. {
  395. if (m_pDataToSend != NULL)
  396. {
  397. DWORD dwWritten = 0;
  398. if (!::WinHttpWriteData(hRequest,
  399. m_pDataToSend,
  400. m_dataToSendSize,
  401. &dwWritten))
  402. {
  403. m_dwLastError = ::GetLastError();
  404. }
  405. }
  406. if (::WinHttpReceiveResponse(hRequest, NULL))
  407. {
  408. DWORD dwSize = 0;
  409. BOOL bResult = FALSE;
  410. bResult = ::WinHttpQueryHeaders(hRequest,
  411. WINHTTP_QUERY_RAW_HEADERS_CRLF,
  412. WINHTTP_HEADER_NAME_BY_INDEX,
  413. NULL,
  414. &dwSize,
  415. WINHTTP_NO_HEADER_INDEX);
  416. if (bResult || (!bResult && (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)))
  417. {
  418. wchar_t *szHeader = new wchar_t[dwSize];
  419. if (szHeader != NULL)
  420. {
  421. memset(szHeader, 0, dwSize * sizeof(wchar_t));
  422. if (::WinHttpQueryHeaders(hRequest,
  423. WINHTTP_QUERY_RAW_HEADERS_CRLF,
  424. WINHTTP_HEADER_NAME_BY_INDEX,
  425. szHeader,
  426. &dwSize,
  427. WINHTTP_NO_HEADER_INDEX))
  428. {
  429. m_responseHeader.assign(szHeader);
  430. vector<wstring> result;
  431. wstring regExp = L"";
  432. if (!m_bForceCharset)
  433. {
  434. regExp = L"charset={[A-Za-z0-9\\-_]+}";
  435. if (ParseRegExp(regExp, false, 1, m_responseHeader, result) && result.size() > 0)
  436. {
  437. m_responseCharset = result[0];
  438. }
  439. }
  440. regExp = L"Content-Length: {[0-9]+}";
  441. if (ParseRegExp(regExp, false, 1, m_responseHeader, result) && result.size() > 0)
  442. {
  443. m_responseByteCount = (unsigned int)_wtoi(result[0].c_str());
  444. }
  445. regExp = L"Location: {[0-9]+}";
  446. if (ParseRegExp(regExp, false, 1, m_responseHeader, result) && result.size() > 0)
  447. {
  448. m_location = result[0];
  449. }
  450. regExp = L"Set-Cookie:\\b*{.+?}\\n";
  451. if (ParseRegExp(regExp, false, 1, m_responseHeader, result) && result.size() > 0)
  452. {
  453. for (vector<wstring>::size_type i = 0; i < result.size(); i++)
  454. {
  455. m_responseCookies += result[i];
  456. if (i != result.size() - 1)
  457. {
  458. m_responseCookies += L"; ";
  459. }
  460. }
  461. m_responseCookies = Trim(m_responseCookies, L" ");
  462. if (m_responseCookies.size() > 0 && m_responseCookies[m_responseCookies.size() - 1] != L';')
  463. {
  464. m_responseCookies += L";";
  465. }
  466. }
  467. }
  468. delete[] szHeader;
  469. }
  470. }
  471.  
  472. dwSize = 0;
  473. bResult = ::WinHttpQueryHeaders(hRequest,
  474. WINHTTP_QUERY_STATUS_CODE,
  475. WINHTTP_HEADER_NAME_BY_INDEX,
  476. NULL,
  477. &dwSize,
  478. WINHTTP_NO_HEADER_INDEX);
  479. if (bResult || (!bResult && (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)))
  480. {
  481. wchar_t *szStatusCode = new wchar_t[dwSize];
  482. if (szStatusCode != NULL)
  483. {
  484. memset(szStatusCode, 0, dwSize * sizeof(wchar_t));
  485. if (::WinHttpQueryHeaders(hRequest,
  486. WINHTTP_QUERY_STATUS_CODE,
  487. WINHTTP_HEADER_NAME_BY_INDEX,
  488. szStatusCode,
  489. &dwSize,
  490. WINHTTP_NO_HEADER_INDEX))
  491. {
  492. m_statusCode = szStatusCode;
  493. }
  494. delete[] szStatusCode;
  495. }
  496. }
  497.  
  498. unsigned int iMaxBufferSize = INT_BUFFERSIZE;
  499. unsigned int iCurrentBufferSize = 0;
  500. if (m_pResponse != NULL)
  501. {
  502. delete[] m_pResponse;
  503. m_pResponse = NULL;
  504. }
  505. m_pResponse = new BYTE[iMaxBufferSize];
  506. if (m_pResponse == NULL)
  507. {
  508. bRetVal = false;
  509. break;
  510. }
  511. memset(m_pResponse, 0, iMaxBufferSize);
  512. do
  513. {
  514. dwSize = 0;
  515. if (::WinHttpQueryDataAvailable(hRequest, &dwSize))
  516. {
  517. SetProgress(iCurrentBufferSize);
  518. BYTE *pResponse = new BYTE[dwSize + 1];
  519. if (pResponse != NULL)
  520. {
  521. memset(pResponse, 0, (dwSize + 1) * sizeof(BYTE));
  522. DWORD dwRead = 0;
  523. if (::WinHttpReadData(hRequest,
  524. pResponse,
  525. dwSize,
  526. &dwRead))
  527. {
  528. if (dwRead + iCurrentBufferSize > iMaxBufferSize)
  529. {
  530. BYTE *pOldBuffer = m_pResponse;
  531. m_pResponse = new BYTE[iMaxBufferSize * 2];
  532. if (m_pResponse == NULL)
  533. {
  534. m_pResponse = pOldBuffer;
  535. bRetVal = false;
  536. break;
  537. }
  538. iMaxBufferSize *= 2;
  539. memset(m_pResponse, 0, iMaxBufferSize);
  540. memcpy(m_pResponse, pOldBuffer, iCurrentBufferSize);
  541. delete[] pOldBuffer;
  542. }
  543. memcpy(m_pResponse + iCurrentBufferSize, pResponse, dwRead);
  544. iCurrentBufferSize += dwRead;
  545. }
  546. delete[] pResponse;
  547. }
  548. }
  549. else
  550. {
  551. m_dwLastError = ::GetLastError();
  552. }
  553. } while (dwSize > 0);
  554. SetProgress(iCurrentBufferSize);
  555. m_responseByteCountReceived = iCurrentBufferSize;
  556.  
  557. UINT codePage = CP_ACP;
  558. DWORD dwFlag = MB_PRECOMPOSED;
  559. if (_wcsnicmp(m_responseCharset.c_str(), L"utf-8", 5) == 0)
  560. {
  561. codePage = CP_UTF8;
  562. dwFlag = 0;
  563. }
  564. int iLength = ::MultiByteToWideChar(codePage,
  565. dwFlag,
  566. (LPCSTR)m_pResponse,
  567. m_responseByteCountReceived + 1,
  568. NULL,
  569. 0);
  570. if (iLength <= 0)
  571. {
  572. // Use CP_ACP if UTF-8 fail
  573. codePage = CP_ACP;
  574. dwFlag = MB_PRECOMPOSED;
  575. iLength = ::MultiByteToWideChar(codePage,
  576. dwFlag,
  577. (LPCSTR)m_pResponse,
  578. m_responseByteCountReceived + 1,
  579. NULL,
  580. 0);
  581. }
  582. if (iLength > 0)
  583. {
  584. wchar_t *wideChar = new wchar_t[iLength];
  585. if (wideChar != NULL)
  586. {
  587. memset(wideChar, 0, iLength * sizeof(wchar_t));
  588. iLength = ::MultiByteToWideChar(codePage,
  589. dwFlag,
  590. (LPCSTR)m_pResponse,
  591. m_responseByteCountReceived + 1,
  592. wideChar,
  593. iLength);
  594. if (iLength > 0)
  595. {
  596. m_responseContent = wideChar;
  597. }
  598. delete[] wideChar;
  599. }
  600. }
  601. bGetReponseSucceed = true;
  602.  
  603. // If the resposne html web page size is less than 200, retry.
  604. if (verb == L"GET" && !disableAutoRedirect)
  605. {
  606. wstring regExp = L"{<html>}";
  607. vector<wstring> result;
  608. if (ParseRegExp(regExp, false, 1, m_responseContent, result) && result.size() > 0)
  609. {
  610. regExp = L"{</html>}";
  611. if (!ParseRegExp(regExp, false, 1, m_responseContent, result) || result.size() <= 0)
  612. {
  613. m_dwLastError = ERROR_INVALID_DATA;
  614. bGetReponseSucceed = false;
  615. }
  616. }
  617. }
  618. }
  619. else
  620. {
  621. m_dwLastError = ::GetLastError();
  622. }
  623. }
  624. } // while
  625. if (!bGetReponseSucceed)
  626. {
  627. bRetVal = false;
  628. }
  629.  
  630. ::WinHttpCloseHandle(hRequest);
  631. }
  632. ::WinHttpCloseHandle(hConnect);
  633. }
  634.  
  635. }
  636.  
  637. return bRetVal;
  638. }
  639.  
  640. wstring WinHttpClient::GetResponseHeader(void)
  641. {
  642. return m_responseHeader;
  643. }
  644.  
  645. wstring WinHttpClient::GetResponseContent(void)
  646. {
  647. return m_responseContent;
  648. }
  649.  
  650. wstring WinHttpClient::GetResponseCharset(void)
  651. {
  652. return m_responseCharset;
  653. }
  654.  
  655. wstring WinHttpClient::GetRequestHost(void)
  656. {
  657. return m_requestHost;
  658. }
  659.  
  660. bool WinHttpClient::SaveResponseToFile(const wstring &filePath)
  661. {
  662. if (m_pResponse == NULL || m_responseByteCountReceived <= 0)
  663. {
  664. return false;
  665. }
  666. FILE *f = NULL;
  667. int iResult = _wfopen_s(&f, filePath.c_str(), L"wb");
  668. if (iResult == 0 && f != NULL)
  669. {
  670. fwrite(m_pResponse, m_responseByteCountReceived, 1, f);
  671. fclose(f);
  672. return true;
  673. }
  674.  
  675. return false;
  676. }
  677.  
  678. bool WinHttpClient::SetProgress(unsigned int byteCountReceived)
  679. {
  680. bool bReturn = false;
  681. if (m_pfProcessProc != NULL && m_responseByteCount > 0)
  682. {
  683. double dProgress = (double)byteCountReceived * 100 / m_responseByteCount;
  684. m_pfProcessProc(dProgress);
  685. bReturn = true;
  686. }
  687.  
  688. return bReturn;
  689. }
  690.  
  691. wstring WinHttpClient::GetResponseCookies(void)
  692. {
  693. return m_responseCookies;
  694. }
  695.  
  696. bool WinHttpClient::SetAdditionalRequestCookies(const wstring &cookies)
  697. {
  698. m_additionalRequestCookies = cookies;
  699.  
  700. return true;
  701. }
  702.  
  703. bool WinHttpClient::SetAdditionalDataToSend(BYTE *data, unsigned int dataSize)
  704. {
  705. if (data == NULL || dataSize < 0)
  706. {
  707. return false;
  708. }
  709.  
  710. if (m_pDataToSend != NULL)
  711. {
  712. delete[] m_pDataToSend;
  713. }
  714. m_pDataToSend = NULL;
  715. m_pDataToSend = new BYTE[dataSize];
  716. if (m_pDataToSend != NULL)
  717. {
  718. memcpy(m_pDataToSend, data, dataSize);
  719. m_dataToSendSize = dataSize;
  720. return true;
  721. }
  722.  
  723. return false;
  724. }
  725.  
  726. // Reset additional data fields
  727. bool WinHttpClient::ResetAdditionalDataToSend(void)
  728. {
  729. if (m_pDataToSend != NULL)
  730. {
  731. delete[] m_pDataToSend;
  732. }
  733.  
  734. m_pDataToSend = NULL;
  735. m_dataToSendSize = 0;
  736.  
  737. return true;
  738. }
  739.  
  740. // Allow us to reset the url on subsequent requests
  741. bool WinHttpClient::UpdateUrl(const wstring &url)
  742. {
  743. m_requestURL = url;
  744. ResetAdditionalDataToSend();
  745.  
  746. return true;
  747. }
  748.  
  749. bool WinHttpClient::SetAdditionalRequestHeaders(const wstring &additionalRequestHeaders)
  750. {
  751. m_additionalRequestHeaders = additionalRequestHeaders;
  752.  
  753. return true;
  754. }
  755.  
  756. bool WinHttpClient::SetProxy(const wstring &proxy)
  757. {
  758. m_proxy = proxy;
  759.  
  760. return true;
  761. }
  762.  
  763. // If we don't require valid SSL Certs then accept any
  764. // certificate on an SSL connection
  765. bool WinHttpClient::SetRequireValidSslCertificates(bool require)
  766. {
  767. m_requireValidSsl = require;
  768.  
  769. return true;
  770. }
  771.  
  772. const BYTE *WinHttpClient::GetRawResponseContent(void)
  773. {
  774. return m_pResponse;
  775. }
  776.  
  777. unsigned int WinHttpClient::GetRawResponseContentLength(void)
  778. {
  779. return m_responseByteCount;
  780. }
  781.  
  782. unsigned int WinHttpClient::GetRawResponseReceivedContentLength(void)
  783. {
  784. return m_responseByteCountReceived;
  785. }
  786.  
  787. DWORD WinHttpClient::GetLastError(void)
  788. {
  789. return m_dwLastError;
  790. }
  791.  
  792. wstring WinHttpClient::GetResponseStatusCode(void)
  793. {
  794. return m_statusCode;
  795. }
  796.  
  797. bool WinHttpClient::SetUserAgent(const wstring &userAgent)
  798. {
  799. m_userAgent = userAgent;
  800.  
  801. return true;
  802. }
  803.  
  804. bool WinHttpClient::SetForceCharset(const wstring &charset)
  805. {
  806. m_responseCharset = charset;
  807.  
  808. return true;
  809. }
  810.  
  811. bool WinHttpClient::SetProxyUsername(const wstring &username)
  812. {
  813. m_proxyUsername = username;
  814.  
  815. return true;
  816. }
  817.  
  818. bool WinHttpClient::SetProxyPassword(const std::wstring &password)
  819. {
  820. m_proxyPassword = password;
  821.  
  822. return true;
  823. }
  824.  
  825. wstring WinHttpClient::GetResponseLocation(void)
  826. {
  827. return m_location;
  828. }
  829.  
  830. bool WinHttpClient::SetTimeouts(unsigned int resolveTimeout,
  831. unsigned int connectTimeout,
  832. unsigned int sendTimeout,
  833. unsigned int receiveTimeout)
  834. {
  835. m_resolveTimeout = resolveTimeout;
  836. m_connectTimeout = connectTimeout;
  837. m_sendTimeout = sendTimeout;
  838. m_receiveTimeout = receiveTimeout;
  839.  
  840. return true;
  841. }
  842.  
  843. #endif // WINHTTPCLIENT_H
  844.  
  845. class network
  846. {
  847. private:
  848. std::wstring siteurl;
  849. public:
  850. network(std::wstring url)
  851. {
  852. this->siteurl = url;
  853. }
  854.  
  855. std::wstring post(std::string message)
  856. {
  857. WinHttpClient client(this->siteurl);
  858.  
  859. string data = message;
  860. client.SetAdditionalDataToSend((BYTE*)data.c_str(), (unsigned int)data.size());
  861.  
  862. client.SetRequireValidSslCertificates(true);
  863.  
  864. wchar_t szSize[50] = L"";
  865. swprintf_s(szSize, L"%zd", data.size());
  866. std::wstring headers = L"Content-Length: ";
  867. headers += szSize;
  868. headers += L"\r\nContent-Type: application/x-www-form-urlencoded\r\n";
  869. client.SetAdditionalRequestHeaders(headers);
  870.  
  871. client.SendHttpRequest(L"POST");
  872.  
  873. return client.GetResponseContent();
  874. }
  875. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement