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.

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