Remove BooleanPrefMember usage from Data Reduction Proxy IO classes.
[chromium-blink-merge.git] / net / proxy / proxy_service_unittest.cc
blob5a4ca69944c8760380d3527796be2f713a2f2299
1 // Copyright (c) 2012 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.
5 #include "net/proxy/proxy_service.h"
7 #include <vector>
9 #include "base/format_macros.h"
10 #include "base/logging.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "net/base/load_flags.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/network_delegate_impl.h"
16 #include "net/base/test_completion_callback.h"
17 #include "net/log/captured_net_log_entry.h"
18 #include "net/log/net_log.h"
19 #include "net/log/net_log_unittest.h"
20 #include "net/log/test_net_log.h"
21 #include "net/proxy/dhcp_proxy_script_fetcher.h"
22 #include "net/proxy/mock_proxy_resolver.h"
23 #include "net/proxy/mock_proxy_script_fetcher.h"
24 #include "net/proxy/proxy_config_service.h"
25 #include "net/proxy/proxy_resolver.h"
26 #include "net/proxy/proxy_script_fetcher.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "url/gurl.h"
30 using base::ASCIIToUTF16;
32 // TODO(eroman): Write a test which exercises
33 // ProxyService::SuspendAllPendingRequests().
34 namespace net {
35 namespace {
37 // This polling policy will decide to poll every 1 ms.
38 class ImmediatePollPolicy : public ProxyService::PacPollPolicy {
39 public:
40 ImmediatePollPolicy() {}
42 Mode GetNextDelay(int error,
43 base::TimeDelta current_delay,
44 base::TimeDelta* next_delay) const override {
45 *next_delay = base::TimeDelta::FromMilliseconds(1);
46 return MODE_USE_TIMER;
49 private:
50 DISALLOW_COPY_AND_ASSIGN(ImmediatePollPolicy);
53 // This polling policy chooses a fantastically large delay. In other words, it
54 // will never trigger a poll
55 class NeverPollPolicy : public ProxyService::PacPollPolicy {
56 public:
57 NeverPollPolicy() {}
59 Mode GetNextDelay(int error,
60 base::TimeDelta current_delay,
61 base::TimeDelta* next_delay) const override {
62 *next_delay = base::TimeDelta::FromDays(60);
63 return MODE_USE_TIMER;
66 private:
67 DISALLOW_COPY_AND_ASSIGN(NeverPollPolicy);
70 // This polling policy starts a poll immediately after network activity.
71 class ImmediateAfterActivityPollPolicy : public ProxyService::PacPollPolicy {
72 public:
73 ImmediateAfterActivityPollPolicy() {}
75 Mode GetNextDelay(int error,
76 base::TimeDelta current_delay,
77 base::TimeDelta* next_delay) const override {
78 *next_delay = base::TimeDelta();
79 return MODE_START_AFTER_ACTIVITY;
82 private:
83 DISALLOW_COPY_AND_ASSIGN(ImmediateAfterActivityPollPolicy);
86 // This test fixture is used to partially disable the background polling done by
87 // the ProxyService (which it uses to detect whenever its PAC script contents or
88 // WPAD results have changed).
90 // We disable the feature by setting the poll interval to something really
91 // large, so it will never actually be reached even on the slowest bots that run
92 // these tests.
94 // We disable the polling in order to avoid any timing dependencies in the
95 // tests. If the bot were to run the tests very slowly and we hadn't disabled
96 // polling, then it might start a background re-try in the middle of our test
97 // and confuse our expectations leading to flaky failures.
99 // The tests which verify the polling code re-enable the polling behavior but
100 // are careful to avoid timing problems.
101 class ProxyServiceTest : public testing::Test {
102 protected:
103 void SetUp() override {
104 testing::Test::SetUp();
105 previous_policy_ =
106 ProxyService::set_pac_script_poll_policy(&never_poll_policy_);
109 void TearDown() override {
110 // Restore the original policy.
111 ProxyService::set_pac_script_poll_policy(previous_policy_);
112 testing::Test::TearDown();
115 private:
116 NeverPollPolicy never_poll_policy_;
117 const ProxyService::PacPollPolicy* previous_policy_;
120 const char kValidPacScript1[] = "pac-script-v1-FindProxyForURL";
121 const char kValidPacScript2[] = "pac-script-v2-FindProxyForURL";
123 class MockProxyConfigService: public ProxyConfigService {
124 public:
125 explicit MockProxyConfigService(const ProxyConfig& config)
126 : availability_(CONFIG_VALID),
127 config_(config) {
130 explicit MockProxyConfigService(const std::string& pac_url)
131 : availability_(CONFIG_VALID),
132 config_(ProxyConfig::CreateFromCustomPacURL(GURL(pac_url))) {
135 void AddObserver(Observer* observer) override {
136 observers_.AddObserver(observer);
139 void RemoveObserver(Observer* observer) override {
140 observers_.RemoveObserver(observer);
143 ConfigAvailability GetLatestProxyConfig(ProxyConfig* results) override {
144 if (availability_ == CONFIG_VALID)
145 *results = config_;
146 return availability_;
149 void SetConfig(const ProxyConfig& config) {
150 availability_ = CONFIG_VALID;
151 config_ = config;
152 FOR_EACH_OBSERVER(Observer, observers_,
153 OnProxyConfigChanged(config_, availability_));
156 private:
157 ConfigAvailability availability_;
158 ProxyConfig config_;
159 ObserverList<Observer, true> observers_;
162 // A test network delegate that exercises the OnResolveProxy callback.
163 class TestResolveProxyNetworkDelegate : public NetworkDelegateImpl {
164 public:
165 TestResolveProxyNetworkDelegate()
166 : on_resolve_proxy_called_(false),
167 add_proxy_(false),
168 remove_proxy_(false),
169 proxy_service_(NULL) {
172 void OnResolveProxy(const GURL& url,
173 int load_flags,
174 const ProxyService& proxy_service,
175 ProxyInfo* result) override {
176 on_resolve_proxy_called_ = true;
177 proxy_service_ = &proxy_service;
178 DCHECK(!add_proxy_ || !remove_proxy_);
179 if (add_proxy_) {
180 result->UseNamedProxy("delegate_proxy.com");
181 } else if (remove_proxy_) {
182 result->UseDirect();
186 bool on_resolve_proxy_called() const {
187 return on_resolve_proxy_called_;
190 void set_add_proxy(bool add_proxy) {
191 add_proxy_ = add_proxy;
194 void set_remove_proxy(bool remove_proxy) {
195 remove_proxy_ = remove_proxy;
198 const ProxyService* proxy_service() const {
199 return proxy_service_;
202 private:
203 bool on_resolve_proxy_called_;
204 bool add_proxy_;
205 bool remove_proxy_;
206 const ProxyService* proxy_service_;
209 // A test network delegate that exercises the OnProxyFallback callback.
210 class TestProxyFallbackNetworkDelegate : public NetworkDelegateImpl {
211 public:
212 TestProxyFallbackNetworkDelegate()
213 : on_proxy_fallback_called_(false),
214 proxy_fallback_net_error_(OK) {
217 void OnProxyFallback(const ProxyServer& proxy_server,
218 int net_error) override {
219 proxy_server_ = proxy_server;
220 proxy_fallback_net_error_ = net_error;
221 on_proxy_fallback_called_ = true;
224 bool on_proxy_fallback_called() const {
225 return on_proxy_fallback_called_;
228 const ProxyServer& proxy_server() const {
229 return proxy_server_;
232 int proxy_fallback_net_error() const {
233 return proxy_fallback_net_error_;
236 private:
237 bool on_proxy_fallback_called_;
238 ProxyServer proxy_server_;
239 int proxy_fallback_net_error_;
242 } // namespace
244 TEST_F(ProxyServiceTest, Direct) {
245 MockAsyncProxyResolver resolver;
246 ProxyService service(
247 new MockProxyConfigService(ProxyConfig::CreateDirect()),
248 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
250 GURL url("http://www.google.com/");
252 ProxyInfo info;
253 TestCompletionCallback callback;
254 BoundTestNetLog log;
255 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(),
256 NULL, NULL, log.bound());
257 EXPECT_EQ(OK, rv);
258 EXPECT_TRUE(resolver.pending_requests().empty());
260 EXPECT_TRUE(info.is_direct());
261 EXPECT_TRUE(info.proxy_resolve_start_time().is_null());
262 EXPECT_TRUE(info.proxy_resolve_end_time().is_null());
264 // Check the NetLog was filled correctly.
265 CapturedNetLogEntry::List entries;
266 log.GetEntries(&entries);
268 EXPECT_EQ(3u, entries.size());
269 EXPECT_TRUE(LogContainsBeginEvent(
270 entries, 0, NetLog::TYPE_PROXY_SERVICE));
271 EXPECT_TRUE(LogContainsEvent(
272 entries, 1, NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST,
273 NetLog::PHASE_NONE));
274 EXPECT_TRUE(LogContainsEndEvent(
275 entries, 2, NetLog::TYPE_PROXY_SERVICE));
278 TEST_F(ProxyServiceTest, OnResolveProxyCallbackAddProxy) {
279 ProxyConfig config;
280 config.proxy_rules().ParseFromString("foopy1:8080");
281 config.set_auto_detect(false);
282 config.proxy_rules().bypass_rules.ParseFromString("*.org");
284 ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
286 GURL url("http://www.google.com/");
287 GURL bypass_url("http://internet.org");
289 ProxyInfo info;
290 TestCompletionCallback callback;
291 BoundTestNetLog log;
293 // First, warm up the ProxyService.
294 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(),
295 NULL, NULL, log.bound());
296 EXPECT_EQ(OK, rv);
298 // Verify that network delegate is invoked.
299 TestResolveProxyNetworkDelegate delegate;
300 rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(), NULL,
301 &delegate, log.bound());
302 EXPECT_TRUE(delegate.on_resolve_proxy_called());
303 EXPECT_EQ(&service, delegate.proxy_service());
305 // Verify that the NetworkDelegate's behavior is stateless across
306 // invocations of ResolveProxy. Start by having the callback add a proxy
307 // and checking that subsequent requests are not affected.
308 delegate.set_add_proxy(true);
310 // Callback should interpose:
311 rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(), NULL,
312 &delegate, log.bound());
313 EXPECT_FALSE(info.is_direct());
314 EXPECT_EQ(info.proxy_server().host_port_pair().host(), "delegate_proxy.com");
315 delegate.set_add_proxy(false);
317 // Check non-bypassed URL:
318 rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(), NULL,
319 &delegate, log.bound());
320 EXPECT_FALSE(info.is_direct());
321 EXPECT_EQ(info.proxy_server().host_port_pair().host(), "foopy1");
323 // Check bypassed URL:
324 rv = service.ResolveProxy(bypass_url, LOAD_NORMAL, &info, callback.callback(),
325 NULL, &delegate, log.bound());
326 EXPECT_TRUE(info.is_direct());
329 TEST_F(ProxyServiceTest, OnResolveProxyCallbackRemoveProxy) {
330 // Same as OnResolveProxyCallbackAddProxy, but verify that the
331 // NetworkDelegate's behavior is stateless across invocations after it
332 // *removes* a proxy.
333 ProxyConfig config;
334 config.proxy_rules().ParseFromString("foopy1:8080");
335 config.set_auto_detect(false);
336 config.proxy_rules().bypass_rules.ParseFromString("*.org");
338 ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
340 GURL url("http://www.google.com/");
341 GURL bypass_url("http://internet.org");
343 ProxyInfo info;
344 TestCompletionCallback callback;
345 BoundTestNetLog log;
347 // First, warm up the ProxyService.
348 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(),
349 NULL, NULL, log.bound());
350 EXPECT_EQ(OK, rv);
352 TestResolveProxyNetworkDelegate delegate;
353 delegate.set_remove_proxy(true);
355 // Callback should interpose:
356 rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(), NULL,
357 &delegate, log.bound());
358 EXPECT_TRUE(info.is_direct());
359 delegate.set_remove_proxy(false);
361 // Check non-bypassed URL:
362 rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(), NULL,
363 &delegate, log.bound());
364 EXPECT_FALSE(info.is_direct());
365 EXPECT_EQ(info.proxy_server().host_port_pair().host(), "foopy1");
367 // Check bypassed URL:
368 rv = service.ResolveProxy(bypass_url, LOAD_NORMAL, &info, callback.callback(),
369 NULL, &delegate, log.bound());
370 EXPECT_TRUE(info.is_direct());
373 TEST_F(ProxyServiceTest, PAC) {
374 MockProxyConfigService* config_service =
375 new MockProxyConfigService("http://foopy/proxy.pac");
377 MockAsyncProxyResolver resolver;
379 ProxyService service(
380 config_service,
381 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
383 GURL url("http://www.google.com/");
385 ProxyInfo info;
386 TestCompletionCallback callback;
387 ProxyService::PacRequest* request;
388 BoundTestNetLog log;
390 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(),
391 &request, NULL, log.bound());
392 EXPECT_EQ(ERR_IO_PENDING, rv);
394 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request));
396 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
397 resolver.pending_set_pac_script_request()->script_data()->url());
398 resolver.pending_set_pac_script_request()->CompleteNow(OK);
400 ASSERT_EQ(1u, resolver.pending_requests().size());
401 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
403 // Set the result in proxy resolver.
404 resolver.pending_requests()[0]->results()->UseNamedProxy("foopy");
405 resolver.pending_requests()[0]->CompleteNow(OK);
407 EXPECT_EQ(OK, callback.WaitForResult());
408 EXPECT_FALSE(info.is_direct());
409 EXPECT_EQ("foopy:80", info.proxy_server().ToURI());
410 EXPECT_TRUE(info.did_use_pac_script());
412 EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
413 EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
414 EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
416 // Check the NetLog was filled correctly.
417 CapturedNetLogEntry::List entries;
418 log.GetEntries(&entries);
420 EXPECT_EQ(5u, entries.size());
421 EXPECT_TRUE(LogContainsBeginEvent(
422 entries, 0, NetLog::TYPE_PROXY_SERVICE));
423 EXPECT_TRUE(LogContainsBeginEvent(
424 entries, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
425 EXPECT_TRUE(LogContainsEndEvent(
426 entries, 2, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
427 EXPECT_TRUE(LogContainsEndEvent(
428 entries, 4, NetLog::TYPE_PROXY_SERVICE));
431 // Test that the proxy resolver does not see the URL's username/password
432 // or its reference section.
433 TEST_F(ProxyServiceTest, PAC_NoIdentityOrHash) {
434 MockProxyConfigService* config_service =
435 new MockProxyConfigService("http://foopy/proxy.pac");
437 MockAsyncProxyResolver resolver;
439 ProxyService service(
440 config_service,
441 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
443 GURL url("http://username:password@www.google.com/?ref#hash#hash");
445 ProxyInfo info;
446 TestCompletionCallback callback;
447 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(),
448 NULL, NULL, BoundNetLog());
449 EXPECT_EQ(ERR_IO_PENDING, rv);
451 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
452 resolver.pending_set_pac_script_request()->script_data()->url());
453 resolver.pending_set_pac_script_request()->CompleteNow(OK);
455 ASSERT_EQ(1u, resolver.pending_requests().size());
456 // The URL should have been simplified, stripping the username/password/hash.
457 EXPECT_EQ(GURL("http://www.google.com/?ref"),
458 resolver.pending_requests()[0]->url());
460 // We end here without ever completing the request -- destruction of
461 // ProxyService will cancel the outstanding request.
464 TEST_F(ProxyServiceTest, PAC_FailoverWithoutDirect) {
465 MockProxyConfigService* config_service =
466 new MockProxyConfigService("http://foopy/proxy.pac");
467 MockAsyncProxyResolver resolver;
469 ProxyService service(
470 config_service,
471 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
473 GURL url("http://www.google.com/");
475 ProxyInfo info;
476 TestCompletionCallback callback1;
477 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
478 NULL, NULL, BoundNetLog());
479 EXPECT_EQ(ERR_IO_PENDING, rv);
481 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
482 resolver.pending_set_pac_script_request()->script_data()->url());
483 resolver.pending_set_pac_script_request()->CompleteNow(OK);
485 ASSERT_EQ(1u, resolver.pending_requests().size());
486 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
488 // Set the result in proxy resolver.
489 resolver.pending_requests()[0]->results()->UseNamedProxy("foopy:8080");
490 resolver.pending_requests()[0]->CompleteNow(OK);
492 EXPECT_EQ(OK, callback1.WaitForResult());
493 EXPECT_FALSE(info.is_direct());
494 EXPECT_EQ("foopy:8080", info.proxy_server().ToURI());
495 EXPECT_TRUE(info.did_use_pac_script());
497 EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
498 EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
499 EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
501 // Now, imagine that connecting to foopy:8080 fails: there is nothing
502 // left to fallback to, since our proxy list was NOT terminated by
503 // DIRECT.
504 NetworkDelegateImpl network_delegate;
505 TestCompletionCallback callback2;
506 ProxyServer expected_proxy_server = info.proxy_server();
507 rv = service.ReconsiderProxyAfterError(
508 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
509 callback2.callback(), NULL, &network_delegate, BoundNetLog());
510 // ReconsiderProxyAfterError returns error indicating nothing left.
511 EXPECT_EQ(ERR_FAILED, rv);
512 EXPECT_TRUE(info.is_empty());
515 // Test that if the execution of the PAC script fails (i.e. javascript runtime
516 // error), and the PAC settings are non-mandatory, that we fall-back to direct.
517 TEST_F(ProxyServiceTest, PAC_RuntimeError) {
518 MockProxyConfigService* config_service =
519 new MockProxyConfigService("http://foopy/proxy.pac");
520 MockAsyncProxyResolver resolver;
522 ProxyService service(
523 config_service,
524 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
526 GURL url("http://this-causes-js-error/");
528 ProxyInfo info;
529 TestCompletionCallback callback1;
530 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
531 NULL, NULL, BoundNetLog());
532 EXPECT_EQ(ERR_IO_PENDING, rv);
534 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
535 resolver.pending_set_pac_script_request()->script_data()->url());
536 resolver.pending_set_pac_script_request()->CompleteNow(OK);
538 ASSERT_EQ(1u, resolver.pending_requests().size());
539 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
541 // Simulate a failure in the PAC executor.
542 resolver.pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_FAILED);
544 EXPECT_EQ(OK, callback1.WaitForResult());
546 // Since the PAC script was non-mandatory, we should have fallen-back to
547 // DIRECT.
548 EXPECT_TRUE(info.is_direct());
549 EXPECT_TRUE(info.did_use_pac_script());
550 EXPECT_EQ(1, info.config_id());
552 EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
553 EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
554 EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
557 // The proxy list could potentially contain the DIRECT fallback choice
558 // in a location other than the very end of the list, and could even
559 // specify it multiple times.
561 // This is not a typical usage, but we will obey it.
562 // (If we wanted to disallow this type of input, the right place to
563 // enforce it would be in parsing the PAC result string).
565 // This test will use the PAC result string:
567 // "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20"
569 // For which we expect it to try DIRECT, then foobar:10, then DIRECT again,
570 // then foobar:20, and then give up and error.
572 // The important check of this test is to make sure that DIRECT is not somehow
573 // cached as being a bad proxy.
574 TEST_F(ProxyServiceTest, PAC_FailoverAfterDirect) {
575 MockProxyConfigService* config_service =
576 new MockProxyConfigService("http://foopy/proxy.pac");
577 MockAsyncProxyResolver resolver;
579 ProxyService service(
580 config_service,
581 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
583 GURL url("http://www.google.com/");
585 ProxyInfo info;
586 TestCompletionCallback callback1;
587 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
588 NULL, NULL, BoundNetLog());
589 EXPECT_EQ(ERR_IO_PENDING, rv);
591 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
592 resolver.pending_set_pac_script_request()->script_data()->url());
593 resolver.pending_set_pac_script_request()->CompleteNow(OK);
595 ASSERT_EQ(1u, resolver.pending_requests().size());
596 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
598 // Set the result in proxy resolver.
599 resolver.pending_requests()[0]->results()->UsePacString(
600 "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20");
601 resolver.pending_requests()[0]->CompleteNow(OK);
603 EXPECT_EQ(OK, callback1.WaitForResult());
604 EXPECT_TRUE(info.is_direct());
606 // Fallback 1.
607 TestCompletionCallback callback2;
608 rv = service.ReconsiderProxyAfterError(
609 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
610 callback2.callback(), NULL, NULL, BoundNetLog());
611 EXPECT_EQ(OK, rv);
612 EXPECT_FALSE(info.is_direct());
613 EXPECT_EQ("foobar:10", info.proxy_server().ToURI());
615 // Fallback 2.
616 NetworkDelegateImpl network_delegate;
617 ProxyServer expected_proxy_server3 = info.proxy_server();
618 TestCompletionCallback callback3;
619 rv = service.ReconsiderProxyAfterError(
620 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
621 callback3.callback(), NULL, &network_delegate, BoundNetLog());
622 EXPECT_EQ(OK, rv);
623 EXPECT_TRUE(info.is_direct());
625 // Fallback 3.
626 ProxyServer expected_proxy_server4 = info.proxy_server();
627 TestCompletionCallback callback4;
628 rv = service.ReconsiderProxyAfterError(
629 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
630 callback4.callback(), NULL, &network_delegate, BoundNetLog());
631 EXPECT_EQ(OK, rv);
632 EXPECT_FALSE(info.is_direct());
633 EXPECT_EQ("foobar:20", info.proxy_server().ToURI());
635 // Fallback 4 -- Nothing to fall back to!
636 ProxyServer expected_proxy_server5 = info.proxy_server();
637 TestCompletionCallback callback5;
638 rv = service.ReconsiderProxyAfterError(
639 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
640 callback5.callback(), NULL, &network_delegate, BoundNetLog());
641 EXPECT_EQ(ERR_FAILED, rv);
642 EXPECT_TRUE(info.is_empty());
645 TEST_F(ProxyServiceTest, PAC_ConfigSourcePropagates) {
646 // Test whether the ProxyConfigSource set by the ProxyConfigService is applied
647 // to ProxyInfo after the proxy is resolved via a PAC script.
648 ProxyConfig config =
649 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
650 config.set_source(PROXY_CONFIG_SOURCE_TEST);
652 MockProxyConfigService* config_service = new MockProxyConfigService(config);
653 MockAsyncProxyResolver resolver;
654 ProxyService service(
655 config_service,
656 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
658 // Resolve something.
659 GURL url("http://www.google.com/");
660 ProxyInfo info;
661 TestCompletionCallback callback;
662 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(),
663 NULL, NULL, BoundNetLog());
664 ASSERT_EQ(ERR_IO_PENDING, rv);
665 resolver.pending_set_pac_script_request()->CompleteNow(OK);
666 ASSERT_EQ(1u, resolver.pending_requests().size());
668 // Set the result in proxy resolver.
669 resolver.pending_requests()[0]->results()->UseNamedProxy("foopy");
670 resolver.pending_requests()[0]->CompleteNow(OK);
672 EXPECT_EQ(OK, callback.WaitForResult());
673 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
674 EXPECT_TRUE(info.did_use_pac_script());
676 EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
677 EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
678 EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
681 TEST_F(ProxyServiceTest, ProxyResolverFails) {
682 // Test what happens when the ProxyResolver fails. The download and setting
683 // of the PAC script have already succeeded, so this corresponds with a
684 // javascript runtime error while calling FindProxyForURL().
686 MockProxyConfigService* config_service =
687 new MockProxyConfigService("http://foopy/proxy.pac");
689 MockAsyncProxyResolver resolver;
691 ProxyService service(
692 config_service,
693 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
695 // Start first resolve request.
696 GURL url("http://www.google.com/");
697 ProxyInfo info;
698 TestCompletionCallback callback1;
699 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
700 NULL, NULL, BoundNetLog());
701 EXPECT_EQ(ERR_IO_PENDING, rv);
703 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
704 resolver.pending_set_pac_script_request()->script_data()->url());
705 resolver.pending_set_pac_script_request()->CompleteNow(OK);
707 ASSERT_EQ(1u, resolver.pending_requests().size());
708 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
710 // Fail the first resolve request in MockAsyncProxyResolver.
711 resolver.pending_requests()[0]->CompleteNow(ERR_FAILED);
713 // Although the proxy resolver failed the request, ProxyService implicitly
714 // falls-back to DIRECT.
715 EXPECT_EQ(OK, callback1.WaitForResult());
716 EXPECT_TRUE(info.is_direct());
718 // Failed PAC executions still have proxy resolution times.
719 EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
720 EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
721 EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
723 // The second resolve request will try to run through the proxy resolver,
724 // regardless of whether the first request failed in it.
725 TestCompletionCallback callback2;
726 rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback2.callback(), NULL,
727 NULL, BoundNetLog());
728 EXPECT_EQ(ERR_IO_PENDING, rv);
730 ASSERT_EQ(1u, resolver.pending_requests().size());
731 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
733 // This time we will have the resolver succeed (perhaps the PAC script has
734 // a dependency on the current time).
735 resolver.pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
736 resolver.pending_requests()[0]->CompleteNow(OK);
738 EXPECT_EQ(OK, callback2.WaitForResult());
739 EXPECT_FALSE(info.is_direct());
740 EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
743 TEST_F(ProxyServiceTest, ProxyResolverTerminatedDuringRequest) {
744 // Test what happens when the ProxyResolver fails with a fatal error while
745 // a GetProxyForURL() call is in progress.
747 MockProxyConfigService* config_service =
748 new MockProxyConfigService("http://foopy/proxy.pac");
750 MockAsyncProxyResolver resolver;
752 ProxyService service(
753 config_service,
754 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), nullptr);
756 // Start first resolve request.
757 GURL url("http://www.google.com/");
758 ProxyInfo info;
759 TestCompletionCallback callback1;
760 int rv =
761 service.ResolveProxy(url, net::LOAD_NORMAL, &info, callback1.callback(),
762 nullptr, nullptr, BoundNetLog());
763 EXPECT_EQ(ERR_IO_PENDING, rv);
765 ASSERT_TRUE(resolver.pending_set_pac_script_request());
766 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
767 resolver.pending_set_pac_script_request()->script_data()->url());
768 resolver.pending_set_pac_script_request()->CompleteNow(OK);
770 ASSERT_EQ(1u, resolver.pending_requests().size());
771 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
773 // Fail the first resolve request in MockAsyncProxyResolver.
774 resolver.pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_TERMINATED);
776 // Although the proxy resolver failed the request, ProxyService implicitly
777 // falls-back to DIRECT.
778 EXPECT_EQ(OK, callback1.WaitForResult());
779 EXPECT_TRUE(info.is_direct());
781 // Failed PAC executions still have proxy resolution times.
782 EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
783 EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
784 EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
786 // With no other requests, the ProxyService waits for a new request before
787 // initializing a new ProxyResolver.
788 EXPECT_FALSE(resolver.pending_set_pac_script_request());
790 TestCompletionCallback callback2;
791 rv = service.ResolveProxy(url, net::LOAD_NORMAL, &info, callback2.callback(),
792 nullptr, nullptr, BoundNetLog());
793 EXPECT_EQ(ERR_IO_PENDING, rv);
795 ASSERT_TRUE(resolver.pending_set_pac_script_request());
796 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
797 resolver.pending_set_pac_script_request()->script_data()->url());
798 resolver.pending_set_pac_script_request()->CompleteNow(OK);
800 ASSERT_EQ(1u, resolver.pending_requests().size());
801 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
803 // This time we will have the resolver succeed.
804 resolver.pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
805 resolver.pending_requests()[0]->CompleteNow(OK);
807 EXPECT_EQ(OK, callback2.WaitForResult());
808 EXPECT_FALSE(info.is_direct());
809 EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
812 TEST_F(ProxyServiceTest,
813 ProxyResolverTerminatedDuringRequestWithConcurrentRequest) {
814 // Test what happens when the ProxyResolver fails with a fatal error while
815 // a GetProxyForURL() call is in progress.
817 MockProxyConfigService* config_service =
818 new MockProxyConfigService("http://foopy/proxy.pac");
820 MockAsyncProxyResolver resolver;
822 ProxyService service(
823 config_service,
824 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), nullptr);
826 // Start two resolve requests.
827 GURL url1("http://www.google.com/");
828 GURL url2("https://www.google.com/");
829 ProxyInfo info;
830 TestCompletionCallback callback1;
831 int rv =
832 service.ResolveProxy(url1, net::LOAD_NORMAL, &info, callback1.callback(),
833 nullptr, nullptr, BoundNetLog());
834 EXPECT_EQ(ERR_IO_PENDING, rv);
835 TestCompletionCallback callback2;
836 rv = service.ResolveProxy(url2, net::LOAD_NORMAL, &info, callback2.callback(),
837 nullptr, nullptr, BoundNetLog());
838 EXPECT_EQ(ERR_IO_PENDING, rv);
840 ASSERT_TRUE(resolver.pending_set_pac_script_request());
841 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
842 resolver.pending_set_pac_script_request()->script_data()->url());
843 resolver.pending_set_pac_script_request()->CompleteNow(OK);
845 ASSERT_EQ(2u, resolver.pending_requests().size());
846 EXPECT_EQ(url1, resolver.pending_requests()[0]->url());
847 EXPECT_EQ(url2, resolver.pending_requests()[1]->url());
849 // Fail the first resolve request in MockAsyncProxyResolver.
850 resolver.pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_TERMINATED);
852 // Although the proxy resolver failed the request, ProxyService implicitly
853 // falls-back to DIRECT.
854 EXPECT_EQ(OK, callback1.WaitForResult());
855 EXPECT_TRUE(info.is_direct());
857 // Failed PAC executions still have proxy resolution times.
858 EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
859 EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
860 EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
862 // The second request is cancelled when the proxy resolver terminates.
863 ASSERT_EQ(1u, resolver.cancelled_requests().size());
864 EXPECT_EQ(url2, resolver.cancelled_requests()[0]->url());
866 // Since a second request was in progress, the ProxyService starts
867 // initializating a new ProxyResolver.
868 ASSERT_TRUE(resolver.pending_set_pac_script_request());
869 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
870 resolver.pending_set_pac_script_request()->script_data()->url());
871 resolver.pending_set_pac_script_request()->CompleteNow(OK);
873 ASSERT_EQ(1u, resolver.pending_requests().size());
874 EXPECT_EQ(url2, resolver.pending_requests()[0]->url());
876 // This request succeeds.
877 resolver.pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
878 resolver.pending_requests()[0]->CompleteNow(OK);
880 EXPECT_EQ(OK, callback2.WaitForResult());
881 EXPECT_FALSE(info.is_direct());
882 EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
885 TEST_F(ProxyServiceTest, ProxyScriptFetcherFailsDownloadingMandatoryPac) {
886 // Test what happens when the ProxyScriptResolver fails to download a
887 // mandatory PAC script.
889 ProxyConfig config(
890 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
891 config.set_pac_mandatory(true);
893 MockProxyConfigService* config_service = new MockProxyConfigService(config);
895 MockAsyncProxyResolver resolver;
897 ProxyService service(
898 config_service,
899 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
901 // Start first resolve request.
902 GURL url("http://www.google.com/");
903 ProxyInfo info;
904 TestCompletionCallback callback1;
905 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
906 NULL, NULL, BoundNetLog());
907 EXPECT_EQ(ERR_IO_PENDING, rv);
909 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
910 resolver.pending_set_pac_script_request()->script_data()->url());
911 resolver.pending_set_pac_script_request()->CompleteNow(ERR_FAILED);
913 ASSERT_EQ(0u, resolver.pending_requests().size());
914 // As the proxy resolver failed the request and is configured for a mandatory
915 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
916 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
917 callback1.WaitForResult());
918 EXPECT_FALSE(info.is_direct());
920 // As the proxy resolver failed the request and is configured for a mandatory
921 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
922 TestCompletionCallback callback2;
923 rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback2.callback(), NULL,
924 NULL, BoundNetLog());
925 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, rv);
926 EXPECT_FALSE(info.is_direct());
929 TEST_F(ProxyServiceTest, ProxyResolverFailsParsingJavaScriptMandatoryPac) {
930 // Test what happens when the ProxyResolver fails that is configured to use a
931 // mandatory PAC script. The download of the PAC script has already
932 // succeeded but the PAC script contains no valid javascript.
934 ProxyConfig config(
935 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
936 config.set_pac_mandatory(true);
938 MockProxyConfigService* config_service = new MockProxyConfigService(config);
940 MockAsyncProxyResolverExpectsBytes resolver;
942 ProxyService service(
943 config_service,
944 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
946 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
947 DhcpProxyScriptFetcher* dhcp_fetcher = new DoNothingDhcpProxyScriptFetcher();
948 service.SetProxyScriptFetchers(fetcher, dhcp_fetcher);
950 // Start resolve request.
951 GURL url("http://www.google.com/");
952 ProxyInfo info;
953 TestCompletionCallback callback;
954 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(),
955 NULL, NULL, BoundNetLog());
956 EXPECT_EQ(ERR_IO_PENDING, rv);
958 // Check that nothing has been sent to the proxy resolver yet.
959 ASSERT_EQ(0u, resolver.pending_requests().size());
961 // Downloading the PAC script succeeds.
962 EXPECT_TRUE(fetcher->has_pending_request());
963 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
964 fetcher->NotifyFetchCompletion(OK, "invalid-script-contents");
966 EXPECT_FALSE(fetcher->has_pending_request());
967 ASSERT_EQ(0u, resolver.pending_requests().size());
969 // Since ProxyScriptDecider failed to identify a valid PAC and PAC was
970 // mandatory for this configuration, the ProxyService must not implicitly
971 // fall-back to DIRECT.
972 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
973 callback.WaitForResult());
974 EXPECT_FALSE(info.is_direct());
977 TEST_F(ProxyServiceTest, ProxyResolverFailsInJavaScriptMandatoryPac) {
978 // Test what happens when the ProxyResolver fails that is configured to use a
979 // mandatory PAC script. The download and setting of the PAC script have
980 // already succeeded, so this corresponds with a javascript runtime error
981 // while calling FindProxyForURL().
983 ProxyConfig config(
984 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
985 config.set_pac_mandatory(true);
987 MockProxyConfigService* config_service = new MockProxyConfigService(config);
989 MockAsyncProxyResolver resolver;
991 ProxyService service(
992 config_service,
993 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
995 // Start first resolve request.
996 GURL url("http://www.google.com/");
997 ProxyInfo info;
998 TestCompletionCallback callback1;
999 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
1000 NULL, NULL, BoundNetLog());
1001 EXPECT_EQ(ERR_IO_PENDING, rv);
1003 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1004 resolver.pending_set_pac_script_request()->script_data()->url());
1005 resolver.pending_set_pac_script_request()->CompleteNow(OK);
1007 ASSERT_EQ(1u, resolver.pending_requests().size());
1008 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
1010 // Fail the first resolve request in MockAsyncProxyResolver.
1011 resolver.pending_requests()[0]->CompleteNow(ERR_FAILED);
1013 // As the proxy resolver failed the request and is configured for a mandatory
1014 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
1015 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
1016 callback1.WaitForResult());
1017 EXPECT_FALSE(info.is_direct());
1019 // The second resolve request will try to run through the proxy resolver,
1020 // regardless of whether the first request failed in it.
1021 TestCompletionCallback callback2;
1022 rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback2.callback(), NULL,
1023 NULL, BoundNetLog());
1024 EXPECT_EQ(ERR_IO_PENDING, rv);
1026 ASSERT_EQ(1u, resolver.pending_requests().size());
1027 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
1029 // This time we will have the resolver succeed (perhaps the PAC script has
1030 // a dependency on the current time).
1031 resolver.pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
1032 resolver.pending_requests()[0]->CompleteNow(OK);
1034 EXPECT_EQ(OK, callback2.WaitForResult());
1035 EXPECT_FALSE(info.is_direct());
1036 EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
1039 TEST_F(ProxyServiceTest, ProxyFallback) {
1040 // Test what happens when we specify multiple proxy servers and some of them
1041 // are bad.
1043 MockProxyConfigService* config_service =
1044 new MockProxyConfigService("http://foopy/proxy.pac");
1046 MockAsyncProxyResolver resolver;
1048 ProxyService service(
1049 config_service,
1050 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
1052 GURL url("http://www.google.com/");
1054 // Get the proxy information.
1055 ProxyInfo info;
1056 TestCompletionCallback callback1;
1057 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
1058 NULL, NULL, BoundNetLog());
1059 EXPECT_EQ(ERR_IO_PENDING, rv);
1061 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1062 resolver.pending_set_pac_script_request()->script_data()->url());
1063 resolver.pending_set_pac_script_request()->CompleteNow(OK);
1065 ASSERT_EQ(1u, resolver.pending_requests().size());
1066 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
1068 // Set the result in proxy resolver.
1069 resolver.pending_requests()[0]->results()->UseNamedProxy(
1070 "foopy1:8080;foopy2:9090");
1071 resolver.pending_requests()[0]->CompleteNow(OK);
1073 // The first item is valid.
1074 EXPECT_EQ(OK, callback1.WaitForResult());
1075 EXPECT_FALSE(info.is_direct());
1076 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
1078 EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
1079 EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
1080 EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
1081 base::TimeTicks proxy_resolve_start_time = info.proxy_resolve_start_time();
1082 base::TimeTicks proxy_resolve_end_time = info.proxy_resolve_end_time();
1084 // Fake an error on the proxy.
1085 TestCompletionCallback callback2;
1086 rv = service.ReconsiderProxyAfterError(
1087 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
1088 callback2.callback(), NULL, NULL, BoundNetLog());
1089 EXPECT_EQ(OK, rv);
1091 // Proxy times should not have been modified by fallback.
1092 EXPECT_EQ(proxy_resolve_start_time, info.proxy_resolve_start_time());
1093 EXPECT_EQ(proxy_resolve_end_time, info.proxy_resolve_end_time());
1095 // The second proxy should be specified.
1096 EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
1097 // Report back that the second proxy worked. This will globally mark the
1098 // first proxy as bad.
1099 TestProxyFallbackNetworkDelegate test_delegate;
1100 service.ReportSuccess(info, &test_delegate);
1101 EXPECT_EQ("foopy1:8080", test_delegate.proxy_server().ToURI());
1102 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED,
1103 test_delegate.proxy_fallback_net_error());
1105 TestCompletionCallback callback3;
1106 rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback3.callback(), NULL,
1107 NULL, BoundNetLog());
1108 EXPECT_EQ(ERR_IO_PENDING, rv);
1110 ASSERT_EQ(1u, resolver.pending_requests().size());
1111 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
1113 // Set the result in proxy resolver -- the second result is already known
1114 // to be bad, so we will not try to use it initially.
1115 resolver.pending_requests()[0]->results()->UseNamedProxy(
1116 "foopy3:7070;foopy1:8080;foopy2:9090");
1117 resolver.pending_requests()[0]->CompleteNow(OK);
1119 EXPECT_EQ(OK, callback3.WaitForResult());
1120 EXPECT_FALSE(info.is_direct());
1121 EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI());
1123 // Proxy times should have been updated, so get them again.
1124 EXPECT_LE(proxy_resolve_end_time, info.proxy_resolve_start_time());
1125 EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
1126 EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
1127 EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
1128 proxy_resolve_start_time = info.proxy_resolve_start_time();
1129 proxy_resolve_end_time = info.proxy_resolve_end_time();
1131 // We fake another error. It should now try the third one.
1132 TestCompletionCallback callback4;
1133 rv = service.ReconsiderProxyAfterError(
1134 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
1135 callback4.callback(), NULL, NULL, BoundNetLog());
1136 EXPECT_EQ(OK, rv);
1137 EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
1139 // We fake another error. At this point we have tried all of the
1140 // proxy servers we thought were valid; next we try the proxy server
1141 // that was in our bad proxies map (foopy1:8080).
1142 TestCompletionCallback callback5;
1143 rv = service.ReconsiderProxyAfterError(
1144 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
1145 callback5.callback(), NULL, NULL, BoundNetLog());
1146 EXPECT_EQ(OK, rv);
1147 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
1149 // Fake another error, the last proxy is gone, the list should now be empty,
1150 // so there is nothing left to try.
1151 TestCompletionCallback callback6;
1152 rv = service.ReconsiderProxyAfterError(
1153 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
1154 callback6.callback(), NULL, NULL, BoundNetLog());
1155 EXPECT_EQ(ERR_FAILED, rv);
1156 EXPECT_FALSE(info.is_direct());
1157 EXPECT_TRUE(info.is_empty());
1159 // Proxy times should not have been modified by fallback.
1160 EXPECT_EQ(proxy_resolve_start_time, info.proxy_resolve_start_time());
1161 EXPECT_EQ(proxy_resolve_end_time, info.proxy_resolve_end_time());
1163 // Look up proxies again
1164 TestCompletionCallback callback7;
1165 rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback7.callback(), NULL,
1166 NULL, BoundNetLog());
1167 EXPECT_EQ(ERR_IO_PENDING, rv);
1169 ASSERT_EQ(1u, resolver.pending_requests().size());
1170 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
1172 // This time, the first 3 results have been found to be bad, but only the
1173 // first proxy has been confirmed ...
1174 resolver.pending_requests()[0]->results()->UseNamedProxy(
1175 "foopy1:8080;foopy3:7070;foopy2:9090;foopy4:9091");
1176 resolver.pending_requests()[0]->CompleteNow(OK);
1178 // ... therefore, we should see the second proxy first.
1179 EXPECT_EQ(OK, callback7.WaitForResult());
1180 EXPECT_FALSE(info.is_direct());
1181 EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI());
1183 EXPECT_LE(proxy_resolve_end_time, info.proxy_resolve_start_time());
1184 EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
1185 EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
1186 // TODO(nsylvain): Test that the proxy can be retried after the delay.
1189 // This test is similar to ProxyFallback, but this time we have an explicit
1190 // fallback choice to DIRECT.
1191 TEST_F(ProxyServiceTest, ProxyFallbackToDirect) {
1192 MockProxyConfigService* config_service =
1193 new MockProxyConfigService("http://foopy/proxy.pac");
1195 MockAsyncProxyResolver resolver;
1197 ProxyService service(
1198 config_service,
1199 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
1201 GURL url("http://www.google.com/");
1203 // Get the proxy information.
1204 ProxyInfo info;
1205 TestCompletionCallback callback1;
1206 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
1207 NULL, NULL, BoundNetLog());
1208 EXPECT_EQ(ERR_IO_PENDING, rv);
1210 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1211 resolver.pending_set_pac_script_request()->script_data()->url());
1212 resolver.pending_set_pac_script_request()->CompleteNow(OK);
1214 ASSERT_EQ(1u, resolver.pending_requests().size());
1215 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
1217 // Set the result in proxy resolver.
1218 resolver.pending_requests()[0]->results()->UsePacString(
1219 "PROXY foopy1:8080; PROXY foopy2:9090; DIRECT");
1220 resolver.pending_requests()[0]->CompleteNow(OK);
1222 // Get the first result.
1223 EXPECT_EQ(OK, callback1.WaitForResult());
1224 EXPECT_FALSE(info.is_direct());
1225 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
1227 // Fake an error on the proxy.
1228 TestCompletionCallback callback2;
1229 rv = service.ReconsiderProxyAfterError(
1230 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
1231 callback2.callback(), NULL, NULL, BoundNetLog());
1232 EXPECT_EQ(OK, rv);
1234 // Now we get back the second proxy.
1235 EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
1237 // Fake an error on this proxy as well.
1238 TestCompletionCallback callback3;
1239 rv = service.ReconsiderProxyAfterError(
1240 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
1241 callback3.callback(), NULL, NULL, BoundNetLog());
1242 EXPECT_EQ(OK, rv);
1244 // Finally, we get back DIRECT.
1245 EXPECT_TRUE(info.is_direct());
1247 EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
1248 EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
1249 EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
1251 // Now we tell the proxy service that even DIRECT failed.
1252 TestCompletionCallback callback4;
1253 rv = service.ReconsiderProxyAfterError(
1254 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
1255 callback4.callback(), NULL, NULL, BoundNetLog());
1256 // There was nothing left to try after DIRECT, so we are out of
1257 // choices.
1258 EXPECT_EQ(ERR_FAILED, rv);
1261 TEST_F(ProxyServiceTest, ProxyFallback_NewSettings) {
1262 // Test proxy failover when new settings are available.
1264 MockProxyConfigService* config_service =
1265 new MockProxyConfigService("http://foopy/proxy.pac");
1267 MockAsyncProxyResolver resolver;
1269 ProxyService service(
1270 config_service,
1271 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
1273 GURL url("http://www.google.com/");
1275 // Get the proxy information.
1276 ProxyInfo info;
1277 TestCompletionCallback callback1;
1278 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
1279 NULL, NULL, BoundNetLog());
1280 EXPECT_EQ(ERR_IO_PENDING, rv);
1282 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1283 resolver.pending_set_pac_script_request()->script_data()->url());
1284 resolver.pending_set_pac_script_request()->CompleteNow(OK);
1286 ASSERT_EQ(1u, resolver.pending_requests().size());
1287 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
1289 // Set the result in proxy resolver.
1290 resolver.pending_requests()[0]->results()->UseNamedProxy(
1291 "foopy1:8080;foopy2:9090");
1292 resolver.pending_requests()[0]->CompleteNow(OK);
1294 // The first item is valid.
1295 EXPECT_EQ(OK, callback1.WaitForResult());
1296 EXPECT_FALSE(info.is_direct());
1297 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
1299 // Fake an error on the proxy, and also a new configuration on the proxy.
1300 config_service->SetConfig(
1301 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy-new/proxy.pac")));
1303 TestCompletionCallback callback2;
1304 rv = service.ReconsiderProxyAfterError(
1305 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
1306 callback2.callback(), NULL, NULL, BoundNetLog());
1307 EXPECT_EQ(ERR_IO_PENDING, rv);
1309 EXPECT_EQ(GURL("http://foopy-new/proxy.pac"),
1310 resolver.pending_set_pac_script_request()->script_data()->url());
1311 resolver.pending_set_pac_script_request()->CompleteNow(OK);
1313 ASSERT_EQ(1u, resolver.pending_requests().size());
1314 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
1316 resolver.pending_requests()[0]->results()->UseNamedProxy(
1317 "foopy1:8080;foopy2:9090");
1318 resolver.pending_requests()[0]->CompleteNow(OK);
1320 // The first proxy is still there since the configuration changed.
1321 EXPECT_EQ(OK, callback2.WaitForResult());
1322 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
1324 // We fake another error. It should now ignore the first one.
1325 TestCompletionCallback callback3;
1326 rv = service.ReconsiderProxyAfterError(
1327 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
1328 callback3.callback(), NULL, NULL, BoundNetLog());
1329 EXPECT_EQ(OK, rv);
1330 EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
1332 // We simulate a new configuration.
1333 config_service->SetConfig(
1334 ProxyConfig::CreateFromCustomPacURL(
1335 GURL("http://foopy-new2/proxy.pac")));
1337 // We fake another error. It should go back to the first proxy.
1338 TestCompletionCallback callback4;
1339 rv = service.ReconsiderProxyAfterError(
1340 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
1341 callback4.callback(), NULL, NULL, BoundNetLog());
1342 EXPECT_EQ(ERR_IO_PENDING, rv);
1344 EXPECT_EQ(GURL("http://foopy-new2/proxy.pac"),
1345 resolver.pending_set_pac_script_request()->script_data()->url());
1346 resolver.pending_set_pac_script_request()->CompleteNow(OK);
1348 ASSERT_EQ(1u, resolver.pending_requests().size());
1349 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
1351 resolver.pending_requests()[0]->results()->UseNamedProxy(
1352 "foopy1:8080;foopy2:9090");
1353 resolver.pending_requests()[0]->CompleteNow(OK);
1355 EXPECT_EQ(OK, callback4.WaitForResult());
1356 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
1358 EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
1359 EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
1360 EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
1363 TEST_F(ProxyServiceTest, ProxyFallback_BadConfig) {
1364 // Test proxy failover when the configuration is bad.
1366 MockProxyConfigService* config_service =
1367 new MockProxyConfigService("http://foopy/proxy.pac");
1369 MockAsyncProxyResolver resolver;
1371 ProxyService service(
1372 config_service,
1373 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
1375 GURL url("http://www.google.com/");
1377 // Get the proxy information.
1378 ProxyInfo info;
1379 TestCompletionCallback callback1;
1380 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
1381 NULL, NULL, BoundNetLog());
1382 EXPECT_EQ(ERR_IO_PENDING, rv);
1384 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1385 resolver.pending_set_pac_script_request()->script_data()->url());
1386 resolver.pending_set_pac_script_request()->CompleteNow(OK);
1387 ASSERT_EQ(1u, resolver.pending_requests().size());
1388 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
1390 resolver.pending_requests()[0]->results()->UseNamedProxy(
1391 "foopy1:8080;foopy2:9090");
1392 resolver.pending_requests()[0]->CompleteNow(OK);
1394 // The first item is valid.
1395 EXPECT_EQ(OK, callback1.WaitForResult());
1396 EXPECT_FALSE(info.is_direct());
1397 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
1399 // Fake a proxy error.
1400 TestCompletionCallback callback2;
1401 rv = service.ReconsiderProxyAfterError(
1402 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
1403 callback2.callback(), NULL, NULL, BoundNetLog());
1404 EXPECT_EQ(OK, rv);
1406 // The first proxy is ignored, and the second one is selected.
1407 EXPECT_FALSE(info.is_direct());
1408 EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
1410 // Fake a PAC failure.
1411 ProxyInfo info2;
1412 TestCompletionCallback callback3;
1413 rv = service.ResolveProxy(url, LOAD_NORMAL, &info2, callback3.callback(),
1414 NULL, NULL, BoundNetLog());
1415 EXPECT_EQ(ERR_IO_PENDING, rv);
1417 ASSERT_EQ(1u, resolver.pending_requests().size());
1418 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
1420 // This simulates a javascript runtime error in the PAC script.
1421 resolver.pending_requests()[0]->CompleteNow(ERR_FAILED);
1423 // Although the resolver failed, the ProxyService will implicitly fall-back
1424 // to a DIRECT connection.
1425 EXPECT_EQ(OK, callback3.WaitForResult());
1426 EXPECT_TRUE(info2.is_direct());
1427 EXPECT_FALSE(info2.is_empty());
1429 // The PAC script will work properly next time and successfully return a
1430 // proxy list. Since we have not marked the configuration as bad, it should
1431 // "just work" the next time we call it.
1432 ProxyInfo info3;
1433 TestCompletionCallback callback4;
1434 rv = service.ReconsiderProxyAfterError(
1435 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info3,
1436 callback4.callback(), NULL, NULL, BoundNetLog());
1437 EXPECT_EQ(ERR_IO_PENDING, rv);
1439 ASSERT_EQ(1u, resolver.pending_requests().size());
1440 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
1442 resolver.pending_requests()[0]->results()->UseNamedProxy(
1443 "foopy1:8080;foopy2:9090");
1444 resolver.pending_requests()[0]->CompleteNow(OK);
1446 // The first proxy is not there since the it was added to the bad proxies
1447 // list by the earlier ReconsiderProxyAfterError().
1448 EXPECT_EQ(OK, callback4.WaitForResult());
1449 EXPECT_FALSE(info3.is_direct());
1450 EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI());
1452 EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
1453 EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
1454 EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
1457 TEST_F(ProxyServiceTest, ProxyFallback_BadConfigMandatory) {
1458 // Test proxy failover when the configuration is bad.
1460 ProxyConfig config(
1461 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
1463 config.set_pac_mandatory(true);
1464 MockProxyConfigService* config_service = new MockProxyConfigService(config);
1466 MockAsyncProxyResolver resolver;
1468 ProxyService service(
1469 config_service,
1470 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
1472 GURL url("http://www.google.com/");
1474 // Get the proxy information.
1475 ProxyInfo info;
1476 TestCompletionCallback callback1;
1477 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
1478 NULL, NULL, BoundNetLog());
1479 EXPECT_EQ(ERR_IO_PENDING, rv);
1481 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1482 resolver.pending_set_pac_script_request()->script_data()->url());
1483 resolver.pending_set_pac_script_request()->CompleteNow(OK);
1484 ASSERT_EQ(1u, resolver.pending_requests().size());
1485 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
1487 resolver.pending_requests()[0]->results()->UseNamedProxy(
1488 "foopy1:8080;foopy2:9090");
1489 resolver.pending_requests()[0]->CompleteNow(OK);
1491 // The first item is valid.
1492 EXPECT_EQ(OK, callback1.WaitForResult());
1493 EXPECT_FALSE(info.is_direct());
1494 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
1496 // Fake a proxy error.
1497 TestCompletionCallback callback2;
1498 rv = service.ReconsiderProxyAfterError(
1499 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
1500 callback2.callback(), NULL, NULL, BoundNetLog());
1501 EXPECT_EQ(OK, rv);
1503 // The first proxy is ignored, and the second one is selected.
1504 EXPECT_FALSE(info.is_direct());
1505 EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
1507 // Fake a PAC failure.
1508 ProxyInfo info2;
1509 TestCompletionCallback callback3;
1510 rv = service.ResolveProxy(url, LOAD_NORMAL, &info2, callback3.callback(),
1511 NULL, NULL, BoundNetLog());
1512 EXPECT_EQ(ERR_IO_PENDING, rv);
1514 ASSERT_EQ(1u, resolver.pending_requests().size());
1515 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
1517 // This simulates a javascript runtime error in the PAC script.
1518 resolver.pending_requests()[0]->CompleteNow(ERR_FAILED);
1520 // Although the resolver failed, the ProxyService will NOT fall-back
1521 // to a DIRECT connection as it is configured as mandatory.
1522 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
1523 callback3.WaitForResult());
1524 EXPECT_FALSE(info2.is_direct());
1525 EXPECT_TRUE(info2.is_empty());
1527 // The PAC script will work properly next time and successfully return a
1528 // proxy list. Since we have not marked the configuration as bad, it should
1529 // "just work" the next time we call it.
1530 ProxyInfo info3;
1531 TestCompletionCallback callback4;
1532 rv = service.ReconsiderProxyAfterError(
1533 url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info3,
1534 callback4.callback(), NULL, NULL, BoundNetLog());
1535 EXPECT_EQ(ERR_IO_PENDING, rv);
1537 ASSERT_EQ(1u, resolver.pending_requests().size());
1538 EXPECT_EQ(url, resolver.pending_requests()[0]->url());
1540 resolver.pending_requests()[0]->results()->UseNamedProxy(
1541 "foopy1:8080;foopy2:9090");
1542 resolver.pending_requests()[0]->CompleteNow(OK);
1544 // The first proxy is not there since the it was added to the bad proxies
1545 // list by the earlier ReconsiderProxyAfterError().
1546 EXPECT_EQ(OK, callback4.WaitForResult());
1547 EXPECT_FALSE(info3.is_direct());
1548 EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI());
1551 TEST_F(ProxyServiceTest, ProxyBypassList) {
1552 // Test that the proxy bypass rules are consulted.
1554 TestCompletionCallback callback[2];
1555 ProxyInfo info[2];
1556 ProxyConfig config;
1557 config.proxy_rules().ParseFromString("foopy1:8080;foopy2:9090");
1558 config.set_auto_detect(false);
1559 config.proxy_rules().bypass_rules.ParseFromString("*.org");
1561 ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
1563 int rv;
1564 GURL url1("http://www.webkit.org");
1565 GURL url2("http://www.webkit.com");
1567 // Request for a .org domain should bypass proxy.
1568 rv = service.ResolveProxy(url1, LOAD_NORMAL, &info[0], callback[0].callback(),
1569 NULL, NULL, BoundNetLog());
1570 EXPECT_EQ(OK, rv);
1571 EXPECT_TRUE(info[0].is_direct());
1573 // Request for a .com domain hits the proxy.
1574 rv = service.ResolveProxy(url2, LOAD_NORMAL, &info[1], callback[1].callback(),
1575 NULL, NULL, BoundNetLog());
1576 EXPECT_EQ(OK, rv);
1577 EXPECT_EQ("foopy1:8080", info[1].proxy_server().ToURI());
1581 TEST_F(ProxyServiceTest, PerProtocolProxyTests) {
1582 ProxyConfig config;
1583 config.proxy_rules().ParseFromString("http=foopy1:8080;https=foopy2:8080");
1584 config.set_auto_detect(false);
1586 ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
1587 GURL test_url("http://www.msn.com");
1588 ProxyInfo info;
1589 TestCompletionCallback callback;
1590 int rv =
1591 service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
1592 NULL, NULL, BoundNetLog());
1593 EXPECT_EQ(OK, rv);
1594 EXPECT_FALSE(info.is_direct());
1595 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
1598 ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
1599 GURL test_url("ftp://ftp.google.com");
1600 ProxyInfo info;
1601 TestCompletionCallback callback;
1602 int rv =
1603 service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
1604 NULL, NULL, BoundNetLog());
1605 EXPECT_EQ(OK, rv);
1606 EXPECT_TRUE(info.is_direct());
1607 EXPECT_EQ("direct://", info.proxy_server().ToURI());
1610 ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
1611 GURL test_url("https://webbranch.techcu.com");
1612 ProxyInfo info;
1613 TestCompletionCallback callback;
1614 int rv =
1615 service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
1616 NULL, NULL, BoundNetLog());
1617 EXPECT_EQ(OK, rv);
1618 EXPECT_FALSE(info.is_direct());
1619 EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
1622 config.proxy_rules().ParseFromString("foopy1:8080");
1623 ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
1624 GURL test_url("http://www.microsoft.com");
1625 ProxyInfo info;
1626 TestCompletionCallback callback;
1627 int rv =
1628 service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
1629 NULL, NULL, BoundNetLog());
1630 EXPECT_EQ(OK, rv);
1631 EXPECT_FALSE(info.is_direct());
1632 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
1636 TEST_F(ProxyServiceTest, ProxyConfigSourcePropagates) {
1637 // Test that the proxy config source is set correctly when resolving proxies
1638 // using manual proxy rules. Namely, the config source should only be set if
1639 // any of the rules were applied.
1641 ProxyConfig config;
1642 config.set_source(PROXY_CONFIG_SOURCE_TEST);
1643 config.proxy_rules().ParseFromString("https=foopy2:8080");
1644 ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
1645 GURL test_url("http://www.google.com");
1646 ProxyInfo info;
1647 TestCompletionCallback callback;
1648 int rv =
1649 service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
1650 NULL, NULL, BoundNetLog());
1651 ASSERT_EQ(OK, rv);
1652 // Should be SOURCE_TEST, even if there are no HTTP proxies configured.
1653 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
1656 ProxyConfig config;
1657 config.set_source(PROXY_CONFIG_SOURCE_TEST);
1658 config.proxy_rules().ParseFromString("https=foopy2:8080");
1659 ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
1660 GURL test_url("https://www.google.com");
1661 ProxyInfo info;
1662 TestCompletionCallback callback;
1663 int rv =
1664 service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
1665 NULL, NULL, BoundNetLog());
1666 ASSERT_EQ(OK, rv);
1667 // Used the HTTPS proxy. So source should be TEST.
1668 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
1671 ProxyConfig config;
1672 config.set_source(PROXY_CONFIG_SOURCE_TEST);
1673 ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
1674 GURL test_url("http://www.google.com");
1675 ProxyInfo info;
1676 TestCompletionCallback callback;
1677 int rv =
1678 service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
1679 NULL, NULL, BoundNetLog());
1680 ASSERT_EQ(OK, rv);
1681 // ProxyConfig is empty. Source should still be TEST.
1682 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
1686 // If only HTTP and a SOCKS proxy are specified, check if ftp/https queries
1687 // fall back to the SOCKS proxy.
1688 TEST_F(ProxyServiceTest, DefaultProxyFallbackToSOCKS) {
1689 ProxyConfig config;
1690 config.proxy_rules().ParseFromString("http=foopy1:8080;socks=foopy2:1080");
1691 config.set_auto_detect(false);
1692 EXPECT_EQ(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
1693 config.proxy_rules().type);
1696 ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
1697 GURL test_url("http://www.msn.com");
1698 ProxyInfo info;
1699 TestCompletionCallback callback;
1700 int rv =
1701 service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
1702 NULL, NULL, BoundNetLog());
1703 EXPECT_EQ(OK, rv);
1704 EXPECT_FALSE(info.is_direct());
1705 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
1708 ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
1709 GURL test_url("ftp://ftp.google.com");
1710 ProxyInfo info;
1711 TestCompletionCallback callback;
1712 int rv =
1713 service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
1714 NULL, NULL, BoundNetLog());
1715 EXPECT_EQ(OK, rv);
1716 EXPECT_FALSE(info.is_direct());
1717 EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
1720 ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
1721 GURL test_url("https://webbranch.techcu.com");
1722 ProxyInfo info;
1723 TestCompletionCallback callback;
1724 int rv =
1725 service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
1726 NULL, NULL, BoundNetLog());
1727 EXPECT_EQ(OK, rv);
1728 EXPECT_FALSE(info.is_direct());
1729 EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
1732 ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
1733 GURL test_url("unknown://www.microsoft.com");
1734 ProxyInfo info;
1735 TestCompletionCallback callback;
1736 int rv =
1737 service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
1738 NULL, NULL, BoundNetLog());
1739 EXPECT_EQ(OK, rv);
1740 EXPECT_FALSE(info.is_direct());
1741 EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
1745 // Test cancellation of an in-progress request.
1746 TEST_F(ProxyServiceTest, CancelInProgressRequest) {
1747 MockProxyConfigService* config_service =
1748 new MockProxyConfigService("http://foopy/proxy.pac");
1750 MockAsyncProxyResolver resolver;
1752 ProxyService service(
1753 config_service,
1754 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
1756 // Start 3 requests.
1758 ProxyInfo info1;
1759 TestCompletionCallback callback1;
1760 int rv =
1761 service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
1762 callback1.callback(), NULL, NULL, BoundNetLog());
1763 EXPECT_EQ(ERR_IO_PENDING, rv);
1765 // Nothing has been sent to the proxy resolver yet, since the proxy
1766 // resolver has not been configured yet.
1767 ASSERT_EQ(0u, resolver.pending_requests().size());
1769 // Successfully initialize the PAC script.
1770 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1771 resolver.pending_set_pac_script_request()->script_data()->url());
1772 resolver.pending_set_pac_script_request()->CompleteNow(OK);
1774 ASSERT_EQ(1u, resolver.pending_requests().size());
1775 EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());
1777 ProxyInfo info2;
1778 TestCompletionCallback callback2;
1779 ProxyService::PacRequest* request2;
1780 rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
1781 callback2.callback(), &request2, NULL,
1782 BoundNetLog());
1783 EXPECT_EQ(ERR_IO_PENDING, rv);
1784 ASSERT_EQ(2u, resolver.pending_requests().size());
1785 EXPECT_EQ(GURL("http://request2"), resolver.pending_requests()[1]->url());
1787 ProxyInfo info3;
1788 TestCompletionCallback callback3;
1789 rv = service.ResolveProxy(GURL("http://request3"), LOAD_NORMAL, &info3,
1790 callback3.callback(), NULL, NULL, BoundNetLog());
1791 EXPECT_EQ(ERR_IO_PENDING, rv);
1792 ASSERT_EQ(3u, resolver.pending_requests().size());
1793 EXPECT_EQ(GURL("http://request3"), resolver.pending_requests()[2]->url());
1795 // Cancel the second request
1796 service.CancelPacRequest(request2);
1798 ASSERT_EQ(2u, resolver.pending_requests().size());
1799 EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());
1800 EXPECT_EQ(GURL("http://request3"), resolver.pending_requests()[1]->url());
1802 // Complete the two un-cancelled requests.
1803 // We complete the last one first, just to mix it up a bit.
1804 resolver.pending_requests()[1]->results()->UseNamedProxy("request3:80");
1805 resolver.pending_requests()[1]->CompleteNow(OK);
1807 resolver.pending_requests()[0]->results()->UseNamedProxy("request1:80");
1808 resolver.pending_requests()[0]->CompleteNow(OK);
1810 // Complete and verify that requests ran as expected.
1811 EXPECT_EQ(OK, callback1.WaitForResult());
1812 EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
1814 EXPECT_FALSE(callback2.have_result()); // Cancelled.
1815 ASSERT_EQ(1u, resolver.cancelled_requests().size());
1816 EXPECT_EQ(GURL("http://request2"), resolver.cancelled_requests()[0]->url());
1818 EXPECT_EQ(OK, callback3.WaitForResult());
1819 EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
1822 // Test the initial PAC download for resolver that expects bytes.
1823 TEST_F(ProxyServiceTest, InitialPACScriptDownload) {
1824 MockProxyConfigService* config_service =
1825 new MockProxyConfigService("http://foopy/proxy.pac");
1827 MockAsyncProxyResolverExpectsBytes resolver;
1829 ProxyService service(
1830 config_service,
1831 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
1833 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
1834 service.SetProxyScriptFetchers(fetcher,
1835 new DoNothingDhcpProxyScriptFetcher());
1837 // Start 3 requests.
1839 ProxyInfo info1;
1840 TestCompletionCallback callback1;
1841 ProxyService::PacRequest* request1;
1842 int rv = service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
1843 callback1.callback(), &request1, NULL,
1844 BoundNetLog());
1845 EXPECT_EQ(ERR_IO_PENDING, rv);
1847 // The first request should have triggered download of PAC script.
1848 EXPECT_TRUE(fetcher->has_pending_request());
1849 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
1851 ProxyInfo info2;
1852 TestCompletionCallback callback2;
1853 ProxyService::PacRequest* request2;
1854 rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
1855 callback2.callback(), &request2, NULL,
1856 BoundNetLog());
1857 EXPECT_EQ(ERR_IO_PENDING, rv);
1859 ProxyInfo info3;
1860 TestCompletionCallback callback3;
1861 ProxyService::PacRequest* request3;
1862 rv = service.ResolveProxy(GURL("http://request3"), LOAD_NORMAL, &info3,
1863 callback3.callback(), &request3, NULL,
1864 BoundNetLog());
1865 EXPECT_EQ(ERR_IO_PENDING, rv);
1867 // Nothing has been sent to the resolver yet.
1868 EXPECT_TRUE(resolver.pending_requests().empty());
1870 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
1871 service.GetLoadState(request1));
1872 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
1873 service.GetLoadState(request2));
1874 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
1875 service.GetLoadState(request3));
1877 // At this point the ProxyService should be waiting for the
1878 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1879 // PAC script download completion.
1880 fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
1882 // Now that the PAC script is downloaded, it will have been sent to the proxy
1883 // resolver.
1884 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
1885 resolver.pending_set_pac_script_request()->script_data()->utf16());
1886 resolver.pending_set_pac_script_request()->CompleteNow(OK);
1888 ASSERT_EQ(3u, resolver.pending_requests().size());
1889 EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());
1890 EXPECT_EQ(GURL("http://request2"), resolver.pending_requests()[1]->url());
1891 EXPECT_EQ(GURL("http://request3"), resolver.pending_requests()[2]->url());
1893 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request1));
1894 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request2));
1895 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request3));
1897 // Complete all the requests (in some order).
1898 // Note that as we complete requests, they shift up in |pending_requests()|.
1900 resolver.pending_requests()[2]->results()->UseNamedProxy("request3:80");
1901 resolver.pending_requests()[2]->CompleteNow(OK);
1903 resolver.pending_requests()[0]->results()->UseNamedProxy("request1:80");
1904 resolver.pending_requests()[0]->CompleteNow(OK);
1906 resolver.pending_requests()[0]->results()->UseNamedProxy("request2:80");
1907 resolver.pending_requests()[0]->CompleteNow(OK);
1909 // Complete and verify that requests ran as expected.
1910 EXPECT_EQ(OK, callback1.WaitForResult());
1911 EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
1912 EXPECT_FALSE(info1.proxy_resolve_start_time().is_null());
1913 EXPECT_FALSE(info1.proxy_resolve_end_time().is_null());
1914 EXPECT_LE(info1.proxy_resolve_start_time(), info1.proxy_resolve_end_time());
1916 EXPECT_EQ(OK, callback2.WaitForResult());
1917 EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
1918 EXPECT_FALSE(info2.proxy_resolve_start_time().is_null());
1919 EXPECT_FALSE(info2.proxy_resolve_end_time().is_null());
1920 EXPECT_LE(info2.proxy_resolve_start_time(), info2.proxy_resolve_end_time());
1922 EXPECT_EQ(OK, callback3.WaitForResult());
1923 EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
1924 EXPECT_FALSE(info3.proxy_resolve_start_time().is_null());
1925 EXPECT_FALSE(info3.proxy_resolve_end_time().is_null());
1926 EXPECT_LE(info3.proxy_resolve_start_time(), info3.proxy_resolve_end_time());
1929 // Test changing the ProxyScriptFetcher while PAC download is in progress.
1930 TEST_F(ProxyServiceTest, ChangeScriptFetcherWhilePACDownloadInProgress) {
1931 MockProxyConfigService* config_service =
1932 new MockProxyConfigService("http://foopy/proxy.pac");
1934 MockAsyncProxyResolverExpectsBytes resolver;
1936 ProxyService service(
1937 config_service,
1938 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
1940 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
1941 service.SetProxyScriptFetchers(fetcher,
1942 new DoNothingDhcpProxyScriptFetcher());
1944 // Start 2 requests.
1946 ProxyInfo info1;
1947 TestCompletionCallback callback1;
1948 int rv =
1949 service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
1950 callback1.callback(), NULL, NULL, BoundNetLog());
1951 EXPECT_EQ(ERR_IO_PENDING, rv);
1953 // The first request should have triggered download of PAC script.
1954 EXPECT_TRUE(fetcher->has_pending_request());
1955 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
1957 ProxyInfo info2;
1958 TestCompletionCallback callback2;
1959 rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
1960 callback2.callback(), NULL, NULL, BoundNetLog());
1961 EXPECT_EQ(ERR_IO_PENDING, rv);
1963 // At this point the ProxyService should be waiting for the
1964 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1965 // PAC script download completion.
1967 // We now change out the ProxyService's script fetcher. We should restart
1968 // the initialization with the new fetcher.
1970 fetcher = new MockProxyScriptFetcher;
1971 service.SetProxyScriptFetchers(fetcher,
1972 new DoNothingDhcpProxyScriptFetcher());
1974 // Nothing has been sent to the resolver yet.
1975 EXPECT_TRUE(resolver.pending_requests().empty());
1977 fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
1979 // Now that the PAC script is downloaded, it will have been sent to the proxy
1980 // resolver.
1981 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
1982 resolver.pending_set_pac_script_request()->script_data()->utf16());
1983 resolver.pending_set_pac_script_request()->CompleteNow(OK);
1985 ASSERT_EQ(2u, resolver.pending_requests().size());
1986 EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());
1987 EXPECT_EQ(GURL("http://request2"), resolver.pending_requests()[1]->url());
1990 // Test cancellation of a request, while the PAC script is being fetched.
1991 TEST_F(ProxyServiceTest, CancelWhilePACFetching) {
1992 MockProxyConfigService* config_service =
1993 new MockProxyConfigService("http://foopy/proxy.pac");
1995 MockAsyncProxyResolverExpectsBytes resolver;
1997 ProxyService service(
1998 config_service,
1999 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
2001 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
2002 service.SetProxyScriptFetchers(fetcher,
2003 new DoNothingDhcpProxyScriptFetcher());
2005 // Start 3 requests.
2006 ProxyInfo info1;
2007 TestCompletionCallback callback1;
2008 ProxyService::PacRequest* request1;
2009 BoundTestNetLog log1;
2010 int rv =
2011 service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
2012 callback1.callback(), &request1, NULL, log1.bound());
2013 EXPECT_EQ(ERR_IO_PENDING, rv);
2015 // The first request should have triggered download of PAC script.
2016 EXPECT_TRUE(fetcher->has_pending_request());
2017 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
2019 ProxyInfo info2;
2020 TestCompletionCallback callback2;
2021 ProxyService::PacRequest* request2;
2022 rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
2023 callback2.callback(), &request2, NULL,
2024 BoundNetLog());
2025 EXPECT_EQ(ERR_IO_PENDING, rv);
2027 ProxyInfo info3;
2028 TestCompletionCallback callback3;
2029 rv = service.ResolveProxy(GURL("http://request3"), LOAD_NORMAL, &info3,
2030 callback3.callback(), NULL, NULL, BoundNetLog());
2031 EXPECT_EQ(ERR_IO_PENDING, rv);
2033 // Nothing has been sent to the resolver yet.
2034 EXPECT_TRUE(resolver.pending_requests().empty());
2036 // Cancel the first 2 requests.
2037 service.CancelPacRequest(request1);
2038 service.CancelPacRequest(request2);
2040 // At this point the ProxyService should be waiting for the
2041 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2042 // PAC script download completion.
2043 fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
2045 // Now that the PAC script is downloaded, it will have been sent to the
2046 // proxy resolver.
2047 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
2048 resolver.pending_set_pac_script_request()->script_data()->utf16());
2049 resolver.pending_set_pac_script_request()->CompleteNow(OK);
2051 ASSERT_EQ(1u, resolver.pending_requests().size());
2052 EXPECT_EQ(GURL("http://request3"), resolver.pending_requests()[0]->url());
2054 // Complete all the requests.
2055 resolver.pending_requests()[0]->results()->UseNamedProxy("request3:80");
2056 resolver.pending_requests()[0]->CompleteNow(OK);
2058 EXPECT_EQ(OK, callback3.WaitForResult());
2059 EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
2061 EXPECT_TRUE(resolver.cancelled_requests().empty());
2063 EXPECT_FALSE(callback1.have_result()); // Cancelled.
2064 EXPECT_FALSE(callback2.have_result()); // Cancelled.
2066 CapturedNetLogEntry::List entries1;
2067 log1.GetEntries(&entries1);
2069 // Check the NetLog for request 1 (which was cancelled) got filled properly.
2070 EXPECT_EQ(4u, entries1.size());
2071 EXPECT_TRUE(LogContainsBeginEvent(
2072 entries1, 0, NetLog::TYPE_PROXY_SERVICE));
2073 EXPECT_TRUE(LogContainsBeginEvent(
2074 entries1, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
2075 // Note that TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC is never completed before
2076 // the cancellation occured.
2077 EXPECT_TRUE(LogContainsEvent(
2078 entries1, 2, NetLog::TYPE_CANCELLED, NetLog::PHASE_NONE));
2079 EXPECT_TRUE(LogContainsEndEvent(
2080 entries1, 3, NetLog::TYPE_PROXY_SERVICE));
2083 // Test that if auto-detect fails, we fall-back to the custom pac.
2084 TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac) {
2085 ProxyConfig config;
2086 config.set_auto_detect(true);
2087 config.set_pac_url(GURL("http://foopy/proxy.pac"));
2088 config.proxy_rules().ParseFromString("http=foopy:80"); // Won't be used.
2090 MockProxyConfigService* config_service = new MockProxyConfigService(config);
2091 MockAsyncProxyResolverExpectsBytes resolver;
2092 ProxyService service(
2093 config_service,
2094 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
2096 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
2097 service.SetProxyScriptFetchers(fetcher,
2098 new DoNothingDhcpProxyScriptFetcher());
2100 // Start 2 requests.
2102 ProxyInfo info1;
2103 TestCompletionCallback callback1;
2104 int rv =
2105 service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
2106 callback1.callback(), NULL, NULL, BoundNetLog());
2107 EXPECT_EQ(ERR_IO_PENDING, rv);
2109 ProxyInfo info2;
2110 TestCompletionCallback callback2;
2111 ProxyService::PacRequest* request2;
2112 rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
2113 callback2.callback(), &request2, NULL,
2114 BoundNetLog());
2115 EXPECT_EQ(ERR_IO_PENDING, rv);
2117 // Check that nothing has been sent to the proxy resolver yet.
2118 ASSERT_EQ(0u, resolver.pending_requests().size());
2120 // It should be trying to auto-detect first -- FAIL the autodetect during
2121 // the script download.
2122 EXPECT_TRUE(fetcher->has_pending_request());
2123 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
2124 fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
2126 // Next it should be trying the custom PAC url.
2127 EXPECT_TRUE(fetcher->has_pending_request());
2128 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
2129 fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
2131 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
2132 resolver.pending_set_pac_script_request()->script_data()->utf16());
2133 resolver.pending_set_pac_script_request()->CompleteNow(OK);
2135 // Now finally, the pending requests should have been sent to the resolver
2136 // (which was initialized with custom PAC script).
2138 ASSERT_EQ(2u, resolver.pending_requests().size());
2139 EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());
2140 EXPECT_EQ(GURL("http://request2"), resolver.pending_requests()[1]->url());
2142 // Complete the pending requests.
2143 resolver.pending_requests()[1]->results()->UseNamedProxy("request2:80");
2144 resolver.pending_requests()[1]->CompleteNow(OK);
2145 resolver.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2146 resolver.pending_requests()[0]->CompleteNow(OK);
2148 // Verify that requests ran as expected.
2149 EXPECT_EQ(OK, callback1.WaitForResult());
2150 EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
2151 EXPECT_FALSE(info1.proxy_resolve_start_time().is_null());
2152 EXPECT_FALSE(info1.proxy_resolve_end_time().is_null());
2153 EXPECT_LE(info1.proxy_resolve_start_time(), info1.proxy_resolve_end_time());
2155 EXPECT_EQ(OK, callback2.WaitForResult());
2156 EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
2157 EXPECT_FALSE(info2.proxy_resolve_start_time().is_null());
2158 EXPECT_FALSE(info2.proxy_resolve_end_time().is_null());
2159 EXPECT_LE(info2.proxy_resolve_start_time(), info2.proxy_resolve_end_time());
2162 // This is the same test as FallbackFromAutodetectToCustomPac, except
2163 // the auto-detect script fails parsing rather than downloading.
2164 TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac2) {
2165 ProxyConfig config;
2166 config.set_auto_detect(true);
2167 config.set_pac_url(GURL("http://foopy/proxy.pac"));
2168 config.proxy_rules().ParseFromString("http=foopy:80"); // Won't be used.
2170 MockProxyConfigService* config_service = new MockProxyConfigService(config);
2171 MockAsyncProxyResolverExpectsBytes resolver;
2172 ProxyService service(
2173 config_service,
2174 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
2176 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
2177 service.SetProxyScriptFetchers(fetcher,
2178 new DoNothingDhcpProxyScriptFetcher());
2180 // Start 2 requests.
2182 ProxyInfo info1;
2183 TestCompletionCallback callback1;
2184 int rv =
2185 service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
2186 callback1.callback(), NULL, NULL, BoundNetLog());
2187 EXPECT_EQ(ERR_IO_PENDING, rv);
2189 ProxyInfo info2;
2190 TestCompletionCallback callback2;
2191 ProxyService::PacRequest* request2;
2192 rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
2193 callback2.callback(), &request2, NULL,
2194 BoundNetLog());
2195 EXPECT_EQ(ERR_IO_PENDING, rv);
2197 // Check that nothing has been sent to the proxy resolver yet.
2198 ASSERT_EQ(0u, resolver.pending_requests().size());
2200 // It should be trying to auto-detect first -- succeed the download.
2201 EXPECT_TRUE(fetcher->has_pending_request());
2202 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
2203 fetcher->NotifyFetchCompletion(OK, "invalid-script-contents");
2205 // The script contents passed failed basic verification step (since didn't
2206 // contain token FindProxyForURL), so it was never passed to the resolver.
2208 // Next it should be trying the custom PAC url.
2209 EXPECT_TRUE(fetcher->has_pending_request());
2210 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
2211 fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
2213 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
2214 resolver.pending_set_pac_script_request()->script_data()->utf16());
2215 resolver.pending_set_pac_script_request()->CompleteNow(OK);
2217 // Now finally, the pending requests should have been sent to the resolver
2218 // (which was initialized with custom PAC script).
2220 ASSERT_EQ(2u, resolver.pending_requests().size());
2221 EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());
2222 EXPECT_EQ(GURL("http://request2"), resolver.pending_requests()[1]->url());
2224 // Complete the pending requests.
2225 resolver.pending_requests()[1]->results()->UseNamedProxy("request2:80");
2226 resolver.pending_requests()[1]->CompleteNow(OK);
2227 resolver.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2228 resolver.pending_requests()[0]->CompleteNow(OK);
2230 // Verify that requests ran as expected.
2231 EXPECT_EQ(OK, callback1.WaitForResult());
2232 EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
2234 EXPECT_EQ(OK, callback2.WaitForResult());
2235 EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
2238 // Test that if all of auto-detect, a custom PAC script, and manual settings
2239 // are given, then we will try them in that order.
2240 TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomToManual) {
2241 ProxyConfig config;
2242 config.set_auto_detect(true);
2243 config.set_pac_url(GURL("http://foopy/proxy.pac"));
2244 config.proxy_rules().ParseFromString("http=foopy:80");
2246 MockProxyConfigService* config_service = new MockProxyConfigService(config);
2247 MockAsyncProxyResolverExpectsBytes resolver;
2248 ProxyService service(
2249 config_service,
2250 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
2252 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
2253 service.SetProxyScriptFetchers(fetcher,
2254 new DoNothingDhcpProxyScriptFetcher());
2256 // Start 2 requests.
2258 ProxyInfo info1;
2259 TestCompletionCallback callback1;
2260 int rv =
2261 service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
2262 callback1.callback(), NULL, NULL, BoundNetLog());
2263 EXPECT_EQ(ERR_IO_PENDING, rv);
2265 ProxyInfo info2;
2266 TestCompletionCallback callback2;
2267 ProxyService::PacRequest* request2;
2268 rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
2269 callback2.callback(), &request2, NULL,
2270 BoundNetLog());
2271 EXPECT_EQ(ERR_IO_PENDING, rv);
2273 // Check that nothing has been sent to the proxy resolver yet.
2274 ASSERT_EQ(0u, resolver.pending_requests().size());
2276 // It should be trying to auto-detect first -- fail the download.
2277 EXPECT_TRUE(fetcher->has_pending_request());
2278 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
2279 fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
2281 // Next it should be trying the custom PAC url -- fail the download.
2282 EXPECT_TRUE(fetcher->has_pending_request());
2283 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
2284 fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
2286 // Since we never managed to initialize a resolver, nothing should have been
2287 // sent to it.
2288 ASSERT_EQ(0u, resolver.pending_requests().size());
2290 // Verify that requests ran as expected -- they should have fallen back to
2291 // the manual proxy configuration for HTTP urls.
2292 EXPECT_EQ(OK, callback1.WaitForResult());
2293 EXPECT_EQ("foopy:80", info1.proxy_server().ToURI());
2295 EXPECT_EQ(OK, callback2.WaitForResult());
2296 EXPECT_EQ("foopy:80", info2.proxy_server().ToURI());
2299 // Test that the bypass rules are NOT applied when using autodetect.
2300 TEST_F(ProxyServiceTest, BypassDoesntApplyToPac) {
2301 ProxyConfig config;
2302 config.set_auto_detect(true);
2303 config.set_pac_url(GURL("http://foopy/proxy.pac"));
2304 config.proxy_rules().ParseFromString("http=foopy:80"); // Not used.
2305 config.proxy_rules().bypass_rules.ParseFromString("www.google.com");
2307 MockProxyConfigService* config_service = new MockProxyConfigService(config);
2308 MockAsyncProxyResolverExpectsBytes resolver;
2309 ProxyService service(
2310 config_service,
2311 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
2313 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
2314 service.SetProxyScriptFetchers(fetcher,
2315 new DoNothingDhcpProxyScriptFetcher());
2317 // Start 1 requests.
2319 ProxyInfo info1;
2320 TestCompletionCallback callback1;
2321 int rv =
2322 service.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL, &info1,
2323 callback1.callback(), NULL, NULL, BoundNetLog());
2324 EXPECT_EQ(ERR_IO_PENDING, rv);
2326 // Check that nothing has been sent to the proxy resolver yet.
2327 ASSERT_EQ(0u, resolver.pending_requests().size());
2329 // It should be trying to auto-detect first -- succeed the download.
2330 EXPECT_TRUE(fetcher->has_pending_request());
2331 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
2332 fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
2334 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
2335 resolver.pending_set_pac_script_request()->script_data()->utf16());
2336 resolver.pending_set_pac_script_request()->CompleteNow(OK);
2338 ASSERT_EQ(1u, resolver.pending_requests().size());
2339 EXPECT_EQ(GURL("http://www.google.com"),
2340 resolver.pending_requests()[0]->url());
2342 // Complete the pending request.
2343 resolver.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2344 resolver.pending_requests()[0]->CompleteNow(OK);
2346 // Verify that request ran as expected.
2347 EXPECT_EQ(OK, callback1.WaitForResult());
2348 EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
2350 // Start another request, it should pickup the bypass item.
2351 ProxyInfo info2;
2352 TestCompletionCallback callback2;
2353 rv = service.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL, &info2,
2354 callback2.callback(), NULL, NULL, BoundNetLog());
2355 EXPECT_EQ(ERR_IO_PENDING, rv);
2357 ASSERT_EQ(1u, resolver.pending_requests().size());
2358 EXPECT_EQ(GURL("http://www.google.com"),
2359 resolver.pending_requests()[0]->url());
2361 // Complete the pending request.
2362 resolver.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2363 resolver.pending_requests()[0]->CompleteNow(OK);
2365 EXPECT_EQ(OK, callback2.WaitForResult());
2366 EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
2369 // Delete the ProxyService while InitProxyResolver has an outstanding
2370 // request to the script fetcher. When run under valgrind, should not
2371 // have any memory errors (used to be that the ProxyScriptFetcher was
2372 // being deleted prior to the InitProxyResolver).
2373 TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingFetch) {
2374 ProxyConfig config =
2375 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
2377 MockProxyConfigService* config_service = new MockProxyConfigService(config);
2378 MockAsyncProxyResolverExpectsBytes resolver;
2379 ProxyService service(
2380 config_service,
2381 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
2383 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
2384 service.SetProxyScriptFetchers(fetcher,
2385 new DoNothingDhcpProxyScriptFetcher());
2387 // Start 1 request.
2389 ProxyInfo info1;
2390 TestCompletionCallback callback1;
2391 int rv =
2392 service.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL, &info1,
2393 callback1.callback(), NULL, NULL, BoundNetLog());
2394 EXPECT_EQ(ERR_IO_PENDING, rv);
2396 // Check that nothing has been sent to the proxy resolver yet.
2397 ASSERT_EQ(0u, resolver.pending_requests().size());
2399 // InitProxyResolver should have issued a request to the ProxyScriptFetcher
2400 // and be waiting on that to complete.
2401 EXPECT_TRUE(fetcher->has_pending_request());
2402 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
2405 // Delete the ProxyService while InitProxyResolver has an outstanding
2406 // request to the proxy resolver. When run under valgrind, should not
2407 // have any memory errors (used to be that the ProxyResolver was
2408 // being deleted prior to the InitProxyResolver).
2409 TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingSet) {
2410 MockProxyConfigService* config_service =
2411 new MockProxyConfigService("http://foopy/proxy.pac");
2413 MockAsyncProxyResolver resolver;
2415 ProxyService service(
2416 config_service,
2417 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
2419 GURL url("http://www.google.com/");
2421 ProxyInfo info;
2422 TestCompletionCallback callback;
2423 int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(),
2424 NULL, NULL, BoundNetLog());
2425 EXPECT_EQ(ERR_IO_PENDING, rv);
2427 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
2428 resolver.pending_set_pac_script_request()->script_data()->url());
2431 TEST_F(ProxyServiceTest, ResetProxyConfigService) {
2432 ProxyConfig config1;
2433 config1.proxy_rules().ParseFromString("foopy1:8080");
2434 config1.set_auto_detect(false);
2435 ProxyService service(new MockProxyConfigService(config1), nullptr, NULL);
2437 ProxyInfo info;
2438 TestCompletionCallback callback1;
2439 int rv =
2440 service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info,
2441 callback1.callback(), NULL, NULL, BoundNetLog());
2442 EXPECT_EQ(OK, rv);
2443 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
2445 ProxyConfig config2;
2446 config2.proxy_rules().ParseFromString("foopy2:8080");
2447 config2.set_auto_detect(false);
2448 service.ResetConfigService(new MockProxyConfigService(config2));
2449 TestCompletionCallback callback2;
2450 rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info,
2451 callback2.callback(), NULL, NULL, BoundNetLog());
2452 EXPECT_EQ(OK, rv);
2453 EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
2456 // Test that when going from a configuration that required PAC to one
2457 // that does NOT, we unset the variable |should_use_proxy_resolver_|.
2458 TEST_F(ProxyServiceTest, UpdateConfigFromPACToDirect) {
2459 ProxyConfig config = ProxyConfig::CreateAutoDetect();
2461 MockProxyConfigService* config_service = new MockProxyConfigService(config);
2462 MockAsyncProxyResolver resolver;
2463 ProxyService service(
2464 config_service,
2465 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
2467 // Start 1 request.
2469 ProxyInfo info1;
2470 TestCompletionCallback callback1;
2471 int rv =
2472 service.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL, &info1,
2473 callback1.callback(), NULL, NULL, BoundNetLog());
2474 EXPECT_EQ(ERR_IO_PENDING, rv);
2476 // Check that nothing has been sent to the proxy resolver yet.
2477 ASSERT_EQ(0u, resolver.pending_requests().size());
2479 // Successfully set the autodetect script.
2480 EXPECT_EQ(ProxyResolverScriptData::TYPE_AUTO_DETECT,
2481 resolver.pending_set_pac_script_request()->script_data()->type());
2482 resolver.pending_set_pac_script_request()->CompleteNow(OK);
2484 // Complete the pending request.
2485 ASSERT_EQ(1u, resolver.pending_requests().size());
2486 resolver.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2487 resolver.pending_requests()[0]->CompleteNow(OK);
2489 // Verify that request ran as expected.
2490 EXPECT_EQ(OK, callback1.WaitForResult());
2491 EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
2493 // Force the ProxyService to pull down a new proxy configuration.
2494 // (Even though the configuration isn't old/bad).
2496 // This new configuration no longer has auto_detect set, so
2497 // requests should complete synchronously now as direct-connect.
2498 config_service->SetConfig(ProxyConfig::CreateDirect());
2500 // Start another request -- the effective configuration has changed.
2501 ProxyInfo info2;
2502 TestCompletionCallback callback2;
2503 rv = service.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL, &info2,
2504 callback2.callback(), NULL, NULL, BoundNetLog());
2505 EXPECT_EQ(OK, rv);
2507 EXPECT_TRUE(info2.is_direct());
2510 TEST_F(ProxyServiceTest, NetworkChangeTriggersPacRefetch) {
2511 MockProxyConfigService* config_service =
2512 new MockProxyConfigService("http://foopy/proxy.pac");
2514 MockAsyncProxyResolverExpectsBytes resolver;
2516 TestNetLog log;
2518 ProxyService service(
2519 config_service,
2520 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), &log);
2522 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
2523 service.SetProxyScriptFetchers(fetcher,
2524 new DoNothingDhcpProxyScriptFetcher());
2526 // Disable the "wait after IP address changes" hack, so this unit-test can
2527 // complete quickly.
2528 service.set_stall_proxy_auto_config_delay(base::TimeDelta());
2530 // Start 1 request.
2532 ProxyInfo info1;
2533 TestCompletionCallback callback1;
2534 int rv =
2535 service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
2536 callback1.callback(), NULL, NULL, BoundNetLog());
2537 EXPECT_EQ(ERR_IO_PENDING, rv);
2539 // The first request should have triggered initial download of PAC script.
2540 EXPECT_TRUE(fetcher->has_pending_request());
2541 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
2543 // Nothing has been sent to the resolver yet.
2544 EXPECT_TRUE(resolver.pending_requests().empty());
2546 // At this point the ProxyService should be waiting for the
2547 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2548 // PAC script download completion.
2549 fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
2551 // Now that the PAC script is downloaded, the request will have been sent to
2552 // the proxy resolver.
2553 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
2554 resolver.pending_set_pac_script_request()->script_data()->utf16());
2555 resolver.pending_set_pac_script_request()->CompleteNow(OK);
2557 ASSERT_EQ(1u, resolver.pending_requests().size());
2558 EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());
2560 // Complete the pending request.
2561 resolver.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2562 resolver.pending_requests()[0]->CompleteNow(OK);
2564 // Wait for completion callback, and verify that the request ran as expected.
2565 EXPECT_EQ(OK, callback1.WaitForResult());
2566 EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
2568 // Now simluate a change in the network. The ProxyConfigService is still
2569 // going to return the same PAC URL as before, but this URL needs to be
2570 // refetched on the new network.
2571 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
2572 base::MessageLoop::current()->RunUntilIdle(); // Notification happens async.
2574 // Start a second request.
2575 ProxyInfo info2;
2576 TestCompletionCallback callback2;
2577 rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
2578 callback2.callback(), NULL, NULL, BoundNetLog());
2579 EXPECT_EQ(ERR_IO_PENDING, rv);
2581 // This second request should have triggered the re-download of the PAC
2582 // script (since we marked the network as having changed).
2583 EXPECT_TRUE(fetcher->has_pending_request());
2584 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
2586 // Nothing has been sent to the resolver yet.
2587 EXPECT_TRUE(resolver.pending_requests().empty());
2589 // Simulate the PAC script fetch as having completed (this time with
2590 // different data).
2591 fetcher->NotifyFetchCompletion(OK, kValidPacScript2);
2593 // Now that the PAC script is downloaded, the second request will have been
2594 // sent to the proxy resolver.
2595 EXPECT_EQ(ASCIIToUTF16(kValidPacScript2),
2596 resolver.pending_set_pac_script_request()->script_data()->utf16());
2597 resolver.pending_set_pac_script_request()->CompleteNow(OK);
2599 ASSERT_EQ(1u, resolver.pending_requests().size());
2600 EXPECT_EQ(GURL("http://request2"), resolver.pending_requests()[0]->url());
2602 // Complete the pending second request.
2603 resolver.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2604 resolver.pending_requests()[0]->CompleteNow(OK);
2606 // Wait for completion callback, and verify that the request ran as expected.
2607 EXPECT_EQ(OK, callback2.WaitForResult());
2608 EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
2610 // Check that the expected events were output to the log stream. In particular
2611 // PROXY_CONFIG_CHANGED should have only been emitted once (for the initial
2612 // setup), and NOT a second time when the IP address changed.
2613 CapturedNetLogEntry::List entries;
2614 log.GetEntries(&entries);
2616 EXPECT_TRUE(LogContainsEntryWithType(entries, 0,
2617 NetLog::TYPE_PROXY_CONFIG_CHANGED));
2618 ASSERT_EQ(9u, entries.size());
2619 for (size_t i = 1; i < entries.size(); ++i)
2620 EXPECT_NE(NetLog::TYPE_PROXY_CONFIG_CHANGED, entries[i].type);
2623 // This test verifies that the PAC script specified by the settings is
2624 // periodically polled for changes. Specifically, if the initial fetch fails due
2625 // to a network error, we will eventually re-configure the service to use the
2626 // script once it becomes available.
2627 TEST_F(ProxyServiceTest, PACScriptRefetchAfterFailure) {
2628 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2629 // runs quickly.
2630 ImmediatePollPolicy poll_policy;
2631 ProxyService::set_pac_script_poll_policy(&poll_policy);
2633 MockProxyConfigService* config_service =
2634 new MockProxyConfigService("http://foopy/proxy.pac");
2636 MockAsyncProxyResolverExpectsBytes resolver;
2638 ProxyService service(
2639 config_service,
2640 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
2642 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
2643 service.SetProxyScriptFetchers(fetcher,
2644 new DoNothingDhcpProxyScriptFetcher());
2646 // Start 1 request.
2648 ProxyInfo info1;
2649 TestCompletionCallback callback1;
2650 int rv =
2651 service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
2652 callback1.callback(), NULL, NULL, BoundNetLog());
2653 EXPECT_EQ(ERR_IO_PENDING, rv);
2655 // The first request should have triggered initial download of PAC script.
2656 EXPECT_TRUE(fetcher->has_pending_request());
2657 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
2659 // Nothing has been sent to the resolver yet.
2660 EXPECT_TRUE(resolver.pending_requests().empty());
2662 // At this point the ProxyService should be waiting for the
2663 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2664 // PAC script download completion.
2666 // We simulate a failed download attempt, the proxy service should now
2667 // fall-back to DIRECT connections.
2668 fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
2670 ASSERT_TRUE(resolver.pending_requests().empty());
2672 // Wait for completion callback, and verify it used DIRECT.
2673 EXPECT_EQ(OK, callback1.WaitForResult());
2674 EXPECT_TRUE(info1.is_direct());
2676 // At this point we have initialized the proxy service using a PAC script,
2677 // however it failed and fell-back to DIRECT.
2679 // A background task to periodically re-check the PAC script for validity will
2680 // have been started. We will now wait for the next download attempt to start.
2682 // Note that we shouldn't have to wait long here, since our test enables a
2683 // special unit-test mode.
2684 fetcher->WaitUntilFetch();
2686 ASSERT_TRUE(resolver.pending_requests().empty());
2688 // Make sure that our background checker is trying to download the expected
2689 // PAC script (same one as before). This time we will simulate a successful
2690 // download of the script.
2691 EXPECT_TRUE(fetcher->has_pending_request());
2692 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
2693 fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
2695 base::MessageLoop::current()->RunUntilIdle();
2697 // Now that the PAC script is downloaded, it should be used to initialize the
2698 // ProxyResolver. Simulate a successful parse.
2699 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
2700 resolver.pending_set_pac_script_request()->script_data()->utf16());
2701 resolver.pending_set_pac_script_request()->CompleteNow(OK);
2703 // At this point the ProxyService should have re-configured itself to use the
2704 // PAC script (thereby recovering from the initial fetch failure). We will
2705 // verify that the next Resolve request uses the resolver rather than
2706 // DIRECT.
2708 // Start a second request.
2709 ProxyInfo info2;
2710 TestCompletionCallback callback2;
2711 rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
2712 callback2.callback(), NULL, NULL, BoundNetLog());
2713 EXPECT_EQ(ERR_IO_PENDING, rv);
2715 // Check that it was sent to the resolver.
2716 ASSERT_EQ(1u, resolver.pending_requests().size());
2717 EXPECT_EQ(GURL("http://request2"), resolver.pending_requests()[0]->url());
2719 // Complete the pending second request.
2720 resolver.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2721 resolver.pending_requests()[0]->CompleteNow(OK);
2723 // Wait for completion callback, and verify that the request ran as expected.
2724 EXPECT_EQ(OK, callback2.WaitForResult());
2725 EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
2728 // This test verifies that the PAC script specified by the settings is
2729 // periodically polled for changes. Specifically, if the initial fetch succeeds,
2730 // however at a later time its *contents* change, we will eventually
2731 // re-configure the service to use the new script.
2732 TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentChange) {
2733 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2734 // runs quickly.
2735 ImmediatePollPolicy poll_policy;
2736 ProxyService::set_pac_script_poll_policy(&poll_policy);
2738 MockProxyConfigService* config_service =
2739 new MockProxyConfigService("http://foopy/proxy.pac");
2741 MockAsyncProxyResolverExpectsBytes resolver;
2743 ProxyService service(
2744 config_service,
2745 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
2747 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
2748 service.SetProxyScriptFetchers(fetcher,
2749 new DoNothingDhcpProxyScriptFetcher());
2751 // Start 1 request.
2753 ProxyInfo info1;
2754 TestCompletionCallback callback1;
2755 int rv =
2756 service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
2757 callback1.callback(), NULL, NULL, BoundNetLog());
2758 EXPECT_EQ(ERR_IO_PENDING, rv);
2760 // The first request should have triggered initial download of PAC script.
2761 EXPECT_TRUE(fetcher->has_pending_request());
2762 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
2764 // Nothing has been sent to the resolver yet.
2765 EXPECT_TRUE(resolver.pending_requests().empty());
2767 // At this point the ProxyService should be waiting for the
2768 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2769 // PAC script download completion.
2770 fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
2772 // Now that the PAC script is downloaded, the request will have been sent to
2773 // the proxy resolver.
2774 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
2775 resolver.pending_set_pac_script_request()->script_data()->utf16());
2776 resolver.pending_set_pac_script_request()->CompleteNow(OK);
2778 ASSERT_EQ(1u, resolver.pending_requests().size());
2779 EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());
2781 // Complete the pending request.
2782 resolver.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2783 resolver.pending_requests()[0]->CompleteNow(OK);
2785 // Wait for completion callback, and verify that the request ran as expected.
2786 EXPECT_EQ(OK, callback1.WaitForResult());
2787 EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
2789 // At this point we have initialized the proxy service using a PAC script.
2791 // A background task to periodically re-check the PAC script for validity will
2792 // have been started. We will now wait for the next download attempt to start.
2794 // Note that we shouldn't have to wait long here, since our test enables a
2795 // special unit-test mode.
2796 fetcher->WaitUntilFetch();
2798 ASSERT_TRUE(resolver.pending_requests().empty());
2800 // Make sure that our background checker is trying to download the expected
2801 // PAC script (same one as before). This time we will simulate a successful
2802 // download of a DIFFERENT script.
2803 EXPECT_TRUE(fetcher->has_pending_request());
2804 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
2805 fetcher->NotifyFetchCompletion(OK, kValidPacScript2);
2807 base::MessageLoop::current()->RunUntilIdle();
2809 // Now that the PAC script is downloaded, it should be used to initialize the
2810 // ProxyResolver. Simulate a successful parse.
2811 EXPECT_EQ(ASCIIToUTF16(kValidPacScript2),
2812 resolver.pending_set_pac_script_request()->script_data()->utf16());
2813 resolver.pending_set_pac_script_request()->CompleteNow(OK);
2815 // At this point the ProxyService should have re-configured itself to use the
2816 // new PAC script.
2818 // Start a second request.
2819 ProxyInfo info2;
2820 TestCompletionCallback callback2;
2821 rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
2822 callback2.callback(), NULL, NULL, BoundNetLog());
2823 EXPECT_EQ(ERR_IO_PENDING, rv);
2825 // Check that it was sent to the resolver.
2826 ASSERT_EQ(1u, resolver.pending_requests().size());
2827 EXPECT_EQ(GURL("http://request2"), resolver.pending_requests()[0]->url());
2829 // Complete the pending second request.
2830 resolver.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2831 resolver.pending_requests()[0]->CompleteNow(OK);
2833 // Wait for completion callback, and verify that the request ran as expected.
2834 EXPECT_EQ(OK, callback2.WaitForResult());
2835 EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
2838 // This test verifies that the PAC script specified by the settings is
2839 // periodically polled for changes. Specifically, if the initial fetch succeeds
2840 // and so does the next poll, however the contents of the downloaded script
2841 // have NOT changed, then we do not bother to re-initialize the proxy resolver.
2842 TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentUnchanged) {
2843 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2844 // runs quickly.
2845 ImmediatePollPolicy poll_policy;
2846 ProxyService::set_pac_script_poll_policy(&poll_policy);
2848 MockProxyConfigService* config_service =
2849 new MockProxyConfigService("http://foopy/proxy.pac");
2851 MockAsyncProxyResolverExpectsBytes resolver;
2853 ProxyService service(
2854 config_service,
2855 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
2857 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
2858 service.SetProxyScriptFetchers(fetcher,
2859 new DoNothingDhcpProxyScriptFetcher());
2861 // Start 1 request.
2863 ProxyInfo info1;
2864 TestCompletionCallback callback1;
2865 int rv =
2866 service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
2867 callback1.callback(), NULL, NULL, BoundNetLog());
2868 EXPECT_EQ(ERR_IO_PENDING, rv);
2870 // The first request should have triggered initial download of PAC script.
2871 EXPECT_TRUE(fetcher->has_pending_request());
2872 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
2874 // Nothing has been sent to the resolver yet.
2875 EXPECT_TRUE(resolver.pending_requests().empty());
2877 // At this point the ProxyService should be waiting for the
2878 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2879 // PAC script download completion.
2880 fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
2882 // Now that the PAC script is downloaded, the request will have been sent to
2883 // the proxy resolver.
2884 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
2885 resolver.pending_set_pac_script_request()->script_data()->utf16());
2886 resolver.pending_set_pac_script_request()->CompleteNow(OK);
2888 ASSERT_EQ(1u, resolver.pending_requests().size());
2889 EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());
2891 // Complete the pending request.
2892 resolver.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2893 resolver.pending_requests()[0]->CompleteNow(OK);
2895 // Wait for completion callback, and verify that the request ran as expected.
2896 EXPECT_EQ(OK, callback1.WaitForResult());
2897 EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
2899 // At this point we have initialized the proxy service using a PAC script.
2901 // A background task to periodically re-check the PAC script for validity will
2902 // have been started. We will now wait for the next download attempt to start.
2904 // Note that we shouldn't have to wait long here, since our test enables a
2905 // special unit-test mode.
2906 fetcher->WaitUntilFetch();
2908 ASSERT_TRUE(resolver.pending_requests().empty());
2910 // Make sure that our background checker is trying to download the expected
2911 // PAC script (same one as before). We will simulate the same response as
2912 // last time (i.e. the script is unchanged).
2913 EXPECT_TRUE(fetcher->has_pending_request());
2914 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
2915 fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
2917 base::MessageLoop::current()->RunUntilIdle();
2919 ASSERT_FALSE(resolver.has_pending_set_pac_script_request());
2921 // At this point the ProxyService is still running the same PAC script as
2922 // before.
2924 // Start a second request.
2925 ProxyInfo info2;
2926 TestCompletionCallback callback2;
2927 rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
2928 callback2.callback(), NULL, NULL, BoundNetLog());
2929 EXPECT_EQ(ERR_IO_PENDING, rv);
2931 // Check that it was sent to the resolver.
2932 ASSERT_EQ(1u, resolver.pending_requests().size());
2933 EXPECT_EQ(GURL("http://request2"), resolver.pending_requests()[0]->url());
2935 // Complete the pending second request.
2936 resolver.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2937 resolver.pending_requests()[0]->CompleteNow(OK);
2939 // Wait for completion callback, and verify that the request ran as expected.
2940 EXPECT_EQ(OK, callback2.WaitForResult());
2941 EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
2944 // This test verifies that the PAC script specified by the settings is
2945 // periodically polled for changes. Specifically, if the initial fetch succeeds,
2946 // however at a later time it starts to fail, we should re-configure the
2947 // ProxyService to stop using that PAC script.
2948 TEST_F(ProxyServiceTest, PACScriptRefetchAfterSuccess) {
2949 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2950 // runs quickly.
2951 ImmediatePollPolicy poll_policy;
2952 ProxyService::set_pac_script_poll_policy(&poll_policy);
2954 MockProxyConfigService* config_service =
2955 new MockProxyConfigService("http://foopy/proxy.pac");
2957 MockAsyncProxyResolverExpectsBytes resolver;
2959 ProxyService service(
2960 config_service,
2961 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
2963 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
2964 service.SetProxyScriptFetchers(fetcher,
2965 new DoNothingDhcpProxyScriptFetcher());
2967 // Start 1 request.
2969 ProxyInfo info1;
2970 TestCompletionCallback callback1;
2971 int rv =
2972 service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
2973 callback1.callback(), NULL, NULL, BoundNetLog());
2974 EXPECT_EQ(ERR_IO_PENDING, rv);
2976 // The first request should have triggered initial download of PAC script.
2977 EXPECT_TRUE(fetcher->has_pending_request());
2978 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
2980 // Nothing has been sent to the resolver yet.
2981 EXPECT_TRUE(resolver.pending_requests().empty());
2983 // At this point the ProxyService should be waiting for the
2984 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2985 // PAC script download completion.
2986 fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
2988 // Now that the PAC script is downloaded, the request will have been sent to
2989 // the proxy resolver.
2990 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
2991 resolver.pending_set_pac_script_request()->script_data()->utf16());
2992 resolver.pending_set_pac_script_request()->CompleteNow(OK);
2994 ASSERT_EQ(1u, resolver.pending_requests().size());
2995 EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());
2997 // Complete the pending request.
2998 resolver.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2999 resolver.pending_requests()[0]->CompleteNow(OK);
3001 // Wait for completion callback, and verify that the request ran as expected.
3002 EXPECT_EQ(OK, callback1.WaitForResult());
3003 EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
3005 // At this point we have initialized the proxy service using a PAC script.
3007 // A background task to periodically re-check the PAC script for validity will
3008 // have been started. We will now wait for the next download attempt to start.
3010 // Note that we shouldn't have to wait long here, since our test enables a
3011 // special unit-test mode.
3012 fetcher->WaitUntilFetch();
3014 ASSERT_TRUE(resolver.pending_requests().empty());
3016 // Make sure that our background checker is trying to download the expected
3017 // PAC script (same one as before). This time we will simulate a failure
3018 // to download the script.
3019 EXPECT_TRUE(fetcher->has_pending_request());
3020 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
3021 fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
3023 base::MessageLoop::current()->RunUntilIdle();
3025 // At this point the ProxyService should have re-configured itself to use
3026 // DIRECT connections rather than the given proxy resolver.
3028 // Start a second request.
3029 ProxyInfo info2;
3030 TestCompletionCallback callback2;
3031 rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
3032 callback2.callback(), NULL, NULL, BoundNetLog());
3033 EXPECT_EQ(OK, rv);
3034 EXPECT_TRUE(info2.is_direct());
3037 // Tests that the code which decides at what times to poll the PAC
3038 // script follows the expected policy.
3039 TEST_F(ProxyServiceTest, PACScriptPollingPolicy) {
3040 // Retrieve the internal polling policy implementation used by ProxyService.
3041 scoped_ptr<ProxyService::PacPollPolicy> policy =
3042 ProxyService::CreateDefaultPacPollPolicy();
3044 int error;
3045 ProxyService::PacPollPolicy::Mode mode;
3046 const base::TimeDelta initial_delay = base::TimeDelta::FromMilliseconds(-1);
3047 base::TimeDelta delay = initial_delay;
3049 // --------------------------------------------------
3050 // Test the poll sequence in response to a failure.
3051 // --------------------------------------------------
3052 error = ERR_NAME_NOT_RESOLVED;
3054 // Poll #0
3055 mode = policy->GetNextDelay(error, initial_delay, &delay);
3056 EXPECT_EQ(8, delay.InSeconds());
3057 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_USE_TIMER, mode);
3059 // Poll #1
3060 mode = policy->GetNextDelay(error, delay, &delay);
3061 EXPECT_EQ(32, delay.InSeconds());
3062 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
3064 // Poll #2
3065 mode = policy->GetNextDelay(error, delay, &delay);
3066 EXPECT_EQ(120, delay.InSeconds());
3067 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
3069 // Poll #3
3070 mode = policy->GetNextDelay(error, delay, &delay);
3071 EXPECT_EQ(14400, delay.InSeconds());
3072 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
3074 // Poll #4
3075 mode = policy->GetNextDelay(error, delay, &delay);
3076 EXPECT_EQ(14400, delay.InSeconds());
3077 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
3079 // --------------------------------------------------
3080 // Test the poll sequence in response to a success.
3081 // --------------------------------------------------
3082 error = OK;
3084 // Poll #0
3085 mode = policy->GetNextDelay(error, initial_delay, &delay);
3086 EXPECT_EQ(43200, delay.InSeconds());
3087 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
3089 // Poll #1
3090 mode = policy->GetNextDelay(error, delay, &delay);
3091 EXPECT_EQ(43200, delay.InSeconds());
3092 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
3094 // Poll #2
3095 mode = policy->GetNextDelay(error, delay, &delay);
3096 EXPECT_EQ(43200, delay.InSeconds());
3097 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
3100 // This tests the polling of the PAC script. Specifically, it tests that
3101 // polling occurs in response to user activity.
3102 TEST_F(ProxyServiceTest, PACScriptRefetchAfterActivity) {
3103 ImmediateAfterActivityPollPolicy poll_policy;
3104 ProxyService::set_pac_script_poll_policy(&poll_policy);
3106 MockProxyConfigService* config_service =
3107 new MockProxyConfigService("http://foopy/proxy.pac");
3109 MockAsyncProxyResolverExpectsBytes resolver;
3111 ProxyService service(
3112 config_service,
3113 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
3115 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
3116 service.SetProxyScriptFetchers(fetcher,
3117 new DoNothingDhcpProxyScriptFetcher());
3119 // Start 1 request.
3121 ProxyInfo info1;
3122 TestCompletionCallback callback1;
3123 int rv =
3124 service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
3125 callback1.callback(), NULL, NULL, BoundNetLog());
3126 EXPECT_EQ(ERR_IO_PENDING, rv);
3128 // The first request should have triggered initial download of PAC script.
3129 EXPECT_TRUE(fetcher->has_pending_request());
3130 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
3132 // Nothing has been sent to the resolver yet.
3133 EXPECT_TRUE(resolver.pending_requests().empty());
3135 // At this point the ProxyService should be waiting for the
3136 // ProxyScriptFetcher to invoke its completion callback, notifying it of
3137 // PAC script download completion.
3138 fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
3140 // Now that the PAC script is downloaded, the request will have been sent to
3141 // the proxy resolver.
3142 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
3143 resolver.pending_set_pac_script_request()->script_data()->utf16());
3144 resolver.pending_set_pac_script_request()->CompleteNow(OK);
3146 ASSERT_EQ(1u, resolver.pending_requests().size());
3147 EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());
3149 // Complete the pending request.
3150 resolver.pending_requests()[0]->results()->UseNamedProxy("request1:80");
3151 resolver.pending_requests()[0]->CompleteNow(OK);
3153 // Wait for completion callback, and verify that the request ran as expected.
3154 EXPECT_EQ(OK, callback1.WaitForResult());
3155 EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
3157 // At this point we have initialized the proxy service using a PAC script.
3158 // Our PAC poller is set to update ONLY in response to network activity,
3159 // (i.e. another call to ResolveProxy()).
3161 ASSERT_FALSE(fetcher->has_pending_request());
3162 ASSERT_TRUE(resolver.pending_requests().empty());
3164 // Start a second request.
3165 ProxyInfo info2;
3166 TestCompletionCallback callback2;
3167 rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
3168 callback2.callback(), NULL, NULL, BoundNetLog());
3169 EXPECT_EQ(ERR_IO_PENDING, rv);
3171 // This request should have sent work to the resolver; complete it.
3172 ASSERT_EQ(1u, resolver.pending_requests().size());
3173 EXPECT_EQ(GURL("http://request2"), resolver.pending_requests()[0]->url());
3174 resolver.pending_requests()[0]->results()->UseNamedProxy("request2:80");
3175 resolver.pending_requests()[0]->CompleteNow(OK);
3177 EXPECT_EQ(OK, callback2.WaitForResult());
3178 EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
3180 // In response to getting that resolve request, the poller should have
3181 // started the next poll, and made it as far as to request the download.
3183 EXPECT_TRUE(fetcher->has_pending_request());
3184 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
3186 // This time we will fail the download, to simulate a PAC script change.
3187 fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
3189 // Drain the message loop, so ProxyService is notified of the change
3190 // and has a chance to re-configure itself.
3191 base::MessageLoop::current()->RunUntilIdle();
3193 // Start a third request -- this time we expect to get a direct connection
3194 // since the PAC script poller experienced a failure.
3195 ProxyInfo info3;
3196 TestCompletionCallback callback3;
3197 rv = service.ResolveProxy(GURL("http://request3"), LOAD_NORMAL, &info3,
3198 callback3.callback(), NULL, NULL, BoundNetLog());
3199 EXPECT_EQ(OK, rv);
3200 EXPECT_TRUE(info3.is_direct());
3203 // Test that the synchronous resolution fails when a PAC script is active.
3204 TEST_F(ProxyServiceTest, SynchronousWithPAC) {
3205 MockProxyConfigService* config_service =
3206 new MockProxyConfigService("http://foopy/proxy.pac");
3208 MockAsyncProxyResolver resolver;
3210 ProxyService service(
3211 config_service,
3212 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
3214 GURL url("http://www.google.com/");
3216 ProxyInfo info;
3217 info.UseDirect();
3218 BoundTestNetLog log;
3220 bool synchronous_success = service.TryResolveProxySynchronously(
3221 url, LOAD_NORMAL, &info, NULL, log.bound());
3222 EXPECT_FALSE(synchronous_success);
3224 // No request should have been queued.
3225 EXPECT_EQ(0u, resolver.pending_requests().size());
3227 // |info| should not have been modified.
3228 EXPECT_TRUE(info.is_direct());
3231 // Test that synchronous results are returned correctly if a fixed proxy
3232 // configuration is active.
3233 TEST_F(ProxyServiceTest, SynchronousWithFixedConfiguration) {
3234 ProxyConfig config;
3235 config.proxy_rules().ParseFromString("foopy1:8080");
3236 config.set_auto_detect(false);
3238 MockAsyncProxyResolver resolver;
3240 ProxyService service(
3241 new MockProxyConfigService(config),
3242 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver)), NULL);
3244 GURL url("http://www.google.com/");
3246 ProxyInfo info;
3247 BoundTestNetLog log;
3249 bool synchronous_success = service.TryResolveProxySynchronously(
3250 url, LOAD_NORMAL, &info, NULL, log.bound());
3251 EXPECT_TRUE(synchronous_success);
3252 EXPECT_FALSE(info.is_direct());
3253 EXPECT_EQ("foopy1", info.proxy_server().host_port_pair().host());
3255 // No request should have been queued.
3256 EXPECT_EQ(0u, resolver.pending_requests().size());
3259 } // namespace net