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.

1064 lines
24 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. http.cxx
  5. Abstract:
  6. Contains methods for HTTP_REQUEST_HANDLE_OBJECT class
  7. Contents:
  8. RMakeHttpReqObjectHandle
  9. HTTP_REQUEST_HANDLE_OBJECT::HTTP_REQUEST_HANDLE_OBJECT
  10. HTTP_REQUEST_HANDLE_OBJECT::~HTTP_REQUEST_HANDLE_OBJECT
  11. HTTP_REQUEST_HANDLE_OBJECT::SetProxyName
  12. HTTP_REQUEST_HANDLE_OBJECT::GetProxyName
  13. HTTP_REQUEST_HANDLE_OBJECT::ReuseObject
  14. HTTP_REQUEST_HANDLE_OBJECT::ResetObject
  15. HTTP_REQUEST_HANDLE_OBJECT::SetAuthenticated
  16. HTTP_REQUEST_HANDLE_OBJECT::IsAuthenticated
  17. Author:
  18. Madan Appiah (madana) 16-Nov-1994
  19. Environment:
  20. User Mode - Win32
  21. Revision History:
  22. Sophia Chung (sophiac) 14-Feb-1995 (added FTP and Archie class impl.)
  23. (code adopted from madana)
  24. --*/
  25. #include <wininetp.h>
  26. //
  27. // functions
  28. //
  29. DWORD
  30. RMakeHttpReqObjectHandle(
  31. IN HINTERNET ParentHandle,
  32. IN OUT HINTERNET * ChildHandle,
  33. IN CLOSE_HANDLE_FUNC wCloseFunc,
  34. IN DWORD dwFlags,
  35. IN DWORD_PTR dwContext
  36. )
  37. /*++
  38. Routine Description:
  39. C-callable wrapper for creating an HTTP_REQUEST_HANDLE_OBJECT
  40. Arguments:
  41. ParentHandle - mapped address of parent (connect) handle
  42. ChildHandle - IN: protocol-specific handle value associated with object
  43. *** NOT USED FOR HTTP ***
  44. OUT: mapped address of HTTP_REQUEST_HANDLE_OBJECT
  45. wCloseFunc - address of protocol-specific function to be called when
  46. object is closed
  47. *** NOT USED FOR HTTP ***
  48. dwFlags - app-supplied flags
  49. dwContext - app-supplied context value
  50. Return Value:
  51. DWORD
  52. Success - ERROR_SUCCESS
  53. Failure - ERROR_NOT_ENOUGH_MEMORY
  54. --*/
  55. {
  56. DWORD error;
  57. HTTP_REQUEST_HANDLE_OBJECT * hHttp;
  58. hHttp = New HTTP_REQUEST_HANDLE_OBJECT(
  59. (INTERNET_CONNECT_HANDLE_OBJECT *)ParentHandle,
  60. *ChildHandle,
  61. wCloseFunc,
  62. dwFlags,
  63. dwContext
  64. );
  65. if (hHttp != NULL) {
  66. error = hHttp->GetStatus();
  67. if (error == ERROR_SUCCESS) {
  68. //
  69. // inform the app of the new handle
  70. //
  71. error = InternetIndicateStatusNewHandle((LPVOID)hHttp);
  72. //
  73. // ERROR_WINHTTP_OPERATION_CANCELLED is the only error that we are
  74. // expecting here. If we get this error then the app has cancelled
  75. // the operation. Either way, the handle we just generated will be
  76. // already deleted
  77. //
  78. if (error != ERROR_SUCCESS) {
  79. INET_ASSERT(error == ERROR_WINHTTP_OPERATION_CANCELLED);
  80. hHttp = NULL;
  81. }
  82. } else {
  83. delete hHttp;
  84. hHttp = NULL;
  85. }
  86. } else {
  87. error = ERROR_NOT_ENOUGH_MEMORY;
  88. }
  89. *ChildHandle = (HINTERNET)hHttp;
  90. return error;
  91. }
  92. //
  93. // HTTP_REQUEST_HANDLE_OBJECT class implementation
  94. //
  95. HTTP_REQUEST_HANDLE_OBJECT::HTTP_REQUEST_HANDLE_OBJECT(
  96. INTERNET_CONNECT_HANDLE_OBJECT * Parent,
  97. HINTERNET Child,
  98. CLOSE_HANDLE_FUNC wCloseFunc,
  99. DWORD dwFlags,
  100. DWORD_PTR dwContext
  101. ) : INTERNET_CONNECT_HANDLE_OBJECT(Parent)
  102. /*++
  103. Routine Description:
  104. Constructor for direct-to-net HTTP_REQUEST_HANDLE_OBJECT
  105. Arguments:
  106. Parent - parent object
  107. Child - IN: HTTPREQ structure pointer
  108. OUT: pointer to created HTTP_REQUEST_HANDLE_OBJECT
  109. wCloseFunc - address of function that closes/destroys HTTPREQ structure
  110. dwFlags - open flags (e.g. INTERNET_FLAG_RELOAD)
  111. dwContext - caller-supplied request context value
  112. Return Value:
  113. None.
  114. --*/
  115. {
  116. if (g_pAsyncCount)
  117. {
  118. if (Parent && Parent->IsAsyncHandle())
  119. {
  120. g_pAsyncCount->AddRef();
  121. }
  122. }
  123. else
  124. {
  125. RIP(FALSE);
  126. }
  127. _pProxyCreds = NULL;
  128. _pServerCreds = NULL;
  129. _PreferredScheme = 0;
  130. _SupportedSchemes = 0;
  131. _AuthTarget = 0;
  132. _SecurityLevel = WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM;
  133. _pszRealm = NULL;
  134. _Context = dwContext;
  135. _Socket = NULL;
  136. _QueryBuffer = NULL;
  137. _QueryBufferLength = 0;
  138. _QueryOffset = 0;
  139. _QueryBytesAvailable = 0;
  140. _bKeepAliveConnection = FALSE;
  141. _bNoLongerKeepAlive = FALSE;
  142. _OpenFlags = dwFlags | INTERNET_FLAG_KEEP_CONNECTION;
  143. _State = HttpRequestStateCreating;
  144. _RequestMethod = HTTP_METHOD_TYPE_UNKNOWN;
  145. _dwOptionalSaved = 0;
  146. _lpOptionalSaved = NULL;
  147. _fOptionalSaved = FALSE;
  148. _bIsWriteRequired = FALSE;
  149. _ResponseBuffer = NULL;
  150. _ResponseBufferLength = 0;
  151. ResetResponseVariables();
  152. _RequestHeaders.SetIsRequestHeaders(TRUE);
  153. _ResponseHeaders.SetIsRequestHeaders(FALSE);
  154. _fTalkingToSecureServerViaProxy = FALSE;
  155. _bViaProxy = 0;
  156. _fRequestUsingProxy = FALSE;
  157. _bWantKeepAlive = FALSE;
  158. _ServerInfo = NULL;
  159. _OriginServer = NULL;
  160. SetServerInfoWithScheme(INTERNET_SCHEME_HTTP, FALSE);
  161. //
  162. // set the read/write buffer sizes to the default values (4K)
  163. //
  164. _ReadBufferSize = (4 K);
  165. _WriteBufferSize = (4 K);
  166. _CacheUrlName = NULL;
  167. SetObjectType(TypeHttpRequestHandle);
  168. _pAuthCtx = NULL;
  169. _pTunnelAuthCtx = NULL;
  170. _pCreds = NULL;
  171. _NoResetBits.Dword = 0; // only here are we ever allowed to assign to Dword.
  172. SetDisableNTLMPreauth(GlobalDisableNTLMPreAuth);
  173. _ProxyHostName = NULL;
  174. _ProxyHostNameLength = NULL;
  175. _ProxyPort = INTERNET_INVALID_PORT_NUMBER;
  176. _SocksProxyHostName = NULL;
  177. _SocksProxyHostNameLength = NULL;
  178. _SocksProxyPort = INTERNET_INVALID_PORT_NUMBER;
  179. _HaveReadFileExData = FALSE;
  180. memset(&_BuffersOut, 0, sizeof(_BuffersOut));
  181. _BuffersOut.dwStructSize = sizeof(_BuffersOut);
  182. _BuffersOut.lpvBuffer = (LPVOID)&_ReadFileExData;
  183. m_fPPAbortSend = FALSE;
  184. _dwEnableFlags = 0;
  185. SetPriority(0);
  186. #ifdef RLF_TEST_CODE
  187. static long l = 0;
  188. SetPriority(l++);
  189. #endif
  190. _RTT = 0;
  191. if (_Status == ERROR_SUCCESS) {
  192. _Status = _RequestHeaders.GetError();
  193. if (_Status == ERROR_SUCCESS) {
  194. _Status = _ResponseHeaders.GetError();
  195. }
  196. }
  197. // Timeout and retry parameters
  198. INTERNET_HANDLE_OBJECT* pRoot = GetRootHandle(Parent);
  199. OPTIONAL_SESSION_PARAMS* pParams = pRoot->GetOptionalParams();
  200. if (pParams)
  201. {
  202. _dwResolveTimeout = pParams->dwResolveTimeout;
  203. _dwConnectTimeout = pParams->dwConnectTimeout;
  204. _dwConnectRetries = pParams->dwConnectRetries;
  205. _dwSendTimeout = pParams->dwSendTimeout;
  206. _dwReceiveTimeout = pParams->dwReceiveTimeout;
  207. }
  208. else
  209. {
  210. _dwResolveTimeout = GlobalResolveTimeout;
  211. _dwConnectTimeout = GlobalConnectTimeout;
  212. _dwConnectRetries = GlobalConnectRetries;
  213. _dwSendTimeout = GlobalSendTimeout;
  214. _dwReceiveTimeout = GlobalReceiveTimeout;
  215. }
  216. if (_OpenFlags & WINHTTP_FLAG_SECURE)
  217. {
  218. m_pSecurityInfo = pRoot->GetSslSessionCache()->Find(GetHostName());
  219. if (NULL == m_pSecurityInfo)
  220. {
  221. m_pSecurityInfo = New SECURITY_CACHE_LIST_ENTRY(GetHostName());
  222. }
  223. }
  224. else
  225. {
  226. m_pSecurityInfo = NULL;
  227. }
  228. if (_Status == ERROR_SUCCESS && IsAsyncHandle())
  229. {
  230. if (!_AsyncCritSec.Init())
  231. {
  232. _Status = ERROR_NOT_ENOUGH_MEMORY;
  233. }
  234. _fAsyncFsmInProgress = FALSE;
  235. }
  236. }
  237. HTTP_REQUEST_HANDLE_OBJECT::~HTTP_REQUEST_HANDLE_OBJECT(
  238. VOID
  239. )
  240. /*++
  241. Routine Description:
  242. Destructor for HTTP_REQUEST_HANDLE_OBJECT
  243. Arguments:
  244. None.
  245. Return Value:
  246. None.
  247. --*/
  248. {
  249. DEBUG_ENTER((DBG_OBJECTS,
  250. None,
  251. "~HTTP_REQUEST_HANDLE_OBJECT",
  252. "%#x",
  253. this
  254. ));
  255. //
  256. // close the socket (or free it to the pool if keep-alive)
  257. //
  258. //
  259. // Authentication Note:
  260. // The CloseConnection parameter to force the connection closed
  261. // is set if we received a challenge but didn't respond, otherwise
  262. // IIS will get confused when a subsequent request recycles the
  263. // socket from the keep-alive pool.
  264. //
  265. CloseConnection(GetAuthState() == AUTHSTATE_CHALLENGE);
  266. //
  267. // If there's an authentication context, unload the provider.
  268. //
  269. if (_pAuthCtx) {
  270. delete _pAuthCtx;
  271. }
  272. if (_pTunnelAuthCtx) {
  273. delete _pTunnelAuthCtx;
  274. }
  275. //
  276. // free the various buffers
  277. //
  278. FreeResponseBuffer();
  279. FreeQueryBuffer();
  280. SetProxyName(NULL,NULL,0);
  281. FreeURL();
  282. if (m_pSecurityInfo != NULL) {
  283. m_pSecurityInfo->Release();
  284. }
  285. if (_pProxyCreds)
  286. {
  287. delete _pProxyCreds;
  288. }
  289. if (_pServerCreds)
  290. {
  291. delete _pServerCreds;
  292. }
  293. if (_pszRealm)
  294. {
  295. FREE_MEMORY(_pszRealm);
  296. }
  297. if (_ServerInfo != NULL)
  298. _ServerInfo->Dereference();
  299. if (_OriginServer != NULL)
  300. _OriginServer->Dereference();
  301. if (g_pAsyncCount)
  302. {
  303. g_pAsyncCount->Release();
  304. }
  305. else
  306. {
  307. RIP(FALSE);
  308. }
  309. // There should be no work items left in the blocked queue.
  310. INET_ASSERT(_FsmWorkItemList.GetCount() == 0);
  311. DEBUG_LEAVE(0);
  312. }
  313. VOID
  314. HTTP_REQUEST_HANDLE_OBJECT::SetProxyName(
  315. IN LPSTR lpszProxyHostName,
  316. IN DWORD dwProxyHostNameLength,
  317. IN INTERNET_PORT ProxyPort
  318. )
  319. /*++
  320. Routine Description:
  321. Set proxy name in object. If already have name, free it. Don't set name if
  322. current pointer is input
  323. Arguments:
  324. lpszProxyHostName - pointer to proxy name to add
  325. dwProxyHostNameLength - length of proxy name
  326. ProxyPort - port
  327. Return Value:
  328. None.
  329. --*/
  330. {
  331. DEBUG_ENTER((DBG_HTTP,
  332. None,
  333. "HTTP_REQUEST_HANDLE_OBJECT::SetProxyName",
  334. "{%q, %d, %d}%q, %d, %d",
  335. _ProxyHostName,
  336. _ProxyHostNameLength,
  337. _ProxyPort,
  338. lpszProxyHostName,
  339. dwProxyHostNameLength,
  340. ProxyPort
  341. ));
  342. if (lpszProxyHostName != _ProxyHostName) {
  343. if (_ProxyHostName != NULL) {
  344. _ProxyHostName = (LPSTR)FREE_MEMORY(_ProxyHostName);
  345. INET_ASSERT(_ProxyHostName == NULL);
  346. SetOverrideProxyMode(FALSE);
  347. }
  348. if (lpszProxyHostName != NULL) {
  349. _ProxyHostName = NEW_STRING(lpszProxyHostName);
  350. if (_ProxyHostName == NULL) {
  351. dwProxyHostNameLength = 0;
  352. }
  353. }
  354. _ProxyHostNameLength = dwProxyHostNameLength;
  355. _ProxyPort = ProxyPort;
  356. } else if (lpszProxyHostName != NULL) {
  357. DEBUG_PRINT(HTTP,
  358. WARNING,
  359. ("!!! lpszProxyHostName == _ProxyHostName (%#x)\n",
  360. lpszProxyHostName
  361. ));
  362. INET_ASSERT(dwProxyHostNameLength == _ProxyHostNameLength);
  363. INET_ASSERT(ProxyPort == _ProxyPort);
  364. }
  365. DEBUG_LEAVE(0);
  366. }
  367. VOID
  368. HTTP_REQUEST_HANDLE_OBJECT::GetProxyName(
  369. OUT LPSTR* lplpszProxyHostName,
  370. OUT LPDWORD lpdwProxyHostNameLength,
  371. OUT LPINTERNET_PORT lpProxyPort
  372. )
  373. /*++
  374. Routine Description:
  375. Return address & length of proxy name plus proxy port
  376. Arguments:
  377. lplpszProxyHostName - returned address of name
  378. lpdwProxyHostNameLength - returned length of name
  379. lpProxyPort - returned port
  380. Return Value:
  381. None.
  382. --*/
  383. {
  384. DEBUG_ENTER((DBG_HTTP,
  385. None,
  386. "HTTP_REQUEST_HANDLE_OBJECT::GetProxyName",
  387. "{%q, %d, %d}%#x, %#x, %#x",
  388. _ProxyHostName,
  389. _ProxyHostNameLength,
  390. _ProxyPort,
  391. lplpszProxyHostName,
  392. lpdwProxyHostNameLength,
  393. lpProxyPort
  394. ));
  395. *lplpszProxyHostName = _ProxyHostName;
  396. *lpdwProxyHostNameLength = _ProxyHostNameLength;
  397. *lpProxyPort = _ProxyPort;
  398. DEBUG_LEAVE(0);
  399. }
  400. VOID
  401. HTTP_REQUEST_HANDLE_OBJECT::ReuseObject(
  402. VOID
  403. )
  404. /*++
  405. Routine Description:
  406. Make the object re-usable: clear out any received data and headers and
  407. reset the state to open
  408. Arguments:
  409. None.
  410. Return Value:
  411. None.
  412. --*/
  413. {
  414. DEBUG_ENTER((DBG_HTTP,
  415. None,
  416. "HTTP_REQUEST_HANDLE_OBJECT::ReuseObject",
  417. NULL
  418. ));
  419. _ResponseHeaders.FreeHeaders();
  420. FreeResponseBuffer();
  421. ResetResponseVariables();
  422. _ResponseHeaders.Initialize();
  423. SetState(HttpRequestStateOpen);
  424. ResetEndOfFile();
  425. _ResponseFilterList.ClearList();
  426. _QueryOffset = 0;
  427. _QueryBytesAvailable = 0;
  428. _dwQuerySetCookieHeader = 0;
  429. if (m_pSecurityInfo) {
  430. m_pSecurityInfo->Release();
  431. }
  432. m_pSecurityInfo = NULL;
  433. DEBUG_LEAVE(0);
  434. }
  435. DWORD
  436. HTTP_REQUEST_HANDLE_OBJECT::ResetObject(
  437. IN BOOL bForce,
  438. IN BOOL bFreeRequestHeaders
  439. )
  440. /*++
  441. Routine Description:
  442. This method is called when we we are clearing out a partially completed
  443. transaction, mainly for when we have determined that an if-modified-since
  444. request, or a response that has not invalidated the cache entry can be
  445. retrieved from cache (this is a speed issue)
  446. Abort the connection and clear out the response headers and response
  447. buffer; clear the response variables (all done by AbortConnection()).
  448. If bFreeRequestHeaders, clear out the request headers.
  449. Reinitialize the response headers. We do not reset the object state, but we
  450. do reset the end-of-file status
  451. Arguments:
  452. bForce - TRUE if connection is forced closed
  453. bFreeRequestHeaders - TRUE if request headers should be freed
  454. Return Value:
  455. DWORD
  456. Success - ERROR_SUCCESS
  457. Failure -
  458. --*/
  459. {
  460. DEBUG_ENTER((DBG_HTTP,
  461. Dword,
  462. "HTTP_REQUEST_HANDLE_OBJECT::ResetObject",
  463. "%B, %B",
  464. bForce,
  465. bFreeRequestHeaders
  466. ));
  467. DWORD error;
  468. error = AbortConnection(bForce);
  469. if (error == ERROR_SUCCESS) {
  470. if (bFreeRequestHeaders) {
  471. _RequestHeaders.FreeHeaders();
  472. }
  473. _ResponseHeaders.Initialize();
  474. ResetEndOfFile();
  475. }
  476. DEBUG_LEAVE(error);
  477. return error;
  478. }
  479. VOID
  480. HTTP_REQUEST_HANDLE_OBJECT::SetAuthenticated(
  481. VOID
  482. )
  483. /*++
  484. Routine Description:
  485. description-of-function.
  486. Arguments:
  487. SetAuthenticated -
  488. Return Value:
  489. None.
  490. --*/
  491. {
  492. if (!_Socket)
  493. {
  494. INET_ASSERT(FALSE);
  495. }
  496. else
  497. {
  498. _Socket->SetAuthenticated();
  499. }
  500. }
  501. BOOL
  502. HTTP_REQUEST_HANDLE_OBJECT::IsAuthenticated(
  503. VOID
  504. )
  505. /*++
  506. Routine Description:
  507. description-of-function.
  508. Arguments:
  509. IsAuthenticated -
  510. Return Value:
  511. BOOL
  512. --*/
  513. {
  514. return (_Socket ? _Socket->IsAuthenticated() : FALSE);
  515. }
  516. DWORD
  517. HTTP_REQUEST_HANDLE_OBJECT::SetObjectName(
  518. LPSTR lpszObjectName,
  519. LPSTR lpszExtension,
  520. URLGEN_FUNC * procProtocolUrl
  521. )
  522. {
  523. DWORD dwLen, dwError;
  524. INTERNET_SCHEME schemeType;
  525. //
  526. // if there is already an object name, then free it. We are replacing it
  527. //
  528. //
  529. // BUGBUG - make _CacheUrlString an ICSTRING
  530. //
  531. FreeURL();
  532. //
  533. // get protocol specific url
  534. //
  535. if (procProtocolUrl) {
  536. //
  537. // if we are going via proxy AND this is an FTP object AND the user name
  538. // consists of <username>@<servername> then <servername> is the real
  539. // server name, and _HostName is the name of the proxy
  540. //
  541. //
  542. // BUGBUG - this is a bit of a hack(!)
  543. //
  544. // Note: FTP support has been removed (ssulzer, 3/2000).
  545. //
  546. LPSTR target = _HostName.StringAddress();
  547. schemeType = GetSchemeType();
  548. // make the scheme type https if necessary
  549. schemeType = (((schemeType == INTERNET_SCHEME_DEFAULT)||
  550. (schemeType == INTERNET_SCHEME_HTTP)) &&
  551. (GetOpenFlags() & WINHTTP_FLAG_SECURE))?
  552. INTERNET_SCHEME_HTTPS: schemeType;
  553. LPSTR lpszNewUrl = NULL;
  554. dwError = (*procProtocolUrl)(schemeType,
  555. target,
  556. NULL,
  557. lpszObjectName,
  558. lpszExtension,
  559. _HostPort,
  560. &lpszNewUrl,
  561. &dwLen
  562. );
  563. if (dwError == ERROR_SUCCESS) {
  564. if (!SetURLPtr (&lpszNewUrl)) {
  565. FREE_MEMORY (lpszNewUrl);
  566. dwError = ERROR_NOT_ENOUGH_MEMORY;
  567. }
  568. }
  569. }
  570. else {
  571. dwError = ERROR_INVALID_PARAMETER;
  572. }
  573. if (dwError == ERROR_SUCCESS) {
  574. DEBUG_PRINT(HANDLE,
  575. INFO,
  576. ("Url: %s\n",
  577. _CacheUrlName
  578. ));
  579. }
  580. return dwError;
  581. }
  582. //=============================================================================
  583. BOOL HTTP_REQUEST_HANDLE_OBJECT::GetUserAndPass
  584. (BOOL fProxy, LPSTR *pszUser, LPSTR *pszPass)
  585. {
  586. DWORD dwUser, dwPass;
  587. if (fProxy)
  588. {
  589. dwUser = WINHTTP_OPTION_PROXY_USERNAME & WINHTTP_OPTION_MASK;
  590. dwPass = WINHTTP_OPTION_PROXY_PASSWORD & WINHTTP_OPTION_MASK;
  591. }
  592. else
  593. {
  594. dwUser = WINHTTP_OPTION_USERNAME & WINHTTP_OPTION_MASK;
  595. dwPass = WINHTTP_OPTION_PASSWORD & WINHTTP_OPTION_MASK;
  596. }
  597. *pszUser = _xsProp[dwUser].GetPtr();
  598. *pszPass = _xsProp[dwPass].GetPtr();
  599. if (*pszUser && *pszPass)
  600. return TRUE;
  601. else
  602. {
  603. *pszUser = NULL;
  604. *pszPass = NULL;
  605. return FALSE;
  606. }
  607. }
  608. //=============================================================================
  609. BOOL HTTP_REQUEST_HANDLE_OBJECT::SetURL (LPSTR lpszUrl)
  610. {
  611. LPSTR lpszNew;
  612. // Make an undecorated copy of the URL.
  613. lpszNew = NewString(lpszUrl);
  614. if (!lpszNew)
  615. return FALSE;
  616. // Clear any previous cache key and record the new one.
  617. FreeURL();
  618. INET_ASSERT (lpszNew);
  619. _CacheUrlName = lpszNew;
  620. return TRUE;
  621. }
  622. //=============================================================================
  623. BOOL HTTP_REQUEST_HANDLE_OBJECT::SetURLPtr(LPSTR* ppszUrl)
  624. {
  625. // Swap in the new URL as the cache key.
  626. FreeURL();
  627. _CacheUrlName = *ppszUrl;
  628. *ppszUrl = NULL;
  629. return TRUE;
  630. }
  631. //=============================================================================
  632. DWORD HTTP_REQUEST_HANDLE_OBJECT::SetServerInfoWithScheme(
  633. IN INTERNET_SCHEME tScheme,
  634. IN BOOL bDoResolution,
  635. IN OPTIONAL BOOL fNtlm
  636. )
  637. /*++
  638. Routine Description:
  639. Associates a SERVER_INFO with this INTERNET_CONNECT_HANDLE_OBJECT based on
  640. the host name for which this object was created and an optional scheme
  641. type
  642. Arguments:
  643. tScheme - scheme type we want SERVER_INFO for
  644. bDoResolution - TRUE if we are to resolve the host name if creating a new
  645. SERVER_INFO object
  646. fNtlm - TRUE if we are tunnelling for NTLM
  647. Return Value:
  648. DWORD
  649. Success - ERROR_SUCCESS
  650. Failure - ERROR_NOT_ENOUGH_MEMORY
  651. --*/
  652. {
  653. DEBUG_ENTER((DBG_OBJECTS,
  654. Dword,
  655. "INTERNET_CONNECT_HANDLE_OBJECT::SetServerInfo",
  656. "%s (%d), %B, %B",
  657. InternetMapScheme(tScheme),
  658. tScheme,
  659. bDoResolution,
  660. fNtlm
  661. ));
  662. if (_ServerInfo != NULL) {
  663. ::ReleaseServerInfo(_ServerInfo);
  664. }
  665. //
  666. // use the base service type to find the server info
  667. //
  668. //dprintf("getting server info for %q (current = %q)\n", hostName, GetHostName());
  669. INTERNET_HANDLE_OBJECT * lpParent = GetRootHandle (this);
  670. DWORD error = lpParent->GetServerInfo(GetHostName(),
  671. INTERNET_SERVICE_HTTP,
  672. bDoResolution,
  673. &_ServerInfo
  674. );
  675. DEBUG_LEAVE(error);
  676. return error;
  677. }
  678. //=============================================================================
  679. DWORD HTTP_REQUEST_HANDLE_OBJECT::SetServerInfo(
  680. IN LPSTR lpszServerName,
  681. IN DWORD dwServerNameLength
  682. )
  683. /*++
  684. Routine Description:
  685. Associates a SERVER_INFO with this INTERNET_CONNECT_HANDLE_OBJECT based on
  686. the host name in the parameters
  687. Arguments:
  688. lpszServerName - name of server
  689. dwServerNameLength - length of lpszServerName
  690. Return Value:
  691. DWORD
  692. Success - ERROR_SUCCESS
  693. Failure - ERROR_NOT_ENOUGH_MEMORY
  694. --*/
  695. {
  696. DEBUG_ENTER((DBG_OBJECTS,
  697. Dword,
  698. "INTERNET_CONNECT_HANDLE_OBJECT::SetServerInfo",
  699. "%q, %d",
  700. lpszServerName,
  701. dwServerNameLength
  702. ));
  703. if (_ServerInfo != NULL) {
  704. ::ReleaseServerInfo(_ServerInfo);
  705. }
  706. //
  707. // use the base service type to find the server info
  708. //
  709. char hostName[INTERNET_MAX_HOST_NAME_LENGTH + 1];
  710. int copyLength = (int)min(sizeof(hostName) - 1, dwServerNameLength);
  711. memcpy(hostName, lpszServerName, copyLength);
  712. hostName[copyLength] = '\0';
  713. INTERNET_HANDLE_OBJECT * lpParent = GetRootHandle (this);
  714. DWORD error = lpParent->GetServerInfo(hostName,
  715. INTERNET_SERVICE_HTTP,
  716. FALSE,
  717. &_ServerInfo
  718. );
  719. DEBUG_LEAVE(error);
  720. return error;
  721. }
  722. //=============================================================================
  723. VOID HTTP_REQUEST_HANDLE_OBJECT::SetOriginServer(
  724. IN CServerInfo * pServerInfo
  725. )
  726. /*++
  727. Routine Description:
  728. description-of-function.
  729. Arguments:
  730. pServerInfo -
  731. Return Value:
  732. None.
  733. --*/
  734. {
  735. DEBUG_ENTER((DBG_OBJECTS,
  736. None,
  737. "INTERNET_CONNECT_HANDLE_OBJECT::SetOriginServer",
  738. "%#x{%q}",
  739. pServerInfo,
  740. pServerInfo ? pServerInfo->GetHostName() : ""
  741. ));
  742. if (_OriginServer == NULL) {
  743. _OriginServer = pServerInfo;
  744. if (pServerInfo != NULL) {
  745. pServerInfo->Reference();
  746. }
  747. }
  748. DEBUG_LEAVE(0);
  749. }
  750. DWORD
  751. HTTP_REQUEST_HANDLE_OBJECT::ScheduleWorkItem()
  752. {
  753. DEBUG_ENTER((DBG_ASYNC,
  754. Dword,
  755. "HTTP_REQUEST_HANDLE_OBJECT::ScheduleWorkItem",
  756. NULL
  757. ));
  758. CFsm *pFsm = NULL;
  759. DWORD dwError = ERROR_SUCCESS;
  760. _FsmWorkItemList.DequeueHead(&pFsm);
  761. if (pFsm)
  762. {
  763. DEBUG_PRINT(ASYNC,
  764. INFO,
  765. ("Queueing work item %#x with %d blocked async work items remaining\n",
  766. pFsm,
  767. _FsmWorkItemList.GetCount()
  768. ));
  769. pFsm->SetThreadInfo(InternetGetThreadInfo());
  770. pFsm->SetPushPop(TRUE);
  771. pFsm->Push();
  772. dwError = pFsm->QueueWorkItem();
  773. }
  774. DEBUG_LEAVE(dwError);
  775. return dwError;
  776. }