HttpHelper.h 31 KB

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