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.

2348 lines
57 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. //
  14. // manifests
  15. //
  16. #include "hdrstr.hxx"
  17. #include "hdrbuf.hxx"
  18. #include "hdrparse.hxx"
  19. //
  20. // macros
  21. //
  22. #define IS_VALID_HTTP_STATE(p, api, ref) \
  23. (p)->CheckState(HTTPREQ_STATE_ ## api ## _OK)
  24. #define IsValidHttpState(api) \
  25. CheckState(HTTPREQ_STATE_ ## api ## _OK)
  26. extern PROXY_INFO_GLOBAL * g_pGlobalProxyInfo;
  27. //
  28. // types
  29. //
  30. typedef enum {
  31. HTTP_HEADER_TYPE_UNKNOWN = 0,
  32. HTTP_HEADER_TYPE_ACCEPT
  33. } HTTP_HEADER_TYPE;
  34. //
  35. // HTTP state is no longer stored as an enum. There are 4 related pieces
  36. // of data associated with the HTTP state:
  37. // 1) state
  38. // 2) allowed actions
  39. // 3) has WinHttpReceiveResponse been called
  40. // 4) is WinHttpWriteData call needed to send additional optional data
  41. //
  42. // 2 is directly tied to the state value. 3 stores whether or not
  43. // the client has called WinHttpReceiveResponse, which is now required.
  44. // 4 marks whether if there is additional optional data (indicated by having
  45. // the total optional length greater than the optional length/data passed
  46. // to WinHttpSendRequest.
  47. typedef enum {
  48. //
  49. // The request handle is in the process of being created
  50. //
  51. HttpRequestStateCreating = 0 | HTTPREQ_STATE_ANYTHING_OK,
  52. //
  53. // The request handle is open, but the request has not been sent to the
  54. // server
  55. //
  56. HttpRequestStateOpen = 1 | HTTPREQ_STATE_CLOSE_OK
  57. | HTTPREQ_STATE_ADD_OK
  58. | HTTPREQ_STATE_SEND_OK
  59. | HTTPREQ_STATE_READ_OK
  60. | HTTPREQ_STATE_QUERY_REQUEST_OK
  61. | HTTPREQ_STATE_QUERY_RESPONSE_OK
  62. | HTTPREQ_STATE_ANYTHING_OK,
  63. //
  64. // The request has been sent to the server, but the response headers have
  65. // not been received
  66. //
  67. HttpRequestStateRequest = 2 | HTTPREQ_STATE_CLOSE_OK
  68. | HTTPREQ_STATE_QUERY_REQUEST_OK
  69. | HTTPREQ_STATE_WRITE_OK
  70. | HTTPREQ_STATE_ANYTHING_OK,
  71. //
  72. // The response headers are being received, but not yet completed
  73. //
  74. HttpRequestStateResponse = 3 | HTTPREQ_STATE_CLOSE_OK
  75. | HTTPREQ_STATE_WRITE_OK
  76. | HTTPREQ_STATE_ANYTHING_OK,
  77. //
  78. // The response headers have been received, and there is object data
  79. // available to read
  80. //
  81. //
  82. // QFE 3576: It's possible that we're init'ing a new request,
  83. // but the previous request hasn't been drained yet.
  84. // Since we know it will always be drained, the lowest
  85. // impact change is to allow headers to be replaced
  86. // if we're in a state with potential data left to receive.
  87. HttpRequestStateObjectData = 4 | HTTPREQ_STATE_CLOSE_OK
  88. | HTTPREQ_STATE_ADD_OK
  89. | HTTPREQ_STATE_READ_OK
  90. | HTTPREQ_STATE_QUERY_REQUEST_OK
  91. | HTTPREQ_STATE_QUERY_RESPONSE_OK
  92. | HTTPREQ_STATE_REUSE_OK
  93. | HTTPREQ_STATE_ANYTHING_OK,
  94. //
  95. // A fatal error occurred
  96. //
  97. HttpRequestStateError = 5 | HTTPREQ_STATE_CLOSE_OK
  98. | HTTPREQ_STATE_ANYTHING_OK,
  99. //
  100. // The request is closing
  101. //
  102. HttpRequestStateClosing = 6 | HTTPREQ_STATE_ANYTHING_OK,
  103. //
  104. // the data has been drained from the request object and it can be re-used
  105. //
  106. HttpRequestStateReopen = 7 | HTTPREQ_STATE_CLOSE_OK
  107. | HTTPREQ_STATE_ADD_OK
  108. | HTTPREQ_STATE_READ_OK
  109. | HTTPREQ_STATE_QUERY_REQUEST_OK
  110. | HTTPREQ_STATE_QUERY_RESPONSE_OK
  111. | HTTPREQ_STATE_REUSE_OK
  112. | HTTPREQ_STATE_ANYTHING_OK
  113. } HTTPREQ_STATE, FAR * LPHTTPREQ_STATE;
  114. //
  115. // general prototypes
  116. //
  117. HTTP_METHOD_TYPE
  118. MapHttpRequestMethod(
  119. IN LPCSTR lpszVerb
  120. );
  121. DWORD
  122. MapHttpMethodType(
  123. IN HTTP_METHOD_TYPE tMethod,
  124. OUT LPCSTR * lplpcszName
  125. );
  126. DWORD
  127. CreateEscapedUrlPath(
  128. IN LPSTR lpszUrlPath,
  129. OUT LPSTR * lplpszEncodedUrlPath
  130. );
  131. #if INET_DEBUG
  132. LPSTR
  133. MapHttpMethodType(
  134. IN HTTP_METHOD_TYPE tMethod
  135. );
  136. #endif
  137. //
  138. // forward references
  139. //
  140. class CFsm;
  141. class CFsm_HttpSendRequest;
  142. class CFsm_MakeConnection;
  143. class CFsm_OpenConnection;
  144. class CFsm_OpenProxyTunnel;
  145. class CFsm_SendRequest;
  146. class CFsm_ReceiveResponse;
  147. class CFsm_HttpReadData;
  148. class CFsm_HttpWriteData;
  149. class CFsm_ReadData;
  150. class CFsm_HttpQueryAvailable;
  151. class CFsm_DrainResponse;
  152. class CFsm_Redirect;
  153. class CFsm_ReadLoop;
  154. //
  155. // classes
  156. //
  157. //
  158. // flags for AddHeader
  159. //
  160. #define CLEAN_HEADER 0x00000001 // if set, header should be cleaned up
  161. #define ADD_HEADER_IF_NEW HTTP_ADDREQ_FLAG_ADD_IF_NEW // only add the header if it doesn't already exist
  162. #define ADD_HEADER HTTP_ADDREQ_FLAG_ADD // if replacing and header not found, add it
  163. #define COALESCE_HEADER_WITH_COMMA HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA // headers of the same name will be coalesced
  164. #define COALESCE_HEADER_WITH_SEMICOLON HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON // headers of the same name will be coalesced
  165. #define REPLACE_HEADER HTTP_ADDREQ_FLAG_REPLACE // not currently used internally
  166. struct WINHTTP_REQUEST_CREDENTIALS
  167. {
  168. DWORD _AuthScheme;
  169. PSTR _pszRealm;
  170. PSTR _pszUserName;
  171. PSTR _pszPassword;
  172. WINHTTP_REQUEST_CREDENTIALS(DWORD AuthScheme,
  173. PCSTR pszRealm,
  174. PCSTR pszUserName,
  175. PCSTR pszPassword)
  176. {
  177. _AuthScheme = AuthScheme;
  178. _pszRealm = pszRealm ? NewString(pszRealm) : NULL;
  179. _pszUserName = pszUserName ? NewString(pszUserName) : NULL;
  180. _pszPassword = pszPassword ? NewString(pszPassword) : NULL;
  181. }
  182. ~WINHTTP_REQUEST_CREDENTIALS(void)
  183. {
  184. if (_pszRealm)
  185. {
  186. FREE_MEMORY(_pszRealm);
  187. }
  188. if (_pszUserName)
  189. {
  190. FREE_MEMORY(_pszUserName);
  191. }
  192. if (_pszPassword)
  193. {
  194. FREE_MEMORY(_pszPassword);
  195. }
  196. }
  197. };
  198. /*++
  199. Class Description:
  200. This class defines the HTTP_REQUEST_HANDLE_OBJECT.
  201. Private Member functions:
  202. None.
  203. Public Member functions:
  204. --*/
  205. class HTTP_REQUEST_HANDLE_OBJECT : public INTERNET_CONNECT_HANDLE_OBJECT {
  206. public:
  207. CServerInfo * _ServerInfo;
  208. CServerInfo * _OriginServer;
  209. LPSTR _CacheUrlName;
  210. // String properties, e.g. auth creds
  211. XSTRING _xsProp[NUM_INTERNET_STRING_OPTION];
  212. DWORD _ReadBufferSize;
  213. DWORD _WriteBufferSize;
  214. WINHTTP_REQUEST_CREDENTIALS* _pProxyCreds;
  215. WINHTTP_REQUEST_CREDENTIALS* _pServerCreds;
  216. DWORD _PreferredScheme;
  217. DWORD _SupportedSchemes;
  218. DWORD _AuthTarget;
  219. LPSTR _pszRealm;
  220. private:
  221. DWORD _SecurityLevel;
  222. BOOL m_fPPAbortSend;
  223. //
  224. // m_lPriority - relative priority used to determine which request gets the
  225. // next available connection
  226. //
  227. LONG m_lPriority;
  228. //
  229. // _Socket - this is the socket we are using for this request. It may be a
  230. // pre-existing keep-alive connection or a new connection (not necessarily
  231. // keep-alive)
  232. //
  233. ICSocket * _Socket;
  234. //
  235. // _bKeepAliveConnection - if TRUE, _Socket is keep-alive, else we must
  236. // really close it
  237. //
  238. BOOL _bKeepAliveConnection;
  239. //
  240. // _bNoLongerKeepAlive - if this ever gets set to TRUE its because we began
  241. // with a keep-alive connection which reverted to non-keep-alive when the
  242. // server responded with no "(Proxy-)Connection: Keep-Alive" header
  243. //
  244. BOOL _bNoLongerKeepAlive;
  245. //
  246. // _QueryBuffer - buffer used to query socket data available
  247. //
  248. LPVOID _QueryBuffer;
  249. //
  250. // _QueryBufferLength - length of _QueryBuffer
  251. //
  252. DWORD _QueryBufferLength;
  253. //
  254. // _QueryOffset - offset of next read from _QueryBuffer
  255. //
  256. DWORD _QueryOffset;
  257. //
  258. // _QueryBytesAvailable - number of bytes we think are available for this
  259. // socket in the query buffer
  260. //
  261. DWORD _QueryBytesAvailable;
  262. //
  263. // _OpenFlags - flags specified in HttpOpenRequest()
  264. //
  265. DWORD _OpenFlags;
  266. //
  267. // _State - the HTTP request/response state
  268. //
  269. WORD _State;
  270. //
  271. // HTTP request information
  272. //
  273. //
  274. // _RequestHeaders - collection of request headers, including the request
  275. // line
  276. //
  277. HTTP_HEADERS _RequestHeaders;
  278. //
  279. // _RequestMethod - (known) method used to make HTTP request
  280. //
  281. HTTP_METHOD_TYPE _RequestMethod;
  282. //
  283. // Values for optional data saved offin handle when in negotiate stage.
  284. //
  285. DWORD _dwOptionalSaved;
  286. LPVOID _lpOptionalSaved;
  287. BOOL _fOptionalSaved;
  288. // Value to provide information on whether Writes are required, to the FSM kicked off by ReceiveResponse
  289. // during a redirect. Since this FSM doesn't have the information, we squirrel it away in the handle:
  290. BOOL _bIsWriteRequired;
  291. //
  292. // HTTP response information
  293. //
  294. //
  295. // _ResponseHeaders - collection of response headers, including the status
  296. // line
  297. //
  298. HTTP_HEADER_PARSER _ResponseHeaders;
  299. //
  300. // _StatusCode - return status from the server
  301. //
  302. DWORD _StatusCode;
  303. //
  304. // _ResponseBuffer - pointer to the buffer containing part or all of
  305. // response, starting with headers (if >= HTTP/1.0, i.e. if IsUpLevel)
  306. //
  307. LPBYTE _ResponseBuffer;
  308. //
  309. // _ResponseBufferLength - length of _ResponseBuffer
  310. //
  311. DWORD _ResponseBufferLength;
  312. //
  313. // _BytesReceived - number of bytes received into _ResponseBuffer
  314. //
  315. DWORD _BytesReceived;
  316. //
  317. // _ResponseScanned - amount of response buffers scanned for eof headers
  318. //
  319. DWORD _ResponseScanned;
  320. //
  321. // _ResponseBufferDataReadyToRead - special length of response buffer,
  322. // set if we've parsed it from a chunk-transfer stream, this will be
  323. // the correct length
  324. //
  325. DWORD _ResponseBufferDataReadyToRead;
  326. //
  327. // _DataOffset - the offset in _ResponseBuffer at which the response data
  328. // starts (data after headers)
  329. //
  330. DWORD _DataOffset;
  331. //
  332. // _BytesRemaining - number of _ContentLength bytes remaining to be read by
  333. // application
  334. //
  335. DWORD _BytesRemaining;
  336. //
  337. // _ContentLength - as parsed from the response headers
  338. //
  339. DWORD _ContentLength;
  340. //
  341. // _BytesInSocket - if content-length, the number of bytes we have yet to
  342. // receive from the socket
  343. //
  344. DWORD _BytesInSocket;
  345. //
  346. // _ResponseFilterList - transfer and content encoding filters to process
  347. // e.g. chunked and compression
  348. //
  349. FILTER_LIST _ResponseFilterList;
  350. // _bViaProxy - TRUE if the request was made via a proxy
  351. // move this to request handle
  352. BYTE _bViaProxy;
  353. //
  354. // _fTalkingToSecureServerViaProxy - We're talking SSL, but
  355. // actually we're connected through a proxy so things
  356. // need to be carefully watched. Don't send a Proxy
  357. // Username and Password to the the secure sever.
  358. //
  359. BOOL _fTalkingToSecureServerViaProxy;
  360. //
  361. // _fRequestUsingProxy - TRUE if we're actually using the proxy
  362. // to reach the server. Needed to keep track of whether
  363. // we're using the proxy or not.
  364. //
  365. BOOL _fRequestUsingProxy;
  366. //
  367. // _bWantKeepAlive - TRUE if we want a keep-alive connection
  368. //
  369. BOOL _bWantKeepAlive;
  370. //
  371. // _dwQuerySetCookieHeader - Passed to HttpQueryInfo to track what
  372. // cookie header we're parsing.
  373. //
  374. DWORD _dwQuerySetCookieHeader;
  375. //
  376. // _Union - get at flags individually, or as DWORD so they can be zapped
  377. //
  378. union {
  379. //
  380. // Flags - several bits of information gleaned from the response, such
  381. // as whether the server responded with a "connection: keep-alive", etc.
  382. //
  383. struct {
  384. DWORD Eof : 1; // we have received all response
  385. DWORD DownLevel : 1; // response is HTTP/0.9
  386. DWORD UpLevel : 1; // response is HTTP/1.0 or greater
  387. DWORD Http1_1Response : 1; // response is HTTP/1.1 or greater
  388. DWORD KeepAlive : 1; // response contains keep-alive header
  389. DWORD ConnCloseResponse : 1; // response contains connection: close header
  390. DWORD PersistServer : 1; // have persistent connection to server
  391. DWORD PersistProxy : 1; // have persistent connection to proxy
  392. DWORD Data : 1; // set if we have got to the data part
  393. DWORD ContentLength : 1; // set if we have parsed Content-Length
  394. DWORD ChunkEncoding : 1; // set if we have parsed a Transfer-Encoding: chunked
  395. DWORD BadNSServer : 1; // set when server is bogus NS 1.1
  396. DWORD ConnCloseChecked : 1; // set when we have checked for Connection: Close
  397. DWORD ConnCloseReq : 1; // set if Connection: Close in request headers
  398. DWORD ProxyConnCloseReq : 1; // set if Proxy-Connection: Close in request headers
  399. //DWORD CookieUI : 1; // set if we're doing Cookie UI
  400. } Flags;
  401. //
  402. // Dword - used in initialization and ReuseObject
  403. //
  404. DWORD Dword;
  405. } _Union;
  406. //
  407. // Filter, authentication related members.
  408. //
  409. AUTHCTX* _pAuthCtx; // authentication context
  410. AUTHCTX* _pTunnelAuthCtx; // context for nested request
  411. AUTH_CREDS* _pCreds; // AUTH_CREDS* for Basic, Digest authctxt
  412. union {
  413. struct {
  414. // AuthState: none, negotiate, challenge, or need tunnel.
  415. DWORD AuthState : 2;
  416. // TRUE if KA socket should be flushed with password cache.
  417. DWORD IsAuthorized : 1;
  418. // TRUE if this handle should ignore general proxy settings,
  419. // and use the proxy found in this object
  420. DWORD OverrideProxyMode : 1;
  421. // TRUE, if we are using a proxy to create a tunnel.
  422. DWORD IsTunnel : 1;
  423. // TRUE, if a method body is to be transmitted.
  424. DWORD MethodBody : 1;
  425. // TRUE, if NTLM preauth is to be disabled.
  426. DWORD DisableNTLMPreauth : 1;
  427. } Flags;
  428. //
  429. // Dword - used in initialization ONLY, do NOT use ELSEWHERE !
  430. //
  431. DWORD Dword;
  432. } _NoResetBits;
  433. //
  434. // Proxy, and Socks Proxy Information, used to decide if need to go through
  435. // a proxy, a socks proxy, or no proxy at all (NULLs).
  436. //
  437. LPSTR _ProxyHostName;
  438. DWORD _ProxyHostNameLength;
  439. INTERNET_PORT _ProxyPort;
  440. LPSTR _SocksProxyHostName;
  441. DWORD _SocksProxyHostNameLength;
  442. INTERNET_PORT _SocksProxyPort;
  443. //
  444. // _ProxySchemeType - Used to determine the proxy scheme, in proxy override mode.
  445. //
  446. //INTERNET_SCHEME _ProxySchemeType;
  447. //
  448. // InternetReadFileEx data
  449. //
  450. #ifndef unix
  451. DWORD _ReadFileExData;
  452. #else
  453. BYTE _ReadFileExData;
  454. #endif /* unix */
  455. BOOL _HaveReadFileExData;
  456. INTERNET_BUFFERS _BuffersOut;
  457. //
  458. // _AddCRLFToPost - TRUE if we need to add a CRLF to the POST.
  459. //
  460. BOOL _AddCRLFToPOST;
  461. //
  462. // info we used to keep in the secure socket object
  463. //
  464. SECURITY_CACHE_LIST_ENTRY *m_pSecurityInfo;
  465. //
  466. // _RTT - round-trip time for this request
  467. //
  468. DWORD _RTT;
  469. // Timeout and retry parameters
  470. DWORD _dwResolveTimeout;
  471. DWORD _dwConnectTimeout;
  472. DWORD _dwConnectRetries;
  473. DWORD _dwSendTimeout;
  474. DWORD _dwReceiveTimeout;
  475. // WinHttpSetOption enable feature flags
  476. DWORD _dwEnableFlags;
  477. // Helpers for synchronizing request work items
  478. BOOL _fAsyncFsmInProgress;
  479. CCritSec _AsyncCritSec;
  480. CTList<CFsm *> _FsmWorkItemList;
  481. //
  482. // private response functions
  483. //
  484. PRIVATE
  485. BOOL
  486. FindEndOfHeader(
  487. IN OUT LPSTR * lpszResponse,
  488. IN LPSTR lpszEnd,
  489. OUT LPDWORD lpdwHeaderLength
  490. );
  491. PRIVATE
  492. VOID
  493. CheckForWellKnownHeader(
  494. IN LPSTR lpszHeader,
  495. IN DWORD dwHeaderLength,
  496. IN DWORD iSlot
  497. );
  498. PRIVATE
  499. DWORD
  500. CheckWellKnownHeaders(
  501. VOID
  502. );
  503. VOID ZapFlags(VOID) {
  504. //
  505. // clear out all bits
  506. //
  507. _Union.Dword = 0;
  508. }
  509. public:
  510. HTTP_REQUEST_HANDLE_OBJECT(
  511. INTERNET_CONNECT_HANDLE_OBJECT *Parent,
  512. HINTERNET Child,
  513. CLOSE_HANDLE_FUNC wCloseFunc,
  514. DWORD dwFlags,
  515. DWORD_PTR dwContext
  516. );
  517. virtual ~HTTP_REQUEST_HANDLE_OBJECT(VOID);
  518. virtual HINTERNET_HANDLE_TYPE GetHandleType(VOID)
  519. {
  520. return TypeHttpRequestHandle;
  521. }
  522. //
  523. // request headers functions
  524. //
  525. DWORD
  526. AddRequest(
  527. IN LPSTR lpszVerb,
  528. IN LPSTR lpszObjectName,
  529. IN LPSTR lpszVersion
  530. ) {
  531. return _RequestHeaders.AddRequest(lpszVerb,
  532. lpszObjectName,
  533. lpszVersion
  534. );
  535. }
  536. DWORD
  537. ModifyRequest(
  538. IN HTTP_METHOD_TYPE tMethod,
  539. IN LPSTR lpszObjectName,
  540. IN DWORD dwObjectNameLength,
  541. IN LPSTR lpszVersion OPTIONAL,
  542. IN DWORD dwVersionLength
  543. ) {
  544. DWORD error;
  545. error = _RequestHeaders.ModifyRequest(tMethod,
  546. lpszObjectName,
  547. dwObjectNameLength,
  548. lpszVersion,
  549. dwVersionLength
  550. );
  551. if (error == ERROR_SUCCESS) {
  552. SetMethodType(tMethod);
  553. }
  554. return error;
  555. }
  556. BOOL PPAbort(void) const {
  557. return m_fPPAbortSend;
  558. }
  559. VOID SetPPAbort(BOOL fToAbort) {
  560. m_fPPAbortSend = fToAbort;
  561. }
  562. VOID SetMethodType(IN LPCSTR lpszVerb) {
  563. _RequestMethod = MapHttpRequestMethod(lpszVerb);
  564. }
  565. VOID SetMethodType(IN HTTP_METHOD_TYPE tMethod) {
  566. _RequestMethod = tMethod;
  567. }
  568. HTTP_METHOD_TYPE GetMethodType(VOID) const {
  569. return _RequestMethod;
  570. }
  571. LPSTR
  572. CreateRequestBuffer(
  573. OUT LPDWORD lpdwRequestLength,
  574. IN LPVOID lpOptional,
  575. IN DWORD dwOptionalLength,
  576. IN BOOL bExtraCrLf,
  577. IN DWORD dwMaxPacketLength,
  578. OUT LPBOOL lpbCombinedData
  579. );
  580. DWORD
  581. AddRequestHeader(
  582. IN LPSTR lpszHeaderName,
  583. IN DWORD dwHeaderNameLength,
  584. IN LPSTR lpszHeaderValue,
  585. IN DWORD dwHeaderValueLength,
  586. IN DWORD dwIndex,
  587. IN DWORD dwFlags
  588. ) {
  589. return _RequestHeaders.AddHeader(lpszHeaderName,
  590. dwHeaderNameLength,
  591. lpszHeaderValue,
  592. dwHeaderValueLength,
  593. dwIndex,
  594. dwFlags
  595. );
  596. }
  597. DWORD
  598. AddRequestHeader(
  599. IN DWORD dwQueryIndex,
  600. IN LPSTR lpszHeaderValue,
  601. IN DWORD dwHeaderValueLength,
  602. IN DWORD dwIndex,
  603. IN DWORD dwFlags
  604. ) {
  605. return _RequestHeaders.AddHeader(dwQueryIndex,
  606. lpszHeaderValue,
  607. dwHeaderValueLength,
  608. dwIndex,
  609. dwFlags
  610. );
  611. }
  612. DWORD
  613. ReplaceRequestHeader(
  614. IN LPSTR lpszHeaderName,
  615. IN DWORD dwHeaderNameLength,
  616. IN LPSTR lpszHeaderValue,
  617. IN DWORD dwHeaderValueLength,
  618. IN DWORD dwIndex,
  619. IN DWORD dwFlags
  620. ) {
  621. return _RequestHeaders.ReplaceHeader(lpszHeaderName,
  622. dwHeaderNameLength,
  623. lpszHeaderValue,
  624. dwHeaderValueLength,
  625. dwIndex,
  626. dwFlags
  627. );
  628. }
  629. DWORD
  630. ReplaceRequestHeader(
  631. IN DWORD dwQueryIndex,
  632. IN LPSTR lpszHeaderValue,
  633. IN DWORD dwHeaderValueLength,
  634. IN DWORD dwIndex,
  635. IN DWORD dwFlags
  636. ) {
  637. return _RequestHeaders.ReplaceHeader(dwQueryIndex,
  638. lpszHeaderValue,
  639. dwHeaderValueLength,
  640. dwIndex,
  641. dwFlags
  642. );
  643. }
  644. DWORD
  645. QueryRequestHeader(
  646. IN LPCSTR lpszHeaderName,
  647. IN DWORD dwHeaderNameLength,
  648. IN LPVOID lpBuffer,
  649. IN OUT LPDWORD lpdwBufferLength,
  650. IN DWORD dwModifiers,
  651. IN OUT LPDWORD lpdwIndex
  652. );
  653. DWORD
  654. QueryRequestHeader(
  655. IN DWORD dwQueryIndex,
  656. IN LPVOID lpBuffer,
  657. IN OUT LPDWORD lpdwBufferLength,
  658. IN DWORD dwModifiers,
  659. IN OUT LPDWORD lpdwIndex
  660. );
  661. //
  662. // response headers functions
  663. //
  664. VOID
  665. ReplaceStatusHeader(
  666. IN LPCSTR lpszStatus
  667. );
  668. DWORD
  669. ReplaceResponseHeader(
  670. IN DWORD dwQueryIndex,
  671. IN LPSTR lpszHeaderValue,
  672. IN DWORD dwHeaderValueLength,
  673. IN DWORD dwIndex,
  674. IN DWORD dwFlags)
  675. {
  676. return _ResponseHeaders.ReplaceHeader(dwQueryIndex,
  677. lpszHeaderValue,
  678. dwHeaderValueLength,
  679. dwIndex,
  680. dwFlags
  681. );
  682. }
  683. DWORD
  684. AddInternalResponseHeader(
  685. IN DWORD dwHeaderIndex,
  686. IN LPSTR lpszHeader,
  687. IN DWORD dwHeaderLength
  688. );
  689. DWORD
  690. UpdateResponseHeaders(
  691. IN OUT LPBOOL lpbEof
  692. );
  693. DWORD
  694. CreateResponseHeaders(
  695. IN OUT LPSTR* ppszBuffer,
  696. IN DWORD dwBufferLength
  697. );
  698. DWORD
  699. FindResponseHeader(
  700. IN LPSTR lpszHeaderName,
  701. OUT LPSTR lpBuffer,
  702. IN OUT LPDWORD lpdwBufferLength
  703. );
  704. DWORD
  705. QueryResponseVersionDword(
  706. IN OUT LPDWORD lpdwVersionMajor,
  707. IN OUT LPDWORD lpdwVersionMinor
  708. );
  709. DWORD
  710. QueryResponseVersion(
  711. IN LPVOID lpBuffer,
  712. IN OUT LPDWORD lpdwBufferLength
  713. );
  714. DWORD
  715. QueryStatusCode(
  716. IN LPVOID lpBuffer,
  717. IN OUT LPDWORD lpdwBufferLength,
  718. IN DWORD dwModifiers
  719. );
  720. DWORD
  721. QueryStatusText(
  722. IN LPVOID lpBuffer,
  723. IN OUT LPDWORD lpdwBufferLength
  724. );
  725. DWORD
  726. FastQueryResponseHeader(
  727. IN DWORD dwQueryIndex,
  728. OUT LPVOID *lplpBuffer,
  729. IN OUT LPDWORD lpdwBufferLength,
  730. IN OUT DWORD dwIndex
  731. )
  732. {
  733. return _ResponseHeaders.FastFindHeader(
  734. (LPSTR)_ResponseBuffer,
  735. dwQueryIndex,
  736. lplpBuffer,
  737. lpdwBufferLength,
  738. dwIndex
  739. );
  740. }
  741. DWORD
  742. FastQueryRequestHeader(
  743. IN DWORD dwQueryIndex,
  744. OUT LPVOID *lplpBuffer,
  745. IN OUT LPDWORD lpdwBufferLength,
  746. IN OUT DWORD dwIndex
  747. )
  748. {
  749. return _RequestHeaders.FastFindHeader(
  750. (LPSTR)_ResponseBuffer,
  751. dwQueryIndex,
  752. lplpBuffer,
  753. lpdwBufferLength,
  754. dwIndex
  755. );
  756. }
  757. DWORD
  758. QueryResponseHeader(
  759. IN LPCSTR lpszHeaderName,
  760. IN DWORD dwHeaderNameLength,
  761. IN LPVOID lpBuffer,
  762. IN OUT LPDWORD lpdwBufferLength,
  763. IN DWORD dwModifiers,
  764. IN OUT LPDWORD lpdwIndex
  765. )
  766. {
  767. //
  768. // this is the slow manner for finding a header, avoid doing this by calling
  769. // the faster method
  770. //
  771. return _ResponseHeaders.FindHeader((LPSTR)_ResponseBuffer,
  772. lpszHeaderName,
  773. dwHeaderNameLength,
  774. dwModifiers,
  775. lpBuffer,
  776. lpdwBufferLength,
  777. lpdwIndex
  778. );
  779. }
  780. DWORD
  781. QueryResponseHeader(
  782. IN DWORD dwQueryIndex,
  783. IN LPVOID lpBuffer,
  784. IN OUT LPDWORD lpdwBufferLength,
  785. IN DWORD dwModifiers,
  786. IN OUT LPDWORD lpdwIndex
  787. )
  788. {
  789. return _ResponseHeaders.FindHeader((LPSTR)_ResponseBuffer,
  790. dwQueryIndex,
  791. dwModifiers,
  792. lpBuffer,
  793. lpdwBufferLength,
  794. lpdwIndex
  795. );
  796. }
  797. BOOL IsResponseHeaderPresent(DWORD dwQueryIndex) const {
  798. return _ResponseHeaders.IsHeaderPresent(dwQueryIndex);
  799. }
  800. BOOL IsRequestHeaderPresent(DWORD dwQueryIndex) const {
  801. return _RequestHeaders.IsHeaderPresent(dwQueryIndex);
  802. }
  803. DWORD
  804. QueryRawResponseHeaders(
  805. IN BOOL bCrLfTerminated,
  806. OUT LPVOID lpBuffer,
  807. IN OUT LPDWORD lpdwBufferLength
  808. );
  809. HEADER_STRING * GetStatusLine(VOID) const {
  810. //
  811. // _StatusLine is just a reference for the first response header
  812. //
  813. return _ResponseHeaders.GetFirstHeader();
  814. }
  815. //
  816. // general headers methods
  817. //
  818. DWORD
  819. QueryInfo(
  820. IN DWORD dwInfoLevel,
  821. IN LPCSTR lpszName,
  822. OUT LPVOID lpBuffer,
  823. IN OUT LPDWORD lpdwBufferLength,
  824. IN OUT LPDWORD lpdwIndex
  825. );
  826. DWORD
  827. QueryFilteredRawResponseHeaders(
  828. LPSTR *lplpFilterList,
  829. DWORD cListElements,
  830. BOOL fExclude,
  831. BOOL fSkipVerb,
  832. BOOL bCrLfTerminated,
  833. OUT LPVOID lpBuffer,
  834. IN OUT LPDWORD lpdwBufferLength
  835. )
  836. {
  837. return (_ResponseHeaders.QueryFilteredRawHeaders(
  838. (LPSTR)_ResponseBuffer,
  839. lplpFilterList,
  840. cListElements,
  841. fExclude,
  842. fSkipVerb,
  843. bCrLfTerminated,
  844. lpBuffer,
  845. lpdwBufferLength));
  846. };
  847. DWORD
  848. QueryRequestHeadersWithEcho(
  849. BOOL bCrLfTerminated,
  850. OUT LPVOID lpBuffer,
  851. IN OUT LPDWORD lpdwBufferLength
  852. );
  853. //
  854. // connection-oriented methods
  855. //
  856. DWORD
  857. InitBeginSendRequest(
  858. IN LPCSTR lpszHeaders OPTIONAL,
  859. IN DWORD dwHeadersLength,
  860. IN LPVOID *lplpOptional,
  861. IN LPDWORD lpdwOptionalLength,
  862. IN DWORD dwOptionalLengthTotal
  863. );
  864. DWORD
  865. QueueAsyncSendRequest(
  866. IN LPVOID lpOptional OPTIONAL,
  867. IN DWORD dwOptionalLength,
  868. IN AR_TYPE arRequest,
  869. IN FARPROC lpfpAsyncCallback
  870. );
  871. DWORD
  872. HttpBeginSendRequest(
  873. IN LPVOID lpOptional OPTIONAL,
  874. IN DWORD dwOptionalLength
  875. );
  876. DWORD
  877. HttpEndSendRequest(
  878. VOID
  879. );
  880. DWORD
  881. SockConnect(
  882. IN LPSTR TargetServer,
  883. IN INTERNET_PORT TcpipPort,
  884. IN LPSTR SocksHostName,
  885. IN INTERNET_PORT SocksPort
  886. );
  887. DWORD
  888. OpenConnection(
  889. IN BOOL NoKeepAlive,
  890. IN BOOL fNoCreate = FALSE
  891. );
  892. DWORD
  893. OpenConnection_Fsm(
  894. IN CFsm_OpenConnection * Fsm
  895. );
  896. DWORD
  897. CloseConnection(
  898. IN BOOL ForceClosed
  899. );
  900. VOID
  901. ReleaseConnection(
  902. IN BOOL bClose,
  903. IN BOOL bIndicate,
  904. IN BOOL bDelete
  905. );
  906. DWORD
  907. AbortConnection(
  908. IN BOOL bForce
  909. );
  910. DWORD
  911. OpenProxyTunnel(
  912. VOID
  913. );
  914. DWORD
  915. OpenProxyTunnel_Fsm(
  916. IN CFsm_OpenProxyTunnel * Fsm
  917. );
  918. DWORD
  919. CloneResponseBuffer(
  920. IN HTTP_REQUEST_HANDLE_OBJECT *pChildRequestObj
  921. );
  922. DWORD
  923. HttpReadData_Fsm(
  924. IN CFsm_HttpReadData * Fsm
  925. );
  926. DWORD
  927. HttpWriteData_Fsm(
  928. IN CFsm_HttpWriteData * Fsm
  929. );
  930. DWORD
  931. ReadResponse(
  932. VOID
  933. );
  934. DWORD
  935. ReadData(
  936. OUT LPVOID lpBuffer,
  937. IN DWORD dwNumberOfBytesToRead,
  938. OUT LPDWORD lpdwNumberOfBytesRead,
  939. IN BOOL fNoAsync,
  940. IN DWORD dwSocketFlags
  941. );
  942. DWORD
  943. ReadData_Fsm(
  944. IN CFsm_ReadData * Fsm
  945. );
  946. DWORD
  947. WriteData(
  948. OUT LPVOID lpBuffer,
  949. IN DWORD dwNumberOfBytesToWrite,
  950. OUT LPDWORD lpdwNumberOfBytesWritten
  951. );
  952. DWORD
  953. QueryDataAvailable(
  954. OUT LPDWORD lpdwNumberOfBytesAvailable
  955. );
  956. DWORD
  957. QueryAvailable_Fsm(
  958. IN CFsm_HttpQueryAvailable * Fsm
  959. );
  960. DWORD
  961. DrainResponse(
  962. OUT LPBOOL lpbDrained
  963. );
  964. DWORD
  965. DrainResponse_Fsm(
  966. IN CFsm_DrainResponse * Fsm
  967. );
  968. DWORD
  969. Redirect(
  970. IN HTTP_METHOD_TYPE tMethod,
  971. IN BOOL fRedirectToProxy
  972. );
  973. DWORD
  974. Redirect_Fsm(
  975. IN CFsm_Redirect * Fsm
  976. );
  977. DWORD
  978. BuildProxyMessage(
  979. IN CFsm_HttpSendRequest * Fsm,
  980. AUTO_PROXY_ASYNC_MSG * pProxyMsg,
  981. IN OUT URL_COMPONENTS * pUrlComponents
  982. );
  983. DWORD
  984. QueryProxySettings(
  985. IN CFsm_HttpSendRequest * Fsm,
  986. INTERNET_HANDLE_OBJECT * pInternet,
  987. IN OUT URL_COMPONENTS * pUrlComponents
  988. );
  989. DWORD
  990. CheckForCachedProxySettings(
  991. IN AUTO_PROXY_ASYNC_MSG *pProxyMsg,
  992. OUT CServerInfo **ppProxyServerInfo
  993. );
  994. DWORD
  995. ProcessProxySettings(
  996. IN CFsm_HttpSendRequest * Fsm,
  997. IN OUT URL_COMPONENTS * pUrlComponents,
  998. OUT LPSTR * lplpszRequestObject,
  999. OUT DWORD * lpdwRequestObjectSize
  1000. );
  1001. DWORD
  1002. UpdateRequestInfo(
  1003. IN CFsm_HttpSendRequest * Fsm,
  1004. IN LPSTR lpszObject,
  1005. IN DWORD dwcbObject,
  1006. IN OUT URL_COMPONENTS * pUrlComponents,
  1007. IN OUT CServerInfo **ppProxyServerInfo
  1008. );
  1009. DWORD
  1010. UpdateProxyInfo(
  1011. IN CFsm_HttpSendRequest * Fsm,
  1012. IN BOOL fCallback
  1013. );
  1014. BOOL
  1015. FindConnCloseRequestHeader(
  1016. IN DWORD dwHeaderIndex
  1017. );
  1018. VOID
  1019. RemoveAllRequestHeadersByName(
  1020. IN DWORD dwQueryIndex
  1021. );
  1022. //
  1023. // response buffer/data methods
  1024. //
  1025. BOOL IsBufferedData(VOID) {
  1026. BOOL fIsBufferedData;
  1027. //INET_ASSERT(IsData());
  1028. fIsBufferedData = (_DataOffset < _BytesReceived) ? TRUE : FALSE;
  1029. if ( fIsBufferedData &&
  1030. IsChunkEncoding() &&
  1031. _ResponseBufferDataReadyToRead == 0 )
  1032. {
  1033. fIsBufferedData = FALSE;
  1034. }
  1035. return (fIsBufferedData);
  1036. }
  1037. DWORD BufferedDataLength(VOID) {
  1038. return (DWORD)(_BytesReceived - _DataOffset);
  1039. }
  1040. DWORD BufferDataAvailToRead(VOID) {
  1041. return ( IsChunkEncoding() ) ? _ResponseBufferDataReadyToRead : BufferedDataLength() ;
  1042. }
  1043. VOID ReduceDataAvailToRead(DWORD dwReduceBy)
  1044. {
  1045. if ( IsChunkEncoding() )
  1046. {
  1047. _ResponseBufferDataReadyToRead -= dwReduceBy;
  1048. }
  1049. //else
  1050. //{
  1051. _DataOffset += dwReduceBy;
  1052. //}
  1053. }
  1054. LPVOID BufferedDataStart(VOID) {
  1055. return (LPVOID)(_ResponseBuffer + _DataOffset);
  1056. }
  1057. VOID SetCookieQuery(DWORD QueryIndex) {
  1058. _dwQuerySetCookieHeader = QueryIndex;
  1059. }
  1060. DWORD GetCookieQuery(VOID) const {
  1061. return _dwQuerySetCookieHeader;
  1062. }
  1063. VOID SetContentLength(DWORD ContentLength) {
  1064. _ContentLength = ContentLength;
  1065. }
  1066. DWORD GetContentLength(VOID) const {
  1067. return _ContentLength;
  1068. }
  1069. DWORD GetBytesInSocket(VOID) const {
  1070. return _BytesInSocket;
  1071. }
  1072. DWORD GetBytesRemaining(VOID) const {
  1073. return _BytesRemaining;
  1074. }
  1075. DWORD GetStatusCode(VOID) const {
  1076. return _StatusCode;
  1077. }
  1078. void SetStatusCode(DWORD StatusCode) {
  1079. _StatusCode = StatusCode;
  1080. }
  1081. VOID FreeResponseBuffer(VOID) {
  1082. if (_ResponseBuffer != NULL) {
  1083. _ResponseBuffer = (LPBYTE)FREE_MEMORY((HLOCAL)_ResponseBuffer);
  1084. INET_ASSERT(_ResponseBuffer == NULL);
  1085. }
  1086. _ResponseBufferLength = 0;
  1087. _BytesReceived = 0;
  1088. _DataOffset = 0;
  1089. }
  1090. VOID FreeQueryBuffer(VOID) {
  1091. if (_QueryBuffer != NULL) {
  1092. _QueryBuffer = (LPVOID)FREE_MEMORY((HLOCAL)_QueryBuffer);
  1093. INET_ASSERT(_QueryBuffer == NULL);
  1094. _QueryBuffer = NULL;
  1095. _QueryBufferLength = 0;
  1096. _QueryOffset = 0;
  1097. _QueryBytesAvailable = 0;
  1098. }
  1099. }
  1100. BOOL HaveQueryData(VOID) {
  1101. return (_QueryBytesAvailable != 0) ? TRUE : FALSE;
  1102. }
  1103. DWORD CopyQueriedData(LPVOID lpBuffer, DWORD dwBufferLength) {
  1104. INET_ASSERT(lpBuffer != NULL);
  1105. INET_ASSERT(dwBufferLength != 0);
  1106. DWORD len = min(_QueryBytesAvailable, dwBufferLength);
  1107. if (len != 0) {
  1108. memcpy(lpBuffer,
  1109. (LPVOID)((LPBYTE)_QueryBuffer + _QueryOffset),
  1110. len
  1111. );
  1112. _QueryOffset += len;
  1113. _QueryBytesAvailable -= len;
  1114. }
  1115. return len;
  1116. }
  1117. VOID ResetResponseVariables(VOID) {
  1118. _StatusCode = 0;
  1119. _BytesReceived = 0;
  1120. _ResponseScanned = 0;
  1121. _ResponseBufferDataReadyToRead = 0;
  1122. _DataOffset = 0;
  1123. _BytesRemaining = 0;
  1124. _ContentLength = 0;
  1125. _BytesInSocket = 0;
  1126. ZapFlags();
  1127. }
  1128. DWORD GetBufferSize(IN DWORD SizeIndex) {
  1129. switch (SizeIndex) {
  1130. case WINHTTP_OPTION_READ_BUFFER_SIZE:
  1131. return _ReadBufferSize;
  1132. case WINHTTP_OPTION_WRITE_BUFFER_SIZE:
  1133. return _WriteBufferSize;
  1134. default:
  1135. //
  1136. // BUGBUG - global default
  1137. //
  1138. return (4 K);
  1139. }
  1140. }
  1141. VOID SetBufferSize(IN DWORD SizeIndex, IN DWORD Size) {
  1142. switch (SizeIndex) {
  1143. case WINHTTP_OPTION_READ_BUFFER_SIZE:
  1144. _ReadBufferSize = Size;
  1145. break;
  1146. case WINHTTP_OPTION_WRITE_BUFFER_SIZE:
  1147. _WriteBufferSize = Size;
  1148. break;
  1149. }
  1150. }
  1151. //
  1152. // flags methods
  1153. //
  1154. VOID SetEof(BOOL Value) {
  1155. _Union.Flags.Eof = Value ? 1 : 0;
  1156. }
  1157. BOOL IsEof(VOID) const {
  1158. return _Union.Flags.Eof;
  1159. }
  1160. VOID SetDownLevel(BOOL Value) {
  1161. _Union.Flags.DownLevel = Value ? 1 : 0;
  1162. }
  1163. BOOL IsDownLevel(VOID) const {
  1164. return _Union.Flags.DownLevel;
  1165. }
  1166. BOOL IsRequestHttp1_1() {
  1167. return (_RequestHeaders.MajorVersion() > 1)
  1168. ? TRUE
  1169. : (((_RequestHeaders.MajorVersion() == 1)
  1170. && (_RequestHeaders.MinorVersion() >= 1))
  1171. ? TRUE
  1172. : FALSE);
  1173. }
  1174. BOOL IsRequestHttp1_0() {
  1175. return ((_RequestHeaders.MajorVersion() == 1)
  1176. && (_RequestHeaders.MinorVersion() == 0));
  1177. }
  1178. VOID SetResponseHttp1_1(BOOL Value) {
  1179. _Union.Flags.Http1_1Response = Value ? 1 : 0;
  1180. }
  1181. BOOL IsResponseHttp1_1(VOID) const {
  1182. return _Union.Flags.Http1_1Response;
  1183. }
  1184. VOID SetUpLevel(BOOL Value) {
  1185. _Union.Flags.UpLevel = Value ? 1 : 0;
  1186. }
  1187. BOOL IsUpLevel(VOID) const {
  1188. return _Union.Flags.UpLevel;
  1189. }
  1190. VOID SetKeepAlive(BOOL Value) {
  1191. _Union.Flags.KeepAlive = Value ? 1 : 0;
  1192. }
  1193. BOOL IsKeepAlive(VOID) const {
  1194. return _Union.Flags.KeepAlive;
  1195. }
  1196. VOID SetConnCloseResponse(BOOL Value) {
  1197. _Union.Flags.ConnCloseResponse = Value ? 1 : 0;
  1198. }
  1199. BOOL IsConnCloseResponse(VOID) const {
  1200. return _Union.Flags.ConnCloseResponse;
  1201. }
  1202. VOID SetData(BOOL Value) {
  1203. _Union.Flags.Data = Value ? 1 : 0;
  1204. }
  1205. BOOL IsData(VOID) const {
  1206. return _Union.Flags.Data;
  1207. }
  1208. VOID SetOpenFlags(DWORD OpenFlags) {
  1209. _OpenFlags = OpenFlags;
  1210. }
  1211. DWORD GetOpenFlags(VOID) const {
  1212. return _OpenFlags;
  1213. }
  1214. VOID SetEnableFlags(DWORD dwEnableFlags) {
  1215. _dwEnableFlags = dwEnableFlags;
  1216. }
  1217. DWORD GetEnableFlags(VOID) const {
  1218. return _dwEnableFlags;
  1219. }
  1220. VOID SetHaveChunkEncoding(BOOL Value) {
  1221. _Union.Flags.ChunkEncoding = Value ? 1 : 0;
  1222. }
  1223. BOOL IsChunkEncoding(VOID) const {
  1224. return _Union.Flags.ChunkEncoding;
  1225. }
  1226. BOOL IsDecodingFinished(VOID) {
  1227. return _ResponseFilterList.IsFinished();
  1228. }
  1229. VOID SetHaveContentLength(BOOL Value) {
  1230. _Union.Flags.ContentLength = Value ? 1 : 0;
  1231. }
  1232. BOOL IsContentLength(VOID) const {
  1233. return _Union.Flags.ContentLength;
  1234. }
  1235. VOID SetBadNSServer(BOOL Value) {
  1236. _Union.Flags.BadNSServer = Value ? 1 : 0;
  1237. }
  1238. BOOL IsBadNSServer(VOID) const {
  1239. return _Union.Flags.BadNSServer ? TRUE : FALSE;
  1240. }
  1241. VOID SetCheckedConnCloseRequest(BOOL bProxy, BOOL bFound) {
  1242. _Union.Flags.ConnCloseChecked = 1;
  1243. if (bProxy) {
  1244. _Union.Flags.ProxyConnCloseReq = bFound ? 1 : 0;
  1245. } else {
  1246. _Union.Flags.ConnCloseReq = bFound ? 1 : 0;
  1247. }
  1248. }
  1249. BOOL CheckedConnCloseRequest(VOID) {
  1250. return (_Union.Flags.ConnCloseChecked == 1) ? TRUE : FALSE;
  1251. }
  1252. BOOL IsConnCloseRequest(BOOL bProxyHeader) {
  1253. return bProxyHeader
  1254. ? (_Union.Flags.ProxyConnCloseReq == 1)
  1255. : (_Union.Flags.ConnCloseReq == 1);
  1256. }
  1257. VOID
  1258. SetBadNSReceiveTimeout(
  1259. VOID
  1260. );
  1261. VOID SetOverrideProxyMode(BOOL Value) {
  1262. _NoResetBits.Flags.OverrideProxyMode = (Value ? TRUE : FALSE );
  1263. }
  1264. BOOL IsOverrideProxyMode() const {
  1265. return _NoResetBits.Flags.OverrideProxyMode;
  1266. }
  1267. VOID SetWantKeepAlive(BOOL Value) {
  1268. _bWantKeepAlive = Value;
  1269. }
  1270. BOOL IsWantKeepAlive(VOID) const {
  1271. return _bWantKeepAlive;
  1272. }
  1273. VOID SetAddCRLF(BOOL Value) {
  1274. _AddCRLFToPOST = Value;
  1275. }
  1276. //
  1277. // Bit to distinguish nested request for establishing a tunnel.
  1278. //
  1279. VOID SetTunnel (VOID) {
  1280. _NoResetBits.Flags.IsTunnel = 1;
  1281. }
  1282. BOOL IsTunnel(VOID) const {
  1283. return (BOOL) _NoResetBits.Flags.IsTunnel;
  1284. }
  1285. //
  1286. // secure (socket) methods
  1287. //
  1288. VOID SetSecureFlags(DWORD Flags) {
  1289. if(m_pSecurityInfo)
  1290. {
  1291. m_pSecurityInfo->SetSecureFlags(Flags);
  1292. }
  1293. }
  1294. VOID SetSecurityLevel(DWORD SecurityLevel) {
  1295. _SecurityLevel = SecurityLevel;
  1296. }
  1297. DWORD GetSecureFlags(VOID) {
  1298. if(m_pSecurityInfo)
  1299. {
  1300. return m_pSecurityInfo->GetSecureFlags();
  1301. }
  1302. return 0;
  1303. }
  1304. VOID SetStatusFlags(DWORD Flags)
  1305. {
  1306. if(m_pSecurityInfo)
  1307. {
  1308. m_pSecurityInfo->SetStatusFlags(Flags);
  1309. }
  1310. }
  1311. DWORD GetStatusFlags(VOID)
  1312. {
  1313. if(m_pSecurityInfo)
  1314. {
  1315. return m_pSecurityInfo->GetStatusFlags();
  1316. }
  1317. return 0;
  1318. }
  1319. DWORD GetSecurityLevel(VOID) {
  1320. return _SecurityLevel;
  1321. }
  1322. BOOL LockHeaders(VOID) {
  1323. return _RequestHeaders.LockHeaders();
  1324. }
  1325. VOID UnlockHeaders(VOID) {
  1326. _RequestHeaders.UnlockHeaders();
  1327. }
  1328. //
  1329. // GetCertChainList (and)
  1330. // SetCertChainList -
  1331. // Sets and Gets Client Authentication Cert Chains.
  1332. //
  1333. CERT_CONTEXT_ARRAY* GetCertContextArray(VOID) {
  1334. if(m_pSecurityInfo)
  1335. {
  1336. return m_pSecurityInfo->GetCertContextArray();
  1337. }
  1338. return NULL;
  1339. }
  1340. VOID SetCertContextArray(CERT_CONTEXT_ARRAY* pNewCertContextArray) {
  1341. if(m_pSecurityInfo)
  1342. {
  1343. m_pSecurityInfo->SetCertContextArray(pNewCertContextArray);
  1344. }
  1345. }
  1346. //
  1347. // function to get SSL Certificate Information
  1348. //
  1349. DWORD GetSecurityInfo(LPINTERNET_SECURITY_INFO pInfo) {
  1350. if(m_pSecurityInfo)
  1351. {
  1352. m_pSecurityInfo->CopyOut(*pInfo);
  1353. return ERROR_SUCCESS;
  1354. }
  1355. else
  1356. {
  1357. return ERROR_WINHTTP_INTERNAL_ERROR;
  1358. }
  1359. }
  1360. //
  1361. // authentication related methods
  1362. //
  1363. VOID SetAuthCtx (AUTHCTX *pAuthCtx) {
  1364. _pAuthCtx = pAuthCtx;
  1365. }
  1366. AUTHCTX* GetAuthCtx (VOID) {
  1367. return _pAuthCtx;
  1368. }
  1369. VOID SetCreds (AUTH_CREDS *pCreds) {
  1370. _pCreds = pCreds;
  1371. }
  1372. AUTH_CREDS* GetCreds (VOID) {
  1373. return _pCreds;
  1374. }
  1375. AUTHCTX* GetTunnelAuthCtx (VOID) {
  1376. return _pTunnelAuthCtx;
  1377. }
  1378. BOOL SilentLogonOK(PSTR pszHost)
  1379. {
  1380. if ( !_stricmp(pszHost, "localhost")
  1381. || !_stricmp(pszHost, "loopback")
  1382. || ! strcmp(pszHost, "127.0.0.1")
  1383. )
  1384. {
  1385. return TRUE;
  1386. }
  1387. if (_SecurityLevel == WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW)
  1388. {
  1389. return TRUE;
  1390. }
  1391. if (_SecurityLevel == WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH)
  1392. {
  1393. return FALSE;
  1394. }
  1395. if (_SecurityLevel == WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM)
  1396. {
  1397. if (g_pGlobalProxyInfo->HostBypassesProxy(INTERNET_SCHEME_HTTP, pszHost, strlen(pszHost)))
  1398. {
  1399. return TRUE;
  1400. }
  1401. else
  1402. {
  1403. return FALSE;
  1404. }
  1405. }
  1406. return FALSE;
  1407. }
  1408. DWORD GetAuthState (void) {
  1409. return _NoResetBits.Flags.AuthState;
  1410. }
  1411. void SetAuthState (DWORD dw) {
  1412. INET_ASSERT( dw <= AUTHSTATE_LAST );
  1413. _NoResetBits.Flags.AuthState = dw;
  1414. }
  1415. void SetAuthorized (void) {
  1416. _NoResetBits.Flags.IsAuthorized = 1;
  1417. }
  1418. BOOL IsAuthorized (void) {
  1419. return _NoResetBits.Flags.IsAuthorized;
  1420. }
  1421. void SetMethodBody (void) {
  1422. _NoResetBits.Flags.MethodBody = 1;
  1423. }
  1424. BOOL IsMethodBody (void) {
  1425. return _NoResetBits.Flags.MethodBody;
  1426. }
  1427. void SetDisableNTLMPreauth (BOOL fVal) {
  1428. _NoResetBits.Flags.DisableNTLMPreauth = (DWORD) (fVal ? TRUE : FALSE);
  1429. }
  1430. BOOL IsDisableNTLMPreauth (void) {
  1431. return _NoResetBits.Flags.DisableNTLMPreauth;
  1432. }
  1433. BOOL GetUserAndPass (BOOL fProxy, LPSTR *pszUser, LPSTR *pszPass);
  1434. LPSTR GetProp (DWORD nIndex)
  1435. {
  1436. INET_ASSERT (nIndex < NUM_INTERNET_STRING_OPTION);
  1437. return _xsProp[nIndex].GetPtr();
  1438. }
  1439. BOOL SetProp (DWORD nIndex, LPSTR pszIn)
  1440. {
  1441. INET_ASSERT (pszIn);
  1442. INET_ASSERT (nIndex < NUM_INTERNET_STRING_OPTION);
  1443. return _xsProp[nIndex].SetData(pszIn);
  1444. }
  1445. VOID FreeURL(VOID)
  1446. {
  1447. if (_CacheUrlName != NULL)
  1448. {
  1449. _CacheUrlName = (LPSTR)FREE_MEMORY(_CacheUrlName);
  1450. INET_ASSERT(_CacheUrlName == NULL);
  1451. }
  1452. }
  1453. LPSTR GetURL(VOID)
  1454. {
  1455. return _CacheUrlName;
  1456. }
  1457. BOOL SetURL(LPSTR lpszUrl);
  1458. BOOL SetURLPtr(LPSTR* ppszUrl);
  1459. //
  1460. // proxy methods
  1461. //
  1462. VOID SetViaProxy(BOOL bValue) {
  1463. _bViaProxy = bValue? 1 : 0;
  1464. }
  1465. BOOL IsViaProxy(VOID) const {
  1466. return _bViaProxy;
  1467. }
  1468. BOOL IsTalkingToSecureServerViaProxy(VOID) const {
  1469. return _fTalkingToSecureServerViaProxy;
  1470. }
  1471. VOID SetIsTalkingToSecureServerViaProxy(BOOL fTalkingToSecureServerViaProxy) {
  1472. _fTalkingToSecureServerViaProxy = fTalkingToSecureServerViaProxy;
  1473. }
  1474. VOID SetRequestUsingProxy(BOOL fRequestUsingProxy) {
  1475. _fRequestUsingProxy = fRequestUsingProxy;
  1476. }
  1477. BOOL IsRequestUsingProxy(VOID) const {
  1478. return _fRequestUsingProxy;
  1479. }
  1480. VOID
  1481. GetProxyName(
  1482. OUT LPSTR* lplpszProxyHostName,
  1483. OUT LPDWORD lpdwProxyHostNameLength,
  1484. OUT LPINTERNET_PORT lpProxyPort
  1485. );
  1486. VOID
  1487. SetProxyName(
  1488. IN LPSTR lpszProxyHostName,
  1489. IN DWORD dwProxyHostNameLength,
  1490. IN INTERNET_PORT ProxyPort
  1491. );
  1492. VOID
  1493. GetSocksProxyName(
  1494. LPSTR *lplpszProxyHostName,
  1495. DWORD *lpdwProxyHostNameLength,
  1496. LPINTERNET_PORT lpProxyPort
  1497. )
  1498. {
  1499. *lplpszProxyHostName = _SocksProxyHostName;
  1500. *lpdwProxyHostNameLength = _SocksProxyHostNameLength;
  1501. *lpProxyPort = _SocksProxyPort;
  1502. }
  1503. VOID
  1504. SetSocksProxyName(
  1505. LPSTR lpszProxyHostName,
  1506. DWORD dwProxyHostNameLength,
  1507. INTERNET_PORT ProxyPort
  1508. )
  1509. {
  1510. _SocksProxyHostName = lpszProxyHostName;
  1511. _SocksProxyHostNameLength = dwProxyHostNameLength;
  1512. _SocksProxyPort = ProxyPort;
  1513. }
  1514. VOID ClearPersistentConnection (VOID) {
  1515. _Union.Flags.PersistProxy = 0;
  1516. _Union.Flags.PersistServer = 0;
  1517. }
  1518. VOID SetPersistentConnection (BOOL fProxy) {
  1519. if (fProxy) {
  1520. _Union.Flags.PersistProxy = 1;
  1521. } else {
  1522. _Union.Flags.PersistServer = 1;
  1523. }
  1524. }
  1525. BOOL IsPersistentConnection (BOOL fProxy) {
  1526. return fProxy ?
  1527. _Union.Flags.PersistProxy : _Union.Flags.PersistServer;
  1528. }
  1529. //
  1530. // functions to get/set state
  1531. //
  1532. VOID SetState(HTTPREQ_STATE NewState) {
  1533. DEBUG_PRINT(HTTP,
  1534. INFO,
  1535. ("SetState(): current state %#x [%s], new state %#x [%s]\n",
  1536. _State,
  1537. InternetMapHttpState(_State),
  1538. NewState,
  1539. InternetMapHttpState(NewState)
  1540. ));
  1541. // Preserve state flags that transcend beyond a particular state.
  1542. _State = (NewState | (_State & HTTPREQ_FLAG_MASK));
  1543. }
  1544. WORD GetState() {
  1545. return (_State & ~HTTPREQ_FLAG_MASK);
  1546. }
  1547. BOOL CheckState(WORD Flag) {
  1548. DEBUG_PRINT(HTTP,
  1549. INFO,
  1550. ("CheckState(): current state %#x [%s], checking %#x [%s] - %B\n",
  1551. _State,
  1552. InternetMapHttpState(_State),
  1553. Flag,
  1554. InternetMapHttpStateFlag(Flag),
  1555. (_State & Flag) ? TRUE : FALSE
  1556. ));
  1557. return (_State & Flag) ? TRUE : FALSE;
  1558. }
  1559. BOOL CheckReceiveResponseState()
  1560. {
  1561. DEBUG_PRINT(HTTP,
  1562. INFO,
  1563. ("CheckReceiveResponseState(): current recv response - %B\n",
  1564. _State,
  1565. InternetMapHttpState(_State),
  1566. (_State & HTTPREQ_FLAG_RECV_RESPONSE_CALLED) ? TRUE : FALSE
  1567. ));
  1568. return (_State & HTTPREQ_FLAG_RECV_RESPONSE_CALLED) ? TRUE : FALSE;
  1569. }
  1570. VOID SetReceiveResponseState(BOOL fCalled)
  1571. {
  1572. DEBUG_PRINT(HTTP,
  1573. INFO,
  1574. ("SetReceiveResponseState(): current recv response state %B - %B\n",
  1575. (_State & HTTPREQ_FLAG_RECV_RESPONSE_CALLED) ? TRUE : FALSE,
  1576. fCalled
  1577. ));
  1578. _State = fCalled ? (_State | HTTPREQ_FLAG_RECV_RESPONSE_CALLED) :
  1579. (_State & ~HTTPREQ_FLAG_RECV_RESPONSE_CALLED);
  1580. }
  1581. BOOL CheckWriteDataNeeded()
  1582. {
  1583. DEBUG_PRINT(HTTP,
  1584. INFO,
  1585. ("CheckWriteDataNeeded(): current write data state - %B\n",
  1586. _State,
  1587. InternetMapHttpState(_State),
  1588. (_State & HTTPREQ_FLAG_WRITE_DATA_NEEDED) ? TRUE : FALSE
  1589. ));
  1590. return (_State & HTTPREQ_FLAG_WRITE_DATA_NEEDED) ? TRUE : FALSE;
  1591. }
  1592. VOID SetWriteDataNeeded(BOOL fNeeded)
  1593. {
  1594. DEBUG_PRINT(HTTP,
  1595. INFO,
  1596. ("SetWriteDataNeeded(): current write data state %B - %B\n",
  1597. (_State & HTTPREQ_FLAG_WRITE_DATA_NEEDED) ? TRUE : FALSE,
  1598. fNeeded
  1599. ));
  1600. _State = fNeeded ? (_State | HTTPREQ_FLAG_WRITE_DATA_NEEDED) :
  1601. (_State & ~HTTPREQ_FLAG_WRITE_DATA_NEEDED);
  1602. }
  1603. VOID
  1604. ReuseObject(
  1605. VOID
  1606. );
  1607. DWORD
  1608. ResetObject(
  1609. IN BOOL bForce,
  1610. IN BOOL bFreeRequestHeaders
  1611. );
  1612. VOID SetNoLongerKeepAlive(VOID) {
  1613. _bNoLongerKeepAlive = TRUE;
  1614. }
  1615. BOOL IsNoLongerKeepAlive(VOID) const {
  1616. return _bNoLongerKeepAlive;
  1617. }
  1618. //
  1619. // send.cxx methods
  1620. //
  1621. DWORD
  1622. HttpSendRequest_Start(
  1623. IN CFsm_HttpSendRequest * Fsm
  1624. );
  1625. DWORD
  1626. HttpSendRequest_Finish(
  1627. IN CFsm_HttpSendRequest * Fsm
  1628. );
  1629. DWORD
  1630. MakeConnection_Fsm(
  1631. IN CFsm_MakeConnection * Fsm
  1632. );
  1633. DWORD
  1634. SendRequest_Fsm(
  1635. IN CFsm_SendRequest * Fsm
  1636. );
  1637. DWORD
  1638. ReceiveResponse_Fsm(
  1639. IN CFsm_ReceiveResponse * Fsm
  1640. );
  1641. LPINTERNET_BUFFERS SetReadFileEx(VOID) {
  1642. _BuffersOut.lpvBuffer = (LPVOID)&_ReadFileExData;
  1643. //
  1644. // receive ONE byte
  1645. //
  1646. _BuffersOut.dwBufferLength = 1;
  1647. return &_BuffersOut;
  1648. }
  1649. VOID SetReadFileExData(VOID) {
  1650. _HaveReadFileExData = TRUE;
  1651. }
  1652. VOID ResetReadFileExData(VOID) {
  1653. _HaveReadFileExData = FALSE;
  1654. }
  1655. BOOL HaveReadFileExData(VOID) {
  1656. return _HaveReadFileExData;
  1657. }
  1658. BYTE GetReadFileExData(VOID) {
  1659. ResetReadFileExData();
  1660. return (BYTE)_ReadFileExData;
  1661. }
  1662. //
  1663. // cookie.cxx methods
  1664. //
  1665. int
  1666. CreateCookieHeaderIfNeeded(
  1667. VOID
  1668. );
  1669. DWORD
  1670. ExtractSetCookieHeaders(
  1671. LPDWORD lpdwHeaderIndex
  1672. );
  1673. //
  1674. // priority methods
  1675. //
  1676. LONG GetPriority(VOID) const {
  1677. return m_lPriority;
  1678. }
  1679. VOID SetPriority(LONG lPriority) {
  1680. m_lPriority = lPriority;
  1681. }
  1682. //
  1683. // Round Trip Time methods
  1684. //
  1685. VOID StartRTT(VOID) {
  1686. _RTT = GetTickCountWrap();
  1687. }
  1688. VOID UpdateRTT(VOID) {
  1689. _RTT = (GetTickCountWrap() - _RTT);
  1690. CServerInfo * pServerInfo = GetOriginServer();
  1691. if (pServerInfo != NULL) {
  1692. pServerInfo->UpdateRTT(_RTT);
  1693. }
  1694. }
  1695. DWORD GetRTT(VOID) const {
  1696. return _RTT;
  1697. }
  1698. VOID SetAuthenticated();
  1699. BOOL IsAuthenticated();
  1700. //
  1701. // diagnostic info
  1702. //
  1703. SOCKET GetSocket(VOID) {
  1704. return (_Socket != NULL) ? _Socket->GetSocket() : INVALID_SOCKET;
  1705. }
  1706. DWORD GetSourcePort(VOID) {
  1707. return (_Socket != NULL) ? _Socket->GetSourcePort() : 0;
  1708. }
  1709. DWORD GetDestPort(VOID) {
  1710. return (_Socket != NULL) ? _Socket->GetPort() : 0;
  1711. }
  1712. BOOL FromKeepAlivePool(VOID) const {
  1713. return _bKeepAliveConnection;
  1714. }
  1715. BOOL IsSecure(VOID) {
  1716. return (_Socket != NULL) ? _Socket->IsSecure() : FALSE;
  1717. }
  1718. BOOL SetTimeout(DWORD dwTimeoutOption, DWORD dwTimeoutValue);
  1719. DWORD GetTimeout(DWORD dwTimeoutOption);
  1720. BOOL SetTimeouts(
  1721. IN DWORD dwResolveTimeout,
  1722. IN DWORD dwConnectTimeout,
  1723. IN DWORD dwSendTimeout,
  1724. IN DWORD dwReceiveTimeout
  1725. );
  1726. DWORD
  1727. SetObjectName(
  1728. IN LPSTR lpszObjectName,
  1729. IN LPSTR lpszExtension,
  1730. IN URLGEN_FUNC * procProtocolUrl
  1731. );
  1732. CServerInfo * GetServerInfo(VOID) const {
  1733. return _ServerInfo;
  1734. }
  1735. CServerInfo * GetOriginServer(VOID) const {
  1736. return (_OriginServer != NULL) ? _OriginServer : _ServerInfo;
  1737. }
  1738. VOID
  1739. SetOriginServer(
  1740. IN CServerInfo * pServerInfo
  1741. );
  1742. VOID SetOriginServer(VOID) {
  1743. SetOriginServer(_ServerInfo);
  1744. }
  1745. DWORD
  1746. SetServerInfo(
  1747. CServerInfo * pReferencedServerInfo
  1748. )
  1749. {
  1750. if (_ServerInfo != NULL) {
  1751. ::ReleaseServerInfo(_ServerInfo);
  1752. }
  1753. //
  1754. // WARNING:: THIS ASSUMES a pre-referenced
  1755. // ServerInfo
  1756. //
  1757. _ServerInfo = pReferencedServerInfo;
  1758. return ERROR_SUCCESS;
  1759. }
  1760. DWORD
  1761. SetServerInfo(
  1762. IN LPSTR lpszServerName,
  1763. IN DWORD dwServerNameLength
  1764. );
  1765. DWORD
  1766. SetServerInfo(
  1767. IN BOOL bDoResolution,
  1768. IN OPTIONAL BOOL fNtlm = FALSE
  1769. ) {
  1770. return SetServerInfoWithScheme(GetSchemeType(), bDoResolution, fNtlm);
  1771. }
  1772. DWORD
  1773. SetServerInfoWithScheme(
  1774. IN INTERNET_SCHEME tScheme,
  1775. IN BOOL bDoResolution,
  1776. IN OPTIONAL BOOL fNtlm = FALSE
  1777. );
  1778. BOOL LockAsync()
  1779. {
  1780. return _AsyncCritSec.Lock();
  1781. }
  1782. VOID UnlockAsync()
  1783. {
  1784. return _AsyncCritSec.Unlock();
  1785. }
  1786. VOID SetWorkItemInProgress(BOOL fBusy)
  1787. {
  1788. _fAsyncFsmInProgress = fBusy;
  1789. }
  1790. BOOL IsWorkItemInProgress()
  1791. {
  1792. return _fAsyncFsmInProgress;
  1793. }
  1794. BOOL IsWorkItemListEmpty()
  1795. {
  1796. return (_FsmWorkItemList.GetCount() == 0 ? TRUE : FALSE);
  1797. }
  1798. DWORD ScheduleWorkItem();
  1799. DWORD BlockWorkItem(CFsm *pFsm)
  1800. {
  1801. DEBUG_ENTER((DBG_ASYNC,
  1802. Dword,
  1803. "HTTP_REQUEST_HANDLE_OBJECT::BlockWorkItem",
  1804. NULL
  1805. ));
  1806. DWORD dwError = ERROR_NOT_ENOUGH_MEMORY;
  1807. if (_FsmWorkItemList.AddToTail(pFsm))
  1808. {
  1809. DEBUG_PRINT(ASYNC,
  1810. INFO,
  1811. ("Blocked work item %#x with %d blocked async work items remaining\n",
  1812. pFsm,
  1813. _FsmWorkItemList.GetCount()
  1814. ));
  1815. dwError = ERROR_SUCCESS;
  1816. }
  1817. DEBUG_LEAVE(dwError);
  1818. return dwError;
  1819. }
  1820. VOID FlushWorkItemList()
  1821. {
  1822. DEBUG_ENTER((DBG_ASYNC,
  1823. Dword,
  1824. "HTTP_REQUEST_HANDLE_OBJECT::FlushWorkItemList",
  1825. NULL
  1826. ));
  1827. if (LockAsync())
  1828. {
  1829. while (_FsmWorkItemList.GetCount() > 0)
  1830. {
  1831. ScheduleWorkItem();
  1832. }
  1833. UnlockAsync();
  1834. }
  1835. DEBUG_LEAVE(0);
  1836. }
  1837. VOID SetWriteRequired(BOOL bIsWriteRequired)
  1838. {
  1839. _bIsWriteRequired = bIsWriteRequired;
  1840. }
  1841. BOOL IsWriteRequired()
  1842. {
  1843. return _bIsWriteRequired;
  1844. }
  1845. };