Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3118 lines
74 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. http.hxx
  5. Abstract:
  6. Contains the client-side HTTP handle class
  7. Author:
  8. Richard L Firth (rfirth) 03-Jan-1996
  9. Revision History:
  10. 03-Jan-1996 rfirth
  11. Created
  12. --*/
  13. #pragma warning(disable: 4296)
  14. //
  15. // prototype for glue to urlmon security manager
  16. //
  17. DWORD GetCredPolicy (LPSTR pszUrl);
  18. DWORD GetCookieUrlAction(BOOL fIsSessionCookie, BOOL fIs3rdPartyCookie);
  19. DWORD GetCookiePolicy (LPCSTR pszUrl, DWORD dwUrlAction, BOOL fRestricted = FALSE);
  20. VOID SetStopWarning (LPCSTR pszUrl, DWORD dwPolicy, DWORD dwUrlAction);
  21. DWORD GetClientCertPromptPolicy (LPCSTR pszUrl, BOOL fRestricted = FALSE);
  22. extern "C" DWORD GetZoneFromUrl(LPCSTR pszUrl);
  23. //
  24. // manifests
  25. //
  26. #define INITIAL_HEADERS_COUNT 16
  27. #define HEADERS_INCREMENT 4
  28. #define INVALID_HEADER_INDEX 0xff
  29. #define INVALID_HEADER_SLOT 0xFFFFFFFF
  30. #define HTTPREQ_STATE_ANYTHING_OK 0x8000 // for debug purposes
  31. #define HTTPREQ_STATE_CLOSE_OK 0x4000
  32. #define HTTPREQ_STATE_ADD_OK 0x2000
  33. #define HTTPREQ_STATE_SEND_OK 0x1000
  34. #define HTTPREQ_STATE_READ_OK 0x0800
  35. #define HTTPREQ_STATE_QUERY_REQUEST_OK 0x0400
  36. #define HTTPREQ_STATE_QUERY_RESPONSE_OK 0x0200
  37. #define HTTPREQ_STATE_REUSE_OK 0x0100
  38. #define HTTPREQ_STATE_WRITE_OK 0x0010
  39. //
  40. // macros
  41. //
  42. #define IS_VALID_HTTP_STATE(p, api, ref) \
  43. (p)->CheckState(HTTPREQ_STATE_ ## api ## _OK)
  44. #define IsValidHttpState(api) \
  45. CheckState(HTTPREQ_STATE_ ## api ## _OK)
  46. //
  47. // STRESS_BUG_DEBUG - used to catch a specific stress fault,
  48. // where we have a corrupted crit sec.
  49. //
  50. #define CLEAR_DEBUG_CRIT(x)
  51. #define IS_DEBUG_CRIT_OK(x)
  52. //
  53. // types
  54. //
  55. typedef enum {
  56. HTTP_HEADER_TYPE_UNKNOWN = 0,
  57. HTTP_HEADER_TYPE_ACCEPT
  58. } HTTP_HEADER_TYPE;
  59. typedef enum {
  60. HTTP_METHOD_TYPE_UNKNOWN = -1,
  61. HTTP_METHOD_TYPE_FIRST = 0,
  62. HTTP_METHOD_TYPE_GET= HTTP_METHOD_TYPE_FIRST,
  63. HTTP_METHOD_TYPE_HEAD,
  64. HTTP_METHOD_TYPE_POST,
  65. HTTP_METHOD_TYPE_PUT,
  66. HTTP_METHOD_TYPE_PROPFIND,
  67. HTTP_METHOD_TYPE_PROPPATCH,
  68. HTTP_METHOD_TYPE_LOCK,
  69. HTTP_METHOD_TYPE_UNLOCK,
  70. HTTP_METHOD_TYPE_COPY,
  71. HTTP_METHOD_TYPE_MOVE,
  72. HTTP_METHOD_TYPE_MKCOL,
  73. HTTP_METHOD_TYPE_CONNECT,
  74. HTTP_METHOD_TYPE_DELETE,
  75. HTTP_METHOD_TYPE_LINK,
  76. HTTP_METHOD_TYPE_UNLINK,
  77. HTTP_METHOD_TYPE_BMOVE,
  78. HTTP_METHOD_TYPE_BCOPY,
  79. HTTP_METHOD_TYPE_BPROPFIND,
  80. HTTP_METHOD_TYPE_BPROPPATCH,
  81. HTTP_METHOD_TYPE_BDELETE,
  82. HTTP_METHOD_TYPE_SUBSCRIBE,
  83. HTTP_METHOD_TYPE_UNSUBSCRIBE,
  84. HTTP_METHOD_TYPE_NOTIFY,
  85. HTTP_METHOD_TYPE_POLL,
  86. HTTP_METHOD_TYPE_CHECKIN,
  87. HTTP_METHOD_TYPE_CHECKOUT,
  88. HTTP_METHOD_TYPE_INVOKE,
  89. HTTP_METHOD_TYPE_SEARCH,
  90. HTTP_METHOD_TYPE_PIN,
  91. HTTP_METHOD_TYPE_MPOST,
  92. HTTP_METHOD_TYPE_LAST = HTTP_METHOD_TYPE_MPOST
  93. } HTTP_METHOD_TYPE;
  94. typedef enum {
  95. //
  96. // The request handle is in the process of being created
  97. //
  98. HttpRequestStateCreating = 0 | HTTPREQ_STATE_ANYTHING_OK,
  99. //
  100. // The request handle is open, but the request has not been sent to the
  101. // server
  102. //
  103. HttpRequestStateOpen = 1 | HTTPREQ_STATE_CLOSE_OK
  104. | HTTPREQ_STATE_ADD_OK
  105. | HTTPREQ_STATE_SEND_OK
  106. | HTTPREQ_STATE_READ_OK
  107. | HTTPREQ_STATE_QUERY_REQUEST_OK
  108. | HTTPREQ_STATE_QUERY_RESPONSE_OK
  109. | HTTPREQ_STATE_REUSE_OK
  110. | HTTPREQ_STATE_ANYTHING_OK,
  111. //
  112. // The request has been sent to the server, but the response headers have
  113. // not been received
  114. //
  115. HttpRequestStateRequest = 2 | HTTPREQ_STATE_CLOSE_OK
  116. | HTTPREQ_STATE_QUERY_REQUEST_OK
  117. | HTTPREQ_STATE_WRITE_OK
  118. | HTTPREQ_STATE_ANYTHING_OK,
  119. //
  120. // The response headers are being received, but not yet completed
  121. //
  122. HttpRequestStateResponse = 3 | HTTPREQ_STATE_CLOSE_OK
  123. | HTTPREQ_STATE_WRITE_OK
  124. | HTTPREQ_STATE_ANYTHING_OK,
  125. //
  126. // The response headers have been received, and there is object data
  127. // available to read
  128. //
  129. //
  130. // QFE 3576: It's possible that we're init'ing a new request,
  131. // but the previous request hasn't been drained yet.
  132. // Since we know it will always be drained, the lowest
  133. // impact change is to allow headers to be replaced
  134. // if we're in a state with potential data left to receive.
  135. HttpRequestStateObjectData = 4 | HTTPREQ_STATE_CLOSE_OK
  136. | HTTPREQ_STATE_ADD_OK
  137. | HTTPREQ_STATE_READ_OK
  138. | HTTPREQ_STATE_QUERY_REQUEST_OK
  139. | HTTPREQ_STATE_QUERY_RESPONSE_OK
  140. | HTTPREQ_STATE_REUSE_OK
  141. | HTTPREQ_STATE_ANYTHING_OK,
  142. //
  143. // A fatal error occurred
  144. //
  145. HttpRequestStateError = 5 | HTTPREQ_STATE_CLOSE_OK
  146. | HTTPREQ_STATE_ANYTHING_OK,
  147. //
  148. // The request is closing
  149. //
  150. HttpRequestStateClosing = 6 | HTTPREQ_STATE_ANYTHING_OK,
  151. //
  152. // the data has been drained from the request object and it can be re-used
  153. //
  154. HttpRequestStateReopen = 7 | HTTPREQ_STATE_CLOSE_OK
  155. | HTTPREQ_STATE_ADD_OK
  156. | HTTPREQ_STATE_READ_OK
  157. | HTTPREQ_STATE_QUERY_REQUEST_OK
  158. | HTTPREQ_STATE_QUERY_RESPONSE_OK
  159. | HTTPREQ_STATE_REUSE_OK
  160. | HTTPREQ_STATE_ANYTHING_OK
  161. } HTTPREQ_STATE, FAR * LPHTTPREQ_STATE;
  162. //
  163. // general prototypes
  164. //
  165. HTTP_METHOD_TYPE
  166. MapHttpRequestMethod(
  167. IN LPCSTR lpszVerb
  168. );
  169. DWORD
  170. MapHttpMethodType(
  171. IN HTTP_METHOD_TYPE tMethod,
  172. OUT LPCSTR * lplpcszName
  173. );
  174. DWORD
  175. CreateEscapedUrlPath(
  176. IN LPSTR lpszUrlPath,
  177. OUT LPSTR * lplpszEncodedUrlPath
  178. );
  179. #if INET_DEBUG
  180. LPSTR
  181. MapHttpMethodType(
  182. IN HTTP_METHOD_TYPE tMethod
  183. );
  184. #endif
  185. //
  186. // forward references
  187. //
  188. class CFsm_HttpSendRequest;
  189. class CFsm_MakeConnection;
  190. class CFsm_OpenConnection;
  191. class CFsm_OpenProxyTunnel;
  192. class CFsm_SendRequest;
  193. class CFsm_ReceiveResponse;
  194. class CFsm_HttpReadData;
  195. class CFsm_HttpWriteData;
  196. class CFsm_ReadData;
  197. class CFsm_HttpQueryAvailable;
  198. class CFsm_DrainResponse;
  199. class CFsm_Redirect;
  200. class CFsm_ReadLoop;
  201. struct P3PCookieState;
  202. //
  203. // classes
  204. //
  205. //
  206. // HEADER_STRING - extension of ICSTRING so we can perform hashing on strings.
  207. // Note that we only care about the header value
  208. //
  209. class HEADER_STRING : public ICSTRING {
  210. private:
  211. DWORD m_Hash;
  212. public:
  213. HEADER_STRING() {
  214. SetHash(0);
  215. }
  216. ~HEADER_STRING() {
  217. }
  218. VOID SetHash(DWORD dwHash) {
  219. m_Hash = dwHash;
  220. }
  221. VOID SetNextKnownIndex(BYTE bNextKnown) {
  222. _Union.Bytes.ExtraByte1 = bNextKnown;
  223. }
  224. BYTE * GetNextKnownIndexPtr() {
  225. return &_Union.Bytes.ExtraByte1;
  226. }
  227. DWORD GetNextKnownIndex() {
  228. return ((DWORD)_Union.Bytes.ExtraByte1);
  229. }
  230. DWORD GetHash(VOID) {
  231. return m_Hash;
  232. }
  233. VOID CreateHash(LPSTR lpszBase);
  234. int HashStrnicmp(LPSTR lpBase, LPSTR lpszString, DWORD dwLength, DWORD dwHash)
  235. {
  236. int RetVal = -1;
  237. if ((m_Hash == 0) || (m_Hash == dwHash))
  238. {
  239. if ( Strnicmp(lpBase, lpszString, dwLength) == 0 )
  240. {
  241. LPSTR value;
  242. value = StringAddress(lpBase) + dwLength;
  243. //
  244. // the input string could be a substring of a different header
  245. //
  246. if (*value == ':')
  247. {
  248. RetVal = 0; // success, we have a match here!
  249. }
  250. }
  251. }
  252. return RetVal;
  253. }
  254. HEADER_STRING & operator=(LPSTR String) {
  255. SetHash(0);
  256. return (HEADER_STRING &)ICSTRING::operator=(String);
  257. }
  258. };
  259. //
  260. // HTTP_HEADERS - array of pointers to general HTTP header strings. Headers are
  261. // stored without line termination. _HeadersLength maintains the cumulative
  262. // amount of buffer space required to store all the headers. Accounts for the
  263. // missing line termination sequence
  264. //
  265. #define HTTP_HEADER_SIGNATURE 0x64616548 // "Head"
  266. class HTTP_HEADERS {
  267. public:
  268. //
  269. // _bKnownHeaders - array of bytes which index into lpHeaders
  270. // the 0 column is an error catcher, so all indexes need to be biased by 1 (++'ed)
  271. //
  272. BYTE _bKnownHeaders[HTTP_QUERY_MAX+2];
  273. private:
  274. #if INET_DEBUG
  275. DWORD _Signature;
  276. #endif
  277. //
  278. // _lpHeaders - (growable) array of pointers to headers added by app
  279. //
  280. HEADER_STRING * _lpHeaders;
  281. //
  282. // _TotalSlots - number of pointers in (i.e. size of) _lpHeaders
  283. //
  284. DWORD _TotalSlots;
  285. //
  286. // _NextOpenSlot - offset where the next array is open for allocation
  287. //
  288. DWORD _NextOpenSlot;
  289. //
  290. // _FreeSlots - number of available headers in _lpHeaders
  291. //
  292. DWORD _FreeSlots;
  293. //
  294. // _HeadersLength - the amount of buffer space required to store the headers.
  295. // For each header, includes +2 for the line termination that must be added
  296. // when the header buffer is generated, or when the headers are queried
  297. //
  298. DWORD _HeadersLength;
  299. //
  300. // _IsRequestHeaders - TRUE if this HTTP_HEADERS object describes the
  301. // request headers
  302. //
  303. BOOL _IsRequestHeaders;
  304. //
  305. // _lpszVerb etc. - in the case of request headers, we maintain these
  306. // pointers and corresponding lengths to make modifying the request line
  307. // easier in the case of a redirect
  308. //
  309. // N.B. The pointers are just offsets into the request line AND MUST NOT BE
  310. // FREED
  311. //
  312. LPSTR _lpszVerb;
  313. DWORD _dwVerbLength;
  314. LPSTR _lpszObjectName;
  315. DWORD _dwObjectNameLength;
  316. LPSTR _lpszVersion;
  317. DWORD _dwVersionLength;
  318. DWORD _RequestVersionMajor;
  319. DWORD _RequestVersionMinor;
  320. //
  321. // _Error - status code if error
  322. //
  323. DWORD _Error;
  324. //
  325. // _CritSec - acquire this when accessing header structure - stops multiple
  326. // threads clashing while modifying headers
  327. //
  328. CRITICAL_SECTION _CritSec;
  329. //
  330. // private methods
  331. //
  332. DWORD
  333. AllocateHeaders(
  334. IN DWORD dwNumberOfHeaders
  335. );
  336. public:
  337. HTTP_HEADERS() {
  338. #if INET_DEBUG
  339. _Signature = HTTP_HEADER_SIGNATURE;
  340. #endif
  341. CLEAR_DEBUG_CRIT(_szCritSecBefore);
  342. CLEAR_DEBUG_CRIT(_szCritSecAfter);
  343. InitializeCriticalSection(&_CritSec);
  344. Initialize();
  345. }
  346. ~HTTP_HEADERS() {
  347. DEBUG_ENTER((DBG_OBJECTS,
  348. None,
  349. "~HTTP_HEADERS",
  350. "%#x",
  351. this
  352. ));
  353. #if INET_DEBUG
  354. INET_ASSERT(_Signature == HTTP_HEADER_SIGNATURE);
  355. #endif
  356. FreeHeaders();
  357. DeleteCriticalSection(&_CritSec);
  358. DEBUG_LEAVE(0);
  359. }
  360. VOID Initialize(VOID) {
  361. _lpHeaders = NULL;
  362. _TotalSlots = 0;
  363. _FreeSlots = 0;
  364. _HeadersLength = 0;
  365. _lpszVerb = NULL;
  366. _dwVerbLength = 0;
  367. _lpszObjectName = NULL;
  368. _dwObjectNameLength = 0;
  369. _lpszVersion = NULL;
  370. _dwVersionLength = 0;
  371. _RequestVersionMajor = 0;
  372. _RequestVersionMinor = 0;
  373. _NextOpenSlot = 0;
  374. memset((void *) _bKnownHeaders, INVALID_HEADER_SLOT, ARRAY_ELEMENTS(_bKnownHeaders));
  375. _Error = AllocateHeaders(INITIAL_HEADERS_COUNT);
  376. }
  377. BOOL IsHeaderPresent(DWORD dwQueryIndex) const {
  378. return (_bKnownHeaders[dwQueryIndex] != INVALID_HEADER_INDEX) ? TRUE : FALSE ;
  379. }
  380. VOID LockHeaders(VOID) {
  381. EnterCriticalSection(&_CritSec);
  382. }
  383. VOID UnlockHeaders(VOID) {
  384. LeaveCriticalSection(&_CritSec);
  385. }
  386. VOID
  387. FreeHeaders(
  388. VOID
  389. );
  390. VOID
  391. CopyHeaders(
  392. IN OUT LPSTR * lpBuffer,
  393. IN LPSTR lpszObjectName,
  394. IN DWORD dwObjectNameLength
  395. );
  396. #ifdef COMPRESSED_HEADERS
  397. VOID
  398. CopyCompressedHeaders(
  399. IN OUT LPSTR * lpBuffer
  400. );
  401. #endif //COMPRESSED_HEADERS
  402. HEADER_STRING *
  403. FASTCALL
  404. FindFreeSlot(
  405. DWORD* piSlot
  406. );
  407. HEADER_STRING *
  408. GetSlot(
  409. DWORD iSlot
  410. )
  411. {
  412. return &_lpHeaders[iSlot];
  413. }
  414. LPSTR GetHeaderPointer (LPBYTE pbBase, DWORD iSlot)
  415. {
  416. INET_ASSERT (iSlot < _TotalSlots);
  417. return _lpHeaders[iSlot].StringAddress((LPSTR) pbBase);
  418. }
  419. VOID
  420. ShrinkHeader(
  421. LPBYTE pbBase,
  422. DWORD iSlot,
  423. DWORD dwOldQueryIndex,
  424. DWORD dwNewQueryIndex,
  425. DWORD cbNewSize
  426. );
  427. DWORD
  428. inline
  429. FastFind(
  430. IN DWORD dwQueryIndex,
  431. IN DWORD dwIndex
  432. );
  433. DWORD
  434. inline
  435. FastNukeFind(
  436. IN DWORD dwQueryIndex,
  437. IN DWORD dwIndex,
  438. OUT BYTE **lplpbPrevIndex
  439. );
  440. DWORD
  441. inline
  442. SlowFind(
  443. IN LPSTR lpBase,
  444. IN LPSTR lpszHeaderName,
  445. IN DWORD dwHeaderNameLength,
  446. IN DWORD dwIndex,
  447. IN DWORD dwHash,
  448. OUT DWORD *lpdwQueryIndex,
  449. OUT BYTE **lplpbPrevIndex
  450. );
  451. BYTE
  452. inline
  453. FastAdd(
  454. IN DWORD dwQueryIndex,
  455. IN DWORD dwSlot
  456. );
  457. BOOL
  458. inline
  459. HeaderMatch(
  460. IN DWORD dwHash,
  461. IN LPSTR lpszHeaderName,
  462. IN DWORD dwHeaderNameLength,
  463. OUT DWORD *lpdwQueryIndex
  464. );
  465. VOID
  466. RemoveAllByIndex(
  467. IN DWORD dwQueryIndex
  468. );
  469. VOID RemoveHeader(IN DWORD dwIndex, IN DWORD dwQueryIndex, IN BYTE *pbPrevByte) {
  470. INET_ASSERT(dwIndex < _TotalSlots);
  471. INET_ASSERT(dwIndex != 0);
  472. // INET_ASSERT(_HeadersLength > 2);
  473. INET_ASSERT(_lpHeaders[dwIndex].StringLength() > 2);
  474. INET_ASSERT(_FreeSlots <= _TotalSlots);
  475. //
  476. // remove the length of the header + 2 for CR-LF from the total headers
  477. // length
  478. //
  479. if (_HeadersLength) {
  480. _HeadersLength -= _lpHeaders[dwIndex].StringLength()
  481. + (sizeof("\r\n") - 1)
  482. ;
  483. }
  484. //
  485. // Update the cached known headers, if this is one.
  486. //
  487. if ( dwQueryIndex < INVALID_HEADER_INDEX )
  488. {
  489. *pbPrevByte = (BYTE) _lpHeaders[dwIndex].GetNextKnownIndex();
  490. }
  491. //
  492. // set the header string to NULL. Frees the header buffer
  493. //
  494. _lpHeaders[dwIndex] = (LPSTR)NULL;
  495. //
  496. // we have freed a slot in the headers array
  497. //
  498. if ( _FreeSlots == 0 )
  499. {
  500. _NextOpenSlot = dwIndex;
  501. }
  502. ++_FreeSlots;
  503. INET_ASSERT(_FreeSlots <= _TotalSlots);
  504. }
  505. DWORD GetSlotsInUse (void) {
  506. return _TotalSlots - _FreeSlots;
  507. }
  508. DWORD HeadersLength(VOID) const {
  509. return _HeadersLength;
  510. }
  511. DWORD ObjectNameLength(VOID) const {
  512. return _dwObjectNameLength;
  513. }
  514. LPSTR ObjectName(VOID) const {
  515. return _lpszObjectName;
  516. }
  517. DWORD
  518. AddHeader(
  519. IN LPSTR lpszHeaderName,
  520. IN DWORD dwHeaderNameLength,
  521. IN LPSTR lpszHeaderValue,
  522. IN DWORD dwHeaderValueLength,
  523. IN DWORD dwIndex,
  524. IN DWORD dwFlags
  525. );
  526. DWORD
  527. AddHeader(
  528. IN DWORD dwQueryIndex,
  529. IN LPSTR lpszHeaderValue,
  530. IN DWORD dwHeaderValueLength,
  531. IN DWORD dwIndex,
  532. IN DWORD dwFlags
  533. );
  534. DWORD
  535. ReplaceHeader(
  536. IN LPSTR lpszHeaderName,
  537. IN DWORD dwHeaderNameLength,
  538. IN LPSTR lpszHeaderValue,
  539. IN DWORD dwHeaderValueLength,
  540. IN DWORD dwIndex,
  541. IN DWORD dwFlags
  542. );
  543. DWORD
  544. ReplaceHeader(
  545. IN DWORD dwQueryIndex,
  546. IN LPSTR lpszHeaderValue,
  547. IN DWORD dwHeaderValueLength,
  548. IN DWORD dwIndex,
  549. IN DWORD dwFlags
  550. );
  551. DWORD
  552. FindHeader(
  553. IN LPSTR lpBase,
  554. IN LPSTR lpszHeaderName,
  555. IN DWORD dwHeaderNameLength,
  556. IN DWORD dwModifiers,
  557. OUT LPVOID lpBuffer,
  558. IN OUT LPDWORD lpdwBufferLength,
  559. IN OUT LPDWORD lpdwIndex
  560. );
  561. DWORD
  562. FindHeader(
  563. IN LPSTR lpBase,
  564. IN DWORD dwQueryIndex,
  565. IN DWORD dwModifiers,
  566. OUT LPVOID lpBuffer,
  567. IN OUT LPDWORD lpdwBufferLength,
  568. IN OUT LPDWORD lpdwIndex
  569. );
  570. DWORD
  571. FastFindHeader(
  572. IN LPSTR lpBase,
  573. IN DWORD dwQueryIndex,
  574. OUT LPVOID *lplpBuffer,
  575. IN OUT LPDWORD lpdwBufferLength,
  576. IN OUT DWORD dwIndex
  577. );
  578. DWORD
  579. QueryRawHeaders(
  580. IN LPSTR lpBase,
  581. IN BOOL bCrLfTerminated,
  582. IN LPVOID lpBuffer,
  583. IN OUT LPDWORD lpdwBufferLength
  584. );
  585. DWORD
  586. QueryFilteredRawHeaders(
  587. IN LPSTR lpBase,
  588. IN LPSTR *lplpFilterList,
  589. IN DWORD cListElements,
  590. IN BOOL fExclude,
  591. IN BOOL fSkipVerb,
  592. IN BOOL bCrLfTerminated,
  593. IN LPVOID lpBuffer,
  594. IN OUT LPDWORD lpdwBufferLength
  595. );
  596. DWORD
  597. AddRequest(
  598. IN LPSTR lpszVerb,
  599. IN LPSTR lpszObjectName,
  600. IN LPSTR lpszVersion
  601. );
  602. DWORD
  603. ModifyRequest(
  604. IN HTTP_METHOD_TYPE tMethod,
  605. IN LPSTR lpszObjectName,
  606. IN DWORD dwObjectNameLength,
  607. IN LPSTR lpszVersion OPTIONAL,
  608. IN DWORD dwVersionLength
  609. );
  610. HEADER_STRING * GetFirstHeader(VOID) const {
  611. INET_ASSERT(_lpHeaders != NULL);
  612. return _lpHeaders;
  613. }
  614. HEADER_STRING * GetEmptyHeader(VOID) const {
  615. for (DWORD i = 0; i < _TotalSlots; ++i) {
  616. if (_lpHeaders[i].HaveString() && _lpHeaders[i].StringLength() == 0) {
  617. return &_lpHeaders[i];
  618. }
  619. }
  620. return NULL;
  621. }
  622. VOID SetIsRequestHeaders(BOOL bRequestHeaders) {
  623. _IsRequestHeaders = bRequestHeaders;
  624. }
  625. DWORD GetError(VOID) const {
  626. return _Error;
  627. }
  628. LPSTR GetVerb(LPDWORD lpdwVerbLength) const {
  629. *lpdwVerbLength = _dwVerbLength;
  630. return _lpszVerb;
  631. }
  632. //VOID SetRequestVersion(DWORD dwMajor, DWORD dwMinor) {
  633. // _RequestVersionMajor = dwMajor;
  634. // _RequestVersionMinor = dwMinor;
  635. //}
  636. VOID
  637. SetRequestVersion(
  638. VOID
  639. );
  640. DWORD MajorVersion(VOID) const {
  641. return _RequestVersionMajor;
  642. }
  643. DWORD MinorVersion(VOID) const {
  644. return _RequestVersionMinor;
  645. }
  646. DWORD QueryRequestVersion(
  647. IN LPVOID lpBuffer,
  648. IN OUT LPDWORD lpdwBufferLength
  649. );
  650. };
  651. // class HTTP_HEADER_PARSER
  652. //
  653. // Retrieves HTTP headers from string containing server response headers.
  654. //
  655. class HTTP_HEADER_PARSER : public HTTP_HEADERS
  656. {
  657. public:
  658. HTTP_HEADER_PARSER(
  659. LPSTR lpszHeaders,
  660. DWORD cbHeaders
  661. );
  662. HTTP_HEADER_PARSER()
  663. : HTTP_HEADERS() {}
  664. DWORD
  665. ParseHeaders(
  666. IN LPSTR lpHeaderBase,
  667. IN DWORD dwBufferLength,
  668. IN BOOL fEof,
  669. IN OUT DWORD *lpdwBufferLengthScanned,
  670. OUT LPBOOL pfFoundCompleteLine,
  671. OUT LPBOOL pfFoundEndOfHeaders
  672. );
  673. DWORD
  674. ParseStatusLine(
  675. IN LPSTR lpHeaderBase,
  676. IN DWORD dwBufferLength,
  677. IN BOOL fEof,
  678. IN OUT DWORD *lpdwBufferLengthScanned,
  679. OUT BOOL *lpfNeedMoreBuffer,
  680. OUT DWORD *lpdwStatusCode,
  681. OUT DWORD *lpdwMajorVersion,
  682. OUT DWORD *lpdwMinorVersion
  683. );
  684. };
  685. //
  686. // flags for AddHeader
  687. //
  688. #define CLEAN_HEADER 0x00000001 // if set, header should be cleaned up
  689. #define ADD_HEADER_IF_NEW HTTP_ADDREQ_FLAG_ADD_IF_NEW // only add the header if it doesn't already exist
  690. #define ADD_HEADER HTTP_ADDREQ_FLAG_ADD // if replacing and header not found, add it
  691. #define COALESCE_HEADER_WITH_COMMA HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA // headers of the same name will be coalesced
  692. #define COALESCE_HEADER_WITH_SEMICOLON HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON // headers of the same name will be coalesced
  693. #define REPLACE_HEADER HTTP_ADDREQ_FLAG_REPLACE // not currently used internally
  694. /*++
  695. Class Description:
  696. This class defines the HTTP_REQUEST_HANDLE_OBJECT.
  697. Private Member functions:
  698. None.
  699. Public Member functions:
  700. GetHandle : Virtual function that gets the service handle value from
  701. the generic object handle.
  702. --*/
  703. class HTTP_REQUEST_HANDLE_OBJECT : public INTERNET_CONNECT_HANDLE_OBJECT {
  704. friend class PASSPORT_CTX;
  705. private:
  706. DWORD m_AuthFlag;
  707. BOOL m_fPPAbortSend;
  708. LIST_ENTRY m_PipelineList;
  709. //
  710. // m_lPriority - relative priority used to determine which request gets the
  711. // next available connection
  712. //
  713. LONG m_lPriority;
  714. //
  715. // _Socket - this is the socket we are using for this request. It may be a
  716. // pre-existing keep-alive connection or a new connection (not necessarily
  717. // keep-alive)
  718. //
  719. ICSocket * _Socket;
  720. //
  721. // _bKeepAliveConnection - if TRUE, _Socket is keep-alive, else we must
  722. // really close it
  723. //
  724. BOOL _bKeepAliveConnection;
  725. //
  726. // _bNoLongerKeepAlive - if this ever gets set to TRUE its because we began
  727. // with a keep-alive connection which reverted to non-keep-alive when the
  728. // server responded with no "(Proxy-)Connection: Keep-Alive" header
  729. //
  730. BOOL _bNoLongerKeepAlive;
  731. //
  732. // _QueryBuffer - buffer used to query socket data available
  733. //
  734. LPVOID _QueryBuffer;
  735. //
  736. // _QueryBufferLength - length of _QueryBuffer
  737. //
  738. DWORD _QueryBufferLength;
  739. //
  740. // _QueryOffset - offset of next read from _QueryBuffer
  741. //
  742. DWORD _QueryOffset;
  743. //
  744. // _QueryBytesAvailable - number of bytes we think are available for this
  745. // socket in the query buffer
  746. //
  747. DWORD _QueryBytesAvailable;
  748. //
  749. // _OpenFlags - flags specified in HttpOpenRequest()
  750. //
  751. DWORD _OpenFlags;
  752. //
  753. // _State - the HTTP request/response state
  754. //
  755. HTTPREQ_STATE _State;
  756. //
  757. // HTTP request information
  758. //
  759. //
  760. // _RequestHeaders - collection of request headers, including the request
  761. // line
  762. //
  763. HTTP_HEADERS _RequestHeaders;
  764. //
  765. // _RequestMethod - (known) method used to make HTTP request
  766. //
  767. HTTP_METHOD_TYPE _RequestMethod;
  768. //
  769. // Values for optional data saved offin handle when in negotiate stage.
  770. //
  771. DWORD _dwOptionalSaved;
  772. LPVOID _lpOptionalSaved;
  773. BOOL _fOptionalSaved;
  774. //
  775. // HTTP response information
  776. //
  777. //
  778. // _ResponseHeaders - collection of response headers, including the status
  779. // line
  780. //
  781. HTTP_HEADER_PARSER _ResponseHeaders;
  782. //
  783. // In the case of response headers, remember slot number for
  784. // Content-Length and Content-Range in case we need to fix up
  785. // a 206 partial content response.
  786. //
  787. DWORD _iSlotContentLength;
  788. DWORD _iSlotContentRange;
  789. //
  790. // _StatusCode - return status from the server
  791. //
  792. DWORD _StatusCode;
  793. //
  794. // _ResponseBuffer - pointer to the buffer containing part or all of
  795. // response, starting with headers (if >= HTTP/1.0, i.e. if IsUpLevel)
  796. //
  797. LPBYTE _ResponseBuffer;
  798. //
  799. // _ResponseBufferLength - length of _ResponseBuffer
  800. //
  801. DWORD _ResponseBufferLength;
  802. //
  803. // _BytesReceived - number of bytes received into _ResponseBuffer
  804. //
  805. DWORD _BytesReceived;
  806. //
  807. // _ResponseScanned - amount of response buffers scanned for eof headers
  808. //
  809. DWORD _ResponseScanned;
  810. //
  811. // _ResponseBufferDataReadyToRead - special length of response buffer,
  812. // set if we've parsed it from a chunk-transfer stream, this will be
  813. // the correct length
  814. //
  815. DWORD _ResponseBufferDataReadyToRead;
  816. //
  817. // _DataOffset - the offset in _ResponseBuffer at which the response data
  818. // starts (data after headers)
  819. //
  820. DWORD _DataOffset;
  821. //
  822. // _BytesRemaining - number of _ContentLength bytes remaining to be read by
  823. // application
  824. //
  825. DWORD _BytesRemaining;
  826. //
  827. // _ContentLength - as parsed from the response headers
  828. //
  829. DWORD _ContentLength;
  830. //
  831. // _BytesInSocket - if content-length, the number of bytes we have yet to
  832. // receive from the socket
  833. //
  834. DWORD _BytesInSocket;
  835. //
  836. // time stamps parsed from response
  837. //
  838. FILETIME _ftLastModified;
  839. FILETIME _ftExpires;
  840. FILETIME _ftPostCheck;
  841. //
  842. // to use when committing to cache
  843. //
  844. DWORD _dwCacheEntryType;
  845. //
  846. // cache lookup struct
  847. //
  848. CACHE_ENTRY_INFOEX* _pCacheEntryInfo;
  849. //
  850. // _ctChunkInfo - Chunk Info for tracking a chunk stream.
  851. //
  852. CHUNK_TRANSFER _ctChunkInfo;
  853. //
  854. // _fTalkingToSecureServerViaProxy - We're talking SSL, but
  855. // actually we're connected through a proxy so things
  856. // need to be carefully watched. Don't send a Proxy
  857. // Username and Password to the the secure sever.
  858. //
  859. BOOL _fTalkingToSecureServerViaProxy;
  860. //
  861. // _fRequestUsingProxy - TRUE if we're actually using the proxy
  862. // to reach the server. Needed to keep track of whether
  863. // we're using the proxy or not.
  864. //
  865. BOOL _fRequestUsingProxy;
  866. //
  867. // _bWantKeepAlive - TRUE if we want a keep-alive connection
  868. //
  869. BOOL _bWantKeepAlive;
  870. //
  871. // _bRefresh - TRUE if the response contains a "Refresh" header
  872. //
  873. BOOL _bRefresh;
  874. //
  875. // _RefreshHeader - value from the "Refresh" header, if it exists
  876. //
  877. HEADER_STRING _RefreshHeader;
  878. //
  879. // _dwQuerySetCookieHeader - Passed to HttpQueryInfo to track what
  880. // cookie header we're parsing.
  881. //
  882. DWORD _dwQuerySetCookieHeader;
  883. //
  884. // _Union - get at flags individually, or as DWORD so they can be zapped
  885. //
  886. union {
  887. //
  888. // Flags - several bits of information gleaned from the response, such
  889. // as whether the server responded with a "connection: keep-alive", etc.
  890. //
  891. struct {
  892. DWORD Eof : 1; // we have received all response
  893. DWORD DownLevel : 1; // response is HTTP/0.9
  894. DWORD UpLevel : 1; // response is HTTP/1.0 or greater
  895. DWORD Http1_1Response : 1; // response is HTTP/1.1 or greater
  896. DWORD MustRevalidate : 1; // response contains cache-control: must-revalidate
  897. DWORD KeepAlive : 1; // response contains keep-alive header
  898. DWORD ConnCloseResponse : 1; // response contains connection: close header
  899. DWORD PersistServer : 1; // have persistent connection to server
  900. DWORD PersistProxy : 1; // have persistent connection to proxy
  901. DWORD Data : 1; // set if we have got to the data part
  902. DWORD ContentLength : 1; // set if we have parsed Content-Length
  903. DWORD ChunkEncoding : 1; // set if we have parsed a Transfer-Encoding: chunked
  904. DWORD AutoSync : 1; // set when synchronizing due to sync-mode
  905. DWORD BadNSServer : 1; // set when server is bogus NS 1.1
  906. DWORD ConnCloseChecked : 1; // set when we have checked for Connection: Close
  907. DWORD ConnCloseReq : 1; // set if Connection: Close in request headers
  908. DWORD ProxyConnCloseReq : 1; // set if Proxy-Connection: Close in request headers
  909. //DWORD CookieUI : 1; // set if we're doing Cookie UI
  910. } Flags;
  911. //
  912. // Dword - used in initialization and ReuseObject
  913. //
  914. DWORD Dword;
  915. } _Union;
  916. //
  917. // Filter, authentication related members.
  918. //
  919. AUTHCTX* _pAuthCtx; // authentication context
  920. AUTHCTX* _pTunnelAuthCtx; // context for nested request
  921. PWC* _pPWC; // PWC* for Basic, Digest authctxt
  922. LPVOID _lpBlockingFilter; // filter that requested UI
  923. DWORD _dwCredPolicy; // zone policy on use of credentials
  924. union {
  925. struct {
  926. // AuthState: none, negotiate, challenge, or need tunnel.
  927. DWORD AuthState : 2;
  928. // TRUE if KA socket should be flushed with password cache.
  929. DWORD IsAuthorized : 1;
  930. // TRUE if request has been processed once.
  931. DWORD FirstSendProcessed : 1;
  932. // TRUE if client added header that implies no caching.
  933. DWORD CacheReadDisabled : 1;
  934. // TRUE if this handle should ignore general proxy settings,
  935. // and use the proxy found in this object
  936. DWORD OverrideProxyMode : 1;
  937. // TRUE, if we are using a proxy to create a tunnel.
  938. DWORD IsTunnel : 1;
  939. // TRUE, if the object was originally "/"
  940. DWORD IsObjectRoot : 1;
  941. // TRUE, if a method body is to be transmitted.
  942. DWORD MethodBody : 1;
  943. // TRUE, if NTLM preauth is to be disabled.
  944. DWORD DisableNTLMPreauth : 1;
  945. } Flags;
  946. //
  947. // Dword - used in initialization ONLY, do NOT use ELSEWHERE !
  948. //
  949. DWORD Dword;
  950. } _NoResetBits;
  951. //
  952. // Proxy, and Socks Proxy Information, used to decide if need to go through
  953. // a proxy, a socks proxy, or no proxy at all (NULLs).
  954. //
  955. LPSTR _ProxyHostName;
  956. DWORD _ProxyHostNameLength;
  957. INTERNET_PORT _ProxyPort;
  958. LPSTR _SocksProxyHostName;
  959. DWORD _SocksProxyHostNameLength;
  960. INTERNET_PORT _SocksProxyPort;
  961. //
  962. // _ProxySchemeType - Used to determine the proxy scheme, in proxy override mode.
  963. //
  964. //INTERNET_SCHEME _ProxySchemeType;
  965. //
  966. // InternetReadFileEx data
  967. //
  968. #ifndef unix
  969. DWORD _ReadFileExData;
  970. #else
  971. BYTE _ReadFileExData;
  972. #endif /* unix */
  973. BOOL _HaveReadFileExData;
  974. INTERNET_BUFFERS _BuffersOut;
  975. //
  976. // _redirectCount - The number of times we've redirected on this request
  977. //
  978. DWORD _redirectCount;
  979. //
  980. // _redirectCountedOut - TRUE if we redirected too many times.
  981. //
  982. BOOL _redirectCountedOut;
  983. //
  984. // _AddCRLFToPost - TRUE if we need to add a CRLF to the POST.
  985. //
  986. BOOL _AddCRLFToPOST;
  987. //
  988. // info we used to keep in the secure socket object
  989. //
  990. SECURITY_CACHE_LIST_ENTRY *m_pSecurityInfo;
  991. // To support authentication of proxy auto config scripts,
  992. // each request should only be able to try fetching the script
  993. // just once.
  994. BOOL _fAutoProxyChecked;
  995. //
  996. // _RTT - round-trip time for this request
  997. //
  998. DWORD _RTT;
  999. //
  1000. // _CP - code page to use for char width conversions
  1001. //
  1002. UINT _CP;
  1003. //
  1004. // _fIgnore Offline - ignore global offline (enable loopback)
  1005. //
  1006. BOOL _fIgnoreOffline;
  1007. //
  1008. // _f3rdPartyCookies - treat cookies as 3rd party, that is as originating
  1009. // from a host other than the 'root', downloaded seperately
  1010. //
  1011. BOOL _f3rdPartyCookies;
  1012. // Is the current request blocked on prompt?
  1013. BOOL _fBlockedOnPrompt;
  1014. // _fSendUTF8ServerNameToProxy - app always sends MBCS to wininet for servername.
  1015. // If app. wants wininet to convert this to UTF8 for the proxy.
  1016. BOOL _fSendUTF8ServerNameToProxy;
  1017. // Security-zone for this request
  1018. DWORD _dwSecurityZone;
  1019. // SocketSendBufferLength
  1020. DWORD _dwSocketSendBufferLength;
  1021. //
  1022. // private response functions
  1023. //
  1024. PRIVATE
  1025. BOOL
  1026. FindEndOfHeader(
  1027. IN OUT LPSTR * lpszResponse,
  1028. IN LPSTR lpszEnd,
  1029. OUT LPDWORD lpdwHeaderLength
  1030. );
  1031. PRIVATE
  1032. VOID
  1033. CheckForWellKnownHeader(
  1034. IN LPSTR lpszHeader,
  1035. IN DWORD dwHeaderLength,
  1036. IN DWORD iSlot
  1037. );
  1038. PRIVATE
  1039. VOID
  1040. CheckWellKnownHeaders(
  1041. VOID
  1042. );
  1043. HANDLE GetDownloadFileReadHandle (VOID) {
  1044. if (_CacheFileHandleRead == INVALID_HANDLE_VALUE) {
  1045. _CacheFileHandleRead = CreateFile( _CacheFileName, GENERIC_READ,
  1046. FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
  1047. FILE_ATTRIBUTE_NORMAL, NULL);
  1048. }
  1049. return _CacheFileHandleRead;
  1050. }
  1051. VOID ZapFlags(VOID) {
  1052. //
  1053. // clear out all bits
  1054. //
  1055. _Union.Dword = 0;
  1056. }
  1057. public:
  1058. HTTP_REQUEST_HANDLE_OBJECT(
  1059. INTERNET_CONNECT_HANDLE_OBJECT *Parent,
  1060. HINTERNET Child,
  1061. CLOSE_HANDLE_FUNC wCloseFunc,
  1062. DWORD dwFlags,
  1063. DWORD_PTR dwContext
  1064. );
  1065. virtual ~HTTP_REQUEST_HANDLE_OBJECT(VOID);
  1066. virtual HINTERNET GetHandle(VOID);
  1067. virtual HINTERNET_HANDLE_TYPE GetHandleType(VOID) {
  1068. return TypeHttpRequestHandle;
  1069. }
  1070. //
  1071. // request headers functions
  1072. //
  1073. DWORD
  1074. AddRequest(
  1075. IN LPSTR lpszVerb,
  1076. IN LPSTR lpszObjectName,
  1077. IN LPSTR lpszVersion
  1078. ) {
  1079. return _RequestHeaders.AddRequest(lpszVerb,
  1080. lpszObjectName,
  1081. lpszVersion
  1082. );
  1083. }
  1084. DWORD
  1085. ModifyRequest(
  1086. IN HTTP_METHOD_TYPE tMethod,
  1087. IN LPSTR lpszObjectName,
  1088. IN DWORD dwObjectNameLength,
  1089. IN LPSTR lpszVersion OPTIONAL,
  1090. IN DWORD dwVersionLength
  1091. ) {
  1092. DWORD error;
  1093. error = _RequestHeaders.ModifyRequest(tMethod,
  1094. lpszObjectName,
  1095. dwObjectNameLength,
  1096. lpszVersion,
  1097. dwVersionLength
  1098. );
  1099. if (error == ERROR_SUCCESS) {
  1100. SetMethodType(tMethod);
  1101. }
  1102. return error;
  1103. }
  1104. BOOL PPAbort(void) const {
  1105. return m_fPPAbortSend;
  1106. }
  1107. VOID SetPPAbort(BOOL fToAbort) {
  1108. m_fPPAbortSend = fToAbort;
  1109. }
  1110. VOID SetMethodType(IN LPCSTR lpszVerb) {
  1111. _RequestMethod = MapHttpRequestMethod(lpszVerb);
  1112. }
  1113. VOID SetMethodType(IN HTTP_METHOD_TYPE tMethod) {
  1114. _RequestMethod = tMethod;
  1115. }
  1116. HTTP_METHOD_TYPE GetMethodType(VOID) const {
  1117. return _RequestMethod;
  1118. }
  1119. LPSTR
  1120. CreateRequestBuffer(
  1121. OUT LPDWORD lpdwRequestLength,
  1122. IN LPVOID lpOptional,
  1123. IN DWORD dwOptionalLength,
  1124. IN BOOL bExtraCrLf,
  1125. IN DWORD dwMaxPacketLength,
  1126. OUT LPBOOL lpbCombinedData
  1127. );
  1128. DWORD
  1129. AddRequestHeader(
  1130. IN LPSTR lpszHeaderName,
  1131. IN DWORD dwHeaderNameLength,
  1132. IN LPSTR lpszHeaderValue,
  1133. IN DWORD dwHeaderValueLength,
  1134. IN DWORD dwIndex,
  1135. IN DWORD dwFlags
  1136. ) {
  1137. return _RequestHeaders.AddHeader(lpszHeaderName,
  1138. dwHeaderNameLength,
  1139. lpszHeaderValue,
  1140. dwHeaderValueLength,
  1141. dwIndex,
  1142. dwFlags
  1143. );
  1144. }
  1145. DWORD
  1146. AddRequestHeader(
  1147. IN DWORD dwQueryIndex,
  1148. IN LPSTR lpszHeaderValue,
  1149. IN DWORD dwHeaderValueLength,
  1150. IN DWORD dwIndex,
  1151. IN DWORD dwFlags
  1152. ) {
  1153. return _RequestHeaders.AddHeader(dwQueryIndex,
  1154. lpszHeaderValue,
  1155. dwHeaderValueLength,
  1156. dwIndex,
  1157. dwFlags
  1158. );
  1159. }
  1160. DWORD
  1161. ReplaceRequestHeader(
  1162. IN LPSTR lpszHeaderName,
  1163. IN DWORD dwHeaderNameLength,
  1164. IN LPSTR lpszHeaderValue,
  1165. IN DWORD dwHeaderValueLength,
  1166. IN DWORD dwIndex,
  1167. IN DWORD dwFlags
  1168. ) {
  1169. return _RequestHeaders.ReplaceHeader(lpszHeaderName,
  1170. dwHeaderNameLength,
  1171. lpszHeaderValue,
  1172. dwHeaderValueLength,
  1173. dwIndex,
  1174. dwFlags
  1175. );
  1176. }
  1177. DWORD
  1178. ReplaceRequestHeader(
  1179. IN DWORD dwQueryIndex,
  1180. IN LPSTR lpszHeaderValue,
  1181. IN DWORD dwHeaderValueLength,
  1182. IN DWORD dwIndex,
  1183. IN DWORD dwFlags
  1184. ) {
  1185. return _RequestHeaders.ReplaceHeader(dwQueryIndex,
  1186. lpszHeaderValue,
  1187. dwHeaderValueLength,
  1188. dwIndex,
  1189. dwFlags
  1190. );
  1191. }
  1192. DWORD
  1193. QueryRequestHeader(
  1194. IN LPSTR lpszHeaderName,
  1195. IN DWORD dwHeaderNameLength,
  1196. IN LPVOID lpBuffer,
  1197. IN OUT LPDWORD lpdwBufferLength,
  1198. IN DWORD dwModifiers,
  1199. IN OUT LPDWORD lpdwIndex
  1200. );
  1201. DWORD
  1202. QueryRequestHeader(
  1203. IN DWORD dwQueryIndex,
  1204. IN LPVOID lpBuffer,
  1205. IN OUT LPDWORD lpdwBufferLength,
  1206. IN DWORD dwModifiers,
  1207. IN OUT LPDWORD lpdwIndex
  1208. );
  1209. //
  1210. // response headers functions
  1211. //
  1212. DWORD
  1213. ReplaceResponseHeader(
  1214. IN DWORD dwQueryIndex,
  1215. IN LPSTR lpszHeaderValue,
  1216. IN DWORD dwHeaderValueLength,
  1217. IN DWORD dwIndex,
  1218. IN DWORD dwFlags)
  1219. {
  1220. return _ResponseHeaders.ReplaceHeader(dwQueryIndex,
  1221. lpszHeaderValue,
  1222. dwHeaderValueLength,
  1223. dwIndex,
  1224. dwFlags
  1225. );
  1226. }
  1227. DWORD
  1228. AddInternalResponseHeader(
  1229. IN DWORD dwHeaderIndex,
  1230. IN LPSTR lpszHeader,
  1231. IN DWORD dwHeaderLength
  1232. );
  1233. DWORD
  1234. UpdateResponseHeaders(
  1235. IN OUT LPBOOL lpbEof
  1236. );
  1237. DWORD
  1238. CreateResponseHeaders(
  1239. IN OUT LPSTR* ppszBuffer,
  1240. IN DWORD dwBufferLength
  1241. );
  1242. DWORD
  1243. FindResponseHeader(
  1244. IN LPSTR lpszHeaderName,
  1245. OUT LPSTR lpBuffer,
  1246. IN OUT LPDWORD lpdwBufferLength
  1247. );
  1248. DWORD
  1249. QueryResponseVersionDword(
  1250. IN OUT LPDWORD lpdwVersionMajor,
  1251. IN OUT LPDWORD lpdwVersionMinor
  1252. );
  1253. DWORD
  1254. QueryResponseVersion(
  1255. IN LPVOID lpBuffer,
  1256. IN OUT LPDWORD lpdwBufferLength
  1257. );
  1258. DWORD
  1259. QueryStatusCode(
  1260. IN LPVOID lpBuffer,
  1261. IN OUT LPDWORD lpdwBufferLength,
  1262. IN DWORD dwModifiers
  1263. );
  1264. DWORD
  1265. QueryStatusText(
  1266. IN LPVOID lpBuffer,
  1267. IN OUT LPDWORD lpdwBufferLength
  1268. );
  1269. DWORD
  1270. FastQueryResponseHeader(
  1271. IN DWORD dwQueryIndex,
  1272. OUT LPVOID *lplpBuffer,
  1273. IN OUT LPDWORD lpdwBufferLength,
  1274. IN OUT DWORD dwIndex
  1275. )
  1276. {
  1277. return _ResponseHeaders.FastFindHeader(
  1278. (LPSTR)_ResponseBuffer,
  1279. dwQueryIndex,
  1280. lplpBuffer,
  1281. lpdwBufferLength,
  1282. dwIndex
  1283. );
  1284. }
  1285. DWORD
  1286. FastQueryRequestHeader(
  1287. IN DWORD dwQueryIndex,
  1288. OUT LPVOID *lplpBuffer,
  1289. IN OUT LPDWORD lpdwBufferLength,
  1290. IN OUT DWORD dwIndex
  1291. )
  1292. {
  1293. return _RequestHeaders.FastFindHeader(
  1294. (LPSTR)_ResponseBuffer,
  1295. dwQueryIndex,
  1296. lplpBuffer,
  1297. lpdwBufferLength,
  1298. dwIndex
  1299. );
  1300. }
  1301. DWORD
  1302. QueryResponseHeader(
  1303. IN LPSTR lpszHeaderName,
  1304. IN DWORD dwHeaderNameLength,
  1305. IN LPVOID lpBuffer,
  1306. IN OUT LPDWORD lpdwBufferLength,
  1307. IN DWORD dwModifiers,
  1308. IN OUT LPDWORD lpdwIndex
  1309. )
  1310. {
  1311. //
  1312. // this is the slow manner for finding a header, avoid doing this by calling
  1313. // the faster method
  1314. //
  1315. return _ResponseHeaders.FindHeader((LPSTR)_ResponseBuffer,
  1316. lpszHeaderName,
  1317. dwHeaderNameLength,
  1318. dwModifiers,
  1319. lpBuffer,
  1320. lpdwBufferLength,
  1321. lpdwIndex
  1322. );
  1323. }
  1324. DWORD
  1325. QueryResponseHeader(
  1326. IN DWORD dwQueryIndex,
  1327. IN LPVOID lpBuffer,
  1328. IN OUT LPDWORD lpdwBufferLength,
  1329. IN DWORD dwModifiers,
  1330. IN OUT LPDWORD lpdwIndex
  1331. )
  1332. {
  1333. return _ResponseHeaders.FindHeader((LPSTR)_ResponseBuffer,
  1334. dwQueryIndex,
  1335. dwModifiers,
  1336. lpBuffer,
  1337. lpdwBufferLength,
  1338. lpdwIndex
  1339. );
  1340. }
  1341. BOOL IsResponseHeaderPresent(DWORD dwQueryIndex) const {
  1342. return _ResponseHeaders.IsHeaderPresent(dwQueryIndex);
  1343. }
  1344. BOOL IsRequestHeaderPresent(DWORD dwQueryIndex) const {
  1345. return _RequestHeaders.IsHeaderPresent(dwQueryIndex);
  1346. }
  1347. DWORD
  1348. QueryRawResponseHeaders(
  1349. IN BOOL bCrLfTerminated,
  1350. OUT LPVOID lpBuffer,
  1351. IN OUT LPDWORD lpdwBufferLength
  1352. );
  1353. HEADER_STRING * GetStatusLine(VOID) const {
  1354. //
  1355. // _StatusLine is just a reference for the first response header
  1356. //
  1357. return _ResponseHeaders.GetFirstHeader();
  1358. }
  1359. //
  1360. // general headers methods
  1361. //
  1362. DWORD
  1363. QueryInfo(
  1364. IN DWORD dwInfoLevel,
  1365. OUT LPVOID lpBuffer,
  1366. IN OUT LPDWORD lpdwBufferLength,
  1367. IN OUT LPDWORD lpdwIndex
  1368. );
  1369. DWORD
  1370. QueryFilteredRawResponseHeaders(
  1371. LPSTR *lplpFilterList,
  1372. DWORD cListElements,
  1373. BOOL fExclude,
  1374. BOOL fSkipVerb,
  1375. BOOL bCrLfTerminated,
  1376. OUT LPVOID lpBuffer,
  1377. IN OUT LPDWORD lpdwBufferLength
  1378. )
  1379. {
  1380. return (_ResponseHeaders.QueryFilteredRawHeaders(
  1381. (LPSTR)_ResponseBuffer,
  1382. lplpFilterList,
  1383. cListElements,
  1384. fExclude,
  1385. fSkipVerb,
  1386. bCrLfTerminated,
  1387. lpBuffer,
  1388. lpdwBufferLength));
  1389. };
  1390. DWORD
  1391. QueryRequestHeadersWithEcho(
  1392. BOOL bCrLfTerminated,
  1393. OUT LPVOID lpBuffer,
  1394. IN OUT LPDWORD lpdwBufferLength
  1395. );
  1396. //
  1397. // connection-oriented methods
  1398. //
  1399. DWORD
  1400. InitBeginSendRequest(
  1401. IN LPCSTR lpszHeaders OPTIONAL,
  1402. IN DWORD dwHeadersLength,
  1403. IN LPVOID *lplpOptional,
  1404. IN LPDWORD lpdwOptionalLength,
  1405. IN DWORD dwOptionalLengthTotal,
  1406. OUT LPBOOL pfGoneOffline
  1407. );
  1408. DWORD
  1409. QueueAsyncSendRequest(
  1410. IN LPVOID lpOptional OPTIONAL,
  1411. IN DWORD dwOptionalLength,
  1412. IN AR_TYPE arRequest,
  1413. IN FARPROC lpfpAsyncCallback
  1414. );
  1415. DWORD
  1416. HttpBeginSendRequest(
  1417. IN LPVOID lpOptional OPTIONAL,
  1418. IN DWORD dwOptionalLength
  1419. );
  1420. DWORD
  1421. HttpEndSendRequest(
  1422. VOID
  1423. );
  1424. DWORD
  1425. SockConnect(
  1426. IN LPSTR TargetServer,
  1427. IN INTERNET_PORT TcpipPort,
  1428. IN LPSTR SocksHostName,
  1429. IN INTERNET_PORT SocksPort
  1430. );
  1431. DWORD
  1432. OpenConnection(
  1433. IN BOOL NoKeepAlive,
  1434. IN BOOL fNoCreate = FALSE
  1435. );
  1436. DWORD
  1437. OpenConnection_Fsm(
  1438. IN CFsm_OpenConnection * Fsm
  1439. );
  1440. DWORD
  1441. CloseConnection(
  1442. IN BOOL ForceClosed
  1443. );
  1444. VOID
  1445. ReleaseConnection(
  1446. IN BOOL bClose,
  1447. IN BOOL bIndicate,
  1448. IN BOOL bDelete
  1449. );
  1450. DWORD
  1451. AbortConnection(
  1452. IN BOOL bForce
  1453. );
  1454. DWORD
  1455. OpenProxyTunnel(
  1456. VOID
  1457. );
  1458. DWORD
  1459. OpenProxyTunnel_Fsm(
  1460. IN CFsm_OpenProxyTunnel * Fsm
  1461. );
  1462. DWORD
  1463. CloneResponseBuffer(
  1464. IN HTTP_REQUEST_HANDLE_OBJECT *pChildRequestObj
  1465. );
  1466. DWORD
  1467. CloneResponseBuffer(
  1468. IN LPBYTE pBuffer,
  1469. IN DWORD dwBufferLen
  1470. );
  1471. DWORD
  1472. HttpReadData_Fsm(
  1473. IN CFsm_HttpReadData * Fsm
  1474. );
  1475. DWORD
  1476. HttpWriteData_Fsm(
  1477. IN CFsm_HttpWriteData * Fsm
  1478. );
  1479. DWORD
  1480. ReadResponse(
  1481. VOID
  1482. );
  1483. DWORD
  1484. ReadData(
  1485. OUT LPVOID lpBuffer,
  1486. IN DWORD dwNumberOfBytesToRead,
  1487. OUT LPDWORD lpdwNumberOfBytesRead,
  1488. IN BOOL fNoAsync,
  1489. IN DWORD dwSocketFlags
  1490. );
  1491. DWORD
  1492. ReadData_Fsm(
  1493. IN CFsm_ReadData * Fsm
  1494. );
  1495. DWORD
  1496. WriteData(
  1497. OUT LPVOID lpBuffer,
  1498. IN DWORD dwNumberOfBytesToWrite,
  1499. OUT LPDWORD lpdwNumberOfBytesWritten
  1500. );
  1501. DWORD
  1502. QueryDataAvailable(
  1503. OUT LPDWORD lpdwNumberOfBytesAvailable
  1504. );
  1505. DWORD
  1506. QueryAvailable_Fsm(
  1507. IN CFsm_HttpQueryAvailable * Fsm
  1508. );
  1509. DWORD
  1510. DrainResponse(
  1511. OUT LPBOOL lpbDrained
  1512. );
  1513. DWORD
  1514. DrainResponse_Fsm(
  1515. IN CFsm_DrainResponse * Fsm
  1516. );
  1517. DWORD
  1518. LocalEndCacheWrite(
  1519. IN BOOL fNormal
  1520. );
  1521. VOID
  1522. GetTimeStampsForCache(
  1523. OUT LPFILETIME lpftExpiryTime,
  1524. OUT LPFILETIME lpftLastModTime,
  1525. OUT LPFILETIME lpftPostCheckTime,
  1526. OUT LPBOOL lpfHasExpiry,
  1527. OUT LPBOOL lpfHasLastModTime,
  1528. OUT LPBOOL lpfHasPostCheck
  1529. );
  1530. BOOL IsPartialResponseCacheable (void);
  1531. DWORD
  1532. Redirect(
  1533. IN HTTP_METHOD_TYPE tMethod,
  1534. IN BOOL fRedirectToProxy
  1535. );
  1536. DWORD
  1537. Redirect_Fsm(
  1538. IN CFsm_Redirect * Fsm
  1539. );
  1540. DWORD
  1541. BuildProxyMessage(
  1542. IN CFsm_HttpSendRequest * Fsm,
  1543. AUTO_PROXY_ASYNC_MSG * pProxyMsg,
  1544. IN OUT URL_COMPONENTS * pUrlComponents
  1545. );
  1546. DWORD
  1547. QueryProxySettings(
  1548. IN CFsm_HttpSendRequest * Fsm,
  1549. INTERNET_HANDLE_OBJECT * pInternet,
  1550. IN OUT URL_COMPONENTS * pUrlComponents
  1551. );
  1552. DWORD
  1553. CheckForCachedProxySettings(
  1554. IN AUTO_PROXY_ASYNC_MSG *pProxyMsg,
  1555. OUT CServerInfo **ppProxyServerInfo
  1556. );
  1557. DWORD
  1558. ProcessProxySettings(
  1559. IN CFsm_HttpSendRequest * Fsm,
  1560. IN INTERNET_CONNECT_HANDLE_OBJECT * pConnect,
  1561. IN OUT URL_COMPONENTS * pUrlComponents,
  1562. OUT LPSTR * lplpszRequestObject,
  1563. OUT DWORD * lpdwRequestObjectSize
  1564. );
  1565. DWORD
  1566. UpdateRequestInfo(
  1567. IN CFsm_HttpSendRequest * Fsm,
  1568. IN LPSTR lpszObject,
  1569. IN DWORD dwcbObject,
  1570. IN OUT URL_COMPONENTS * pUrlComponents,
  1571. IN OUT CServerInfo **ppProxyServerInfo
  1572. );
  1573. DWORD
  1574. UpdateProxyInfo(
  1575. IN CFsm_HttpSendRequest * Fsm,
  1576. IN BOOL fCallback
  1577. );
  1578. BOOL
  1579. FindConnCloseRequestHeader(
  1580. IN DWORD dwHeaderIndex
  1581. );
  1582. VOID
  1583. RemoveGzipDeflateEncHeader(
  1584. VOID
  1585. );
  1586. VOID
  1587. RemoveAllRequestHeadersByName(
  1588. IN DWORD dwQueryIndex
  1589. );
  1590. //
  1591. // response buffer/data methods
  1592. //
  1593. BOOL IsBufferedData(VOID) {
  1594. BOOL fIsBufferedData;
  1595. //INET_ASSERT(IsData());
  1596. fIsBufferedData = (_DataOffset < _BytesReceived) ? TRUE : FALSE;
  1597. if ( fIsBufferedData &&
  1598. IsChunkEncoding() &&
  1599. _ResponseBufferDataReadyToRead == 0 )
  1600. {
  1601. fIsBufferedData = FALSE;
  1602. }
  1603. return (fIsBufferedData);
  1604. }
  1605. DWORD BufferedDataLength(VOID) {
  1606. return (DWORD)(_BytesReceived - _DataOffset);
  1607. }
  1608. DWORD BufferDataAvailToRead(VOID) {
  1609. return ( IsChunkEncoding() ) ? _ResponseBufferDataReadyToRead : BufferedDataLength() ;
  1610. }
  1611. VOID ReduceDataAvailToRead(DWORD dwReduceBy)
  1612. {
  1613. if ( IsChunkEncoding() )
  1614. {
  1615. _ResponseBufferDataReadyToRead -= dwReduceBy;
  1616. }
  1617. //else
  1618. //{
  1619. _DataOffset += dwReduceBy;
  1620. //}
  1621. }
  1622. LPVOID BufferedDataStart(VOID) {
  1623. return (LPVOID)(_ResponseBuffer + _DataOffset);
  1624. }
  1625. VOID SetCookieQuery(DWORD QueryIndex) {
  1626. _dwQuerySetCookieHeader = QueryIndex;
  1627. }
  1628. DWORD GetCookieQuery(VOID) const {
  1629. return _dwQuerySetCookieHeader;
  1630. }
  1631. VOID SetContentLength(DWORD ContentLength) {
  1632. _ContentLength = ContentLength;
  1633. }
  1634. DWORD GetContentLength(VOID) const {
  1635. return _ContentLength;
  1636. }
  1637. DWORD GetBytesInSocket(VOID) const {
  1638. return _BytesInSocket;
  1639. }
  1640. DWORD GetBytesRemaining(VOID) const {
  1641. return _BytesRemaining;
  1642. }
  1643. DWORD GetStatusCode(VOID) const {
  1644. return _StatusCode;
  1645. }
  1646. void SetStatusCode(DWORD StatusCode) {
  1647. _StatusCode = StatusCode;
  1648. }
  1649. VOID SetRefreshHeader(LPSTR Header, DWORD Length) {
  1650. _RefreshHeader.MakeCopy(Header, Length);
  1651. }
  1652. HEADER_STRING & GetRefreshHeader(VOID) {
  1653. return _RefreshHeader;
  1654. }
  1655. VOID FreeResponseBuffer(VOID) {
  1656. if (_ResponseBuffer != NULL) {
  1657. _ResponseBuffer = (LPBYTE)FREE_MEMORY((HLOCAL)_ResponseBuffer);
  1658. INET_ASSERT(_ResponseBuffer == NULL);
  1659. }
  1660. _ResponseBufferLength = 0;
  1661. _BytesReceived = 0;
  1662. _DataOffset = 0;
  1663. }
  1664. VOID FreeQueryBuffer(VOID) {
  1665. if (_QueryBuffer != NULL) {
  1666. _QueryBuffer = (LPVOID)FREE_MEMORY((HLOCAL)_QueryBuffer);
  1667. INET_ASSERT(_QueryBuffer == NULL);
  1668. _QueryBuffer = NULL;
  1669. _QueryBufferLength = 0;
  1670. _QueryOffset = 0;
  1671. _QueryBytesAvailable = 0;
  1672. }
  1673. }
  1674. BOOL HaveQueryData(VOID) {
  1675. return (_QueryBytesAvailable != 0) ? TRUE : FALSE;
  1676. }
  1677. DWORD CopyQueriedData(LPVOID lpBuffer, DWORD dwBufferLength) {
  1678. INET_ASSERT(lpBuffer != NULL);
  1679. INET_ASSERT(dwBufferLength != 0);
  1680. DWORD len = min(_QueryBytesAvailable, dwBufferLength);
  1681. if (len != 0) {
  1682. memcpy(lpBuffer,
  1683. (LPVOID)((LPBYTE)_QueryBuffer + _QueryOffset),
  1684. len
  1685. );
  1686. _QueryOffset += len;
  1687. _QueryBytesAvailable -= len;
  1688. }
  1689. return len;
  1690. }
  1691. VOID ResetResponseVariables(VOID) {
  1692. _StatusCode = 0;
  1693. _BytesReceived = 0;
  1694. _ResponseScanned = 0;
  1695. _iSlotContentLength = 0;
  1696. _iSlotContentRange = 0;
  1697. _ResponseBufferDataReadyToRead = 0;
  1698. _DataOffset = 0;
  1699. _BytesRemaining = 0;
  1700. _ContentLength = 0;
  1701. _BytesInSocket = 0;
  1702. ZapFlags();
  1703. _ftLastModified.dwLowDateTime = 0;
  1704. _ftLastModified.dwHighDateTime = 0;
  1705. _ftExpires.dwLowDateTime = 0;
  1706. _ftExpires.dwHighDateTime = 0;
  1707. _ftPostCheck.dwLowDateTime = 0;
  1708. _ftPostCheck.dwHighDateTime = 0;
  1709. }
  1710. //
  1711. // flags methods
  1712. //
  1713. VOID SetEof(BOOL Value) {
  1714. _Union.Flags.Eof = Value ? 1 : 0;
  1715. }
  1716. BOOL IsEof(VOID) const {
  1717. return _Union.Flags.Eof;
  1718. }
  1719. VOID SetDownLevel(BOOL Value) {
  1720. _Union.Flags.DownLevel = Value ? 1 : 0;
  1721. }
  1722. BOOL IsDownLevel(VOID) const {
  1723. return _Union.Flags.DownLevel;
  1724. }
  1725. BOOL IsRequestHttp1_1() {
  1726. return (_RequestHeaders.MajorVersion() > 1)
  1727. ? TRUE
  1728. : (((_RequestHeaders.MajorVersion() == 1)
  1729. && (_RequestHeaders.MinorVersion() >= 1))
  1730. ? TRUE
  1731. : FALSE);
  1732. }
  1733. BOOL IsRequestHttp1_0() {
  1734. return ((_RequestHeaders.MajorVersion() == 1)
  1735. && (_RequestHeaders.MinorVersion() == 0));
  1736. }
  1737. VOID SetResponseHttp1_1(BOOL Value) {
  1738. _Union.Flags.Http1_1Response = Value ? 1 : 0;
  1739. }
  1740. BOOL IsResponseHttp1_1(VOID) const {
  1741. return _Union.Flags.Http1_1Response;
  1742. }
  1743. VOID SetMustRevalidate (VOID) {
  1744. _Union.Flags.MustRevalidate = 1;
  1745. }
  1746. BOOL IsMustRevalidate (VOID) const {
  1747. return _Union.Flags.MustRevalidate;
  1748. }
  1749. VOID SetUpLevel(BOOL Value) {
  1750. _Union.Flags.UpLevel = Value ? 1 : 0;
  1751. }
  1752. BOOL IsUpLevel(VOID) const {
  1753. return _Union.Flags.UpLevel;
  1754. }
  1755. VOID SetKeepAlive(BOOL Value) {
  1756. _Union.Flags.KeepAlive = Value ? 1 : 0;
  1757. }
  1758. BOOL IsKeepAlive(VOID) const {
  1759. return _Union.Flags.KeepAlive;
  1760. }
  1761. VOID SetConnCloseResponse(BOOL Value) {
  1762. _Union.Flags.ConnCloseResponse = Value ? 1 : 0;
  1763. }
  1764. BOOL IsConnCloseResponse(VOID) const {
  1765. return _Union.Flags.ConnCloseResponse;
  1766. }
  1767. VOID SetData(BOOL Value) {
  1768. _Union.Flags.Data = Value ? 1 : 0;
  1769. }
  1770. BOOL IsData(VOID) const {
  1771. return _Union.Flags.Data;
  1772. }
  1773. VOID SetOpenFlags(DWORD OpenFlags) {
  1774. _OpenFlags = OpenFlags;
  1775. }
  1776. DWORD GetOpenFlags(VOID) {
  1777. return _OpenFlags;
  1778. }
  1779. //VOID SetCookieUI(BOOL Value)
  1780. //{
  1781. // _Union.Flags.CookieUI = (Value) ? TRUE : FALSE;
  1782. //}
  1783. //BOOL IsCookieUI() const
  1784. //{
  1785. // return _Union.Flags.CookieUI;
  1786. //}
  1787. VOID SetHaveChunkEncoding(BOOL Value) {
  1788. _Union.Flags.ChunkEncoding = Value ? 1 : 0;
  1789. }
  1790. BOOL IsChunkEncoding(VOID) const {
  1791. return _Union.Flags.ChunkEncoding;
  1792. }
  1793. VOID SetHaveContentLength(BOOL Value) {
  1794. _Union.Flags.ContentLength = Value ? 1 : 0;
  1795. }
  1796. BOOL IsContentLength(VOID) const {
  1797. return _Union.Flags.ContentLength;
  1798. }
  1799. VOID SetAutoSync(VOID) {
  1800. _Union.Flags.AutoSync = 1;
  1801. }
  1802. BOOL IsAutoSync(VOID) {
  1803. return _Union.Flags.AutoSync == 1;
  1804. }
  1805. VOID SetBadNSServer(BOOL Value) {
  1806. _Union.Flags.BadNSServer = Value ? 1 : 0;
  1807. }
  1808. BOOL IsBadNSServer(VOID) const {
  1809. return _Union.Flags.BadNSServer ? TRUE : FALSE;
  1810. }
  1811. VOID SetCheckedConnCloseRequest(BOOL bProxy, BOOL bFound) {
  1812. _Union.Flags.ConnCloseChecked = 1;
  1813. if (bProxy) {
  1814. _Union.Flags.ProxyConnCloseReq = bFound ? 1 : 0;
  1815. } else {
  1816. _Union.Flags.ConnCloseReq = bFound ? 1 : 0;
  1817. }
  1818. }
  1819. BOOL CheckedConnCloseRequest(VOID) {
  1820. return (_Union.Flags.ConnCloseChecked == 1) ? TRUE : FALSE;
  1821. }
  1822. BOOL IsConnCloseRequest(BOOL bProxyHeader) {
  1823. return bProxyHeader
  1824. ? (_Union.Flags.ProxyConnCloseReq == 1)
  1825. : (_Union.Flags.ConnCloseReq == 1);
  1826. }
  1827. VOID
  1828. SetBadNSReceiveTimeout(
  1829. VOID
  1830. );
  1831. BOOL IsChunkedEncodingFinished(VOID) {
  1832. return _ctChunkInfo.IsFinished();
  1833. }
  1834. VOID CheckClientRequestHeaders (VOID);
  1835. VOID SetFirstSendProcessed() {
  1836. _NoResetBits.Flags.FirstSendProcessed = 1;
  1837. }
  1838. BOOL IsFirstSendProcessed() const {
  1839. return _NoResetBits.Flags.FirstSendProcessed;
  1840. }
  1841. VOID SetObjectRoot() {
  1842. _NoResetBits.Flags.IsObjectRoot = 1;
  1843. }
  1844. BOOL IsObjectRoot() {
  1845. return _NoResetBits.Flags.IsObjectRoot;
  1846. }
  1847. VOID SetOverrideProxyMode(BOOL Value) {
  1848. _NoResetBits.Flags.OverrideProxyMode = (Value ? TRUE : FALSE );
  1849. }
  1850. BOOL IsOverrideProxyMode() const {
  1851. return _NoResetBits.Flags.OverrideProxyMode;
  1852. }
  1853. VOID SetCacheReadDisabled (VOID) {
  1854. _NoResetBits.Flags.CacheReadDisabled = 1;
  1855. }
  1856. BOOL IsCacheReadDisabled (VOID) const {
  1857. return _NoResetBits.Flags.CacheReadDisabled;
  1858. }
  1859. VOID SetWantKeepAlive(BOOL Value) {
  1860. _bWantKeepAlive = Value;
  1861. }
  1862. BOOL IsWantKeepAlive(VOID) const {
  1863. return _bWantKeepAlive;
  1864. }
  1865. VOID SetRefresh(BOOL Value) {
  1866. _bRefresh = Value;
  1867. }
  1868. BOOL IsRefresh(VOID) const {
  1869. return _bRefresh;
  1870. }
  1871. VOID SetAddCRLF(BOOL Value) {
  1872. _AddCRLFToPOST = Value;
  1873. }
  1874. //
  1875. // Bit to distinguish nested request for establishing a tunnel.
  1876. //
  1877. VOID SetTunnel (VOID) {
  1878. _NoResetBits.Flags.IsTunnel = 1;
  1879. }
  1880. BOOL IsTunnel(VOID) const {
  1881. return (BOOL) _NoResetBits.Flags.IsTunnel;
  1882. }
  1883. //
  1884. // secure (socket) methods
  1885. //
  1886. VOID SetSecureFlags(DWORD Flags) {
  1887. if(m_pSecurityInfo)
  1888. {
  1889. m_pSecurityInfo->SetSecureFlags(Flags);
  1890. }
  1891. }
  1892. DWORD GetSecureFlags(VOID) {
  1893. if(m_pSecurityInfo)
  1894. {
  1895. return m_pSecurityInfo->GetSecureFlags();
  1896. }
  1897. return 0;
  1898. }
  1899. VOID LockHeaders(VOID) {
  1900. //EnterCriticalSection(&_CritSec);
  1901. _RequestHeaders.LockHeaders();
  1902. }
  1903. VOID UnlockHeaders(VOID) {
  1904. //LeaveCriticalSection(&_CritSec);
  1905. _RequestHeaders.UnlockHeaders();
  1906. }
  1907. VOID SetIgnoreOffline(VOID) {
  1908. _fIgnoreOffline = TRUE;
  1909. }
  1910. //
  1911. // GetCertChainList (and)
  1912. // SetCertChainList -
  1913. // Sets and Gets Client Authentication Cert Chains.
  1914. //
  1915. CERT_CONTEXT_ARRAY* GetCertContextArray(VOID) {
  1916. if(m_pSecurityInfo)
  1917. {
  1918. return m_pSecurityInfo->GetCertContextArray();
  1919. }
  1920. return NULL;
  1921. }
  1922. VOID SetCertContextArray(CERT_CONTEXT_ARRAY* pNewCertContextArray) {
  1923. if(m_pSecurityInfo)
  1924. {
  1925. m_pSecurityInfo->SetCertContextArray(pNewCertContextArray);
  1926. }
  1927. }
  1928. //
  1929. // function to get SSL Certificate Information
  1930. //
  1931. DWORD GetSecurityInfo(LPINTERNET_SECURITY_INFO pInfo) {
  1932. if(m_pSecurityInfo)
  1933. {
  1934. m_pSecurityInfo->CopyOut(*pInfo);
  1935. return ERROR_SUCCESS;
  1936. }
  1937. else
  1938. {
  1939. return ERROR_INTERNET_INTERNAL_ERROR;
  1940. }
  1941. }
  1942. /* Function for determining zone-mapping
  1943. This is a reverse-dependency between WININET and URLMON */
  1944. DWORD GetSecurityZone(BOOL fRevalidate=FALSE) {
  1945. /* already found out which zone this request lives in? */
  1946. if (!fRevalidate &&
  1947. _dwSecurityZone>=URLZONE_PREDEFINED_MIN &&
  1948. _dwSecurityZone<=URLZONE_PREDEFINED_MAX)
  1949. return _dwSecurityZone;
  1950. /* otherwise map the zone and save result on this object */
  1951. if (GetOpenFlags() & INTERNET_FLAG_RESTRICTED_ZONE)
  1952. _dwSecurityZone = URLZONE_UNTRUSTED;
  1953. else
  1954. _dwSecurityZone = GetZoneFromUrl(GetURL());
  1955. return _dwSecurityZone;
  1956. }
  1957. //
  1958. // authentication related methods
  1959. //
  1960. VOID SetAuthCtx (AUTHCTX *pAuthCtx) {
  1961. _pAuthCtx = pAuthCtx;
  1962. }
  1963. AUTHCTX* GetAuthCtx (VOID) {
  1964. return _pAuthCtx;
  1965. }
  1966. VOID SetPWC (PWC *pPWC) {
  1967. _pPWC = pPWC;
  1968. }
  1969. PWC* GetPWC (VOID) {
  1970. return _pPWC;
  1971. }
  1972. AUTHCTX* GetTunnelAuthCtx (VOID) {
  1973. return _pTunnelAuthCtx;
  1974. }
  1975. DWORD GetCredPolicy (VOID)
  1976. {
  1977. if (_dwCredPolicy == 0xFFFFFFFF)
  1978. {
  1979. LPSTR pszUrl;
  1980. if (GetOpenFlags() & INTERNET_FLAG_RESTRICTED_ZONE)
  1981. pszUrl = NULL;
  1982. else
  1983. pszUrl = GetURL();
  1984. _dwCredPolicy = ::GetCredPolicy (pszUrl);
  1985. }
  1986. return _dwCredPolicy;
  1987. }
  1988. DWORD GetAuthState (void) {
  1989. return _NoResetBits.Flags.AuthState;
  1990. }
  1991. void SetAuthState (DWORD dw) {
  1992. INET_ASSERT( dw <= AUTHSTATE_LAST );
  1993. _NoResetBits.Flags.AuthState = dw;
  1994. DEBUG_PRINT(
  1995. HTTP,
  1996. INFO,
  1997. ("authstate on request %#x set to %#x [%s]\n", this, dw, InternetMapAuthState(dw))
  1998. );
  1999. }
  2000. void SetAuthorized (void) {
  2001. _NoResetBits.Flags.IsAuthorized = 1;
  2002. }
  2003. BOOL IsAuthorized (void) {
  2004. return _NoResetBits.Flags.IsAuthorized;
  2005. }
  2006. void SetMethodBody (void) {
  2007. _NoResetBits.Flags.MethodBody = 1;
  2008. }
  2009. BOOL IsMethodBody (void) {
  2010. return _NoResetBits.Flags.MethodBody;
  2011. }
  2012. void SetDisableNTLMPreauth (BOOL fVal) {
  2013. _NoResetBits.Flags.DisableNTLMPreauth = (DWORD) (fVal ? TRUE : FALSE);
  2014. }
  2015. BOOL IsDisableNTLMPreauth (void) {
  2016. return _NoResetBits.Flags.DisableNTLMPreauth;
  2017. }
  2018. LPVOID GetBlockingFilter (void) {
  2019. return _lpBlockingFilter;
  2020. }
  2021. void SetBlockingFilter (LPVOID lpFilter) {
  2022. _lpBlockingFilter = lpFilter;
  2023. }
  2024. void SetAuthFlag(DWORD AuthFlag) {
  2025. m_AuthFlag = AuthFlag;
  2026. }
  2027. DWORD GetAuthFlag(void) {
  2028. return m_AuthFlag;
  2029. }
  2030. //
  2031. // proxy methods
  2032. //
  2033. BOOL IsTalkingToSecureServerViaProxy(VOID) const {
  2034. return _fTalkingToSecureServerViaProxy;
  2035. }
  2036. VOID SetIsTalkingToSecureServerViaProxy(BOOL fTalkingToSecureServerViaProxy) {
  2037. _fTalkingToSecureServerViaProxy = fTalkingToSecureServerViaProxy;
  2038. }
  2039. VOID SetRequestUsingProxy(BOOL fRequestUsingProxy) {
  2040. _fRequestUsingProxy = fRequestUsingProxy;
  2041. }
  2042. BOOL IsRequestUsingProxy(VOID) const {
  2043. return _fRequestUsingProxy;
  2044. }
  2045. VOID
  2046. GetProxyName(
  2047. OUT LPSTR* lplpszProxyHostName,
  2048. OUT LPDWORD lpdwProxyHostNameLength,
  2049. OUT LPINTERNET_PORT lpProxyPort
  2050. );
  2051. VOID
  2052. SetProxyName(
  2053. IN LPSTR lpszProxyHostName,
  2054. IN DWORD dwProxyHostNameLength,
  2055. IN INTERNET_PORT ProxyPort
  2056. );
  2057. VOID
  2058. GetSocksProxyName(
  2059. LPSTR *lplpszProxyHostName,
  2060. DWORD *lpdwProxyHostNameLength,
  2061. LPINTERNET_PORT lpProxyPort
  2062. )
  2063. {
  2064. *lplpszProxyHostName = _SocksProxyHostName;
  2065. *lpdwProxyHostNameLength = _SocksProxyHostNameLength;
  2066. *lpProxyPort = _SocksProxyPort;
  2067. }
  2068. VOID
  2069. SetSocksProxyName(
  2070. LPSTR lpszProxyHostName,
  2071. DWORD dwProxyHostNameLength,
  2072. INTERNET_PORT ProxyPort
  2073. )
  2074. {
  2075. _SocksProxyHostName = lpszProxyHostName;
  2076. _SocksProxyHostNameLength = dwProxyHostNameLength;
  2077. _SocksProxyPort = ProxyPort;
  2078. }
  2079. VOID ClearPersistentConnection (VOID) {
  2080. _Union.Flags.PersistProxy = 0;
  2081. _Union.Flags.PersistServer = 0;
  2082. }
  2083. VOID SetPersistentConnection (BOOL fProxy) {
  2084. if (fProxy) {
  2085. _Union.Flags.PersistProxy = 1;
  2086. } else {
  2087. _Union.Flags.PersistServer = 1;
  2088. }
  2089. }
  2090. BOOL IsPersistentConnection (BOOL fProxy) {
  2091. return fProxy ?
  2092. _Union.Flags.PersistProxy : _Union.Flags.PersistServer;
  2093. }
  2094. //
  2095. // functions to get/set state
  2096. //
  2097. VOID SetState(HTTPREQ_STATE NewState) {
  2098. DEBUG_PRINT(HTTP,
  2099. INFO,
  2100. ("SetState(): current state %#x [%s], new state %#x [%s]\n",
  2101. _State,
  2102. InternetMapHttpState(_State),
  2103. NewState,
  2104. InternetMapHttpState(NewState)
  2105. ));
  2106. _State = NewState;
  2107. }
  2108. BOOL CheckState(DWORD Flag) {
  2109. DEBUG_PRINT(HTTP,
  2110. INFO,
  2111. ("CheckState(): current state %#x [%s], checking %#x [%s] - %B\n",
  2112. _State,
  2113. InternetMapHttpState(_State),
  2114. Flag,
  2115. InternetMapHttpStateFlag(Flag),
  2116. (_State & Flag) ? TRUE : FALSE
  2117. ));
  2118. return (_State & Flag) ? TRUE : FALSE;
  2119. }
  2120. VOID
  2121. ReuseObject(
  2122. VOID
  2123. );
  2124. DWORD
  2125. ResetObject(
  2126. IN BOOL bForce,
  2127. IN BOOL bFreeRequestHeaders
  2128. );
  2129. DWORD SetStreamPointer (LONG lDistanceToMove, DWORD dwMoveMethod);
  2130. BOOL AttemptReadFromFile (LPVOID lpBuf, DWORD cbBuf, DWORD *pcbRead);
  2131. VOID AdvanceReadPosition (DWORD cbRead)
  2132. {
  2133. _dwCurrentStreamPosition += cbRead;
  2134. if (IsKeepAlive() && IsContentLength())
  2135. {
  2136. _BytesRemaining -= cbRead;
  2137. INET_ASSERT (_BytesRemaining + _dwCurrentStreamPosition
  2138. == _ContentLength);
  2139. }
  2140. }
  2141. BOOL IsReadRequest (void)
  2142. {
  2143. return (IsCacheWriteInProgress() &&
  2144. _dwCurrentStreamPosition != _VirtualCacheFileSize);
  2145. }
  2146. DWORD
  2147. ReadLoop_Fsm(
  2148. IN CFsm_ReadLoop * Fsm
  2149. );
  2150. DWORD WriteResponseBufferToCache (VOID);
  2151. DWORD WriteQueryBufferToCache (VOID);
  2152. VOID SetNoLongerKeepAlive(VOID) {
  2153. _bNoLongerKeepAlive = TRUE;
  2154. }
  2155. BOOL IsNoLongerKeepAlive(VOID) const {
  2156. return _bNoLongerKeepAlive;
  2157. }
  2158. //
  2159. // send.cxx methods
  2160. //
  2161. DWORD
  2162. HttpSendRequest_Start(
  2163. IN CFsm_HttpSendRequest * Fsm
  2164. );
  2165. DWORD
  2166. HttpSendRequest_Finish(
  2167. IN CFsm_HttpSendRequest * Fsm
  2168. );
  2169. DWORD
  2170. MakeConnection_Fsm(
  2171. IN CFsm_MakeConnection * Fsm
  2172. );
  2173. DWORD
  2174. SendRequest_Fsm(
  2175. IN CFsm_SendRequest * Fsm
  2176. );
  2177. DWORD
  2178. ReceiveResponse_Fsm(
  2179. IN CFsm_ReceiveResponse * Fsm
  2180. );
  2181. BOOL
  2182. FCanWriteToCache(
  2183. VOID
  2184. );
  2185. BOOL
  2186. FAddIfModifiedSinceHeader(
  2187. IN LPCACHE_ENTRY_INFO lpCei
  2188. );
  2189. BOOL AddHeaderIfEtagFound (IN LPCACHE_ENTRY_INFO lpCei);
  2190. DWORD
  2191. FHttpBeginCacheRetrieval(
  2192. IN BOOL bReset,
  2193. IN BOOL bOffline,
  2194. IN BOOL bNoRetrieveIfExist = FALSE
  2195. );
  2196. DWORD UrlCacheRetrieve (BOOL fOffline)
  2197. {
  2198. INET_ASSERT (!_hCacheStream && !_pCacheEntryInfo);
  2199. return ::UrlCacheRetrieve
  2200. (_CacheUrlName, fOffline, &_hCacheStream, &_pCacheEntryInfo);
  2201. }
  2202. VOID UrlCacheUnlock (VOID);
  2203. BOOL FHttpBeginCacheWrite(VOID);
  2204. DWORD ResumePartialDownload (VOID);
  2205. DWORD
  2206. GetFromCachePreNetIO(
  2207. VOID
  2208. );
  2209. DWORD
  2210. GetFromCachePostNetIO(
  2211. IN DWORD statusCode,
  2212. IN BOOL fVariation = FALSE
  2213. );
  2214. DWORD
  2215. AddTimestampsFromCacheToResponseHeaders(
  2216. IN LPCACHE_ENTRY_INFO lpCacheEntryInfo
  2217. );
  2218. DWORD
  2219. AddTimeHeader(
  2220. IN FILETIME fTime,
  2221. IN DWORD dwHeaderIndex
  2222. );
  2223. LPINTERNET_BUFFERS SetReadFileEx(VOID) {
  2224. _BuffersOut.lpvBuffer = (LPVOID)&_ReadFileExData;
  2225. //
  2226. // receive ONE byte
  2227. //
  2228. _BuffersOut.dwBufferLength = 1;
  2229. return &_BuffersOut;
  2230. }
  2231. VOID SetReadFileExData(VOID) {
  2232. _HaveReadFileExData = TRUE;
  2233. }
  2234. VOID ResetReadFileExData(VOID) {
  2235. _HaveReadFileExData = FALSE;
  2236. }
  2237. BOOL HaveReadFileExData(VOID) {
  2238. return _HaveReadFileExData;
  2239. }
  2240. BYTE GetReadFileExData(VOID) {
  2241. ResetReadFileExData();
  2242. return (BYTE)_ReadFileExData;
  2243. }
  2244. //
  2245. // cookie.cxx methods
  2246. //
  2247. DWORD
  2248. CreateCookieHeaderIfNeeded(
  2249. int *pcCookie
  2250. );
  2251. DWORD
  2252. ExtractSetCookieHeaders(
  2253. LPDWORD lpdwHeaderIndex
  2254. );
  2255. LPCACHE_ENTRY_INFO GetCacheEntryInfo(VOID){
  2256. return _pCacheEntryInfo;
  2257. }
  2258. BOOL IsInCache(VOID) {
  2259. return _pCacheEntryInfo != NULL;
  2260. }
  2261. DWORD GetCacheEntryType (void){
  2262. return _dwCacheEntryType;
  2263. }
  2264. void AddCacheEntryType (DWORD dw){
  2265. _dwCacheEntryType |= dw;
  2266. }
  2267. BOOL CanRetrieveFromCache(BOOL fCheckCache = TRUE) {
  2268. return ((fCheckCache && IsInCache()) || !fCheckCache)
  2269. && !IsAutoSync()
  2270. && !(_OpenFlags
  2271. & (INTERNET_FLAG_RELOAD | INTERNET_FLAG_RESYNCHRONIZE));
  2272. }
  2273. //
  2274. // priority methods
  2275. //
  2276. LONG GetPriority(VOID) const {
  2277. return m_lPriority;
  2278. }
  2279. VOID SetPriority(LONG lPriority) {
  2280. m_lPriority = lPriority;
  2281. }
  2282. BOOL IsAutoProxyChecked(VOID) const {
  2283. return _fAutoProxyChecked;
  2284. }
  2285. VOID SetAutoProxyChecked(BOOL fValue) {
  2286. _fAutoProxyChecked = fValue;
  2287. }
  2288. //
  2289. // Round Trip Time methods
  2290. //
  2291. VOID StartRTT(VOID) {
  2292. _RTT = GetTickCountWrap();
  2293. }
  2294. VOID UpdateRTT(VOID) {
  2295. _RTT = (GetTickCountWrap() - _RTT);
  2296. CServerInfo * pServerInfo = GetOriginServer();
  2297. if (pServerInfo != NULL) {
  2298. pServerInfo->UpdateRTT(_RTT);
  2299. }
  2300. }
  2301. DWORD GetRTT(VOID) const {
  2302. return _RTT;
  2303. }
  2304. VOID SetCodePage(UINT dwCodePage) {
  2305. _CP = dwCodePage;
  2306. }
  2307. UINT GetCodePage(VOID) const {
  2308. return _CP;
  2309. }
  2310. VOID SetAuthenticated();
  2311. BOOL IsAuthenticated();
  2312. //
  2313. // diagnostic info
  2314. //
  2315. SOCKET GetSocket(VOID) {
  2316. return (_Socket != NULL) ? _Socket->GetSocket() : INVALID_SOCKET;
  2317. }
  2318. DWORD GetSourcePort(VOID) {
  2319. return (_Socket != NULL) ? _Socket->GetSourcePort() : 0;
  2320. }
  2321. DWORD GetDestPort(VOID) {
  2322. return (_Socket != NULL) ? _Socket->GetPort() : 0;
  2323. }
  2324. BOOL FromKeepAlivePool(VOID) const {
  2325. return _bKeepAliveConnection;
  2326. }
  2327. BOOL IsSecure(VOID) {
  2328. return (_Socket != NULL) ? _Socket->IsSecure() : FALSE;
  2329. }
  2330. BOOL IsBlockedOnUserInput(VOID) {
  2331. DEBUG_PRINT(THRDINFO,
  2332. INFO,
  2333. ("HTTP_REQUEST_HANDLE_OBJECT[%#x]::IsBlockedOnUserInput() = %B\n",
  2334. this,
  2335. _dwUiBlocked
  2336. ));
  2337. return (BOOL) _dwUiBlocked;
  2338. }
  2339. VOID BlockOnUserInput(DWORD_PTR dwBlockId) {
  2340. DEBUG_PRINT(THRDINFO,
  2341. INFO,
  2342. ("HTTP_REQUEST_HANDLE_OBJECT[%#x]::BlockOnUserInput(dwBlockId=%#x)\n",
  2343. this,
  2344. dwBlockId
  2345. ));
  2346. INET_ASSERT(!_dwUiBlocked);
  2347. _dwUiBlocked = TRUE;
  2348. _dwBlockId = dwBlockId;
  2349. }
  2350. DWORD_PTR GetBlockId(VOID) {
  2351. DEBUG_PRINT(THRDINFO,
  2352. INFO,
  2353. ("HTTP_REQUEST_HANDLE_OBJECT[%#x]::GetBlockId() = %#x\n",
  2354. this,
  2355. _dwBlockId
  2356. ));
  2357. INET_ASSERT(_dwUiBlocked);
  2358. return _dwBlockId;
  2359. }
  2360. VOID UnBlockOnUserInput(VOID) {
  2361. DEBUG_PRINT(THRDINFO,
  2362. INFO,
  2363. ("HTTP_REQUEST_HANDLE_OBJECT[%#x]::UnBlockOnUserInput()\n",
  2364. this
  2365. ));
  2366. INET_ASSERT(_dwUiBlocked);
  2367. _dwUiBlocked = FALSE;
  2368. }
  2369. VOID Set3rdPartyCookies(BOOL f3rdParty)
  2370. {
  2371. _f3rdPartyCookies = f3rdParty;
  2372. }
  2373. BOOL Is3rdPartyCookies(VOID)
  2374. {
  2375. return _f3rdPartyCookies;
  2376. }
  2377. VOID SetSendUTF8ServerNameToProxy(DWORD dwSetVal)
  2378. {
  2379. _fSendUTF8ServerNameToProxy = dwSetVal ? TRUE : FALSE;
  2380. }
  2381. BOOL ShouldSendUTF8ServerNameToProxy()
  2382. {
  2383. return _fSendUTF8ServerNameToProxy;
  2384. }
  2385. VOID SetSocketSendBufferLength(DWORD dwLength)
  2386. {
  2387. _dwSocketSendBufferLength = dwLength;
  2388. }
  2389. DWORD GetSocketSendBufferLength()
  2390. {
  2391. return _dwSocketSendBufferLength;
  2392. }
  2393. };
  2394. //
  2395. // prototypes
  2396. //
  2397. BOOL
  2398. IsCorrectUser(
  2399. IN LPSTR lpszHeaderInfo,
  2400. IN DWORD dwHeaderSize
  2401. );
  2402. //
  2403. // Support for handling cookie policy
  2404. //
  2405. typedef struct _COOKIE_DLG_INFO {
  2406. LPWSTR pszServer;
  2407. PINTERNET_COOKIE pic;
  2408. DWORD dwStopWarning;
  2409. INT cx;
  2410. INT cy;
  2411. LPWSTR pszHeader;
  2412. DWORD dwOperation;
  2413. } COOKIE_DLG_INFO, *PCOOKIE_DLG_INFO;
  2414. // values for dwOperation member
  2415. #define COOKIE_OP_SET 0x01
  2416. #define COOKIE_OP_MODIFY 0x02
  2417. #define COOKIE_OP_GET 0x04
  2418. #define COOKIE_OP_SESSION 0x08
  2419. #define COOKIE_OP_PERSISTENT 0x10
  2420. #define COOKIE_OP_3RD_PARTY 0x20
  2421. DWORD
  2422. ConfirmCookie(
  2423. IN HWND hwnd,
  2424. IN HTTP_REQUEST_HANDLE_OBJECT *pRequest,
  2425. IN COOKIE_DLG_INFO *pInfo
  2426. );