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.

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