windows_system_proxy_resolver_impl_unittest.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "services/proxy_resolver_win/windows_system_proxy_resolver_impl.h"
  5. #include <windows.h>
  6. #include <winhttp.h>
  7. #include <memory>
  8. #include <set>
  9. #include <string>
  10. #include <vector>
  11. #include "base/bind.h"
  12. #include "base/logging.h"
  13. #include "base/memory/ptr_util.h"
  14. #include "base/memory/weak_ptr.h"
  15. #include "base/run_loop.h"
  16. #include "base/strings/utf_string_conversions.h"
  17. #include "base/test/task_environment.h"
  18. #include "base/threading/sequenced_task_runner_handle.h"
  19. #include "mojo/public/cpp/bindings/remote.h"
  20. #include "net/base/net_errors.h"
  21. #include "net/base/proxy_server.h"
  22. #include "net/base/proxy_string_util.h"
  23. #include "net/proxy_resolution/proxy_config.h"
  24. #include "net/proxy_resolution/proxy_list.h"
  25. #include "net/proxy_resolution/win/windows_system_proxy_resolution_service.h"
  26. #include "net/test/test_with_task_environment.h"
  27. #include "services/proxy_resolver_win/public/mojom/proxy_resolver_win.mojom.h"
  28. #include "services/proxy_resolver_win/winhttp_api_wrapper.h"
  29. #include "testing/gtest/include/gtest/gtest.h"
  30. #include "url/gurl.h"
  31. namespace proxy_resolver_win {
  32. namespace {
  33. const GURL kUrl("https://example.test:8080/");
  34. // This limit is arbitrary and exists only to make memory management in this
  35. // test easier.
  36. constexpr uint32_t kMaxProxyEntryLimit = 10u;
  37. void CopySettingToIEProxyConfigString(const std::wstring& setting,
  38. LPWSTR* ie_proxy_config_string) {
  39. // The trailing null for the string is provided by GlobalAlloc, which
  40. // zero-initializes the memory when using the GPTR flag.
  41. *ie_proxy_config_string = static_cast<LPWSTR>(
  42. GlobalAlloc(GPTR, sizeof(wchar_t) * (setting.length() + 1)));
  43. memcpy(*ie_proxy_config_string, setting.data(),
  44. sizeof(wchar_t) * setting.length());
  45. }
  46. // This class will internally validate behavior that MUST be present in the code
  47. // in order to successfully use WinHttp APIs.
  48. class MockWinHttpAPIWrapper final : public WinHttpAPIWrapper {
  49. public:
  50. MockWinHttpAPIWrapper() {}
  51. ~MockWinHttpAPIWrapper() override {
  52. if (did_call_get_proxy_result_) {
  53. EXPECT_TRUE(did_call_free_proxy_result_);
  54. }
  55. EXPECT_TRUE(opened_proxy_resolvers_.empty());
  56. ResetWinHttpResults();
  57. }
  58. void set_call_winhttp_open_success(bool open_success) {
  59. open_success_ = open_success;
  60. }
  61. bool CallWinHttpOpen() override {
  62. did_call_open_ = true;
  63. return open_success_;
  64. }
  65. void set_call_winhttp_set_timeouts_success(bool set_timeouts_success) {
  66. set_timeouts_success_ = set_timeouts_success;
  67. }
  68. bool CallWinHttpSetTimeouts(int resolve_timeout,
  69. int connect_timeout,
  70. int send_timeout,
  71. int receive_timeout) override {
  72. EXPECT_TRUE(did_call_open_);
  73. did_call_set_timeouts_ = true;
  74. return set_timeouts_success_;
  75. }
  76. void set_call_winhttp_set_status_callback_success(
  77. bool set_status_callback_success) {
  78. set_status_callback_success_ = set_status_callback_success;
  79. }
  80. bool CallWinHttpSetStatusCallback(
  81. WINHTTP_STATUS_CALLBACK internet_callback) override {
  82. EXPECT_TRUE(did_call_open_);
  83. EXPECT_NE(internet_callback, nullptr);
  84. EXPECT_EQ(callback_, nullptr);
  85. callback_ = internet_callback;
  86. did_call_set_status_callback_ = true;
  87. return set_status_callback_success_;
  88. }
  89. void set_call_winhttp_get_ie_proxy_config_success(
  90. bool get_ie_proxy_config_success) {
  91. get_ie_proxy_config_success_ = get_ie_proxy_config_success;
  92. }
  93. void set_ie_proxy_config(bool is_autoproxy_enabled,
  94. const std::wstring& pac_url,
  95. const std::wstring& proxy,
  96. const std::wstring& proxy_bypass) {
  97. is_autoproxy_enabled_ = is_autoproxy_enabled;
  98. pac_url_ = pac_url;
  99. proxy_ = proxy;
  100. proxy_bypass_ = proxy_bypass;
  101. }
  102. bool CallWinHttpGetIEProxyConfigForCurrentUser(
  103. WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* ie_proxy_config) override {
  104. did_call_get_ie_proxy_config_ = true;
  105. ie_proxy_config->fAutoDetect = is_autoproxy_enabled_ ? TRUE : FALSE;
  106. if (!pac_url_.empty()) {
  107. CopySettingToIEProxyConfigString(pac_url_,
  108. &ie_proxy_config->lpszAutoConfigUrl);
  109. }
  110. if (!proxy_.empty()) {
  111. CopySettingToIEProxyConfigString(proxy_, &ie_proxy_config->lpszProxy);
  112. }
  113. if (!proxy_bypass_.empty()) {
  114. CopySettingToIEProxyConfigString(proxy_bypass_,
  115. &ie_proxy_config->lpszProxyBypass);
  116. }
  117. return get_ie_proxy_config_success_;
  118. }
  119. void set_call_winhttp_create_proxy_resolver_success(
  120. bool create_proxy_resolver_success) {
  121. create_proxy_resolver_success_ = create_proxy_resolver_success;
  122. }
  123. bool CallWinHttpCreateProxyResolver(HINTERNET* out_resolver_handle) override {
  124. EXPECT_TRUE(did_call_set_status_callback_);
  125. EXPECT_NE(out_resolver_handle, nullptr);
  126. if (!out_resolver_handle)
  127. return false;
  128. did_call_create_proxy_resolver_ = true;
  129. if (!create_proxy_resolver_success_)
  130. return false;
  131. // The caller will be using this handle as an identifier later, so make this
  132. // unique.
  133. *out_resolver_handle =
  134. reinterpret_cast<HINTERNET>(proxy_resolver_identifier_++);
  135. EXPECT_EQ(opened_proxy_resolvers_.count(*out_resolver_handle), 0u);
  136. opened_proxy_resolvers_.emplace(*out_resolver_handle);
  137. return true;
  138. }
  139. void set_call_winhttp_get_proxy_for_url_success(
  140. bool get_proxy_for_url_success) {
  141. get_proxy_for_url_success_ = get_proxy_for_url_success;
  142. }
  143. bool CallWinHttpGetProxyForUrlEx(HINTERNET resolver_handle,
  144. const std::string& url,
  145. WINHTTP_AUTOPROXY_OPTIONS* autoproxy_options,
  146. DWORD_PTR context) override {
  147. // This API must be called only after the session has been correctly set up.
  148. EXPECT_TRUE(did_call_open_);
  149. EXPECT_TRUE(did_call_set_timeouts_);
  150. EXPECT_TRUE(did_call_set_status_callback_);
  151. EXPECT_NE(callback_, nullptr);
  152. EXPECT_TRUE(did_call_get_ie_proxy_config_);
  153. EXPECT_TRUE(did_call_create_proxy_resolver_);
  154. EXPECT_TRUE(!did_call_get_proxy_result_);
  155. EXPECT_TRUE(!did_call_free_proxy_result_);
  156. // This API must always receive valid inputs.
  157. EXPECT_TRUE(!url.empty());
  158. EXPECT_TRUE(autoproxy_options);
  159. EXPECT_FALSE(autoproxy_options->fAutoLogonIfChallenged);
  160. EXPECT_TRUE(autoproxy_options->dwFlags & WINHTTP_AUTOPROXY_ALLOW_STATIC);
  161. EXPECT_TRUE(autoproxy_options->dwFlags & WINHTTP_AUTOPROXY_ALLOW_CM);
  162. if (autoproxy_options->dwFlags & WINHTTP_AUTOPROXY_CONFIG_URL) {
  163. EXPECT_TRUE(autoproxy_options->lpszAutoConfigUrl);
  164. } else {
  165. EXPECT_TRUE(!autoproxy_options->lpszAutoConfigUrl);
  166. }
  167. if (autoproxy_options->dwFlags & WINHTTP_AUTOPROXY_AUTO_DETECT) {
  168. EXPECT_TRUE(autoproxy_options->dwAutoDetectFlags &
  169. WINHTTP_AUTO_DETECT_TYPE_DNS_A);
  170. EXPECT_TRUE(autoproxy_options->dwAutoDetectFlags &
  171. WINHTTP_AUTO_DETECT_TYPE_DHCP);
  172. } else {
  173. EXPECT_TRUE(!autoproxy_options->dwAutoDetectFlags);
  174. }
  175. EXPECT_NE(resolver_handle, nullptr);
  176. EXPECT_EQ(opened_proxy_resolvers_.count(resolver_handle), 1u);
  177. EXPECT_NE(context, 0u);
  178. if (!resolver_handle || !context || !callback_)
  179. return false;
  180. did_call_get_proxy_for_url_ = true;
  181. if (!get_proxy_for_url_success_)
  182. return false;
  183. base::SequencedTaskRunnerHandle::Get()->PostTask(
  184. FROM_HERE,
  185. base::BindOnce(&MockWinHttpAPIWrapper::RunCallback,
  186. base::Unretained(this), resolver_handle, context));
  187. return true;
  188. }
  189. void set_call_winhttp_get_proxy_result_success(
  190. bool get_proxy_result_success) {
  191. get_proxy_result_success_ = get_proxy_result_success;
  192. }
  193. void SetCallbackStatusAndInfo(DWORD callback_status, DWORD info_error) {
  194. callback_status_ = callback_status;
  195. callback_info_ = std::make_unique<WINHTTP_ASYNC_RESULT>();
  196. callback_info_->dwError = info_error;
  197. }
  198. void AddBypassToProxyResults() {
  199. ASSERT_LT(proxy_result_.cEntries, kMaxProxyEntryLimit - 1);
  200. AllocateProxyResultEntriesIfNeeded();
  201. proxy_result_.pEntries[proxy_result_.cEntries].fBypass = TRUE;
  202. proxy_result_.cEntries++;
  203. }
  204. void AddDirectToProxyResults() {
  205. ASSERT_LT(proxy_result_.cEntries, kMaxProxyEntryLimit - 1);
  206. AllocateProxyResultEntriesIfNeeded();
  207. proxy_result_.cEntries++;
  208. }
  209. void AddToProxyResults(INTERNET_SCHEME scheme,
  210. std::wstring proxy_host,
  211. INTERNET_PORT port) {
  212. ASSERT_LT(proxy_result_.cEntries, kMaxProxyEntryLimit - 1);
  213. AllocateProxyResultEntriesIfNeeded();
  214. proxy_list_.push_back(std::move(proxy_host));
  215. wchar_t* proxy_host_raw = const_cast<wchar_t*>(proxy_list_.back().data());
  216. proxy_result_.pEntries[proxy_result_.cEntries].fProxy = TRUE;
  217. proxy_result_.pEntries[proxy_result_.cEntries].ProxyScheme = scheme;
  218. proxy_result_.pEntries[proxy_result_.cEntries].pwszProxy = proxy_host_raw;
  219. proxy_result_.pEntries[proxy_result_.cEntries].ProxyPort = port;
  220. proxy_result_.cEntries++;
  221. }
  222. bool CallWinHttpGetProxyResult(HINTERNET resolver_handle,
  223. WINHTTP_PROXY_RESULT* proxy_result) override {
  224. EXPECT_TRUE(did_call_get_proxy_for_url_);
  225. EXPECT_NE(resolver_handle, nullptr);
  226. EXPECT_EQ(opened_proxy_resolvers_.count(resolver_handle), 1u);
  227. if (!get_proxy_result_success_)
  228. return false;
  229. EXPECT_NE(proxy_result, nullptr);
  230. proxy_result->cEntries = proxy_result_.cEntries;
  231. proxy_result->pEntries = proxy_result_.pEntries;
  232. did_call_get_proxy_result_ = true;
  233. return get_proxy_result_success_;
  234. }
  235. void CallWinHttpFreeProxyResult(WINHTTP_PROXY_RESULT* proxy_result) override {
  236. EXPECT_TRUE(did_call_get_proxy_result_);
  237. EXPECT_NE(proxy_result, nullptr);
  238. did_call_free_proxy_result_ = true;
  239. }
  240. void CallWinHttpCloseHandle(HINTERNET internet_handle) override {
  241. EXPECT_EQ(opened_proxy_resolvers_.count(internet_handle), 1u);
  242. opened_proxy_resolvers_.erase(internet_handle);
  243. }
  244. void ResetWinHttpResults() {
  245. if (proxy_result_.pEntries) {
  246. delete[] proxy_result_.pEntries;
  247. proxy_result_.pEntries = nullptr;
  248. proxy_result_ = {0};
  249. }
  250. proxy_list_.clear();
  251. }
  252. base::WeakPtr<MockWinHttpAPIWrapper> GetWeakPtr() {
  253. return weak_factory_.GetWeakPtr();
  254. }
  255. private:
  256. void RunCallback(HINTERNET resolver_handle, DWORD_PTR context) {
  257. EXPECT_NE(callback_, nullptr);
  258. EXPECT_NE(resolver_handle, nullptr);
  259. EXPECT_EQ(opened_proxy_resolvers_.count(resolver_handle), 1u);
  260. EXPECT_NE(context, 0u);
  261. callback_(resolver_handle, context, callback_status_, callback_info_.get(),
  262. sizeof(callback_info_.get()));
  263. // As soon as the callback resolves, WinHttp may choose to delete the memory
  264. // contained by `callback_info_`. This is simulated here.
  265. callback_info_.reset();
  266. }
  267. void AllocateProxyResultEntriesIfNeeded() {
  268. if (proxy_result_.cEntries != 0)
  269. return;
  270. proxy_result_.pEntries =
  271. new WINHTTP_PROXY_RESULT_ENTRY[kMaxProxyEntryLimit];
  272. std::memset(proxy_result_.pEntries, 0,
  273. kMaxProxyEntryLimit * sizeof(WINHTTP_PROXY_RESULT_ENTRY));
  274. // The memory of the strings above will be backed by a vector of strings.
  275. proxy_list_.reserve(kMaxProxyEntryLimit);
  276. }
  277. // Data configurable by tests to simulate errors and results from WinHttp.
  278. bool open_success_ = true;
  279. bool set_timeouts_success_ = true;
  280. bool set_status_callback_success_ = true;
  281. bool get_ie_proxy_config_success_ = true;
  282. bool create_proxy_resolver_success_ = true;
  283. bool get_proxy_for_url_success_ = true;
  284. bool get_proxy_result_success_ = true;
  285. DWORD callback_status_ = WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE;
  286. std::unique_ptr<WINHTTP_ASYNC_RESULT> callback_info_;
  287. bool is_autoproxy_enabled_ = false;
  288. std::wstring pac_url_;
  289. std::wstring proxy_;
  290. std::wstring proxy_bypass_;
  291. WINHTTP_PROXY_RESULT proxy_result_ = {0};
  292. std::vector<std::wstring> proxy_list_;
  293. // Data used internally in the mock to function and validate its own behavior.
  294. bool did_call_open_ = false;
  295. bool did_call_set_timeouts_ = false;
  296. bool did_call_set_status_callback_ = false;
  297. bool did_call_get_ie_proxy_config_ = false;
  298. int proxy_resolver_identifier_ = 1;
  299. std::set<HINTERNET> opened_proxy_resolvers_;
  300. bool did_call_create_proxy_resolver_ = false;
  301. bool did_call_get_proxy_for_url_ = false;
  302. bool did_call_get_proxy_result_ = false;
  303. bool did_call_free_proxy_result_ = false;
  304. WINHTTP_STATUS_CALLBACK callback_ = nullptr;
  305. base::WeakPtrFactory<MockWinHttpAPIWrapper> weak_factory_{this};
  306. };
  307. } // namespace
  308. // These tests verify the behavior of the WindowsSystemProxyResolverImpl in
  309. // isolation by mocking out the WinHttpAPIWrapper it uses.
  310. class WindowsSystemProxyResolverImplTest : public testing::Test {
  311. public:
  312. void SetUp() override {
  313. testing::Test::SetUp();
  314. if (!net::WindowsSystemProxyResolutionService::IsSupported()) {
  315. GTEST_SKIP()
  316. << "Windows System Proxy Resolution is only supported on Windows 8+.";
  317. }
  318. proxy_resolver_ = std::make_unique<WindowsSystemProxyResolverImpl>(
  319. proxy_resolver_remote_.BindNewPipeAndPassReceiver());
  320. auto winhttp_api_wrapper = std::make_unique<MockWinHttpAPIWrapper>();
  321. winhttp_api_wrapper_ = winhttp_api_wrapper->GetWeakPtr();
  322. proxy_resolver_->SetCreateWinHttpAPIWrapperForTesting(
  323. std::move(winhttp_api_wrapper));
  324. }
  325. void TearDown() override {
  326. ResetProxyResolutionService();
  327. testing::Test::TearDown();
  328. }
  329. MockWinHttpAPIWrapper* winhttp_api_wrapper() {
  330. return winhttp_api_wrapper_.get();
  331. }
  332. void ValidateProxyResult(base::OnceClosure closure,
  333. const net::ProxyList& expected_proxy_list,
  334. net::WinHttpStatus expected_winhttp_status,
  335. int expected_windows_error,
  336. const net::ProxyList& actual_proxy_list,
  337. net::WinHttpStatus actual_winhttp_status,
  338. int actual_windows_error) {
  339. EXPECT_TRUE(expected_proxy_list.Equals(actual_proxy_list));
  340. EXPECT_EQ(expected_winhttp_status, actual_winhttp_status);
  341. EXPECT_EQ(expected_windows_error, actual_windows_error);
  342. std::move(closure).Run();
  343. }
  344. void PerformGetProxyForUrlAndValidateResult(const net::ProxyList& proxy_list,
  345. net::WinHttpStatus winhttp_status,
  346. int windows_error) {
  347. base::RunLoop run_loop;
  348. proxy_resolver_remote_->GetProxyForUrl(
  349. kUrl,
  350. base::BindOnce(&WindowsSystemProxyResolverImplTest::ValidateProxyResult,
  351. base::Unretained(this), run_loop.QuitClosure(),
  352. proxy_list, winhttp_status, windows_error));
  353. run_loop.Run();
  354. }
  355. // Tests that use DoFailedGetProxyForUrlTest validate failure conditions in
  356. // WindowsSystemProxyResolverImpl.
  357. void DoFailedGetProxyForUrlTest(net::WinHttpStatus winhttp_status,
  358. int windows_error) {
  359. PerformGetProxyForUrlAndValidateResult(net::ProxyList(), winhttp_status,
  360. windows_error);
  361. }
  362. // Tests that use DoProxyConfigTest validate that the proxy configs retrieved
  363. // from Windows can be read by WindowsSystemProxyResolverImpl.
  364. void DoProxyConfigTest(const net::ProxyConfig& proxy_config) {
  365. winhttp_api_wrapper()->AddToProxyResults(INTERNET_SCHEME_HTTPS, L"foopy",
  366. 8443);
  367. net::ProxyList proxy_list;
  368. proxy_list.AddProxyServer(
  369. net::PacResultElementToProxyServer("HTTPS foopy:8443"));
  370. std::wstring pac_url;
  371. if (proxy_config.has_pac_url())
  372. pac_url = base::UTF8ToWide(proxy_config.pac_url().spec());
  373. std::wstring proxy;
  374. if (!proxy_config.proxy_rules().single_proxies.IsEmpty()) {
  375. proxy = base::UTF8ToWide(
  376. proxy_config.proxy_rules().single_proxies.ToPacString());
  377. }
  378. std::wstring proxy_bypass;
  379. if (!proxy_config.proxy_rules().bypass_rules.ToString().empty()) {
  380. proxy_bypass =
  381. base::UTF8ToWide(proxy_config.proxy_rules().bypass_rules.ToString());
  382. }
  383. winhttp_api_wrapper_->set_ie_proxy_config(proxy_config.auto_detect(),
  384. pac_url, proxy, proxy_bypass);
  385. PerformGetProxyForUrlAndValidateResult(proxy_list, net::WinHttpStatus::kOk,
  386. 0);
  387. }
  388. // Tests that use DoGetProxyForUrlTest validate successful proxy retrievals.
  389. void DoGetProxyForUrlTest(const net::ProxyList& proxy_list) {
  390. PerformGetProxyForUrlAndValidateResult(proxy_list, net::WinHttpStatus::kOk,
  391. 0);
  392. }
  393. void ResetProxyResolutionService() {
  394. proxy_resolver_remote_.reset();
  395. winhttp_api_wrapper_.reset();
  396. proxy_resolver_.reset();
  397. }
  398. protected:
  399. mojo::Remote<mojom::WindowsSystemProxyResolver> proxy_resolver_remote_;
  400. private:
  401. base::test::TaskEnvironment task_environment_;
  402. std::unique_ptr<WindowsSystemProxyResolverImpl> proxy_resolver_;
  403. base::WeakPtr<MockWinHttpAPIWrapper> winhttp_api_wrapper_;
  404. };
  405. TEST_F(WindowsSystemProxyResolverImplTest, InitializeFailOnOpen) {
  406. winhttp_api_wrapper()->set_call_winhttp_open_success(false);
  407. DoFailedGetProxyForUrlTest(net::WinHttpStatus::kWinHttpOpenFailed, 0);
  408. }
  409. TEST_F(WindowsSystemProxyResolverImplTest, InitializeFailOnSetTimeouts) {
  410. winhttp_api_wrapper()->set_call_winhttp_set_timeouts_success(false);
  411. DoFailedGetProxyForUrlTest(net::WinHttpStatus::kWinHttpSetTimeoutsFailed, 0);
  412. }
  413. TEST_F(WindowsSystemProxyResolverImplTest, InitializeFailOnSetStatusCallback) {
  414. winhttp_api_wrapper()->set_call_winhttp_set_status_callback_success(false);
  415. DoFailedGetProxyForUrlTest(
  416. net::WinHttpStatus::kWinHttpSetStatusCallbackFailed, 0);
  417. }
  418. TEST_F(WindowsSystemProxyResolverImplTest,
  419. GetProxyForUrlFailOnGetIEProxySettings) {
  420. winhttp_api_wrapper()->set_call_winhttp_get_ie_proxy_config_success(false);
  421. DoFailedGetProxyForUrlTest(
  422. net::WinHttpStatus::kWinHttpGetIEProxyConfigForCurrentUserFailed, 0);
  423. }
  424. TEST_F(WindowsSystemProxyResolverImplTest,
  425. GetProxyForUrlFailOnCreateProxyResolver) {
  426. winhttp_api_wrapper()->set_call_winhttp_create_proxy_resolver_success(false);
  427. DoFailedGetProxyForUrlTest(
  428. net::WinHttpStatus::kWinHttpCreateProxyResolverFailed, 0);
  429. }
  430. TEST_F(WindowsSystemProxyResolverImplTest,
  431. GetProxyForUrlFailOnWinHttpGetProxyForUrlEx) {
  432. winhttp_api_wrapper()->set_call_winhttp_get_proxy_for_url_success(false);
  433. DoFailedGetProxyForUrlTest(net::WinHttpStatus::kWinHttpGetProxyForURLExFailed,
  434. 0);
  435. }
  436. TEST_F(WindowsSystemProxyResolverImplTest, GetProxyForUrlFailOnFailedCallback) {
  437. winhttp_api_wrapper()->SetCallbackStatusAndInfo(
  438. WINHTTP_CALLBACK_STATUS_REQUEST_ERROR, API_RECEIVE_RESPONSE);
  439. DoFailedGetProxyForUrlTest(net::WinHttpStatus::kStatusCallbackFailed,
  440. API_RECEIVE_RESPONSE);
  441. }
  442. TEST_F(WindowsSystemProxyResolverImplTest, GetProxyForUrlFailOnGetProxyResult) {
  443. winhttp_api_wrapper()->set_call_winhttp_get_proxy_result_success(false);
  444. DoFailedGetProxyForUrlTest(net::WinHttpStatus::kWinHttpGetProxyResultFailed,
  445. 0);
  446. }
  447. TEST_F(WindowsSystemProxyResolverImplTest, GetProxyForUrlFailOnNoResults) {
  448. DoFailedGetProxyForUrlTest(net::WinHttpStatus::kEmptyProxyList, 0);
  449. }
  450. TEST_F(WindowsSystemProxyResolverImplTest, GetProxyForUrlConfigDirect) {
  451. DoProxyConfigTest(net::ProxyConfig::CreateDirect());
  452. }
  453. TEST_F(WindowsSystemProxyResolverImplTest, GetProxyForUrlConfigAutoDetect) {
  454. DoProxyConfigTest(net::ProxyConfig::CreateAutoDetect());
  455. }
  456. TEST_F(WindowsSystemProxyResolverImplTest, GetProxyForUrlConfigPacUrl) {
  457. const GURL pac_url("http://pac-site.test/path/to/pac-url.pac");
  458. DoProxyConfigTest(net::ProxyConfig::CreateFromCustomPacURL(pac_url));
  459. }
  460. TEST_F(WindowsSystemProxyResolverImplTest, GetProxyForUrlConfigSingleProxy) {
  461. net::ProxyConfig config;
  462. const net::ProxyServer proxy_server =
  463. net::PacResultElementToProxyServer("HTTPS ignored:33");
  464. config.proxy_rules().single_proxies.AddProxyServer(proxy_server);
  465. DoProxyConfigTest(config);
  466. }
  467. TEST_F(WindowsSystemProxyResolverImplTest, GetProxyForUrlConfigBypass) {
  468. net::ProxyConfig config;
  469. config.proxy_rules().bypass_rules.AddRuleFromString("example.test");
  470. DoProxyConfigTest(config);
  471. }
  472. TEST_F(WindowsSystemProxyResolverImplTest,
  473. GetProxyForUrlConfigMultipleSettings) {
  474. net::ProxyConfig config;
  475. config.set_auto_detect(true);
  476. const GURL pac_url("http://pac-site.test/path/to/pac-url.pac");
  477. config.set_pac_url(pac_url);
  478. const net::ProxyServer proxy_server =
  479. net::PacResultElementToProxyServer("HTTPS ignored:33");
  480. config.proxy_rules().single_proxies.AddProxyServer(proxy_server);
  481. DoProxyConfigTest(config);
  482. }
  483. TEST_F(WindowsSystemProxyResolverImplTest, GetProxyForUrlDirect) {
  484. winhttp_api_wrapper()->AddDirectToProxyResults();
  485. net::ProxyList expected_proxy_list;
  486. expected_proxy_list.AddProxyServer(net::ProxyServer::Direct());
  487. DoGetProxyForUrlTest(expected_proxy_list);
  488. }
  489. TEST_F(WindowsSystemProxyResolverImplTest, GetProxyForUrlBypass) {
  490. winhttp_api_wrapper()->AddBypassToProxyResults();
  491. net::ProxyList expected_proxy_list;
  492. expected_proxy_list.AddProxyServer(net::ProxyServer::Direct());
  493. DoGetProxyForUrlTest(expected_proxy_list);
  494. }
  495. TEST_F(WindowsSystemProxyResolverImplTest, GetProxyForUrlHTTP) {
  496. winhttp_api_wrapper()->AddToProxyResults(INTERNET_SCHEME_HTTP, L"foopy",
  497. 8080);
  498. net::ProxyList expected_proxy_list;
  499. expected_proxy_list.AddProxyServer(
  500. net::PacResultElementToProxyServer("PROXY foopy:8080"));
  501. DoGetProxyForUrlTest(expected_proxy_list);
  502. }
  503. TEST_F(WindowsSystemProxyResolverImplTest, GetProxyForUrlHTTPS) {
  504. winhttp_api_wrapper()->AddToProxyResults(INTERNET_SCHEME_HTTPS, L"foopy",
  505. 8443);
  506. net::ProxyList expected_proxy_list;
  507. expected_proxy_list.AddProxyServer(
  508. net::PacResultElementToProxyServer("HTTPS foopy:8443"));
  509. DoGetProxyForUrlTest(expected_proxy_list);
  510. }
  511. TEST_F(WindowsSystemProxyResolverImplTest, GetProxyForUrlSOCKS) {
  512. winhttp_api_wrapper()->AddToProxyResults(INTERNET_SCHEME_SOCKS, L"foopy",
  513. 8080);
  514. net::ProxyList expected_proxy_list;
  515. expected_proxy_list.AddProxyServer(
  516. net::PacResultElementToProxyServer("SOCKS4 foopy:8080"));
  517. DoGetProxyForUrlTest(expected_proxy_list);
  518. }
  519. TEST_F(WindowsSystemProxyResolverImplTest, GetProxyForUrlIDNProxy) {
  520. winhttp_api_wrapper()->AddToProxyResults(INTERNET_SCHEME_HTTPS, L"föopy",
  521. 8080);
  522. // Expect L"föopy" to be ascii-encoded as "xn--fopy-5qa".
  523. net::ProxyList expected_proxy_list;
  524. expected_proxy_list.AddProxyServer(
  525. net::PacResultElementToProxyServer("HTTPS xn--fopy-5qa:8080"));
  526. DoGetProxyForUrlTest(expected_proxy_list);
  527. }
  528. TEST_F(WindowsSystemProxyResolverImplTest,
  529. GetProxyForUrlIgnoreInvalidProxyResults) {
  530. winhttp_api_wrapper()->AddToProxyResults(INTERNET_SCHEME_HTTP, L"foopy",
  531. INTERNET_DEFAULT_PORT);
  532. winhttp_api_wrapper()->AddToProxyResults(INTERNET_SCHEME_FTP, L"foopy", 80);
  533. winhttp_api_wrapper()->AddDirectToProxyResults();
  534. net::ProxyList expected_proxy_list;
  535. expected_proxy_list.AddProxyServer(net::ProxyServer::Direct());
  536. DoGetProxyForUrlTest(expected_proxy_list);
  537. }
  538. TEST_F(WindowsSystemProxyResolverImplTest, GetProxyForUrlMultipleResults) {
  539. winhttp_api_wrapper()->AddToProxyResults(INTERNET_SCHEME_HTTPS, L"foopy",
  540. 8443);
  541. winhttp_api_wrapper()->AddDirectToProxyResults();
  542. net::ProxyList expected_proxy_list;
  543. expected_proxy_list.AddProxyServer(
  544. net::PacResultElementToProxyServer("HTTPS foopy:8443"));
  545. expected_proxy_list.AddProxyServer(net::ProxyServer::Direct());
  546. DoGetProxyForUrlTest(expected_proxy_list);
  547. }
  548. } // namespace proxy_resolver_win