HttpHelper.h 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352
  1. /*
  2. * Copyright: JessMA Open Source (ldcsaa@gmail.com)
  3. *
  4. * Version : 4.2.1
  5. * Author : Bruce Liang
  6. * Website : http://www.jessma.org
  7. * Project : https://github.com/ldcsaa
  8. * Blog : http://www.cnblogs.com/ldcsaa
  9. * Wiki : http://www.oschina.net/p/hp-socket
  10. * QQ Group : 75375912
  11. *
  12. * Licensed under the Apache License, Version 2.0 (the "License");
  13. * you may not use this file except in compliance with the License.
  14. * You may obtain a copy of the License at
  15. *
  16. * http://www.apache.org/licenses/LICENSE-2.0
  17. *
  18. * Unless required by applicable law or agreed to in writing, software
  19. * distributed under the License is distributed on an "AS IS" BASIS,
  20. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21. * See the License for the specific language governing permissions and
  22. * limitations under the License.
  23. */
  24. #pragma once
  25. #include "SocketHelper.h"
  26. #include "HttpCookie.h"
  27. #include "../../Common/Src/http/http_parser.h"
  28. #include "../../Common/Src/zlib/zutil.h"
  29. /************************************************************************
  30. 名称:HTTP 全局常量
  31. 描述:声明 HTTP 组件的公共全局常量
  32. ************************************************************************/
  33. #define HTTP_DEFAULT_PORT 80
  34. #define HTTPS_DEFAULT_PORT 443
  35. #define HTTP_SCHEMA "http://"
  36. #define HTTPS_SCHEMA "https://"
  37. #define HTTP_CRLF "\r\n"
  38. #define HTTP_PORT_SEPARATOR_CHAR ':'
  39. #define HTTP_PATH_SEPARATOR_CHAR '/'
  40. #define HTTP_PATH_SEPARATOR "/"
  41. #define HTTP_HEADER_SEPARATOR ": "
  42. #define HTTP_COOKIE_SEPARATOR "; "
  43. #define HTTP_1_0_STR "HTTP/1.0"
  44. #define HTTP_1_1_STR "HTTP/1.1"
  45. #define HTTP_HEADER_HOST "Host"
  46. #define HTTP_HEADER_COOKIE "Cookie"
  47. #define HTTP_HEADER_SET_COOKIE "Set-Cookie"
  48. #define HTTP_HEADER_CONTENT_TYPE "Content-Type"
  49. #define HTTP_HEADER_CONTENT_LENGTH "Content-Length"
  50. #define HTTP_HEADER_CONTENT_ENCODING "Content-Encoding"
  51. #define HTTP_HEADER_TRANSFER_ENCODING "Transfer-Encoding"
  52. #define HTTP_HEADER_CONNECTION "Connection"
  53. #define HTTP_HEADER_UPGRADE "Upgrade"
  54. #define HTTP_HEADER_VALUE_WEB_SOCKET "WebSocket"
  55. #define HTTP_CONNECTION_CLOSE_VALUE "close"
  56. #define HTTP_CONNECTION_KEEPALIVE_VALUE "keep-alive"
  57. #define HTTP_METHOD_POST "POST"
  58. #define HTTP_METHOD_PUT "PUT"
  59. #define HTTP_METHOD_PATCH "PATCH"
  60. #define HTTP_METHOD_GET "GET"
  61. #define HTTP_METHOD_DELETE "DELETE"
  62. #define HTTP_METHOD_HEAD "HEAD"
  63. #define HTTP_METHOD_TRACE "TRACE"
  64. #define HTTP_METHOD_OPTIONS "OPTIONS"
  65. #define HTTP_METHOD_CONNECT "CONNECT"
  66. #define HTTP_MIN_WS_HEADER_LEN 2
  67. #define HTTP_MAX_WS_HEADER_LEN 14
  68. #define MIN_HTTP_RELEASE_CHECK_INTERVAL 1000
  69. #define MIN_HTTP_RELEASE_DELAY 100
  70. #define MAX_HTTP_RELEASE_DELAY (60 * 1000)
  71. #define DEFAULT_HTTP_RELEASE_DELAY (3 * 1000)
  72. #define DEFAULT_HTTP_VERSION HV_1_1
  73. #define DEFAULT_HTTP_SYNC_CONNECT_TIMEOUT 5000
  74. #define DEFAULT_HTTP_SYNC_REQUEST_TIMEOUT 10000
  75. // ------------------------------------------------------------------------------------------------------------- //
  76. enum EnHttpSyncRequestProgress
  77. {
  78. HSRP_DONE,
  79. HSRP_WAITING,
  80. HSRP_ERROR,
  81. HSRP_CLOSE
  82. };
  83. struct TDyingConnection
  84. {
  85. CONNID connID;
  86. DWORD killTime;
  87. TDyingConnection(CONNID id, DWORD kt = 0)
  88. : connID (id)
  89. , killTime (kt == 0 ? ::TimeGetTime() : kt)
  90. {
  91. }
  92. static TDyingConnection* Construct(CONNID id, DWORD kt = 0) {return new TDyingConnection(id, kt);}
  93. static void Destruct(TDyingConnection* pObj) {if(pObj) delete pObj;}
  94. };
  95. typedef unordered_multimap<CStringA, CStringA,
  96. cstringa_hash_func::hash, cstringa_hash_func::equal_to> THeaderMap;
  97. typedef THeaderMap::const_iterator THeaderMapCI;
  98. typedef THeaderMap::iterator THeaderMapI;
  99. typedef unordered_map<CStringA, CStringA,
  100. cstringa_hash_func::hash, cstringa_hash_func::equal_to> TCookieMap;
  101. typedef TCookieMap::const_iterator TCookieMapCI;
  102. typedef TCookieMap::iterator TCookieMapI;
  103. // ------------------------------------------------------------------------------------------------------------- //
  104. struct TBaseWSHeader
  105. {
  106. public:
  107. BOOL fin()
  108. {
  109. return (data >> 7) & 0x1;
  110. }
  111. void set_fin(BOOL v)
  112. {
  113. data |= ((v ? 1 : 0) << 7);
  114. }
  115. BYTE rsv()
  116. {
  117. return (data >> 4) & 0x7;
  118. }
  119. void set_rsv(BYTE v)
  120. {
  121. data |= ((v & 0x7) << 4);
  122. }
  123. BYTE code()
  124. {
  125. return data & 0xF;
  126. }
  127. void set_code(BYTE v)
  128. {
  129. data |= (v & 0xF);
  130. }
  131. BOOL mask()
  132. {
  133. return (data >> 15) & 0x1;
  134. }
  135. void set_mask(BOOL v)
  136. {
  137. data |= ((v ? 1 : 0) << 15);
  138. }
  139. BYTE len()
  140. {
  141. return (data >> 8) & 0x7F;
  142. }
  143. void set_len(BYTE v)
  144. {
  145. data |= ((v & 0x7F) << 8);
  146. }
  147. USHORT extlen()
  148. {
  149. return ntohs(data >> 16);
  150. }
  151. void set_extlen(USHORT v)
  152. {
  153. data |= (htons(v) << 16);
  154. }
  155. TBaseWSHeader(const BYTE* p, BOOL bZero = FALSE)
  156. : data(*(UINT*)p)
  157. {
  158. if(bZero) data = 0;
  159. }
  160. private:
  161. UINT& data;
  162. };
  163. template<class T> struct TWSContext
  164. {
  165. public:
  166. EnHandleResult Parse(const BYTE* pData, int iLength)
  167. {
  168. ASSERT(pData != nullptr && iLength > 0);
  169. EnHandleResult hr = HR_OK;
  170. BYTE* pTemp = (BYTE*)pData;
  171. int iRemain = iLength;
  172. int iMin = 0;
  173. while(iRemain > 0)
  174. {
  175. if(m_bHeader)
  176. {
  177. iMin = min(m_iHeaderRemain, iRemain);
  178. memcpy(m_szHeader + m_iHeaderLen - m_iHeaderRemain, pTemp, iMin);
  179. m_iHeaderRemain -= iMin;
  180. if(m_iHeaderRemain == 0)
  181. {
  182. TBaseWSHeader bh(m_szHeader);
  183. int iLen = bh.len();
  184. int iExtLen = iLen < 126 ? 0 : (iLen == 126 ? 2 : 8);
  185. int iMaskLen = bh.mask() ? 4 : 0;
  186. int iRealHeaderLen = HTTP_MIN_WS_HEADER_LEN + iExtLen + iMaskLen;
  187. if(m_iHeaderLen < iRealHeaderLen)
  188. {
  189. m_iHeaderRemain = iRealHeaderLen - m_iHeaderLen;
  190. m_iHeaderLen = iRealHeaderLen;
  191. }
  192. else
  193. {
  194. m_ullBodyLen = iExtLen == 0 ? iLen : (iExtLen == 2 ? bh.extlen() : NToH64(*(ULONGLONG*)(m_szHeader + HTTP_MIN_WS_HEADER_LEN)));
  195. m_ullBodyRemain = m_ullBodyLen;
  196. m_lpszMask = iMaskLen > 0 ? m_szHeader + HTTP_MIN_WS_HEADER_LEN + iExtLen : nullptr;
  197. hr = m_pHttpObj->on_ws_message_header(bh.fin(), bh.rsv(), bh.code(), m_lpszMask, m_ullBodyLen);
  198. if(hr == HR_ERROR)
  199. break;
  200. if(m_ullBodyLen > 0)
  201. m_bHeader = FALSE;
  202. else
  203. {
  204. hr = CompleteMessage();
  205. if(hr == HR_ERROR)
  206. break;
  207. }
  208. }
  209. }
  210. }
  211. else
  212. {
  213. iMin = (int)min(m_ullBodyRemain, (ULONGLONG)iRemain);
  214. if(m_lpszMask)
  215. {
  216. int iFactor = (m_ullBodyLen - m_ullBodyRemain) & 0x03;
  217. for(int i = 0; i < iMin; i++)
  218. pTemp[i] = pTemp[i] ^ m_lpszMask[(i + iFactor) & 0x03];
  219. }
  220. m_ullBodyRemain -= iMin;
  221. EnHandleResult hr = m_pHttpObj->on_ws_message_body(pTemp, iMin);
  222. if(hr == HR_ERROR)
  223. break;
  224. if(m_ullBodyRemain == 0)
  225. {
  226. hr = CompleteMessage();
  227. if(hr == HR_ERROR)
  228. break;
  229. }
  230. }
  231. pTemp += iMin;
  232. iRemain -= iMin;
  233. }
  234. return HR_OK;
  235. }
  236. BOOL GetMessageState(BOOL* lpbFinal, BYTE* lpiReserved, BYTE* lpiOperationCode, LPCBYTE* lpszMask, ULONGLONG* lpullBodyLen, ULONGLONG* lpullBodyRemain)
  237. {
  238. TBaseWSHeader bh(m_szHeader);
  239. if(lpbFinal) *lpbFinal = bh.fin();
  240. if(lpiReserved) *lpiReserved = bh.rsv();
  241. if(lpiOperationCode) *lpiOperationCode = bh.code();
  242. if(lpszMask) *lpszMask = m_lpszMask;
  243. if(lpullBodyLen) *lpullBodyLen = m_ullBodyLen;
  244. if(lpullBodyRemain) *lpullBodyRemain = m_ullBodyRemain;
  245. return TRUE;
  246. }
  247. BOOL CopyData(const TWSContext& src)
  248. {
  249. if(&src == this)
  250. return FALSE;
  251. memcpy(m_szHeader, src.m_szHeader, HTTP_MAX_WS_HEADER_LEN);
  252. if(src.m_lpszMask)
  253. m_lpszMask = m_szHeader + (src.m_lpszMask - src.m_szHeader);
  254. else
  255. m_lpszMask = nullptr;
  256. m_ullBodyLen = src.m_ullBodyLen;
  257. m_ullBodyRemain = src.m_ullBodyRemain;
  258. return TRUE;
  259. }
  260. public:
  261. TWSContext(T* pHttpObj) : m_pHttpObj(pHttpObj)
  262. {
  263. Reset();
  264. }
  265. private:
  266. EnHandleResult CompleteMessage()
  267. {
  268. EnHandleResult hr = m_pHttpObj->on_ws_message_complete();
  269. Reset();
  270. return hr;
  271. }
  272. void Reset()
  273. {
  274. m_bHeader = TRUE;
  275. m_lpszMask = nullptr;
  276. m_iHeaderLen = HTTP_MIN_WS_HEADER_LEN;
  277. m_iHeaderRemain = HTTP_MIN_WS_HEADER_LEN;
  278. m_ullBodyLen = 0;
  279. m_ullBodyRemain = 0;
  280. }
  281. private:
  282. T* m_pHttpObj;
  283. BYTE m_szHeader[HTTP_MAX_WS_HEADER_LEN];
  284. const BYTE* m_lpszMask;
  285. BOOL m_bHeader;
  286. int m_iHeaderLen;
  287. int m_iHeaderRemain;
  288. ULONGLONG m_ullBodyLen;
  289. ULONGLONG m_ullBodyRemain;
  290. };
  291. // ------------------------------------------------------------------------------------------------------------- //
  292. /* Http 上下文结构 */
  293. template<class T, class S> struct THttpObjT
  294. {
  295. public:
  296. EnHandleResult Execute(const BYTE* pData, int iLength)
  297. {
  298. ASSERT(pData != nullptr && iLength > 0);
  299. if(m_parser.upgrade)
  300. {
  301. if(m_enUpgrade == HUT_WEB_SOCKET)
  302. return m_pwsContext->Parse(pData, iLength);
  303. else
  304. return m_pContext->DoFireSuperReceive(m_pSocket, pData, iLength);
  305. }
  306. EnHandleResult hr = HR_OK;
  307. int iPased = (int)::http_parser_execute(&m_parser, &sm_settings, (LPCSTR)pData, iLength);
  308. if(m_parser.upgrade)
  309. hr = Upgrade(pData, iLength, iPased);
  310. else if(m_parser.http_errno != HPE_OK)
  311. {
  312. m_pContext->FireParseError(m_pSocket, m_parser.http_errno, ::http_errno_description(HTTP_PARSER_ERRNO(&m_parser)));
  313. hr = HR_ERROR;
  314. }
  315. else
  316. ASSERT(iPased == iLength);
  317. return hr;
  318. }
  319. static int on_message_begin(http_parser* p)
  320. {
  321. THttpObjT* pSelf = Self(p);
  322. pSelf->ResetHeaderState(FALSE, FALSE);
  323. return pSelf->m_pContext->FireMessageBegin(pSelf->m_pSocket);
  324. }
  325. static int on_url(http_parser* p, const char* at, size_t length)
  326. {
  327. EnHttpParseResult hpr = HPR_OK;
  328. THttpObjT* pSelf = Self(p);
  329. pSelf->AppendBuffer(at, length);
  330. if(p->state != s_req_http_start)
  331. return hpr;
  332. hpr = pSelf->ParseUrl();
  333. if(hpr == HPR_OK)
  334. hpr = pSelf->m_pContext->FireRequestLine(pSelf->m_pSocket, ::http_method_str((http_method)p->method), pSelf->GetBuffer());
  335. pSelf->ResetBuffer();
  336. return hpr;
  337. }
  338. static int on_status(http_parser* p, const char* at, size_t length)
  339. {
  340. EnHttpParseResult hpr = HPR_OK;
  341. THttpObjT* pSelf = Self(p);
  342. pSelf->AppendBuffer(at, length);
  343. if(p->state != s_res_line_almost_done)
  344. return hpr;
  345. hpr = pSelf->m_pContext->FireStatusLine(pSelf->m_pSocket, p->status_code, pSelf->GetBuffer());
  346. pSelf->ResetBuffer();
  347. return hpr;
  348. }
  349. static int on_header_field(http_parser* p, const char* at, size_t length)
  350. {
  351. EnHttpParseResult hpr = HPR_OK;
  352. THttpObjT* pSelf = Self(p);
  353. pSelf->AppendBuffer(at, length);
  354. if(p->state != s_header_value_discard_ws)
  355. return hpr;
  356. pSelf->m_strCurHeader = pSelf->GetBuffer();
  357. pSelf->ResetBuffer();
  358. return hpr;
  359. }
  360. static int on_header_value(http_parser* p, const char* at, size_t length)
  361. {
  362. EnHttpParseResult hpr = HPR_OK;
  363. THttpObjT* pSelf = Self(p);
  364. pSelf->AppendBuffer(at, length);
  365. if(p->state != s_header_almost_done && p->state != s_header_field_start)
  366. return hpr;
  367. pSelf->m_headers.emplace(move(THeaderMap::value_type(pSelf->m_strCurHeader, pSelf->GetBuffer())));
  368. hpr = pSelf->m_pContext->FireHeader(pSelf->m_pSocket, pSelf->m_strCurHeader, pSelf->GetBuffer());
  369. if(hpr != HPR_ERROR)
  370. {
  371. if(pSelf->m_bRequest && pSelf->m_strCurHeader == HTTP_HEADER_COOKIE)
  372. hpr = pSelf->ParseCookie();
  373. else if(!pSelf->m_bRequest && pSelf->m_strCurHeader == HTTP_HEADER_SET_COOKIE)
  374. hpr = pSelf->ParseSetCookie();
  375. }
  376. pSelf->ResetBuffer();
  377. return hpr;
  378. }
  379. static int on_headers_complete(http_parser* p)
  380. {
  381. THttpObjT* pSelf = Self(p);
  382. pSelf->CheckUpgrade();
  383. pSelf->ResetHeaderBuffer();
  384. return pSelf->m_pContext->FireHeadersComplete(pSelf->m_pSocket);
  385. }
  386. static int on_body(http_parser* p, const char* at, size_t length)
  387. {
  388. THttpObjT* pSelf = Self(p);
  389. return pSelf->m_pContext->FireBody(pSelf->m_pSocket, (const BYTE*)at, (int)length);
  390. }
  391. static int on_chunk_header(http_parser* p)
  392. {
  393. THttpObjT* pSelf = Self(p);
  394. if(p->state == s_chunk_data || p->state == s_header_field_start)
  395. return pSelf->m_pContext->FireChunkHeader(pSelf->m_pSocket, (int)p->content_length);
  396. return HPR_OK;
  397. }
  398. static int on_chunk_complete(http_parser* p)
  399. {
  400. THttpObjT* pSelf = Self(p);
  401. if(p->state == s_headers_done || p->state == s_message_done)
  402. return pSelf->m_pContext->FireChunkComplete(pSelf->m_pSocket);
  403. return HPR_OK;
  404. }
  405. static int on_message_complete(http_parser* p)
  406. {
  407. THttpObjT* pSelf = Self(p);
  408. EnHttpParseResult hpr = pSelf->m_pContext->FireMessageComplete(pSelf->m_pSocket);
  409. return hpr;
  410. }
  411. EnHandleResult on_ws_message_header(BOOL bFinal, BYTE iReserved, BYTE iOperationCode, const BYTE lpszMask[4], ULONGLONG ullBodyLen)
  412. {
  413. return m_pContext->FireWSMessageHeader(m_pSocket, bFinal, iReserved, iOperationCode, lpszMask, ullBodyLen);
  414. }
  415. EnHandleResult on_ws_message_body(const BYTE* pData, int iLength)
  416. {
  417. return m_pContext->FireWSMessageBody(m_pSocket, pData, iLength);
  418. }
  419. EnHandleResult on_ws_message_complete()
  420. {
  421. return m_pContext->FireWSMessageComplete(m_pSocket);
  422. }
  423. private:
  424. EnHandleResult Upgrade(const BYTE* pData, int iLength, int iPased)
  425. {
  426. ASSERT(m_parser.upgrade);
  427. if(m_pContext->FireUpgrade(m_pSocket, m_enUpgrade) != HPR_OK)
  428. return HR_ERROR;
  429. ResetHeaderState();
  430. if(m_enUpgrade == HUT_WEB_SOCKET)
  431. m_pwsContext = new TWSContext<THttpObjT<T, S>>(this);
  432. if(iPased < iLength)
  433. return Execute(pData + iPased, iLength - iPased);
  434. return HR_OK;
  435. }
  436. void CheckUpgrade()
  437. {
  438. if(!m_parser.upgrade)
  439. return;
  440. if(m_bRequest && m_parser.method == HTTP_CONNECT)
  441. m_enUpgrade = HUT_HTTP_TUNNEL;
  442. else
  443. {
  444. LPCSTR lpszValue;
  445. if(GetHeader(HTTP_HEADER_UPGRADE, &lpszValue) && _stricmp(HTTP_HEADER_VALUE_WEB_SOCKET, lpszValue) == 0)
  446. m_enUpgrade = HUT_WEB_SOCKET;
  447. else
  448. m_enUpgrade = HUT_UNKNOWN;
  449. }
  450. }
  451. EnHttpParseResult ParseUrl()
  452. {
  453. http_parser_url url = {0};
  454. BOOL isConnect = m_parser.method == HTTP_CONNECT;
  455. int rs = ::http_parser_parse_url(m_strBuffer, m_strBuffer.GetLength(), isConnect, &url);
  456. if(rs != HPE_OK)
  457. {
  458. m_parser.http_errno = HPE_INVALID_URL;
  459. return HPR_ERROR;
  460. }
  461. m_usUrlFieldSet = url.field_set;
  462. LPCSTR lpszBuffer = m_strBuffer;
  463. for(int i = 0; i < UF_MAX; i++)
  464. {
  465. if((url.field_set & (1 << i)) != 0)
  466. m_pstrUrlFileds[i].SetString((lpszBuffer + url.field_data[i].off), url.field_data[i].len);
  467. }
  468. return HPR_OK;
  469. }
  470. EnHttpParseResult ParseCookie()
  471. {
  472. int i = 0;
  473. do
  474. {
  475. CStringA tk = m_strBuffer.Tokenize(COOKIE_FIELD_SEP, i);
  476. if(i == -1)
  477. break;
  478. int j = tk.Trim().Find(COOKIE_KV_SEP_CHAR);
  479. if(j <= 0)
  480. continue;
  481. /*
  482. {
  483. m_parser.http_errno = HPE_INVALID_HEADER_TOKEN;
  484. return HPR_ERROR;
  485. }
  486. */
  487. AddCookie(tk.Left(j), tk.Mid(j + 1));
  488. } while(TRUE);
  489. return HPR_OK;
  490. }
  491. EnHttpParseResult ParseSetCookie()
  492. {
  493. CCookieMgr* pCookieMgr = m_pContext->GetCookieMgr();
  494. if(pCookieMgr == nullptr)
  495. return HPR_OK;
  496. LPCSTR lpszDomain = GetDomain();
  497. LPCSTR lpszPath = GetPath();
  498. unique_ptr<CCookie> pCookie(CCookie::FromString(m_strBuffer, lpszDomain, lpszPath));
  499. if(pCookie == nullptr)
  500. return HPR_ERROR;
  501. if(pCookie->Match(lpszDomain, lpszPath, TRUE, m_pContext->IsSecure()))
  502. {
  503. if(pCookie->IsExpired())
  504. DeleteCookie(pCookie->name);
  505. else
  506. AddCookie(pCookie->name, pCookie->value);
  507. }
  508. if(pCookieMgr->IsEnableThirdPartyCookie() || pCookie->IsSameDomain(lpszDomain))
  509. pCookieMgr->SetCookie(*pCookie);
  510. return HPR_OK;
  511. }
  512. public:
  513. DWORD GetFreeTime() const {return m_dwFreeTime;}
  514. void SetFree() {m_dwFreeTime = ::TimeGetTime();}
  515. BOOL IsUpgrade() {return m_parser.upgrade;}
  516. BOOL IsKeepAlive() {return ::http_should_keep_alive(&m_parser);}
  517. USHORT GetVersion() {return MAKEWORD(m_parser.http_major, m_parser.http_minor);}
  518. ULONGLONG GetContentLength() {return m_parser.content_length;}
  519. LPCSTR GetMethod() {return ::http_method_str((http_method)(m_parser.method));}
  520. USHORT GetUrlFieldSet() {return m_usUrlFieldSet;}
  521. USHORT GetStatusCode() {return m_parser.status_code;}
  522. EnHttpUpgradeType GetUpgradeType() {return m_enUpgrade;}
  523. THeaderMap& GetHeaderMap() {return m_headers;}
  524. TCookieMap& GetCookieMap() {return m_cookies;}
  525. BOOL HasReleased() {return m_bReleased;}
  526. void Release() {m_bReleased = TRUE;}
  527. LPCSTR GetContentType()
  528. {
  529. LPCSTR lpszValue = nullptr;
  530. GetHeader(HTTP_HEADER_CONTENT_TYPE, &lpszValue);
  531. return lpszValue;
  532. }
  533. LPCSTR GetContentEncoding()
  534. {
  535. LPCSTR lpszValue = nullptr;
  536. GetHeader(HTTP_HEADER_CONTENT_ENCODING, &lpszValue);
  537. return lpszValue;
  538. }
  539. LPCSTR GetTransferEncoding()
  540. {
  541. LPCSTR lpszValue = nullptr;
  542. GetHeader(HTTP_HEADER_TRANSFER_ENCODING, &lpszValue);
  543. return lpszValue;
  544. }
  545. LPCSTR GetHost()
  546. {
  547. LPCSTR lpszValue = nullptr;
  548. GetHeader(HTTP_HEADER_HOST, &lpszValue);
  549. return lpszValue;
  550. }
  551. USHORT GetParseErrorCode(LPCSTR* lpszErrorDesc = nullptr)
  552. {
  553. if(lpszErrorDesc)
  554. *lpszErrorDesc = ::http_errno_description(HTTP_PARSER_ERRNO(&m_parser));
  555. return m_parser.http_errno;
  556. }
  557. LPCSTR GetUrlField(EnHttpUrlField enField)
  558. {
  559. ASSERT(m_bRequest && enField < HUF_MAX);
  560. if(!m_bRequest || enField >= HUF_MAX)
  561. return nullptr;
  562. return m_pstrUrlFileds[enField];
  563. }
  564. LPCSTR GetPath()
  565. {
  566. if(m_bRequest)
  567. return GetUrlField(HUF_PATH);
  568. else
  569. return *m_pstrRequestPath;
  570. }
  571. LPCSTR GetDomain()
  572. {
  573. ASSERT(!m_bRequest);
  574. return m_pContext->GetRemoteDomain(m_pSocket);
  575. }
  576. LPCSTR GetRequestPath()
  577. {
  578. if(m_bRequest)
  579. return nullptr;
  580. return *m_pstrRequestPath;
  581. }
  582. void SetRequestPath(LPCSTR lpszPath)
  583. {
  584. ASSERT(!m_bRequest);
  585. if(!m_bRequest)
  586. *m_pstrRequestPath = lpszPath;
  587. }
  588. BOOL GetHeader(LPCSTR lpszName, LPCSTR* lpszValue)
  589. {
  590. ASSERT(lpszName);
  591. BOOL isOK = FALSE;
  592. THeaderMapCI it = m_headers.find(lpszName);
  593. if(it != m_headers.end())
  594. {
  595. *lpszValue = it->second;
  596. isOK = TRUE;
  597. }
  598. return isOK;
  599. }
  600. BOOL GetHeaders(LPCSTR lpszName, LPCSTR lpszValue[], DWORD& dwCount)
  601. {
  602. ASSERT(lpszName);
  603. if(lpszValue == nullptr || dwCount == 0)
  604. {
  605. dwCount = (DWORD)m_headers.count(lpszName);
  606. return FALSE;
  607. }
  608. pair<THeaderMapCI, THeaderMapCI> range = m_headers.equal_range(lpszName);
  609. THeaderMapCI it = range.first;
  610. DWORD dwIndex = 0;
  611. while(it != range.second)
  612. {
  613. if(dwIndex < dwCount)
  614. lpszValue[dwIndex] = it->second;
  615. ++dwIndex;
  616. ++it;
  617. }
  618. BOOL isOK = (dwIndex > 0 && dwIndex <= dwCount);
  619. dwCount = dwIndex;
  620. return isOK;
  621. }
  622. BOOL GetAllHeaders(THeader lpHeaders[], DWORD& dwCount)
  623. {
  624. DWORD dwSize = (DWORD)m_headers.size();
  625. if(lpHeaders == nullptr || dwCount == 0 || dwSize == 0 || dwSize > dwCount)
  626. {
  627. dwCount = dwSize;
  628. return FALSE;
  629. }
  630. DWORD dwIndex = 0;
  631. for(THeaderMapCI it = m_headers.begin(), end = m_headers.end(); it != end; ++it, ++dwIndex)
  632. {
  633. lpHeaders[dwIndex].name = it->first;
  634. lpHeaders[dwIndex].value = it->second;
  635. }
  636. dwCount = dwSize;
  637. return TRUE;
  638. }
  639. BOOL GetAllHeaderNames(LPCSTR lpszName[], DWORD& dwCount)
  640. {
  641. DWORD dwSize = (DWORD)m_headers.size();
  642. if(lpszName == nullptr || dwCount == 0 || dwSize == 0 || dwSize > dwCount)
  643. {
  644. dwCount = dwSize;
  645. return FALSE;
  646. }
  647. DWORD dwIndex = 0;
  648. for(THeaderMapCI it = m_headers.begin(), end = m_headers.end(); it != end; ++it, ++dwIndex)
  649. lpszName[dwIndex] = it->first;
  650. dwCount = dwSize;
  651. return TRUE;
  652. }
  653. BOOL AddCookie(LPCSTR lpszName, LPCSTR lpszValue, BOOL bRelpace = TRUE)
  654. {
  655. ASSERT(lpszName);
  656. TCookieMapI it = m_cookies.find(lpszName);
  657. if(it == m_cookies.end())
  658. return m_cookies.emplace(move(TCookieMap::value_type(lpszName, lpszValue))).second;
  659. BOOL isOK = FALSE;
  660. if(bRelpace)
  661. {
  662. it->second = lpszValue;
  663. isOK = TRUE;
  664. }
  665. return isOK;
  666. }
  667. BOOL DeleteCookie(LPCSTR lpszName)
  668. {
  669. ASSERT(lpszName);
  670. return m_cookies.erase(lpszName) > 0;
  671. }
  672. void DeleteAllCookies()
  673. {
  674. m_cookies.clear();
  675. }
  676. BOOL GetCookie(LPCSTR lpszName, LPCSTR* lpszValue)
  677. {
  678. ASSERT(lpszName);
  679. BOOL isOK = FALSE;
  680. TCookieMapCI it = m_cookies.find(lpszName);
  681. if(it != m_cookies.end())
  682. {
  683. *lpszValue = it->second;
  684. isOK = TRUE;
  685. }
  686. return isOK;
  687. }
  688. BOOL GetAllCookies(TCookie lpCookies[], DWORD& dwCount)
  689. {
  690. DWORD dwSize = (DWORD)m_cookies.size();
  691. if(lpCookies == nullptr || dwCount == 0 || dwSize == 0 || dwSize > dwCount)
  692. {
  693. dwCount = dwSize;
  694. return FALSE;
  695. }
  696. DWORD dwIndex = 0;
  697. for(TCookieMapCI it = m_cookies.begin(), end = m_cookies.end(); it != end; ++it, ++dwIndex)
  698. {
  699. lpCookies[dwIndex].name = it->first;
  700. lpCookies[dwIndex].value = it->second;
  701. }
  702. dwCount = dwSize;
  703. return TRUE;
  704. }
  705. BOOL ReloadCookies()
  706. {
  707. CCookieMgr* pCookieMgr = m_pContext->GetCookieMgr();
  708. if(pCookieMgr == nullptr)
  709. return TRUE;
  710. DeleteAllCookies();
  711. CCookieSet cookies;
  712. if(!pCookieMgr->GetCookies(cookies, GetDomain(), GetPath(), TRUE, m_pContext->IsSecure()))
  713. return FALSE;
  714. for(CCookieSetCI it = cookies.begin(), end = cookies.end(); it != end; ++it)
  715. AddCookie(it->name, it->value);
  716. return TRUE;
  717. }
  718. BOOL GetWSMessageState(BOOL* lpbFinal, BYTE* lpiReserved, BYTE* lpiOperationCode, LPCBYTE* lpszMask, ULONGLONG* lpullBodyLen, ULONGLONG* lpullBodyRemain)
  719. {
  720. if(!m_pwsContext)
  721. return FALSE;
  722. return m_pwsContext->GetMessageState(lpbFinal, lpiReserved, lpiOperationCode, lpszMask, lpullBodyLen, lpullBodyRemain);
  723. }
  724. public:
  725. THttpObjT (BOOL bRequest, T* pContext, S* pSocket)
  726. : m_pContext (pContext)
  727. , m_pSocket (pSocket)
  728. , m_bRequest (bRequest)
  729. , m_bReleased (FALSE)
  730. , m_dwFreeTime (0)
  731. , m_usUrlFieldSet (0)
  732. , m_pstrUrlFileds (nullptr)
  733. , m_enUpgrade (HUT_NONE)
  734. , m_pwsContext (nullptr)
  735. {
  736. if(m_bRequest)
  737. m_pstrUrlFileds = new CStringA[HUF_MAX];
  738. else
  739. m_pstrRequestPath = new CStringA;
  740. ResetParser();
  741. }
  742. ~THttpObjT()
  743. {
  744. if(m_bRequest)
  745. delete[] m_pstrUrlFileds;
  746. else
  747. delete m_pstrRequestPath;
  748. ReleaseWSContext();
  749. }
  750. static THttpObjT* Construct(BOOL bRequest, T* pContext, S* pSocket)
  751. {return new THttpObjT(bRequest, pContext, pSocket);}
  752. static void Destruct(THttpObjT* pHttpObj)
  753. {if(pHttpObj) delete pHttpObj;}
  754. void Reset()
  755. {
  756. ResetParser();
  757. ResetHeaderState();
  758. ReleaseWSContext();
  759. m_bReleased = FALSE;
  760. m_enUpgrade = HUT_NONE;
  761. m_dwFreeTime = 0;
  762. }
  763. void Renew(T* pContext, S* pSocket)
  764. {
  765. m_pContext = pContext;
  766. m_pSocket = pSocket;
  767. Reset();
  768. }
  769. BOOL CopyData(const THttpObjT& src)
  770. {
  771. if(&src == this)
  772. return FALSE;
  773. if(m_bRequest != src.m_bRequest)
  774. return FALSE;
  775. void* p = m_parser.data;
  776. m_parser = src.m_parser;
  777. m_parser.data = p;
  778. m_headers = src.m_headers;
  779. m_cookies = src.m_cookies;
  780. if(m_bRequest)
  781. {
  782. m_usUrlFieldSet = src.m_usUrlFieldSet;
  783. for(int i = 0;i < HUF_MAX; i++)
  784. m_pstrUrlFileds[i] = src.m_pstrUrlFileds[i];
  785. }
  786. else
  787. {
  788. *m_pstrRequestPath = *src.m_pstrRequestPath;
  789. }
  790. m_enUpgrade = src.m_enUpgrade;
  791. return TRUE;
  792. }
  793. BOOL CopyWSContext(const THttpObjT& src)
  794. {
  795. if(&src == this)
  796. return FALSE;
  797. if(m_bRequest != src.m_bRequest)
  798. return FALSE;
  799. if(!src.m_pwsContext && !m_pwsContext)
  800. ;
  801. else if(!src.m_pwsContext && m_pwsContext)
  802. {
  803. delete m_pwsContext;
  804. m_pwsContext = nullptr;
  805. }
  806. else
  807. {
  808. if(!m_pwsContext)
  809. m_pwsContext = new TWSContext<THttpObjT<T, S>>(this);
  810. m_pwsContext->CopyData(*src.m_pwsContext);
  811. }
  812. return TRUE;
  813. }
  814. private:
  815. void ResetParser()
  816. {
  817. ::http_parser_init(&m_parser, m_bRequest ? HTTP_REQUEST : HTTP_RESPONSE);
  818. m_parser.data = this;
  819. }
  820. void ResetHeaderState(BOOL bClearCookies = TRUE, BOOL bResetRequestPath = TRUE)
  821. {
  822. if(m_bRequest)
  823. {
  824. if(m_usUrlFieldSet != 0)
  825. {
  826. m_usUrlFieldSet = 0;
  827. for(int i = 0; i < HUF_MAX; i++)
  828. m_pstrUrlFileds[i].Empty();
  829. }
  830. }
  831. else
  832. {
  833. if(bResetRequestPath)
  834. m_pstrRequestPath->Empty();
  835. }
  836. if(m_bRequest || bClearCookies)
  837. DeleteAllCookies();
  838. m_headers.clear();
  839. ResetHeaderBuffer();
  840. }
  841. void ResetHeaderBuffer()
  842. {
  843. ResetBuffer();
  844. m_strCurHeader.Empty();
  845. }
  846. void ReleaseWSContext()
  847. {
  848. if(m_pwsContext)
  849. {
  850. delete m_pwsContext;
  851. m_pwsContext = nullptr;
  852. }
  853. }
  854. void AppendBuffer(const char* at, size_t length) {m_strBuffer.Append(at, (int)length);}
  855. void ResetBuffer() {m_strBuffer.Empty();}
  856. LPCSTR GetBuffer() {return m_strBuffer;}
  857. static THttpObjT* Self(http_parser* p) {return (THttpObjT*)(p->data);}
  858. static T* SelfContext(http_parser* p) {return Self(p)->m_pContext;}
  859. static S* SelfSocketObj(http_parser* p) {return Self(p)->m_pSocket;}
  860. private:
  861. BOOL m_bRequest;
  862. BOOL m_bReleased;
  863. T* m_pContext;
  864. S* m_pSocket;
  865. http_parser m_parser;
  866. THeaderMap m_headers;
  867. TCookieMap m_cookies;
  868. CStringA m_strBuffer;
  869. CStringA m_strCurHeader;
  870. USHORT m_usUrlFieldSet;
  871. union
  872. {
  873. CStringA* m_pstrUrlFileds;
  874. CStringA* m_pstrRequestPath;
  875. };
  876. EnHttpUpgradeType m_enUpgrade;
  877. DWORD m_dwFreeTime;
  878. TWSContext<THttpObjT<T, S>>* m_pwsContext;
  879. static http_parser_settings sm_settings;
  880. };
  881. template<class T, class S> http_parser_settings THttpObjT<T, S>::sm_settings =
  882. {
  883. on_message_begin,
  884. on_url,
  885. on_status,
  886. on_header_field,
  887. on_header_value,
  888. on_headers_complete,
  889. on_body,
  890. on_message_complete,
  891. on_chunk_header,
  892. on_chunk_complete
  893. };
  894. // ------------------------------------------------------------------------------------------------------------- //
  895. template<BOOL is_request, class T, class S> class CHttpObjPoolT
  896. {
  897. typedef THttpObjT<T, S> THttpObj;
  898. typedef CRingPool<THttpObj> TSSLHttpObjList;
  899. typedef CCASQueue<THttpObj> TSSLHttpObjQueue;
  900. public:
  901. THttpObj* PickFreeHttpObj(T* pContext, S* pSocket)
  902. {
  903. DWORD dwIndex;
  904. THttpObj* pHttpObj = nullptr;
  905. if(m_lsFreeHttpObj.TryLock(&pHttpObj, dwIndex))
  906. {
  907. if(::GetTimeGap32(pHttpObj->GetFreeTime()) >= m_dwHttpObjLockTime)
  908. VERIFY(m_lsFreeHttpObj.ReleaseLock(nullptr, dwIndex));
  909. else
  910. {
  911. VERIFY(m_lsFreeHttpObj.ReleaseLock(pHttpObj, dwIndex));
  912. pHttpObj = nullptr;
  913. }
  914. }
  915. if(pHttpObj)
  916. pHttpObj->Renew(pContext, pSocket);
  917. else
  918. {
  919. pHttpObj = THttpObj::Construct(is_request, pContext, pSocket);
  920. ASSERT(pHttpObj);
  921. }
  922. return pHttpObj;
  923. }
  924. void PutFreeHttpObj(THttpObj* pHttpObj)
  925. {
  926. pHttpObj->SetFree();
  927. if(!m_lsFreeHttpObj.TryPut(pHttpObj))
  928. {
  929. m_lsGCHttpObj.PushBack(pHttpObj);
  930. if(m_lsGCHttpObj.Size() > m_dwHttpObjPoolSize)
  931. ReleaseGCHttpObj();
  932. }
  933. }
  934. void Prepare()
  935. {
  936. m_lsFreeHttpObj.Reset(m_dwHttpObjPoolHold);
  937. }
  938. void Clear()
  939. {
  940. THttpObj* pHttpObj = nullptr;
  941. while(m_lsFreeHttpObj.TryGet(&pHttpObj))
  942. delete pHttpObj;
  943. VERIFY(m_lsFreeHttpObj.IsEmpty());
  944. m_lsFreeHttpObj.Reset();
  945. ReleaseGCHttpObj(TRUE);
  946. VERIFY(m_lsGCHttpObj.IsEmpty());
  947. }
  948. private:
  949. void ReleaseGCHttpObj(BOOL bForce = FALSE)
  950. {
  951. THttpObj* pHttpObj = nullptr;
  952. DWORD now = ::TimeGetTime();
  953. while(m_lsGCHttpObj.PopFront(&pHttpObj))
  954. {
  955. if(bForce || (int)(now - pHttpObj->GetFreeTime()) >= (int)m_dwHttpObjLockTime)
  956. delete pHttpObj;
  957. else
  958. {
  959. m_lsGCHttpObj.PushBack(pHttpObj);
  960. break;
  961. }
  962. }
  963. }
  964. public:
  965. void SetHttpObjLockTime (DWORD dwHttpObjLockTime) {m_dwHttpObjLockTime = dwHttpObjLockTime;}
  966. void SetHttpObjPoolSize (DWORD dwHttpObjPoolSize) {m_dwHttpObjPoolSize = dwHttpObjPoolSize;}
  967. void SetHttpObjPoolHold (DWORD dwHttpObjPoolHold) {m_dwHttpObjPoolHold = dwHttpObjPoolHold;}
  968. DWORD GetHttpObjLockTime() {return m_dwHttpObjLockTime;}
  969. DWORD GetHttpObjPoolSize() {return m_dwHttpObjPoolSize;}
  970. DWORD GetHttpObjPoolHold() {return m_dwHttpObjPoolHold;}
  971. public:
  972. CHttpObjPoolT( DWORD dwPoolSize = DEFAULT_HTTPOBJ_POOL_SIZE,
  973. DWORD dwPoolHold = DEFAULT_HTTPOBJ_POOL_HOLD,
  974. DWORD dwLockTime = DEFAULT_HTTPOBJ_LOCK_TIME)
  975. : m_dwHttpObjPoolSize(dwPoolSize)
  976. , m_dwHttpObjPoolHold(dwPoolHold)
  977. , m_dwHttpObjLockTime(dwLockTime)
  978. {
  979. }
  980. ~CHttpObjPoolT() {Clear();}
  981. DECLARE_NO_COPY_CLASS(CHttpObjPoolT)
  982. public:
  983. static const DWORD DEFAULT_HTTPOBJ_LOCK_TIME;
  984. static const DWORD DEFAULT_HTTPOBJ_POOL_SIZE;
  985. static const DWORD DEFAULT_HTTPOBJ_POOL_HOLD;
  986. private:
  987. DWORD m_dwHttpObjLockTime;
  988. DWORD m_dwHttpObjPoolSize;
  989. DWORD m_dwHttpObjPoolHold;
  990. TSSLHttpObjList m_lsFreeHttpObj;
  991. TSSLHttpObjQueue m_lsGCHttpObj;
  992. };
  993. template<BOOL is_request, class T, class S> const DWORD CHttpObjPoolT<is_request, T, S>::DEFAULT_HTTPOBJ_LOCK_TIME = 10 * 1000;
  994. template<BOOL is_request, class T, class S> const DWORD CHttpObjPoolT<is_request, T, S>::DEFAULT_HTTPOBJ_POOL_SIZE = 150;
  995. template<BOOL is_request, class T, class S> const DWORD CHttpObjPoolT<is_request, T, S>::DEFAULT_HTTPOBJ_POOL_HOLD = 600;
  996. // ------------------------------------------------------------------------------------------------------------- //
  997. extern CStringA& GetHttpVersionStr(EnHttpVersion enVersion, CStringA& strResult);
  998. extern CStringA& AdjustRequestPath(LPCSTR lpszPath, CStringA& strPath);
  999. extern LPCSTR GetHttpDefaultStatusCodeDesc(EnHttpStatusCode enCode);
  1000. extern void MakeRequestLine(LPCSTR lpszMethod, LPCSTR lpszPath, EnHttpVersion enVersion, CStringA& strValue);
  1001. extern void MakeStatusLine(EnHttpVersion enVersion, USHORT usStatusCode, LPCSTR lpszDesc, CStringA& strValue);
  1002. extern void MakeHeaderLines(const THeader lpHeaders[], int iHeaderCount, const TCookieMap* pCookies, int iBodyLength, BOOL bRequest, int iConnFlag, LPCSTR lpszDefaultHost, USHORT usPort, CStringA& strValue);
  1003. extern void MakeHttpPacket(const CStringA& strHeader, const BYTE* pBody, int iLength, WSABUF szBuffer[2]);
  1004. extern BOOL MakeWSPacket(BOOL bFinal, BYTE iReserved, BYTE iOperationCode, const BYTE lpszMask[4], BYTE* pData, int iLength, ULONGLONG ullBodyLen, BYTE szHeader[HTTP_MAX_WS_HEADER_LEN], WSABUF szBuffer[2]);
  1005. extern BOOL ParseUrl(const CStringA& strUrl, BOOL& bHttps, CStringA& strHost, USHORT& usPort, CStringA& strPath);
  1006. // CP_XXX -> UNICODE
  1007. BOOL CodePageToUnicode(int iCodePage, const char szSrc[], WCHAR szDest[], int& iDestLength);
  1008. // UNICODE -> CP_XXX
  1009. BOOL UnicodeToCodePage(int iCodePage, const WCHAR szSrc[], char szDest[], int& iDestLength);
  1010. // GBK -> UNICODE
  1011. BOOL GbkToUnicode(const char szSrc[], WCHAR szDest[], int& iDestLength);
  1012. // UNICODE -> GBK
  1013. BOOL UnicodeToGbk(const WCHAR szSrc[], char szDest[], int& iDestLength);
  1014. // UTF8 -> UNICODE
  1015. BOOL Utf8ToUnicode(const char szSrc[], WCHAR szDest[], int& iDestLength);
  1016. // UNICODE -> UTF8
  1017. BOOL UnicodeToUtf8(const WCHAR szSrc[], char szDest[], int& iDestLength);
  1018. // GBK -> UTF8
  1019. BOOL GbkToUtf8(const char szSrc[], char szDest[], int& iDestLength);
  1020. // UTF8 -> GBK
  1021. BOOL Utf8ToGbk(const char szSrc[], char szDest[], int& iDestLength);
  1022. // 普通压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  1023. int Compress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  1024. // 高级压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  1025. int CompressEx(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen, int iLevel = Z_DEFAULT_COMPRESSION, int iMethod = Z_DEFLATED, int iWindowBits = DEF_WBITS, int iMemLevel = DEF_MEM_LEVEL, int iStrategy = Z_DEFAULT_STRATEGY);
  1026. // 普通解压(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  1027. int Uncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  1028. // 高级解压(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  1029. int UncompressEx(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen, int iWindowBits = DEF_WBITS);
  1030. // 推测压缩结果长度
  1031. DWORD GuessCompressBound(DWORD dwSrcLen, BOOL bGZip = FALSE);
  1032. // Gzip 压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  1033. int GZipCompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  1034. // Gzip 解压(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  1035. int GZipUncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  1036. // 推测 Gzip 解压结果长度(如果返回 0 或不合理值则说明输入内容并非有效的 Gzip 格式)
  1037. DWORD GZipGuessUncompressBound(const BYTE* lpszSrc, DWORD dwSrcLen);
  1038. // 计算 Base64 编码后长度
  1039. DWORD GuessBase64EncodeBound(DWORD dwSrcLen);
  1040. // 计算 Base64 解码后长度
  1041. DWORD GuessBase64DecodeBound(const BYTE* lpszSrc, DWORD dwSrcLen);
  1042. // Base64 编码(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  1043. int Base64Encode(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  1044. // Base64 解码(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  1045. int Base64Decode(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  1046. // 计算 URL 编码后长度
  1047. DWORD GuessUrlEncodeBound(const BYTE* lpszSrc, DWORD dwSrcLen);
  1048. // 计算 URL 解码后长度
  1049. DWORD GuessUrlDecodeBound(const BYTE* lpszSrc, DWORD dwSrcLen);
  1050. // URL 编码(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  1051. int UrlEncode(BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  1052. // URL 解码(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  1053. int UrlDecode(BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);