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.

899 lines
25 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. InetSess.cpp
  5. Abstract:
  6. Implements the Passport Session that uses WinInet as the underlying transport.
  7. Author:
  8. Biao Wang (biaow) 01-Oct-2000
  9. --*/
  10. #include "PPdefs.h"
  11. /*
  12. #ifdef HINTERNET
  13. #undef HINTERNET
  14. #endif
  15. #ifdef INTERNET_PORT
  16. #undef INTERNET_PORT
  17. #endif
  18. #include <WinHTTP.h>
  19. */
  20. #define INTERNET_DEFAULT_HTTP_PORT 80
  21. #define INTERNET_DEFAULT_HTTPS_PORT 443
  22. #define WINHTTP_HEADER_NAME_BY_INDEX NULL
  23. #define INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY 0
  24. #define INTERNET_OPEN_TYPE_PRECONFIG INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY
  25. #define INTERNET_FLAG_NO_AUTO_REDIRECT 0x00200000
  26. #define INTERNET_FLAG_NO_AUTH 0x00040000
  27. #define HTTP_QUERY_FLAG_NUMBER 0x20000000
  28. #define HTTP_QUERY_STATUS_CODE 19 // special: part of status line
  29. #define HTTP_STATUS_REDIRECT 302 // object temporarily moved
  30. #define HTTP_QUERY_WWW_AUTHENTICATE 40
  31. typedef
  32. VOID
  33. (CALLBACK * WINHTTP_STATUS_CALLBACK)(
  34. IN HINTERNET hInternet,
  35. IN DWORD_PTR dwContext,
  36. IN DWORD dwInternetStatus,
  37. IN LPVOID lpvStatusInformation OPTIONAL,
  38. IN DWORD dwStatusInformationLength
  39. );
  40. typedef enum
  41. {
  42. INTERNET_SCHEME_PARTIAL = -2,
  43. INTERNET_SCHEME_UNKNOWN = -1,
  44. INTERNET_SCHEME_DEFAULT = 0,
  45. INTERNET_SCHEME_HTTP,
  46. INTERNET_SCHEME_HTTPS,
  47. INTERNET_SCHEME_FILE,
  48. INTERNET_SCHEME_SOCKS,
  49. INTERNET_SCHEME_RES,
  50. INTERNET_SCHEME_FIRST = INTERNET_SCHEME_HTTP,
  51. INTERNET_SCHEME_LAST = INTERNET_SCHEME_RES
  52. } INTERNET_SCHEME, * LPINTERNET_SCHEME;
  53. #include "session.h"
  54. // #include "inetsess.tmh"
  55. //
  56. // func pointer decl for WinInet
  57. //
  58. typedef HINTERNET
  59. (WINAPI * PFN_INTERNET_OPEN)(
  60. IN LPCWSTR lpwszAgent,
  61. IN DWORD dwAccessType,
  62. IN LPCWSTR lpwszProxy OPTIONAL,
  63. IN LPCWSTR lpwszProxyBypass OPTIONAL,
  64. IN DWORD dwFlags
  65. );
  66. typedef HINTERNET
  67. (WINAPI * PFN_INTERNET_CONNECT)(
  68. IN HINTERNET hInternet,
  69. IN LPCWSTR lpwszServerName,
  70. IN INTERNET_PORT nServerPort,
  71. IN DWORD dwFlags
  72. );
  73. typedef HINTERNET
  74. (WINAPI * PFN_OPEN_REQUEST)(
  75. IN HINTERNET hConnect,
  76. IN LPCWSTR lpwszVerb,
  77. IN LPCWSTR lpwszObjectName,
  78. IN LPCWSTR lpwszVersion,
  79. IN LPCWSTR lpwszReferrer OPTIONAL,
  80. IN LPCWSTR FAR * lplpwszAcceptTypes OPTIONAL,
  81. IN DWORD dwFlags
  82. );
  83. typedef BOOL
  84. (WINAPI * PFN_SEND_REQUEST)(
  85. IN HINTERNET hRequest,
  86. IN LPCWSTR lpwszHeaders OPTIONAL,
  87. IN DWORD dwHeadersLength,
  88. IN LPVOID lpOptional OPTIONAL,
  89. IN DWORD dwOptionalLength,
  90. IN DWORD dwTotalLength,
  91. IN DWORD_PTR dwContext
  92. );
  93. typedef BOOL
  94. (WINAPI * PFN_QUERY_INFO)(
  95. IN HINTERNET hRequest,
  96. IN DWORD dwInfoLevel,
  97. IN LPCWSTR lpszName OPTIONAL,
  98. IN LPVOID lpvBuffer,
  99. IN LPDWORD lpdwBufferLength,
  100. IN OUT LPDWORD lpdwIndex
  101. );
  102. typedef BOOL
  103. (WINAPI* PFN_CLOSE_HANDLE)(
  104. IN HINTERNET hInternet
  105. );
  106. typedef BOOL
  107. (WINAPI* PFN_SET_OPTION)(
  108. IN HINTERNET hInternet,
  109. IN DWORD dwOption,
  110. IN LPVOID lpBuffer,
  111. IN DWORD dwBufferLength
  112. );
  113. typedef BOOL
  114. (WINAPI* PFN_QUERY_OPTION)(
  115. IN HINTERNET hInternet,
  116. IN DWORD dwOption,
  117. OUT LPVOID lpBuffer,
  118. IN OUT LPDWORD lpdwBufferLength
  119. );
  120. typedef HINTERNET
  121. (WINAPI* PFN_OPEN_URL)(
  122. IN HINTERNET hInternet,
  123. IN LPCWSTR lpwszUrl,
  124. IN LPCWSTR lpwszHeaders,
  125. IN DWORD dwHeadersLength,
  126. IN DWORD dwFlags,
  127. IN DWORD_PTR dwContext
  128. );
  129. typedef struct {
  130. DWORD dwStructSize; // size of this structure. Used in version check
  131. LPWSTR lpszScheme; // pointer to scheme name
  132. DWORD dwSchemeLength; // length of scheme name
  133. INTERNET_SCHEME nScheme; // enumerated scheme type (if known)
  134. LPWSTR lpszHostName; // pointer to host name
  135. DWORD dwHostNameLength; // length of host name
  136. INTERNET_PORT nPort; // converted port number
  137. LPWSTR lpszUserName; // pointer to user name
  138. DWORD dwUserNameLength; // length of user name
  139. LPWSTR lpszPassword; // pointer to password
  140. DWORD dwPasswordLength; // length of password
  141. LPWSTR lpszUrlPath; // pointer to URL-path
  142. DWORD dwUrlPathLength; // length of URL-path
  143. LPWSTR lpszExtraInfo; // pointer to extra information (e.g. ?foo or #foo)
  144. DWORD dwExtraInfoLength; // length of extra information
  145. } URL_COMPONENTSW, * LPURL_COMPONENTSW;
  146. typedef BOOL
  147. (WINAPI* PFN_CRACK_URL)(
  148. IN LPCWSTR lpszUrl,
  149. IN DWORD dwUrlLength,
  150. IN DWORD dwFlags,
  151. IN OUT PVOID/*LPURL_COMPONENTSW*/ lpUrlComponents
  152. );
  153. typedef BOOL
  154. (WINAPI* PFN_READ_FILE)(
  155. IN HINTERNET hFile,
  156. IN LPVOID lpBuffer,
  157. IN DWORD dwNumberOfBytesToRead,
  158. OUT LPDWORD lpdwNumberOfBytesRead
  159. );
  160. typedef WINHTTP_STATUS_CALLBACK
  161. (WINAPI* PFN_STATUS_CALLBACK)(
  162. IN HINTERNET hInternet,
  163. IN WINHTTP_STATUS_CALLBACK lpfnInternetCallback,
  164. IN DWORD dwNotificationFlags,
  165. IN DWORD_PTR dwReserved
  166. );
  167. typedef BOOL
  168. (WINAPI* PFN_ADD_HEADERS)(
  169. IN HINTERNET hConnect,
  170. IN LPCWSTR lpszHeaders,
  171. IN DWORD dwHeadersLength,
  172. IN DWORD dwModifiers
  173. );
  174. class WINHTTP_SESSION : public SESSION
  175. {
  176. protected:
  177. WINHTTP_SESSION(void);
  178. virtual ~WINHTTP_SESSION(void);
  179. virtual BOOL Open(PCWSTR pwszHttpStack, HINTERNET);
  180. virtual void Close(void);
  181. protected:
  182. virtual HINTERNET Connect(
  183. LPCWSTR lpwszServerName,
  184. INTERNET_PORT);
  185. virtual HINTERNET OpenRequest(
  186. HINTERNET hConnect,
  187. LPCWSTR lpwszVerb,
  188. LPCWSTR lpwszObjectName,
  189. DWORD dwFlags,
  190. DWORD_PTR dwContext = 0);
  191. virtual BOOL SendRequest(
  192. HINTERNET hRequest,
  193. LPCWSTR lpwszHeaders,
  194. DWORD dwHeadersLength,
  195. DWORD_PTR dwContext = 0);
  196. virtual BOOL QueryHeaders(
  197. HINTERNET hRequest,
  198. DWORD dwInfoLevel,
  199. LPVOID lpvBuffer,
  200. LPDWORD lpdwBufferLength,
  201. LPDWORD lpdwIndex = NULL);
  202. virtual BOOL CloseHandle(
  203. IN HINTERNET hInternet);
  204. virtual BOOL QueryOption(
  205. HINTERNET hInternet,
  206. DWORD dwOption,
  207. LPVOID lpBuffer,
  208. LPDWORD lpdwBufferLength);
  209. virtual BOOL SetOption(
  210. HINTERNET hInternet,
  211. DWORD dwOption,
  212. LPVOID lpBuffer,
  213. DWORD dwBufferLength);
  214. virtual HINTERNET OpenUrl(
  215. LPCWSTR lpwszUrl,
  216. LPCWSTR lpwszHeaders,
  217. DWORD dwHeadersLength,
  218. DWORD dwFlags);
  219. virtual BOOL ReadFile(
  220. HINTERNET hFile,
  221. LPVOID lpBuffer,
  222. DWORD dwNumberOfBytesToRead,
  223. LPDWORD lpdwNumberOfBytesRead);
  224. virtual BOOL CrackUrl(
  225. LPCWSTR lpszUrl,
  226. DWORD dwUrlLength,
  227. DWORD dwFlags,
  228. PVOID/*LPURL_COMPONENTSW*/ lpUrlComponents);
  229. virtual PVOID SetStatusCallback(
  230. HINTERNET hInternet,
  231. PVOID lpfnCallback
  232. );
  233. virtual BOOL AddHeaders(
  234. HINTERNET hConnect,
  235. LPCWSTR lpszHeaders,
  236. DWORD dwHeadersLength,
  237. DWORD dwModifiers
  238. );
  239. virtual BOOL IsHostBypassProxy(
  240. INTERNET_SCHEME tScheme,
  241. LPCSTR pszHost,
  242. DWORD cchHost)
  243. {
  244. return TRUE; // biaow: todo
  245. }
  246. #ifdef PP_DEMO
  247. virtual BOOL ContactPartner(PCWSTR pwszPartnerUrl,
  248. PCWSTR pwszVerb,
  249. PCWSTR pwszHeaders,
  250. PWSTR pwszData,
  251. PDWORD pdwDataLength
  252. );
  253. #endif // PP_DEMO
  254. BOOL InitHttpApi(PFN_INTERNET_OPEN*);
  255. protected:
  256. HINTERNET m_hInternet;
  257. PFN_INTERNET_CONNECT m_pfnConnect;
  258. PFN_OPEN_REQUEST m_pfnOpenRequest;
  259. PFN_SEND_REQUEST m_pfnSendRequest;
  260. PFN_QUERY_INFO m_pfnQueryInfo;
  261. PFN_CLOSE_HANDLE m_pfnCloseHandle;
  262. PFN_SET_OPTION m_pfnSetOption;
  263. PFN_OPEN_URL m_pfnOpenUrl;
  264. PFN_QUERY_OPTION m_pfnQueryOption;
  265. PFN_CRACK_URL m_pfnCrack;
  266. PFN_READ_FILE m_pfnReadFile;
  267. PFN_STATUS_CALLBACK m_pfnStatusCallback;
  268. PFN_ADD_HEADERS m_pfnAddHeaders;
  269. friend class SESSION;
  270. friend SESSION* CreateWinHttpSession(void);
  271. };
  272. SESSION* CreateWinHttpSession(void)
  273. {
  274. return new WINHTTP_SESSION();
  275. }
  276. //
  277. // Implementation for WINHTTP_SESSION
  278. //
  279. // -----------------------------------------------------------------------------
  280. WINHTTP_SESSION::WINHTTP_SESSION(void)
  281. {
  282. m_hInternet = NULL;
  283. m_pfnConnect = NULL;
  284. m_pfnOpenRequest = NULL;
  285. m_pfnSendRequest = NULL;
  286. m_pfnQueryInfo = NULL;
  287. m_pfnCloseHandle = NULL;
  288. m_pfnSetOption = NULL;
  289. m_pfnOpenUrl = NULL;
  290. m_pfnQueryOption = NULL;
  291. m_pfnCrack = NULL;
  292. m_pfnReadFile = NULL;
  293. }
  294. // -----------------------------------------------------------------------------
  295. WINHTTP_SESSION::~WINHTTP_SESSION(void)
  296. {
  297. }
  298. // -----------------------------------------------------------------------------
  299. HINTERNET WINHTTP_SESSION::Connect(
  300. LPCWSTR lpwszServerName,
  301. INTERNET_PORT nPort)
  302. {
  303. PP_ASSERT(m_pfnConnect != NULL);
  304. return (*m_pfnConnect)(m_hInternet,
  305. lpwszServerName,
  306. nPort,
  307. 0);
  308. }
  309. // -----------------------------------------------------------------------------
  310. HINTERNET WINHTTP_SESSION::OpenRequest(
  311. HINTERNET hConnect,
  312. LPCWSTR lpwszVerb,
  313. LPCWSTR lpwszObjectName,
  314. DWORD dwFlags,
  315. DWORD_PTR dwContext)
  316. {
  317. PP_ASSERT(m_pfnOpenRequest != NULL);
  318. return (*m_pfnOpenRequest)(hConnect,
  319. lpwszVerb,
  320. lpwszObjectName,
  321. L"HTTP/1.1",
  322. NULL,
  323. NULL,
  324. dwFlags);
  325. }
  326. // -----------------------------------------------------------------------------
  327. BOOL WINHTTP_SESSION::SendRequest(
  328. HINTERNET hRequest,
  329. LPCWSTR lpwszHeaders,
  330. DWORD dwHeadersLength,
  331. DWORD_PTR dwContext)
  332. {
  333. PP_ASSERT(m_pfnSendRequest != NULL);
  334. return (*m_pfnSendRequest)(hRequest,
  335. lpwszHeaders,
  336. dwHeadersLength,
  337. NULL,
  338. 0,
  339. 0, // optional total length
  340. dwContext);
  341. }
  342. // -----------------------------------------------------------------------------
  343. BOOL WINHTTP_SESSION::QueryHeaders(
  344. HINTERNET hRequest,
  345. DWORD dwInfoLevel,
  346. LPVOID lpvBuffer,
  347. LPDWORD lpdwBufferLength,
  348. LPDWORD lpdwIndex)
  349. {
  350. PP_ASSERT(m_pfnQueryInfo != NULL);
  351. return (*m_pfnQueryInfo)(hRequest,
  352. dwInfoLevel,
  353. WINHTTP_HEADER_NAME_BY_INDEX,
  354. lpvBuffer,
  355. lpdwBufferLength,
  356. lpdwIndex);
  357. }
  358. // -----------------------------------------------------------------------------
  359. BOOL WINHTTP_SESSION::CloseHandle(
  360. IN HINTERNET hInternet)
  361. {
  362. PP_ASSERT(m_pfnCloseHandle != NULL);
  363. return (*m_pfnCloseHandle)(hInternet);
  364. }
  365. // -----------------------------------------------------------------------------
  366. BOOL WINHTTP_SESSION::QueryOption(
  367. HINTERNET hInternet,
  368. DWORD dwOption,
  369. LPVOID lpBuffer,
  370. LPDWORD lpdwBufferLength)
  371. {
  372. PP_ASSERT(m_pfnQueryOption != NULL);
  373. return (*m_pfnQueryOption)(hInternet,
  374. dwOption,
  375. lpBuffer,
  376. lpdwBufferLength
  377. );
  378. }
  379. // -----------------------------------------------------------------------------
  380. BOOL WINHTTP_SESSION::SetOption(
  381. HINTERNET hInternet,
  382. DWORD dwOption,
  383. LPVOID lpBuffer,
  384. DWORD dwBufferLength)
  385. {
  386. PP_ASSERT(m_pfnSetOption != NULL);
  387. return (*m_pfnSetOption)(hInternet,
  388. dwOption,
  389. lpBuffer,
  390. dwBufferLength);
  391. }
  392. // -----------------------------------------------------------------------------
  393. HINTERNET WINHTTP_SESSION::OpenUrl(
  394. LPCWSTR lpwszUrl,
  395. LPCWSTR lpwszHeaders,
  396. DWORD dwHeadersLength,
  397. DWORD dwFlags)
  398. {
  399. PP_ASSERT(m_pfnOpenUrl != NULL);
  400. return (*m_pfnOpenUrl)(m_hInternet,
  401. lpwszUrl,
  402. lpwszHeaders,
  403. dwHeadersLength,
  404. dwFlags,
  405. 0);
  406. }
  407. // -----------------------------------------------------------------------------
  408. BOOL WINHTTP_SESSION::ReadFile(
  409. HINTERNET hFile,
  410. LPVOID lpBuffer,
  411. DWORD dwNumberOfBytesToRead,
  412. LPDWORD lpdwNumberOfBytesRead)
  413. {
  414. PP_ASSERT(m_pfnReadFile != NULL);
  415. return (*m_pfnReadFile)(
  416. hFile,
  417. lpBuffer,
  418. dwNumberOfBytesToRead,
  419. lpdwNumberOfBytesRead);
  420. }
  421. BOOL WINHTTP_SESSION::CrackUrl(
  422. LPCWSTR lpszUrl,
  423. DWORD dwUrlLength,
  424. DWORD dwFlags,
  425. PVOID/*LPURL_COMPONENTSW*/ lpUrlComponents)
  426. {
  427. PP_ASSERT (m_pfnCrack != NULL);
  428. return (*m_pfnCrack)(lpszUrl,
  429. dwUrlLength,
  430. dwFlags,
  431. lpUrlComponents);
  432. }
  433. PVOID WINHTTP_SESSION::SetStatusCallback(
  434. HINTERNET hInternet,
  435. PVOID lpfnCallback
  436. )
  437. {
  438. return (*m_pfnStatusCallback)(hInternet,
  439. (WINHTTP_STATUS_CALLBACK)lpfnCallback,
  440. 0,
  441. 0);
  442. }
  443. BOOL WINHTTP_SESSION::AddHeaders(
  444. HINTERNET hConnect,
  445. LPCWSTR lpszHeaders,
  446. DWORD dwHeadersLength,
  447. DWORD dwModifiers
  448. )
  449. {
  450. PP_ASSERT(m_pfnAddHeaders != NULL);
  451. return (*m_pfnAddHeaders)(hConnect,
  452. lpszHeaders,
  453. dwHeadersLength,
  454. dwModifiers
  455. );
  456. }
  457. BOOL WINHTTP_SESSION::InitHttpApi(PFN_INTERNET_OPEN* ppfnInternetOpen)
  458. {
  459. BOOL fRet = FALSE;
  460. m_pfnCloseHandle =
  461. reinterpret_cast<PFN_CLOSE_HANDLE>(::GetProcAddress(m_hHttpStack, "WinHttpCloseHandle"));
  462. if (m_pfnCloseHandle == NULL)
  463. {
  464. DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpCloseHandle not found");
  465. goto exit;
  466. }
  467. *ppfnInternetOpen =
  468. reinterpret_cast<PFN_INTERNET_OPEN>(::GetProcAddress(m_hHttpStack, "WinHttpOpen"));
  469. if (*ppfnInternetOpen == NULL)
  470. {
  471. DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpOpen not found");
  472. goto exit;
  473. }
  474. m_pfnConnect =
  475. reinterpret_cast<PFN_INTERNET_CONNECT>(::GetProcAddress(m_hHttpStack, "WinHttpConnect"));
  476. if (m_pfnConnect == NULL)
  477. {
  478. DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpConnect not found");
  479. goto exit;
  480. }
  481. m_pfnOpenRequest =
  482. reinterpret_cast<PFN_OPEN_REQUEST>(::GetProcAddress(m_hHttpStack, "WinHttpOpenRequest"));
  483. if (m_pfnOpenRequest == NULL)
  484. {
  485. DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpOpenRequest not found");
  486. goto exit;
  487. }
  488. m_pfnSendRequest =
  489. reinterpret_cast<PFN_SEND_REQUEST>(::GetProcAddress(m_hHttpStack, "WinHttpSendRequest"));
  490. if (m_pfnSendRequest == NULL)
  491. {
  492. DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpSendRequest not found");
  493. goto exit;
  494. }
  495. m_pfnQueryInfo =
  496. reinterpret_cast<PFN_QUERY_INFO>(::GetProcAddress(m_hHttpStack, "WinHttpQueryHeaders"));
  497. if (m_pfnQueryInfo == NULL)
  498. {
  499. DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpQueryHeaders not found");
  500. goto exit;
  501. }
  502. m_pfnSetOption =
  503. reinterpret_cast<PFN_SET_OPTION>(::GetProcAddress(m_hHttpStack, "WinHttpSetOption"));
  504. if (m_pfnSetOption == NULL)
  505. {
  506. DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpSetOption not found");
  507. goto exit;
  508. }
  509. m_pfnOpenUrl =
  510. reinterpret_cast<PFN_OPEN_URL>(::GetProcAddress(m_hHttpStack, "WinHttpOpenUrl"));
  511. if (m_pfnOpenUrl == NULL)
  512. {
  513. DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpOpenUrl not found");
  514. goto exit;
  515. }
  516. m_pfnQueryOption =
  517. reinterpret_cast<PFN_QUERY_OPTION>(::GetProcAddress(m_hHttpStack, "WinHttpQueryOption"));
  518. if (m_pfnQueryOption == NULL)
  519. {
  520. DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpQueryOption not found");
  521. goto exit;
  522. }
  523. m_pfnCrack =
  524. reinterpret_cast<PFN_CRACK_URL>(::GetProcAddress(m_hHttpStack, "WinHttpCrackUrl"));
  525. if (m_pfnCrack == NULL)
  526. {
  527. DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpCrackUrl not found");
  528. goto exit;
  529. }
  530. m_pfnReadFile =
  531. reinterpret_cast<PFN_READ_FILE>(::GetProcAddress(m_hHttpStack, "WinHttpReadData"));
  532. if (m_pfnReadFile == NULL)
  533. {
  534. DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpReadData not found");
  535. goto exit;
  536. }
  537. m_pfnStatusCallback =
  538. reinterpret_cast<PFN_STATUS_CALLBACK>(::GetProcAddress(m_hHttpStack, "WinHttpSetStatusCallback"));
  539. if (m_pfnStatusCallback == NULL)
  540. {
  541. DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpSetStatusCallback not found");
  542. goto exit;
  543. }
  544. m_pfnAddHeaders =
  545. reinterpret_cast<PFN_ADD_HEADERS>(::GetProcAddress(m_hHttpStack, "WinHttpAddRequestHeaders"));
  546. if (m_pfnAddHeaders == NULL)
  547. {
  548. DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpAddRequestHeaders not found");
  549. goto exit;
  550. }
  551. fRet = TRUE;
  552. exit:
  553. return fRet;
  554. }
  555. BOOL WINHTTP_SESSION::Open(
  556. PCWSTR pwszHttpStack,
  557. HINTERNET hInternet
  558. )
  559. {
  560. PP_ASSERT(pwszHttpStack != NULL);
  561. DWORD dwErrorCode;
  562. BOOL fRet = FALSE;
  563. PFN_INTERNET_OPEN pfnInternetOpen = NULL;
  564. PP_ASSERT(m_hHttpStack == 0);
  565. m_hHttpStack = ::LoadLibraryW(pwszHttpStack);
  566. if (m_hHttpStack == NULL)
  567. {
  568. dwErrorCode = ::GetLastError();
  569. DoTraceMessage(PP_LOG_ERROR, "failed to load library %ws; error = %d", pwszHttpStack, dwErrorCode);
  570. goto exit;
  571. }
  572. if (InitHttpApi(&pfnInternetOpen) == FALSE)
  573. {
  574. goto exit;
  575. }
  576. if (hInternet)
  577. {
  578. m_hInternet = hInternet;
  579. m_fOwnedSession = FALSE;
  580. }
  581. else
  582. {
  583. m_hInternet = (*pfnInternetOpen)(
  584. L"Microsoft WinHttp Passport Authentication Service 1.4",
  585. INTERNET_OPEN_TYPE_PRECONFIG, // ? name didn't get changed yet
  586. NULL,
  587. NULL,
  588. 0 /*WINHTTP_FLAG_ASYNC*/ // biaow-todo: use async
  589. );
  590. m_fOwnedSession = TRUE;
  591. }
  592. if (m_hInternet == NULL)
  593. {
  594. dwErrorCode = ::GetLastError();
  595. DoTraceMessage(PP_LOG_ERROR, "failed to open an HTTP session through %ws; error = %d",
  596. pwszHttpStack, dwErrorCode);
  597. goto exit;
  598. }
  599. if (SESSION::Open(pwszHttpStack, hInternet) == FALSE)
  600. {
  601. goto exit;
  602. }
  603. fRet = TRUE;
  604. DoTraceMessage(PP_LOG_INFO, "WinInet Http Session opened");
  605. exit:
  606. if (!fRet)
  607. {
  608. if (m_hInternet && m_fOwnedSession)
  609. {
  610. (*m_pfnCloseHandle)(m_hInternet);
  611. m_hInternet = NULL;
  612. }
  613. if (m_hHttpStack)
  614. {
  615. ::FreeLibrary(m_hHttpStack);
  616. m_hHttpStack = NULL;
  617. }
  618. DoTraceMessage(PP_LOG_ERROR, "WinInet Http Session failed");
  619. }
  620. return fRet;
  621. }
  622. void WINHTTP_SESSION::Close(void)
  623. {
  624. PP_ASSERT(m_pfnCloseHandle);
  625. if (m_hInternet && m_fOwnedSession)
  626. {
  627. (*m_pfnCloseHandle)(m_hInternet);
  628. m_pfnCloseHandle = NULL;
  629. }
  630. if (m_hHttpStack)
  631. {
  632. ::FreeLibrary(m_hHttpStack);
  633. m_hHttpStack = NULL;
  634. }
  635. SESSION::Close();
  636. DoTraceMessage(PP_LOG_INFO, "WinInet Http Session closed");
  637. }
  638. #ifdef PP_DEMO
  639. BOOL WINHTTP_SESSION::ContactPartner(PCWSTR pwszPartnerUrl,
  640. PCWSTR pwszVerb,
  641. PCWSTR pwszHeaders,
  642. PWSTR pwszData,
  643. PDWORD pdwDataLength
  644. )
  645. {
  646. BOOL fRet = FALSE;
  647. HINTERNET hConnect = NULL;
  648. HINTERNET hRequest = NULL;
  649. WCHAR ServerName[128];
  650. WCHAR ObjectPath[1024];
  651. URL_COMPONENTSW UrlComps;
  652. ::memset(&UrlComps, 0, sizeof(UrlComps));
  653. UrlComps.dwStructSize = sizeof(UrlComps) / sizeof(WCHAR);
  654. UrlComps.lpszHostName = ServerName;
  655. UrlComps.dwHostNameLength = ARRAYSIZE(ServerName);
  656. UrlComps.lpszUrlPath = ObjectPath;
  657. UrlComps.dwUrlPathLength = ARRAYSIZE(ObjectPath);
  658. PP_ASSERT(m_pfnCrack != NULL);
  659. if ((*m_pfnCrack)(pwszPartnerUrl,
  660. 0,
  661. 0,
  662. &UrlComps) == FALSE)
  663. {
  664. DoTraceMessage(PP_LOG_ERROR,
  665. "WINHTTP_SESSION::ContactPartner() failed; can not crack the URL %ws",
  666. pwszPartnerUrl);
  667. goto exit;
  668. }
  669. PP_ASSERT(m_pfnConnect != NULL);
  670. hConnect = (*m_pfnConnect)(m_hInternet,
  671. UrlComps.lpszHostName,
  672. UrlComps.nPort,
  673. 0);
  674. if (hConnect == NULL)
  675. {
  676. DoTraceMessage(PP_LOG_ERROR,
  677. "WINHTTP_SESSION::ContactPartner() failed; can not open an HTTP sesstion to %ws:%d",
  678. UrlComps.lpszHostName, UrlComps.nPort);
  679. goto exit;
  680. }
  681. PP_ASSERT(m_pfnOpenRequest != NULL);
  682. hRequest = (*m_pfnOpenRequest)(hConnect,
  683. pwszVerb,
  684. UrlComps.lpszUrlPath,
  685. L"HTTP/1.1",
  686. NULL,
  687. NULL,
  688. INTERNET_FLAG_NO_AUTO_REDIRECT | INTERNET_FLAG_NO_AUTH);
  689. if (hRequest == NULL)
  690. {
  691. DoTraceMessage(PP_LOG_ERROR,
  692. "WINHTTP_SESSION::ContactPartner() failed; can not open an HTTP request to %ws:(%ws)",
  693. UrlComps.lpszUrlPath, pwszVerb);
  694. goto exit;
  695. }
  696. PP_ASSERT(m_pfnSendRequest != NULL);
  697. if ((*m_pfnSendRequest)(hRequest,
  698. pwszHeaders,
  699. 0,
  700. NULL,
  701. 0,
  702. 0,
  703. 0) == FALSE)
  704. {
  705. DoTraceMessage(PP_LOG_ERROR,
  706. "WINHTTP_SESSION::ContactPartner() failed; can not send an HTTP request");
  707. goto exit;
  708. }
  709. if (pwszData == NULL)
  710. {
  711. fRet = TRUE;
  712. goto exit;
  713. }
  714. DWORD dwStatus, dwStatusLen;
  715. dwStatusLen = sizeof(dwStatus);
  716. if (!QueryHeaders(hRequest,
  717. HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE,
  718. &dwStatus,
  719. &dwStatusLen))
  720. {
  721. DoTraceMessage(PP_LOG_ERROR,
  722. "WINHTTP_SESSION::ContactPartner() failed; can not query status code");
  723. goto exit;
  724. }
  725. if (dwStatus != HTTP_STATUS_REDIRECT)
  726. {
  727. DoTraceMessage(PP_LOG_ERROR,
  728. "WINHTTP_SESSION::ContactPartner() failed; expecting %d but get %d",
  729. HTTP_STATUS_REDIRECT, dwStatus);
  730. goto exit;
  731. }
  732. ::wcscpy(pwszData, L"WWW-Authenticate: ");
  733. if(!QueryHeaders(hRequest,
  734. HTTP_QUERY_WWW_AUTHENTICATE,
  735. (LPVOID)(pwszData + ::wcslen(L"WWW-Authenticate: ")),
  736. pdwDataLength))
  737. {
  738. DoTraceMessage(PP_LOG_ERROR,
  739. "WINHTTP_SESSION::ContactPartner() failed; no auth headers found");
  740. goto exit;
  741. }
  742. (*m_pfnCloseHandle)(hRequest);
  743. hRequest = NULL;
  744. (*m_pfnCloseHandle)(hConnect);
  745. hConnect = NULL;
  746. fRet = TRUE;
  747. exit:
  748. if (hRequest)
  749. {
  750. (*m_pfnCloseHandle)(hRequest);
  751. hRequest = NULL;
  752. }
  753. if (hConnect)
  754. {
  755. (*m_pfnCloseHandle)(hConnect);
  756. hConnect = NULL;
  757. }
  758. return fRet;
  759. }
  760. #endif // PP_DEMO