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.

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