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"
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/net_log.h"
18 #include "net/log/net_log_unittest.h"
19 #include "net/proxy/dhcp_proxy_script_fetcher.h"
20 #include "net/proxy/mock_proxy_resolver.h"
21 #include "net/proxy/mock_proxy_script_fetcher.h"
22 #include "net/proxy/proxy_config_service.h"
23 #include "net/proxy/proxy_resolver.h"
24 #include "net/proxy/proxy_script_fetcher.h"
25 #include "testing/gtest/include/gtest/gtest.h"
28 using base::ASCIIToUTF16
;
30 // TODO(eroman): Write a test which exercises
31 // ProxyService::SuspendAllPendingRequests().
35 // This polling policy will decide to poll every 1 ms.
36 class ImmediatePollPolicy
: public ProxyService::PacPollPolicy
{
38 ImmediatePollPolicy() {}
40 Mode
GetNextDelay(int error
,
41 base::TimeDelta current_delay
,
42 base::TimeDelta
* next_delay
) const override
{
43 *next_delay
= base::TimeDelta::FromMilliseconds(1);
44 return MODE_USE_TIMER
;
48 DISALLOW_COPY_AND_ASSIGN(ImmediatePollPolicy
);
51 // This polling policy chooses a fantastically large delay. In other words, it
52 // will never trigger a poll
53 class NeverPollPolicy
: public ProxyService::PacPollPolicy
{
57 Mode
GetNextDelay(int error
,
58 base::TimeDelta current_delay
,
59 base::TimeDelta
* next_delay
) const override
{
60 *next_delay
= base::TimeDelta::FromDays(60);
61 return MODE_USE_TIMER
;
65 DISALLOW_COPY_AND_ASSIGN(NeverPollPolicy
);
68 // This polling policy starts a poll immediately after network activity.
69 class ImmediateAfterActivityPollPolicy
: public ProxyService::PacPollPolicy
{
71 ImmediateAfterActivityPollPolicy() {}
73 Mode
GetNextDelay(int error
,
74 base::TimeDelta current_delay
,
75 base::TimeDelta
* next_delay
) const override
{
76 *next_delay
= base::TimeDelta();
77 return MODE_START_AFTER_ACTIVITY
;
81 DISALLOW_COPY_AND_ASSIGN(ImmediateAfterActivityPollPolicy
);
84 // This test fixture is used to partially disable the background polling done by
85 // the ProxyService (which it uses to detect whenever its PAC script contents or
86 // WPAD results have changed).
88 // We disable the feature by setting the poll interval to something really
89 // large, so it will never actually be reached even on the slowest bots that run
92 // We disable the polling in order to avoid any timing dependencies in the
93 // tests. If the bot were to run the tests very slowly and we hadn't disabled
94 // polling, then it might start a background re-try in the middle of our test
95 // and confuse our expectations leading to flaky failures.
97 // The tests which verify the polling code re-enable the polling behavior but
98 // are careful to avoid timing problems.
99 class ProxyServiceTest
: public testing::Test
{
101 void SetUp() override
{
102 testing::Test::SetUp();
104 ProxyService::set_pac_script_poll_policy(&never_poll_policy_
);
107 void TearDown() override
{
108 // Restore the original policy.
109 ProxyService::set_pac_script_poll_policy(previous_policy_
);
110 testing::Test::TearDown();
114 NeverPollPolicy never_poll_policy_
;
115 const ProxyService::PacPollPolicy
* previous_policy_
;
118 const char kValidPacScript1
[] = "pac-script-v1-FindProxyForURL";
119 const char kValidPacScript2
[] = "pac-script-v2-FindProxyForURL";
121 class MockProxyConfigService
: public ProxyConfigService
{
123 explicit MockProxyConfigService(const ProxyConfig
& config
)
124 : availability_(CONFIG_VALID
),
128 explicit MockProxyConfigService(const std::string
& pac_url
)
129 : availability_(CONFIG_VALID
),
130 config_(ProxyConfig::CreateFromCustomPacURL(GURL(pac_url
))) {
133 void AddObserver(Observer
* observer
) override
{
134 observers_
.AddObserver(observer
);
137 void RemoveObserver(Observer
* observer
) override
{
138 observers_
.RemoveObserver(observer
);
141 ConfigAvailability
GetLatestProxyConfig(ProxyConfig
* results
) override
{
142 if (availability_
== CONFIG_VALID
)
144 return availability_
;
147 void SetConfig(const ProxyConfig
& config
) {
148 availability_
= CONFIG_VALID
;
150 FOR_EACH_OBSERVER(Observer
, observers_
,
151 OnProxyConfigChanged(config_
, availability_
));
155 ConfigAvailability availability_
;
157 ObserverList
<Observer
, true> observers_
;
160 // A test network delegate that exercises the OnResolveProxy callback.
161 class TestResolveProxyNetworkDelegate
: public NetworkDelegateImpl
{
163 TestResolveProxyNetworkDelegate()
164 : on_resolve_proxy_called_(false),
166 remove_proxy_(false),
167 proxy_service_(NULL
) {
170 void OnResolveProxy(const GURL
& url
,
172 const ProxyService
& proxy_service
,
173 ProxyInfo
* result
) override
{
174 on_resolve_proxy_called_
= true;
175 proxy_service_
= &proxy_service
;
176 DCHECK(!add_proxy_
|| !remove_proxy_
);
178 result
->UseNamedProxy("delegate_proxy.com");
179 } else if (remove_proxy_
) {
184 bool on_resolve_proxy_called() const {
185 return on_resolve_proxy_called_
;
188 void set_add_proxy(bool add_proxy
) {
189 add_proxy_
= add_proxy
;
192 void set_remove_proxy(bool remove_proxy
) {
193 remove_proxy_
= remove_proxy
;
196 const ProxyService
* proxy_service() const {
197 return proxy_service_
;
201 bool on_resolve_proxy_called_
;
204 const ProxyService
* proxy_service_
;
207 // A test network delegate that exercises the OnProxyFallback callback.
208 class TestProxyFallbackNetworkDelegate
: public NetworkDelegateImpl
{
210 TestProxyFallbackNetworkDelegate()
211 : on_proxy_fallback_called_(false),
212 proxy_fallback_net_error_(OK
) {
215 void OnProxyFallback(const ProxyServer
& proxy_server
,
216 int net_error
) override
{
217 proxy_server_
= proxy_server
;
218 proxy_fallback_net_error_
= net_error
;
219 on_proxy_fallback_called_
= true;
222 bool on_proxy_fallback_called() const {
223 return on_proxy_fallback_called_
;
226 const ProxyServer
& proxy_server() const {
227 return proxy_server_
;
230 int proxy_fallback_net_error() const {
231 return proxy_fallback_net_error_
;
235 bool on_proxy_fallback_called_
;
236 ProxyServer proxy_server_
;
237 int proxy_fallback_net_error_
;
242 TEST_F(ProxyServiceTest
, Direct
) {
243 MockAsyncProxyResolver resolver
;
244 ProxyService
service(
245 new MockProxyConfigService(ProxyConfig::CreateDirect()),
246 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
248 GURL
url("http://www.google.com/");
251 TestCompletionCallback callback
;
252 CapturingBoundNetLog log
;
253 int rv
= service
.ResolveProxy(
254 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
257 EXPECT_TRUE(resolver
.pending_requests().empty());
259 EXPECT_TRUE(info
.is_direct());
260 EXPECT_TRUE(info
.proxy_resolve_start_time().is_null());
261 EXPECT_TRUE(info
.proxy_resolve_end_time().is_null());
263 // Check the NetLog was filled correctly.
264 CapturingNetLog::CapturedEntryList entries
;
265 log
.GetEntries(&entries
);
267 EXPECT_EQ(3u, entries
.size());
268 EXPECT_TRUE(LogContainsBeginEvent(
269 entries
, 0, NetLog::TYPE_PROXY_SERVICE
));
270 EXPECT_TRUE(LogContainsEvent(
271 entries
, 1, NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST
,
272 NetLog::PHASE_NONE
));
273 EXPECT_TRUE(LogContainsEndEvent(
274 entries
, 2, NetLog::TYPE_PROXY_SERVICE
));
277 TEST_F(ProxyServiceTest
, OnResolveProxyCallbackAddProxy
) {
279 config
.proxy_rules().ParseFromString("foopy1:8080");
280 config
.set_auto_detect(false);
281 config
.proxy_rules().bypass_rules
.ParseFromString("*.org");
283 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
285 GURL
url("http://www.google.com/");
286 GURL
bypass_url("http://internet.org");
289 TestCompletionCallback callback
;
290 CapturingBoundNetLog log
;
292 // First, warm up the ProxyService.
293 int rv
= service
.ResolveProxy(
294 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
298 // Verify that network delegate is invoked.
299 TestResolveProxyNetworkDelegate delegate
;
300 rv
= service
.ResolveProxy(
301 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
303 EXPECT_TRUE(delegate
.on_resolve_proxy_called());
304 EXPECT_EQ(&service
, delegate
.proxy_service());
306 // Verify that the NetworkDelegate's behavior is stateless across
307 // invocations of ResolveProxy. Start by having the callback add a proxy
308 // and checking that subsequent requests are not affected.
309 delegate
.set_add_proxy(true);
311 // Callback should interpose:
312 rv
= service
.ResolveProxy(
313 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
315 EXPECT_FALSE(info
.is_direct());
316 EXPECT_EQ(info
.proxy_server().host_port_pair().host(), "delegate_proxy.com");
317 delegate
.set_add_proxy(false);
319 // Check non-bypassed URL:
320 rv
= service
.ResolveProxy(
321 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
323 EXPECT_FALSE(info
.is_direct());
324 EXPECT_EQ(info
.proxy_server().host_port_pair().host(), "foopy1");
326 // Check bypassed URL:
327 rv
= service
.ResolveProxy(
328 bypass_url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
,
329 &delegate
, log
.bound());
330 EXPECT_TRUE(info
.is_direct());
333 TEST_F(ProxyServiceTest
, OnResolveProxyCallbackRemoveProxy
) {
334 // Same as OnResolveProxyCallbackAddProxy, but verify that the
335 // NetworkDelegate's behavior is stateless across invocations after it
336 // *removes* a proxy.
338 config
.proxy_rules().ParseFromString("foopy1:8080");
339 config
.set_auto_detect(false);
340 config
.proxy_rules().bypass_rules
.ParseFromString("*.org");
342 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
344 GURL
url("http://www.google.com/");
345 GURL
bypass_url("http://internet.org");
348 TestCompletionCallback callback
;
349 CapturingBoundNetLog log
;
351 // First, warm up the ProxyService.
352 int rv
= service
.ResolveProxy(
353 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
357 TestResolveProxyNetworkDelegate delegate
;
358 delegate
.set_remove_proxy(true);
360 // Callback should interpose:
361 rv
= service
.ResolveProxy(
362 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
364 EXPECT_TRUE(info
.is_direct());
365 delegate
.set_remove_proxy(false);
367 // Check non-bypassed URL:
368 rv
= service
.ResolveProxy(
369 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
371 EXPECT_FALSE(info
.is_direct());
372 EXPECT_EQ(info
.proxy_server().host_port_pair().host(), "foopy1");
374 // Check bypassed URL:
375 rv
= service
.ResolveProxy(
376 bypass_url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
,
377 &delegate
, log
.bound());
378 EXPECT_TRUE(info
.is_direct());
381 TEST_F(ProxyServiceTest
, PAC
) {
382 MockProxyConfigService
* config_service
=
383 new MockProxyConfigService("http://foopy/proxy.pac");
385 MockAsyncProxyResolver resolver
;
387 ProxyService
service(
389 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
391 GURL
url("http://www.google.com/");
394 TestCompletionCallback callback
;
395 ProxyService::PacRequest
* request
;
396 CapturingBoundNetLog log
;
398 int rv
= service
.ResolveProxy(
399 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), &request
, NULL
,
401 EXPECT_EQ(ERR_IO_PENDING
, rv
);
403 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request
));
405 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
406 resolver
.pending_set_pac_script_request()->script_data()->url());
407 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
409 ASSERT_EQ(1u, resolver
.pending_requests().size());
410 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
412 // Set the result in proxy resolver.
413 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy");
414 resolver
.pending_requests()[0]->CompleteNow(OK
);
416 EXPECT_EQ(OK
, callback
.WaitForResult());
417 EXPECT_FALSE(info
.is_direct());
418 EXPECT_EQ("foopy:80", info
.proxy_server().ToURI());
419 EXPECT_TRUE(info
.did_use_pac_script());
421 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
422 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
423 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
425 // Check the NetLog was filled correctly.
426 CapturingNetLog::CapturedEntryList entries
;
427 log
.GetEntries(&entries
);
429 EXPECT_EQ(5u, entries
.size());
430 EXPECT_TRUE(LogContainsBeginEvent(
431 entries
, 0, NetLog::TYPE_PROXY_SERVICE
));
432 EXPECT_TRUE(LogContainsBeginEvent(
433 entries
, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
434 EXPECT_TRUE(LogContainsEndEvent(
435 entries
, 2, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
436 EXPECT_TRUE(LogContainsEndEvent(
437 entries
, 4, NetLog::TYPE_PROXY_SERVICE
));
440 // Test that the proxy resolver does not see the URL's username/password
441 // or its reference section.
442 TEST_F(ProxyServiceTest
, PAC_NoIdentityOrHash
) {
443 MockProxyConfigService
* config_service
=
444 new MockProxyConfigService("http://foopy/proxy.pac");
446 MockAsyncProxyResolver resolver
;
448 ProxyService
service(
450 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
452 GURL
url("http://username:password@www.google.com/?ref#hash#hash");
455 TestCompletionCallback callback
;
456 int rv
= service
.ResolveProxy(
457 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
459 EXPECT_EQ(ERR_IO_PENDING
, rv
);
461 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
462 resolver
.pending_set_pac_script_request()->script_data()->url());
463 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
465 ASSERT_EQ(1u, resolver
.pending_requests().size());
466 // The URL should have been simplified, stripping the username/password/hash.
467 EXPECT_EQ(GURL("http://www.google.com/?ref"),
468 resolver
.pending_requests()[0]->url());
470 // We end here without ever completing the request -- destruction of
471 // ProxyService will cancel the outstanding request.
474 TEST_F(ProxyServiceTest
, PAC_FailoverWithoutDirect
) {
475 MockProxyConfigService
* config_service
=
476 new MockProxyConfigService("http://foopy/proxy.pac");
477 MockAsyncProxyResolver resolver
;
479 ProxyService
service(
481 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
483 GURL
url("http://www.google.com/");
486 TestCompletionCallback callback1
;
487 int rv
= service
.ResolveProxy(
488 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
490 EXPECT_EQ(ERR_IO_PENDING
, rv
);
492 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
493 resolver
.pending_set_pac_script_request()->script_data()->url());
494 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
496 ASSERT_EQ(1u, resolver
.pending_requests().size());
497 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
499 // Set the result in proxy resolver.
500 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy:8080");
501 resolver
.pending_requests()[0]->CompleteNow(OK
);
503 EXPECT_EQ(OK
, callback1
.WaitForResult());
504 EXPECT_FALSE(info
.is_direct());
505 EXPECT_EQ("foopy:8080", info
.proxy_server().ToURI());
506 EXPECT_TRUE(info
.did_use_pac_script());
508 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
509 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
510 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
512 // Now, imagine that connecting to foopy:8080 fails: there is nothing
513 // left to fallback to, since our proxy list was NOT terminated by
515 NetworkDelegateImpl network_delegate
;
516 TestCompletionCallback callback2
;
517 ProxyServer expected_proxy_server
= info
.proxy_server();
518 rv
= service
.ReconsiderProxyAfterError(
519 url
, net::LOAD_NORMAL
, net::ERR_PROXY_CONNECTION_FAILED
,
520 &info
, callback2
.callback(), NULL
, &network_delegate
, BoundNetLog());
521 // ReconsiderProxyAfterError returns error indicating nothing left.
522 EXPECT_EQ(ERR_FAILED
, rv
);
523 EXPECT_TRUE(info
.is_empty());
526 // Test that if the execution of the PAC script fails (i.e. javascript runtime
527 // error), and the PAC settings are non-mandatory, that we fall-back to direct.
528 TEST_F(ProxyServiceTest
, PAC_RuntimeError
) {
529 MockProxyConfigService
* config_service
=
530 new MockProxyConfigService("http://foopy/proxy.pac");
531 MockAsyncProxyResolver resolver
;
533 ProxyService
service(
535 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
537 GURL
url("http://this-causes-js-error/");
540 TestCompletionCallback callback1
;
541 int rv
= service
.ResolveProxy(
542 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
544 EXPECT_EQ(ERR_IO_PENDING
, rv
);
546 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
547 resolver
.pending_set_pac_script_request()->script_data()->url());
548 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
550 ASSERT_EQ(1u, resolver
.pending_requests().size());
551 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
553 // Simulate a failure in the PAC executor.
554 resolver
.pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_FAILED
);
556 EXPECT_EQ(OK
, callback1
.WaitForResult());
558 // Since the PAC script was non-mandatory, we should have fallen-back to
560 EXPECT_TRUE(info
.is_direct());
561 EXPECT_TRUE(info
.did_use_pac_script());
562 EXPECT_EQ(1, info
.config_id());
564 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
565 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
566 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
569 // The proxy list could potentially contain the DIRECT fallback choice
570 // in a location other than the very end of the list, and could even
571 // specify it multiple times.
573 // This is not a typical usage, but we will obey it.
574 // (If we wanted to disallow this type of input, the right place to
575 // enforce it would be in parsing the PAC result string).
577 // This test will use the PAC result string:
579 // "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20"
581 // For which we expect it to try DIRECT, then foobar:10, then DIRECT again,
582 // then foobar:20, and then give up and error.
584 // The important check of this test is to make sure that DIRECT is not somehow
585 // cached as being a bad proxy.
586 TEST_F(ProxyServiceTest
, PAC_FailoverAfterDirect
) {
587 MockProxyConfigService
* config_service
=
588 new MockProxyConfigService("http://foopy/proxy.pac");
589 MockAsyncProxyResolver resolver
;
591 ProxyService
service(
593 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
595 GURL
url("http://www.google.com/");
598 TestCompletionCallback callback1
;
599 int rv
= service
.ResolveProxy(
600 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
602 EXPECT_EQ(ERR_IO_PENDING
, rv
);
604 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
605 resolver
.pending_set_pac_script_request()->script_data()->url());
606 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
608 ASSERT_EQ(1u, resolver
.pending_requests().size());
609 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
611 // Set the result in proxy resolver.
612 resolver
.pending_requests()[0]->results()->UsePacString(
613 "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20");
614 resolver
.pending_requests()[0]->CompleteNow(OK
);
616 EXPECT_EQ(OK
, callback1
.WaitForResult());
617 EXPECT_TRUE(info
.is_direct());
620 TestCompletionCallback callback2
;
621 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
622 net::ERR_PROXY_CONNECTION_FAILED
,
623 &info
, callback2
.callback(), NULL
,
624 NULL
, BoundNetLog());
626 EXPECT_FALSE(info
.is_direct());
627 EXPECT_EQ("foobar:10", info
.proxy_server().ToURI());
630 NetworkDelegateImpl network_delegate
;
631 ProxyServer expected_proxy_server3
= info
.proxy_server();
632 TestCompletionCallback callback3
;
633 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
634 net::ERR_PROXY_CONNECTION_FAILED
,
635 &info
, callback3
.callback(), NULL
,
636 &network_delegate
, BoundNetLog());
638 EXPECT_TRUE(info
.is_direct());
641 ProxyServer expected_proxy_server4
= info
.proxy_server();
642 TestCompletionCallback callback4
;
643 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
644 net::ERR_PROXY_CONNECTION_FAILED
,
645 &info
, callback4
.callback(), NULL
,
646 &network_delegate
, BoundNetLog());
648 EXPECT_FALSE(info
.is_direct());
649 EXPECT_EQ("foobar:20", info
.proxy_server().ToURI());
651 // Fallback 4 -- Nothing to fall back to!
652 ProxyServer expected_proxy_server5
= info
.proxy_server();
653 TestCompletionCallback callback5
;
654 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
655 net::ERR_PROXY_CONNECTION_FAILED
,
656 &info
, callback5
.callback(), NULL
,
657 &network_delegate
, BoundNetLog());
658 EXPECT_EQ(ERR_FAILED
, rv
);
659 EXPECT_TRUE(info
.is_empty());
662 TEST_F(ProxyServiceTest
, PAC_ConfigSourcePropagates
) {
663 // Test whether the ProxyConfigSource set by the ProxyConfigService is applied
664 // to ProxyInfo after the proxy is resolved via a PAC script.
666 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
667 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
669 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
670 MockAsyncProxyResolver resolver
;
671 ProxyService
service(
673 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
675 // Resolve something.
676 GURL
url("http://www.google.com/");
678 TestCompletionCallback callback
;
679 int rv
= service
.ResolveProxy(
680 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
682 ASSERT_EQ(ERR_IO_PENDING
, rv
);
683 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
684 ASSERT_EQ(1u, resolver
.pending_requests().size());
686 // Set the result in proxy resolver.
687 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy");
688 resolver
.pending_requests()[0]->CompleteNow(OK
);
690 EXPECT_EQ(OK
, callback
.WaitForResult());
691 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
692 EXPECT_TRUE(info
.did_use_pac_script());
694 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
695 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
696 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
699 TEST_F(ProxyServiceTest
, ProxyResolverFails
) {
700 // Test what happens when the ProxyResolver fails. The download and setting
701 // of the PAC script have already succeeded, so this corresponds with a
702 // javascript runtime error while calling FindProxyForURL().
704 MockProxyConfigService
* config_service
=
705 new MockProxyConfigService("http://foopy/proxy.pac");
707 MockAsyncProxyResolver resolver
;
709 ProxyService
service(
711 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
713 // Start first resolve request.
714 GURL
url("http://www.google.com/");
716 TestCompletionCallback callback1
;
717 int rv
= service
.ResolveProxy(
718 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
720 EXPECT_EQ(ERR_IO_PENDING
, rv
);
722 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
723 resolver
.pending_set_pac_script_request()->script_data()->url());
724 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
726 ASSERT_EQ(1u, resolver
.pending_requests().size());
727 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
729 // Fail the first resolve request in MockAsyncProxyResolver.
730 resolver
.pending_requests()[0]->CompleteNow(ERR_FAILED
);
732 // Although the proxy resolver failed the request, ProxyService implicitly
733 // falls-back to DIRECT.
734 EXPECT_EQ(OK
, callback1
.WaitForResult());
735 EXPECT_TRUE(info
.is_direct());
737 // Failed PAC executions still have proxy resolution times.
738 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
739 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
740 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
742 // The second resolve request will try to run through the proxy resolver,
743 // regardless of whether the first request failed in it.
744 TestCompletionCallback callback2
;
745 rv
= service
.ResolveProxy(
746 url
, net::LOAD_NORMAL
, &info
, callback2
.callback(), NULL
, NULL
,
748 EXPECT_EQ(ERR_IO_PENDING
, rv
);
750 ASSERT_EQ(1u, resolver
.pending_requests().size());
751 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
753 // This time we will have the resolver succeed (perhaps the PAC script has
754 // a dependency on the current time).
755 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
756 resolver
.pending_requests()[0]->CompleteNow(OK
);
758 EXPECT_EQ(OK
, callback2
.WaitForResult());
759 EXPECT_FALSE(info
.is_direct());
760 EXPECT_EQ("foopy_valid:8080", info
.proxy_server().ToURI());
763 TEST_F(ProxyServiceTest
, ProxyScriptFetcherFailsDownloadingMandatoryPac
) {
764 // Test what happens when the ProxyScriptResolver fails to download a
765 // mandatory PAC script.
768 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
769 config
.set_pac_mandatory(true);
771 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
773 MockAsyncProxyResolver resolver
;
775 ProxyService
service(
777 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
779 // Start first resolve request.
780 GURL
url("http://www.google.com/");
782 TestCompletionCallback callback1
;
783 int rv
= service
.ResolveProxy(
784 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
786 EXPECT_EQ(ERR_IO_PENDING
, rv
);
788 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
789 resolver
.pending_set_pac_script_request()->script_data()->url());
790 resolver
.pending_set_pac_script_request()->CompleteNow(ERR_FAILED
);
792 ASSERT_EQ(0u, resolver
.pending_requests().size());
793 // As the proxy resolver failed the request and is configured for a mandatory
794 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
795 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
796 callback1
.WaitForResult());
797 EXPECT_FALSE(info
.is_direct());
799 // As the proxy resolver failed the request and is configured for a mandatory
800 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
801 TestCompletionCallback callback2
;
802 rv
= service
.ResolveProxy(
803 url
, net::LOAD_NORMAL
, &info
, callback2
.callback(), NULL
, NULL
,
805 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
, rv
);
806 EXPECT_FALSE(info
.is_direct());
809 TEST_F(ProxyServiceTest
, ProxyResolverFailsParsingJavaScriptMandatoryPac
) {
810 // Test what happens when the ProxyResolver fails that is configured to use a
811 // mandatory PAC script. The download of the PAC script has already
812 // succeeded but the PAC script contains no valid javascript.
815 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
816 config
.set_pac_mandatory(true);
818 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
820 MockAsyncProxyResolverExpectsBytes resolver
;
822 ProxyService
service(
824 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
826 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
827 DhcpProxyScriptFetcher
* dhcp_fetcher
= new DoNothingDhcpProxyScriptFetcher();
828 service
.SetProxyScriptFetchers(fetcher
, dhcp_fetcher
);
830 // Start resolve request.
831 GURL
url("http://www.google.com/");
833 TestCompletionCallback callback
;
834 int rv
= service
.ResolveProxy(
835 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
837 EXPECT_EQ(ERR_IO_PENDING
, rv
);
839 // Check that nothing has been sent to the proxy resolver yet.
840 ASSERT_EQ(0u, resolver
.pending_requests().size());
842 // Downloading the PAC script succeeds.
843 EXPECT_TRUE(fetcher
->has_pending_request());
844 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
845 fetcher
->NotifyFetchCompletion(OK
, "invalid-script-contents");
847 EXPECT_FALSE(fetcher
->has_pending_request());
848 ASSERT_EQ(0u, resolver
.pending_requests().size());
850 // Since ProxyScriptDecider failed to identify a valid PAC and PAC was
851 // mandatory for this configuration, the ProxyService must not implicitly
852 // fall-back to DIRECT.
853 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
854 callback
.WaitForResult());
855 EXPECT_FALSE(info
.is_direct());
858 TEST_F(ProxyServiceTest
, ProxyResolverFailsInJavaScriptMandatoryPac
) {
859 // Test what happens when the ProxyResolver fails that is configured to use a
860 // mandatory PAC script. The download and setting of the PAC script have
861 // already succeeded, so this corresponds with a javascript runtime error
862 // while calling FindProxyForURL().
865 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
866 config
.set_pac_mandatory(true);
868 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
870 MockAsyncProxyResolver resolver
;
872 ProxyService
service(
874 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
876 // Start first resolve request.
877 GURL
url("http://www.google.com/");
879 TestCompletionCallback callback1
;
880 int rv
= service
.ResolveProxy(
881 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
883 EXPECT_EQ(ERR_IO_PENDING
, rv
);
885 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
886 resolver
.pending_set_pac_script_request()->script_data()->url());
887 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
889 ASSERT_EQ(1u, resolver
.pending_requests().size());
890 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
892 // Fail the first resolve request in MockAsyncProxyResolver.
893 resolver
.pending_requests()[0]->CompleteNow(ERR_FAILED
);
895 // As the proxy resolver failed the request and is configured for a mandatory
896 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
897 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
898 callback1
.WaitForResult());
899 EXPECT_FALSE(info
.is_direct());
901 // The second resolve request will try to run through the proxy resolver,
902 // regardless of whether the first request failed in it.
903 TestCompletionCallback callback2
;
904 rv
= service
.ResolveProxy(
905 url
, net::LOAD_NORMAL
, &info
, callback2
.callback(), NULL
, NULL
,
907 EXPECT_EQ(ERR_IO_PENDING
, rv
);
909 ASSERT_EQ(1u, resolver
.pending_requests().size());
910 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
912 // This time we will have the resolver succeed (perhaps the PAC script has
913 // a dependency on the current time).
914 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
915 resolver
.pending_requests()[0]->CompleteNow(OK
);
917 EXPECT_EQ(OK
, callback2
.WaitForResult());
918 EXPECT_FALSE(info
.is_direct());
919 EXPECT_EQ("foopy_valid:8080", info
.proxy_server().ToURI());
922 TEST_F(ProxyServiceTest
, ProxyFallback
) {
923 // Test what happens when we specify multiple proxy servers and some of them
926 MockProxyConfigService
* config_service
=
927 new MockProxyConfigService("http://foopy/proxy.pac");
929 MockAsyncProxyResolver resolver
;
931 ProxyService
service(
933 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
935 GURL
url("http://www.google.com/");
937 // Get the proxy information.
939 TestCompletionCallback callback1
;
940 int rv
= service
.ResolveProxy(
941 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
943 EXPECT_EQ(ERR_IO_PENDING
, rv
);
945 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
946 resolver
.pending_set_pac_script_request()->script_data()->url());
947 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
949 ASSERT_EQ(1u, resolver
.pending_requests().size());
950 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
952 // Set the result in proxy resolver.
953 resolver
.pending_requests()[0]->results()->UseNamedProxy(
954 "foopy1:8080;foopy2:9090");
955 resolver
.pending_requests()[0]->CompleteNow(OK
);
957 // The first item is valid.
958 EXPECT_EQ(OK
, callback1
.WaitForResult());
959 EXPECT_FALSE(info
.is_direct());
960 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
962 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
963 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
964 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
965 base::TimeTicks proxy_resolve_start_time
= info
.proxy_resolve_start_time();
966 base::TimeTicks proxy_resolve_end_time
= info
.proxy_resolve_end_time();
968 // Fake an error on the proxy.
969 TestCompletionCallback callback2
;
970 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
971 net::ERR_PROXY_CONNECTION_FAILED
,
972 &info
, callback2
.callback(), NULL
,
973 NULL
, BoundNetLog());
976 // Proxy times should not have been modified by fallback.
977 EXPECT_EQ(proxy_resolve_start_time
, info
.proxy_resolve_start_time());
978 EXPECT_EQ(proxy_resolve_end_time
, info
.proxy_resolve_end_time());
980 // The second proxy should be specified.
981 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
982 // Report back that the second proxy worked. This will globally mark the
983 // first proxy as bad.
984 TestProxyFallbackNetworkDelegate test_delegate
;
985 service
.ReportSuccess(info
, &test_delegate
);
986 EXPECT_EQ("foopy1:8080", test_delegate
.proxy_server().ToURI());
987 EXPECT_EQ(net::ERR_PROXY_CONNECTION_FAILED
,
988 test_delegate
.proxy_fallback_net_error());
990 TestCompletionCallback callback3
;
991 rv
= service
.ResolveProxy(
992 url
, net::LOAD_NORMAL
, &info
, callback3
.callback(), NULL
, NULL
,
994 EXPECT_EQ(ERR_IO_PENDING
, rv
);
996 ASSERT_EQ(1u, resolver
.pending_requests().size());
997 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
999 // Set the result in proxy resolver -- the second result is already known
1000 // to be bad, so we will not try to use it initially.
1001 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1002 "foopy3:7070;foopy1:8080;foopy2:9090");
1003 resolver
.pending_requests()[0]->CompleteNow(OK
);
1005 EXPECT_EQ(OK
, callback3
.WaitForResult());
1006 EXPECT_FALSE(info
.is_direct());
1007 EXPECT_EQ("foopy3:7070", info
.proxy_server().ToURI());
1009 // Proxy times should have been updated, so get them again.
1010 EXPECT_LE(proxy_resolve_end_time
, info
.proxy_resolve_start_time());
1011 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1012 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1013 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1014 proxy_resolve_start_time
= info
.proxy_resolve_start_time();
1015 proxy_resolve_end_time
= info
.proxy_resolve_end_time();
1017 // We fake another error. It should now try the third one.
1018 TestCompletionCallback callback4
;
1019 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1020 net::ERR_PROXY_CONNECTION_FAILED
,
1021 &info
, callback4
.callback(), NULL
,
1022 NULL
, BoundNetLog());
1024 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1026 // We fake another error. At this point we have tried all of the
1027 // proxy servers we thought were valid; next we try the proxy server
1028 // that was in our bad proxies map (foopy1:8080).
1029 TestCompletionCallback callback5
;
1030 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1031 net::ERR_PROXY_CONNECTION_FAILED
,
1032 &info
, callback5
.callback(), NULL
,
1033 NULL
, BoundNetLog());
1035 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1037 // Fake another error, the last proxy is gone, the list should now be empty,
1038 // so there is nothing left to try.
1039 TestCompletionCallback callback6
;
1040 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1041 net::ERR_PROXY_CONNECTION_FAILED
,
1042 &info
, callback6
.callback(), NULL
,
1043 NULL
, BoundNetLog());
1044 EXPECT_EQ(ERR_FAILED
, rv
);
1045 EXPECT_FALSE(info
.is_direct());
1046 EXPECT_TRUE(info
.is_empty());
1048 // Proxy times should not have been modified by fallback.
1049 EXPECT_EQ(proxy_resolve_start_time
, info
.proxy_resolve_start_time());
1050 EXPECT_EQ(proxy_resolve_end_time
, info
.proxy_resolve_end_time());
1052 // Look up proxies again
1053 TestCompletionCallback callback7
;
1054 rv
= service
.ResolveProxy(url
, net::LOAD_NORMAL
, &info
, callback7
.callback(),
1055 NULL
, NULL
, BoundNetLog());
1056 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1058 ASSERT_EQ(1u, resolver
.pending_requests().size());
1059 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1061 // This time, the first 3 results have been found to be bad, but only the
1062 // first proxy has been confirmed ...
1063 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1064 "foopy1:8080;foopy3:7070;foopy2:9090;foopy4:9091");
1065 resolver
.pending_requests()[0]->CompleteNow(OK
);
1067 // ... therefore, we should see the second proxy first.
1068 EXPECT_EQ(OK
, callback7
.WaitForResult());
1069 EXPECT_FALSE(info
.is_direct());
1070 EXPECT_EQ("foopy3:7070", info
.proxy_server().ToURI());
1072 EXPECT_LE(proxy_resolve_end_time
, info
.proxy_resolve_start_time());
1073 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1074 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1075 // TODO(nsylvain): Test that the proxy can be retried after the delay.
1078 // This test is similar to ProxyFallback, but this time we have an explicit
1079 // fallback choice to DIRECT.
1080 TEST_F(ProxyServiceTest
, ProxyFallbackToDirect
) {
1081 MockProxyConfigService
* config_service
=
1082 new MockProxyConfigService("http://foopy/proxy.pac");
1084 MockAsyncProxyResolver resolver
;
1086 ProxyService
service(
1088 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
1090 GURL
url("http://www.google.com/");
1092 // Get the proxy information.
1094 TestCompletionCallback callback1
;
1095 int rv
= service
.ResolveProxy(
1096 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
1098 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1100 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1101 resolver
.pending_set_pac_script_request()->script_data()->url());
1102 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
1104 ASSERT_EQ(1u, resolver
.pending_requests().size());
1105 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1107 // Set the result in proxy resolver.
1108 resolver
.pending_requests()[0]->results()->UsePacString(
1109 "PROXY foopy1:8080; PROXY foopy2:9090; DIRECT");
1110 resolver
.pending_requests()[0]->CompleteNow(OK
);
1112 // Get the first result.
1113 EXPECT_EQ(OK
, callback1
.WaitForResult());
1114 EXPECT_FALSE(info
.is_direct());
1115 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1117 // Fake an error on the proxy.
1118 TestCompletionCallback callback2
;
1119 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1120 net::ERR_PROXY_CONNECTION_FAILED
,
1121 &info
, callback2
.callback(), NULL
,
1122 NULL
, BoundNetLog());
1125 // Now we get back the second proxy.
1126 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1128 // Fake an error on this proxy as well.
1129 TestCompletionCallback callback3
;
1130 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1131 net::ERR_PROXY_CONNECTION_FAILED
,
1132 &info
, callback3
.callback(), NULL
,
1133 NULL
, BoundNetLog());
1136 // Finally, we get back DIRECT.
1137 EXPECT_TRUE(info
.is_direct());
1139 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1140 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1141 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1143 // Now we tell the proxy service that even DIRECT failed.
1144 TestCompletionCallback callback4
;
1145 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1146 net::ERR_PROXY_CONNECTION_FAILED
,
1147 &info
, callback4
.callback(), NULL
,
1148 NULL
, BoundNetLog());
1149 // There was nothing left to try after DIRECT, so we are out of
1151 EXPECT_EQ(ERR_FAILED
, rv
);
1154 TEST_F(ProxyServiceTest
, ProxyFallback_NewSettings
) {
1155 // Test proxy failover when new settings are available.
1157 MockProxyConfigService
* config_service
=
1158 new MockProxyConfigService("http://foopy/proxy.pac");
1160 MockAsyncProxyResolver resolver
;
1162 ProxyService
service(
1164 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
1166 GURL
url("http://www.google.com/");
1168 // Get the proxy information.
1170 TestCompletionCallback callback1
;
1171 int rv
= service
.ResolveProxy(
1172 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
1174 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1176 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1177 resolver
.pending_set_pac_script_request()->script_data()->url());
1178 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
1180 ASSERT_EQ(1u, resolver
.pending_requests().size());
1181 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1183 // Set the result in proxy resolver.
1184 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1185 "foopy1:8080;foopy2:9090");
1186 resolver
.pending_requests()[0]->CompleteNow(OK
);
1188 // The first item is valid.
1189 EXPECT_EQ(OK
, callback1
.WaitForResult());
1190 EXPECT_FALSE(info
.is_direct());
1191 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1193 // Fake an error on the proxy, and also a new configuration on the proxy.
1194 config_service
->SetConfig(
1195 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy-new/proxy.pac")));
1197 TestCompletionCallback callback2
;
1198 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1199 net::ERR_PROXY_CONNECTION_FAILED
,
1200 &info
, callback2
.callback(), NULL
,
1201 NULL
, BoundNetLog());
1202 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1204 EXPECT_EQ(GURL("http://foopy-new/proxy.pac"),
1205 resolver
.pending_set_pac_script_request()->script_data()->url());
1206 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
1208 ASSERT_EQ(1u, resolver
.pending_requests().size());
1209 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1211 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1212 "foopy1:8080;foopy2:9090");
1213 resolver
.pending_requests()[0]->CompleteNow(OK
);
1215 // The first proxy is still there since the configuration changed.
1216 EXPECT_EQ(OK
, callback2
.WaitForResult());
1217 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1219 // We fake another error. It should now ignore the first one.
1220 TestCompletionCallback callback3
;
1221 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1222 net::ERR_PROXY_CONNECTION_FAILED
,
1223 &info
, callback3
.callback(), NULL
,
1224 NULL
, BoundNetLog());
1226 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1228 // We simulate a new configuration.
1229 config_service
->SetConfig(
1230 ProxyConfig::CreateFromCustomPacURL(
1231 GURL("http://foopy-new2/proxy.pac")));
1233 // We fake another error. It should go back to the first proxy.
1234 TestCompletionCallback callback4
;
1235 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1236 net::ERR_PROXY_CONNECTION_FAILED
,
1237 &info
, callback4
.callback(), NULL
,
1238 NULL
, BoundNetLog());
1239 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1241 EXPECT_EQ(GURL("http://foopy-new2/proxy.pac"),
1242 resolver
.pending_set_pac_script_request()->script_data()->url());
1243 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
1245 ASSERT_EQ(1u, resolver
.pending_requests().size());
1246 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1248 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1249 "foopy1:8080;foopy2:9090");
1250 resolver
.pending_requests()[0]->CompleteNow(OK
);
1252 EXPECT_EQ(OK
, callback4
.WaitForResult());
1253 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1255 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1256 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1257 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1260 TEST_F(ProxyServiceTest
, ProxyFallback_BadConfig
) {
1261 // Test proxy failover when the configuration is bad.
1263 MockProxyConfigService
* config_service
=
1264 new MockProxyConfigService("http://foopy/proxy.pac");
1266 MockAsyncProxyResolver resolver
;
1268 ProxyService
service(
1270 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
1272 GURL
url("http://www.google.com/");
1274 // Get the proxy information.
1276 TestCompletionCallback callback1
;
1277 int rv
= service
.ResolveProxy(
1278 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
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
);
1285 ASSERT_EQ(1u, resolver
.pending_requests().size());
1286 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1288 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1289 "foopy1:8080;foopy2:9090");
1290 resolver
.pending_requests()[0]->CompleteNow(OK
);
1292 // The first item is valid.
1293 EXPECT_EQ(OK
, callback1
.WaitForResult());
1294 EXPECT_FALSE(info
.is_direct());
1295 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1297 // Fake a proxy error.
1298 TestCompletionCallback callback2
;
1299 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1300 net::ERR_PROXY_CONNECTION_FAILED
,
1301 &info
, callback2
.callback(), NULL
,
1302 NULL
, BoundNetLog());
1305 // The first proxy is ignored, and the second one is selected.
1306 EXPECT_FALSE(info
.is_direct());
1307 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1309 // Fake a PAC failure.
1311 TestCompletionCallback callback3
;
1312 rv
= service
.ResolveProxy(
1313 url
, net::LOAD_NORMAL
, &info2
, callback3
.callback(), NULL
, NULL
,
1315 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1317 ASSERT_EQ(1u, resolver
.pending_requests().size());
1318 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1320 // This simulates a javascript runtime error in the PAC script.
1321 resolver
.pending_requests()[0]->CompleteNow(ERR_FAILED
);
1323 // Although the resolver failed, the ProxyService will implicitly fall-back
1324 // to a DIRECT connection.
1325 EXPECT_EQ(OK
, callback3
.WaitForResult());
1326 EXPECT_TRUE(info2
.is_direct());
1327 EXPECT_FALSE(info2
.is_empty());
1329 // The PAC script will work properly next time and successfully return a
1330 // proxy list. Since we have not marked the configuration as bad, it should
1331 // "just work" the next time we call it.
1333 TestCompletionCallback callback4
;
1334 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1335 net::ERR_PROXY_CONNECTION_FAILED
,
1336 &info3
, callback4
.callback(),
1337 NULL
, NULL
, BoundNetLog());
1338 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1340 ASSERT_EQ(1u, resolver
.pending_requests().size());
1341 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1343 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1344 "foopy1:8080;foopy2:9090");
1345 resolver
.pending_requests()[0]->CompleteNow(OK
);
1347 // The first proxy is not there since the it was added to the bad proxies
1348 // list by the earlier ReconsiderProxyAfterError().
1349 EXPECT_EQ(OK
, callback4
.WaitForResult());
1350 EXPECT_FALSE(info3
.is_direct());
1351 EXPECT_EQ("foopy1:8080", info3
.proxy_server().ToURI());
1353 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1354 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1355 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1358 TEST_F(ProxyServiceTest
, ProxyFallback_BadConfigMandatory
) {
1359 // Test proxy failover when the configuration is bad.
1362 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
1364 config
.set_pac_mandatory(true);
1365 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
1367 MockAsyncProxyResolver resolver
;
1369 ProxyService
service(
1371 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
1373 GURL
url("http://www.google.com/");
1375 // Get the proxy information.
1377 TestCompletionCallback callback1
;
1378 int rv
= service
.ResolveProxy(
1379 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
1381 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1383 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1384 resolver
.pending_set_pac_script_request()->script_data()->url());
1385 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
1386 ASSERT_EQ(1u, resolver
.pending_requests().size());
1387 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1389 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1390 "foopy1:8080;foopy2:9090");
1391 resolver
.pending_requests()[0]->CompleteNow(OK
);
1393 // The first item is valid.
1394 EXPECT_EQ(OK
, callback1
.WaitForResult());
1395 EXPECT_FALSE(info
.is_direct());
1396 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1398 // Fake a proxy error.
1399 TestCompletionCallback callback2
;
1400 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1401 net::ERR_PROXY_CONNECTION_FAILED
,
1402 &info
, callback2
.callback(), NULL
,
1403 NULL
, BoundNetLog());
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.
1412 TestCompletionCallback callback3
;
1413 rv
= service
.ResolveProxy(
1414 url
, net::LOAD_NORMAL
, &info2
, callback3
.callback(), NULL
, NULL
,
1416 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1418 ASSERT_EQ(1u, resolver
.pending_requests().size());
1419 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1421 // This simulates a javascript runtime error in the PAC script.
1422 resolver
.pending_requests()[0]->CompleteNow(ERR_FAILED
);
1424 // Although the resolver failed, the ProxyService will NOT fall-back
1425 // to a DIRECT connection as it is configured as mandatory.
1426 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
1427 callback3
.WaitForResult());
1428 EXPECT_FALSE(info2
.is_direct());
1429 EXPECT_TRUE(info2
.is_empty());
1431 // The PAC script will work properly next time and successfully return a
1432 // proxy list. Since we have not marked the configuration as bad, it should
1433 // "just work" the next time we call it.
1435 TestCompletionCallback callback4
;
1436 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1437 net::ERR_PROXY_CONNECTION_FAILED
,
1438 &info3
, callback4
.callback(),
1439 NULL
, NULL
, BoundNetLog());
1440 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1442 ASSERT_EQ(1u, resolver
.pending_requests().size());
1443 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1445 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1446 "foopy1:8080;foopy2:9090");
1447 resolver
.pending_requests()[0]->CompleteNow(OK
);
1449 // The first proxy is not there since the it was added to the bad proxies
1450 // list by the earlier ReconsiderProxyAfterError().
1451 EXPECT_EQ(OK
, callback4
.WaitForResult());
1452 EXPECT_FALSE(info3
.is_direct());
1453 EXPECT_EQ("foopy1:8080", info3
.proxy_server().ToURI());
1456 TEST_F(ProxyServiceTest
, ProxyBypassList
) {
1457 // Test that the proxy bypass rules are consulted.
1459 TestCompletionCallback callback
[2];
1462 config
.proxy_rules().ParseFromString("foopy1:8080;foopy2:9090");
1463 config
.set_auto_detect(false);
1464 config
.proxy_rules().bypass_rules
.ParseFromString("*.org");
1466 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1469 GURL
url1("http://www.webkit.org");
1470 GURL
url2("http://www.webkit.com");
1472 // Request for a .org domain should bypass proxy.
1473 rv
= service
.ResolveProxy(
1474 url1
, net::LOAD_NORMAL
, &info
[0], callback
[0].callback(), NULL
, NULL
,
1477 EXPECT_TRUE(info
[0].is_direct());
1479 // Request for a .com domain hits the proxy.
1480 rv
= service
.ResolveProxy(
1481 url2
, net::LOAD_NORMAL
, &info
[1], callback
[1].callback(), NULL
, NULL
,
1484 EXPECT_EQ("foopy1:8080", info
[1].proxy_server().ToURI());
1488 TEST_F(ProxyServiceTest
, PerProtocolProxyTests
) {
1490 config
.proxy_rules().ParseFromString("http=foopy1:8080;https=foopy2:8080");
1491 config
.set_auto_detect(false);
1493 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1494 GURL
test_url("http://www.msn.com");
1496 TestCompletionCallback callback
;
1497 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1498 callback
.callback(), NULL
, NULL
,
1501 EXPECT_FALSE(info
.is_direct());
1502 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1505 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1506 GURL
test_url("ftp://ftp.google.com");
1508 TestCompletionCallback callback
;
1509 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1510 callback
.callback(), NULL
,
1511 NULL
, BoundNetLog());
1513 EXPECT_TRUE(info
.is_direct());
1514 EXPECT_EQ("direct://", info
.proxy_server().ToURI());
1517 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1518 GURL
test_url("https://webbranch.techcu.com");
1520 TestCompletionCallback callback
;
1521 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1522 callback
.callback(), NULL
,
1523 NULL
, BoundNetLog());
1525 EXPECT_FALSE(info
.is_direct());
1526 EXPECT_EQ("foopy2:8080", info
.proxy_server().ToURI());
1529 config
.proxy_rules().ParseFromString("foopy1:8080");
1530 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1531 GURL
test_url("http://www.microsoft.com");
1533 TestCompletionCallback callback
;
1534 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1535 callback
.callback(), NULL
,
1536 NULL
, BoundNetLog());
1538 EXPECT_FALSE(info
.is_direct());
1539 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1543 TEST_F(ProxyServiceTest
, ProxyConfigSourcePropagates
) {
1544 // Test that the proxy config source is set correctly when resolving proxies
1545 // using manual proxy rules. Namely, the config source should only be set if
1546 // any of the rules were applied.
1549 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1550 config
.proxy_rules().ParseFromString("https=foopy2:8080");
1551 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1552 GURL
test_url("http://www.google.com");
1554 TestCompletionCallback callback
;
1555 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1556 callback
.callback(), NULL
,
1557 NULL
, BoundNetLog());
1559 // Should be SOURCE_TEST, even if there are no HTTP proxies configured.
1560 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1564 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1565 config
.proxy_rules().ParseFromString("https=foopy2:8080");
1566 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1567 GURL
test_url("https://www.google.com");
1569 TestCompletionCallback callback
;
1570 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1571 callback
.callback(), NULL
,
1572 NULL
, BoundNetLog());
1574 // Used the HTTPS proxy. So source should be TEST.
1575 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1579 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1580 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1581 GURL
test_url("http://www.google.com");
1583 TestCompletionCallback callback
;
1584 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1585 callback
.callback(), NULL
,
1586 NULL
, BoundNetLog());
1588 // ProxyConfig is empty. Source should still be TEST.
1589 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1593 // If only HTTP and a SOCKS proxy are specified, check if ftp/https queries
1594 // fall back to the SOCKS proxy.
1595 TEST_F(ProxyServiceTest
, DefaultProxyFallbackToSOCKS
) {
1597 config
.proxy_rules().ParseFromString("http=foopy1:8080;socks=foopy2:1080");
1598 config
.set_auto_detect(false);
1599 EXPECT_EQ(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
1600 config
.proxy_rules().type
);
1603 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1604 GURL
test_url("http://www.msn.com");
1606 TestCompletionCallback callback
;
1607 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1608 callback
.callback(), NULL
,
1609 NULL
, BoundNetLog());
1611 EXPECT_FALSE(info
.is_direct());
1612 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1615 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1616 GURL
test_url("ftp://ftp.google.com");
1618 TestCompletionCallback callback
;
1619 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1620 callback
.callback(), NULL
,
1621 NULL
, BoundNetLog());
1623 EXPECT_FALSE(info
.is_direct());
1624 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1627 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1628 GURL
test_url("https://webbranch.techcu.com");
1630 TestCompletionCallback callback
;
1631 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1632 callback
.callback(), NULL
,
1633 NULL
, BoundNetLog());
1635 EXPECT_FALSE(info
.is_direct());
1636 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1639 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1640 GURL
test_url("unknown://www.microsoft.com");
1642 TestCompletionCallback callback
;
1643 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1644 callback
.callback(), NULL
,
1645 NULL
, BoundNetLog());
1647 EXPECT_FALSE(info
.is_direct());
1648 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1652 // Test cancellation of an in-progress request.
1653 TEST_F(ProxyServiceTest
, CancelInProgressRequest
) {
1654 MockProxyConfigService
* config_service
=
1655 new MockProxyConfigService("http://foopy/proxy.pac");
1657 MockAsyncProxyResolver resolver
;
1659 ProxyService
service(
1661 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
1663 // Start 3 requests.
1666 TestCompletionCallback callback1
;
1667 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1668 &info1
, callback1
.callback(), NULL
, NULL
,
1670 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1672 // Nothing has been sent to the proxy resolver yet, since the proxy
1673 // resolver has not been configured yet.
1674 ASSERT_EQ(0u, resolver
.pending_requests().size());
1676 // Successfully initialize the PAC script.
1677 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1678 resolver
.pending_set_pac_script_request()->script_data()->url());
1679 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
1681 ASSERT_EQ(1u, resolver
.pending_requests().size());
1682 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
1685 TestCompletionCallback callback2
;
1686 ProxyService::PacRequest
* request2
;
1687 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1688 callback2
.callback(), &request2
, NULL
,
1690 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1691 ASSERT_EQ(2u, resolver
.pending_requests().size());
1692 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[1]->url());
1695 TestCompletionCallback callback3
;
1696 rv
= service
.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL
, &info3
,
1697 callback3
.callback(), NULL
, NULL
, BoundNetLog());
1698 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1699 ASSERT_EQ(3u, resolver
.pending_requests().size());
1700 EXPECT_EQ(GURL("http://request3"), resolver
.pending_requests()[2]->url());
1702 // Cancel the second request
1703 service
.CancelPacRequest(request2
);
1705 ASSERT_EQ(2u, resolver
.pending_requests().size());
1706 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
1707 EXPECT_EQ(GURL("http://request3"), resolver
.pending_requests()[1]->url());
1709 // Complete the two un-cancelled requests.
1710 // We complete the last one first, just to mix it up a bit.
1711 resolver
.pending_requests()[1]->results()->UseNamedProxy("request3:80");
1712 resolver
.pending_requests()[1]->CompleteNow(OK
);
1714 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
1715 resolver
.pending_requests()[0]->CompleteNow(OK
);
1717 // Complete and verify that requests ran as expected.
1718 EXPECT_EQ(OK
, callback1
.WaitForResult());
1719 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
1721 EXPECT_FALSE(callback2
.have_result()); // Cancelled.
1722 ASSERT_EQ(1u, resolver
.cancelled_requests().size());
1723 EXPECT_EQ(GURL("http://request2"), resolver
.cancelled_requests()[0]->url());
1725 EXPECT_EQ(OK
, callback3
.WaitForResult());
1726 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
1729 // Test the initial PAC download for resolver that expects bytes.
1730 TEST_F(ProxyServiceTest
, InitialPACScriptDownload
) {
1731 MockProxyConfigService
* config_service
=
1732 new MockProxyConfigService("http://foopy/proxy.pac");
1734 MockAsyncProxyResolverExpectsBytes resolver
;
1736 ProxyService
service(
1738 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
1740 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1741 service
.SetProxyScriptFetchers(fetcher
,
1742 new DoNothingDhcpProxyScriptFetcher());
1744 // Start 3 requests.
1747 TestCompletionCallback callback1
;
1748 ProxyService::PacRequest
* request1
;
1749 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1750 &info1
, callback1
.callback(), &request1
, NULL
,
1752 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1754 // The first request should have triggered download of PAC script.
1755 EXPECT_TRUE(fetcher
->has_pending_request());
1756 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1759 TestCompletionCallback callback2
;
1760 ProxyService::PacRequest
* request2
;
1761 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1762 callback2
.callback(), &request2
, NULL
,
1764 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1767 TestCompletionCallback callback3
;
1768 ProxyService::PacRequest
* request3
;
1769 rv
= service
.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL
, &info3
,
1770 callback3
.callback(), &request3
, NULL
,
1772 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1774 // Nothing has been sent to the resolver yet.
1775 EXPECT_TRUE(resolver
.pending_requests().empty());
1777 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1778 service
.GetLoadState(request1
));
1779 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1780 service
.GetLoadState(request2
));
1781 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1782 service
.GetLoadState(request3
));
1784 // At this point the ProxyService should be waiting for the
1785 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1786 // PAC script download completion.
1787 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
1789 // Now that the PAC script is downloaded, it will have been sent to the proxy
1791 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
1792 resolver
.pending_set_pac_script_request()->script_data()->utf16());
1793 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
1795 ASSERT_EQ(3u, resolver
.pending_requests().size());
1796 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
1797 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[1]->url());
1798 EXPECT_EQ(GURL("http://request3"), resolver
.pending_requests()[2]->url());
1800 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request1
));
1801 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request2
));
1802 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request3
));
1804 // Complete all the requests (in some order).
1805 // Note that as we complete requests, they shift up in |pending_requests()|.
1807 resolver
.pending_requests()[2]->results()->UseNamedProxy("request3:80");
1808 resolver
.pending_requests()[2]->CompleteNow(OK
);
1810 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
1811 resolver
.pending_requests()[0]->CompleteNow(OK
);
1813 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
1814 resolver
.pending_requests()[0]->CompleteNow(OK
);
1816 // Complete and verify that requests ran as expected.
1817 EXPECT_EQ(OK
, callback1
.WaitForResult());
1818 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
1819 EXPECT_FALSE(info1
.proxy_resolve_start_time().is_null());
1820 EXPECT_FALSE(info1
.proxy_resolve_end_time().is_null());
1821 EXPECT_LE(info1
.proxy_resolve_start_time(), info1
.proxy_resolve_end_time());
1823 EXPECT_EQ(OK
, callback2
.WaitForResult());
1824 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
1825 EXPECT_FALSE(info2
.proxy_resolve_start_time().is_null());
1826 EXPECT_FALSE(info2
.proxy_resolve_end_time().is_null());
1827 EXPECT_LE(info2
.proxy_resolve_start_time(), info2
.proxy_resolve_end_time());
1829 EXPECT_EQ(OK
, callback3
.WaitForResult());
1830 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
1831 EXPECT_FALSE(info3
.proxy_resolve_start_time().is_null());
1832 EXPECT_FALSE(info3
.proxy_resolve_end_time().is_null());
1833 EXPECT_LE(info3
.proxy_resolve_start_time(), info3
.proxy_resolve_end_time());
1836 // Test changing the ProxyScriptFetcher while PAC download is in progress.
1837 TEST_F(ProxyServiceTest
, ChangeScriptFetcherWhilePACDownloadInProgress
) {
1838 MockProxyConfigService
* config_service
=
1839 new MockProxyConfigService("http://foopy/proxy.pac");
1841 MockAsyncProxyResolverExpectsBytes resolver
;
1843 ProxyService
service(
1845 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
1847 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1848 service
.SetProxyScriptFetchers(fetcher
,
1849 new DoNothingDhcpProxyScriptFetcher());
1851 // Start 2 requests.
1854 TestCompletionCallback callback1
;
1855 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1856 &info1
, callback1
.callback(), NULL
, NULL
,
1858 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1860 // The first request should have triggered download of PAC script.
1861 EXPECT_TRUE(fetcher
->has_pending_request());
1862 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1865 TestCompletionCallback callback2
;
1866 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1867 callback2
.callback(), NULL
, NULL
, BoundNetLog());
1868 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1870 // At this point the ProxyService should be waiting for the
1871 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1872 // PAC script download completion.
1874 // We now change out the ProxyService's script fetcher. We should restart
1875 // the initialization with the new fetcher.
1877 fetcher
= new MockProxyScriptFetcher
;
1878 service
.SetProxyScriptFetchers(fetcher
,
1879 new DoNothingDhcpProxyScriptFetcher());
1881 // Nothing has been sent to the resolver yet.
1882 EXPECT_TRUE(resolver
.pending_requests().empty());
1884 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
1886 // Now that the PAC script is downloaded, it will have been sent to the proxy
1888 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
1889 resolver
.pending_set_pac_script_request()->script_data()->utf16());
1890 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
1892 ASSERT_EQ(2u, resolver
.pending_requests().size());
1893 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
1894 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[1]->url());
1897 // Test cancellation of a request, while the PAC script is being fetched.
1898 TEST_F(ProxyServiceTest
, CancelWhilePACFetching
) {
1899 MockProxyConfigService
* config_service
=
1900 new MockProxyConfigService("http://foopy/proxy.pac");
1902 MockAsyncProxyResolverExpectsBytes resolver
;
1904 ProxyService
service(
1906 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
1908 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1909 service
.SetProxyScriptFetchers(fetcher
,
1910 new DoNothingDhcpProxyScriptFetcher());
1912 // Start 3 requests.
1914 TestCompletionCallback callback1
;
1915 ProxyService::PacRequest
* request1
;
1916 CapturingBoundNetLog log1
;
1917 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1918 &info1
, callback1
.callback(), &request1
, NULL
,
1920 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1922 // The first request should have triggered download of PAC script.
1923 EXPECT_TRUE(fetcher
->has_pending_request());
1924 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1927 TestCompletionCallback callback2
;
1928 ProxyService::PacRequest
* request2
;
1929 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1930 callback2
.callback(), &request2
, NULL
,
1932 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1935 TestCompletionCallback callback3
;
1936 rv
= service
.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL
, &info3
,
1937 callback3
.callback(), NULL
, NULL
, BoundNetLog());
1938 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1940 // Nothing has been sent to the resolver yet.
1941 EXPECT_TRUE(resolver
.pending_requests().empty());
1943 // Cancel the first 2 requests.
1944 service
.CancelPacRequest(request1
);
1945 service
.CancelPacRequest(request2
);
1947 // At this point the ProxyService should be waiting for the
1948 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1949 // PAC script download completion.
1950 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
1952 // Now that the PAC script is downloaded, it will have been sent to the
1954 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
1955 resolver
.pending_set_pac_script_request()->script_data()->utf16());
1956 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
1958 ASSERT_EQ(1u, resolver
.pending_requests().size());
1959 EXPECT_EQ(GURL("http://request3"), resolver
.pending_requests()[0]->url());
1961 // Complete all the requests.
1962 resolver
.pending_requests()[0]->results()->UseNamedProxy("request3:80");
1963 resolver
.pending_requests()[0]->CompleteNow(OK
);
1965 EXPECT_EQ(OK
, callback3
.WaitForResult());
1966 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
1968 EXPECT_TRUE(resolver
.cancelled_requests().empty());
1970 EXPECT_FALSE(callback1
.have_result()); // Cancelled.
1971 EXPECT_FALSE(callback2
.have_result()); // Cancelled.
1973 CapturingNetLog::CapturedEntryList entries1
;
1974 log1
.GetEntries(&entries1
);
1976 // Check the NetLog for request 1 (which was cancelled) got filled properly.
1977 EXPECT_EQ(4u, entries1
.size());
1978 EXPECT_TRUE(LogContainsBeginEvent(
1979 entries1
, 0, NetLog::TYPE_PROXY_SERVICE
));
1980 EXPECT_TRUE(LogContainsBeginEvent(
1981 entries1
, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
1982 // Note that TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC is never completed before
1983 // the cancellation occured.
1984 EXPECT_TRUE(LogContainsEvent(
1985 entries1
, 2, NetLog::TYPE_CANCELLED
, NetLog::PHASE_NONE
));
1986 EXPECT_TRUE(LogContainsEndEvent(
1987 entries1
, 3, NetLog::TYPE_PROXY_SERVICE
));
1990 // Test that if auto-detect fails, we fall-back to the custom pac.
1991 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomPac
) {
1993 config
.set_auto_detect(true);
1994 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
1995 config
.proxy_rules().ParseFromString("http=foopy:80"); // Won't be used.
1997 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
1998 MockAsyncProxyResolverExpectsBytes resolver
;
1999 ProxyService
service(
2001 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
2003 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2004 service
.SetProxyScriptFetchers(fetcher
,
2005 new DoNothingDhcpProxyScriptFetcher());
2007 // Start 2 requests.
2010 TestCompletionCallback callback1
;
2011 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2012 &info1
, callback1
.callback(), NULL
, NULL
,
2014 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2017 TestCompletionCallback callback2
;
2018 ProxyService::PacRequest
* request2
;
2019 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
2020 callback2
.callback(), &request2
, NULL
,
2022 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2024 // Check that nothing has been sent to the proxy resolver yet.
2025 ASSERT_EQ(0u, resolver
.pending_requests().size());
2027 // It should be trying to auto-detect first -- FAIL the autodetect during
2028 // the script download.
2029 EXPECT_TRUE(fetcher
->has_pending_request());
2030 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2031 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2033 // Next it should be trying the custom PAC url.
2034 EXPECT_TRUE(fetcher
->has_pending_request());
2035 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2036 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2038 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2039 resolver
.pending_set_pac_script_request()->script_data()->utf16());
2040 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
2042 // Now finally, the pending requests should have been sent to the resolver
2043 // (which was initialized with custom PAC script).
2045 ASSERT_EQ(2u, resolver
.pending_requests().size());
2046 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
2047 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[1]->url());
2049 // Complete the pending requests.
2050 resolver
.pending_requests()[1]->results()->UseNamedProxy("request2:80");
2051 resolver
.pending_requests()[1]->CompleteNow(OK
);
2052 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2053 resolver
.pending_requests()[0]->CompleteNow(OK
);
2055 // Verify that requests ran as expected.
2056 EXPECT_EQ(OK
, callback1
.WaitForResult());
2057 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2058 EXPECT_FALSE(info1
.proxy_resolve_start_time().is_null());
2059 EXPECT_FALSE(info1
.proxy_resolve_end_time().is_null());
2060 EXPECT_LE(info1
.proxy_resolve_start_time(), info1
.proxy_resolve_end_time());
2062 EXPECT_EQ(OK
, callback2
.WaitForResult());
2063 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2064 EXPECT_FALSE(info2
.proxy_resolve_start_time().is_null());
2065 EXPECT_FALSE(info2
.proxy_resolve_end_time().is_null());
2066 EXPECT_LE(info2
.proxy_resolve_start_time(), info2
.proxy_resolve_end_time());
2069 // This is the same test as FallbackFromAutodetectToCustomPac, except
2070 // the auto-detect script fails parsing rather than downloading.
2071 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomPac2
) {
2073 config
.set_auto_detect(true);
2074 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2075 config
.proxy_rules().ParseFromString("http=foopy:80"); // Won't be used.
2077 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2078 MockAsyncProxyResolverExpectsBytes resolver
;
2079 ProxyService
service(
2081 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
2083 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2084 service
.SetProxyScriptFetchers(fetcher
,
2085 new DoNothingDhcpProxyScriptFetcher());
2087 // Start 2 requests.
2090 TestCompletionCallback callback1
;
2091 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2092 &info1
, callback1
.callback(), NULL
, NULL
,
2094 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2097 TestCompletionCallback callback2
;
2098 ProxyService::PacRequest
* request2
;
2099 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
2100 callback2
.callback(), &request2
, NULL
,
2102 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2104 // Check that nothing has been sent to the proxy resolver yet.
2105 ASSERT_EQ(0u, resolver
.pending_requests().size());
2107 // It should be trying to auto-detect first -- succeed the download.
2108 EXPECT_TRUE(fetcher
->has_pending_request());
2109 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2110 fetcher
->NotifyFetchCompletion(OK
, "invalid-script-contents");
2112 // The script contents passed failed basic verification step (since didn't
2113 // contain token FindProxyForURL), so it was never passed to the resolver.
2115 // Next it should be trying the custom PAC url.
2116 EXPECT_TRUE(fetcher
->has_pending_request());
2117 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2118 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2120 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2121 resolver
.pending_set_pac_script_request()->script_data()->utf16());
2122 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
2124 // Now finally, the pending requests should have been sent to the resolver
2125 // (which was initialized with custom PAC script).
2127 ASSERT_EQ(2u, resolver
.pending_requests().size());
2128 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
2129 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[1]->url());
2131 // Complete the pending requests.
2132 resolver
.pending_requests()[1]->results()->UseNamedProxy("request2:80");
2133 resolver
.pending_requests()[1]->CompleteNow(OK
);
2134 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2135 resolver
.pending_requests()[0]->CompleteNow(OK
);
2137 // Verify that requests ran as expected.
2138 EXPECT_EQ(OK
, callback1
.WaitForResult());
2139 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2141 EXPECT_EQ(OK
, callback2
.WaitForResult());
2142 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2145 // Test that if all of auto-detect, a custom PAC script, and manual settings
2146 // are given, then we will try them in that order.
2147 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomToManual
) {
2149 config
.set_auto_detect(true);
2150 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2151 config
.proxy_rules().ParseFromString("http=foopy:80");
2153 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2154 MockAsyncProxyResolverExpectsBytes resolver
;
2155 ProxyService
service(
2157 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
2159 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2160 service
.SetProxyScriptFetchers(fetcher
,
2161 new DoNothingDhcpProxyScriptFetcher());
2163 // Start 2 requests.
2166 TestCompletionCallback callback1
;
2167 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2168 &info1
, callback1
.callback(), NULL
, NULL
,
2170 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2173 TestCompletionCallback callback2
;
2174 ProxyService::PacRequest
* request2
;
2175 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
2176 callback2
.callback(), &request2
, NULL
,
2178 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2180 // Check that nothing has been sent to the proxy resolver yet.
2181 ASSERT_EQ(0u, resolver
.pending_requests().size());
2183 // It should be trying to auto-detect first -- fail the download.
2184 EXPECT_TRUE(fetcher
->has_pending_request());
2185 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2186 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2188 // Next it should be trying the custom PAC url -- fail the download.
2189 EXPECT_TRUE(fetcher
->has_pending_request());
2190 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2191 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2193 // Since we never managed to initialize a resolver, nothing should have been
2195 ASSERT_EQ(0u, resolver
.pending_requests().size());
2197 // Verify that requests ran as expected -- they should have fallen back to
2198 // the manual proxy configuration for HTTP urls.
2199 EXPECT_EQ(OK
, callback1
.WaitForResult());
2200 EXPECT_EQ("foopy:80", info1
.proxy_server().ToURI());
2202 EXPECT_EQ(OK
, callback2
.WaitForResult());
2203 EXPECT_EQ("foopy:80", info2
.proxy_server().ToURI());
2206 // Test that the bypass rules are NOT applied when using autodetect.
2207 TEST_F(ProxyServiceTest
, BypassDoesntApplyToPac
) {
2209 config
.set_auto_detect(true);
2210 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2211 config
.proxy_rules().ParseFromString("http=foopy:80"); // Not used.
2212 config
.proxy_rules().bypass_rules
.ParseFromString("www.google.com");
2214 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2215 MockAsyncProxyResolverExpectsBytes resolver
;
2216 ProxyService
service(
2218 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
2220 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2221 service
.SetProxyScriptFetchers(fetcher
,
2222 new DoNothingDhcpProxyScriptFetcher());
2224 // Start 1 requests.
2227 TestCompletionCallback callback1
;
2228 int rv
= service
.ResolveProxy(
2229 GURL("http://www.google.com"), net::LOAD_NORMAL
, &info1
,
2230 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2231 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2233 // Check that nothing has been sent to the proxy resolver yet.
2234 ASSERT_EQ(0u, resolver
.pending_requests().size());
2236 // It should be trying to auto-detect first -- succeed the download.
2237 EXPECT_TRUE(fetcher
->has_pending_request());
2238 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2239 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2241 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2242 resolver
.pending_set_pac_script_request()->script_data()->utf16());
2243 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
2245 ASSERT_EQ(1u, resolver
.pending_requests().size());
2246 EXPECT_EQ(GURL("http://www.google.com"),
2247 resolver
.pending_requests()[0]->url());
2249 // Complete the pending request.
2250 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2251 resolver
.pending_requests()[0]->CompleteNow(OK
);
2253 // Verify that request ran as expected.
2254 EXPECT_EQ(OK
, callback1
.WaitForResult());
2255 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2257 // Start another request, it should pickup the bypass item.
2259 TestCompletionCallback callback2
;
2260 rv
= service
.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL
,
2261 &info2
, callback2
.callback(), NULL
, NULL
,
2263 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2265 ASSERT_EQ(1u, resolver
.pending_requests().size());
2266 EXPECT_EQ(GURL("http://www.google.com"),
2267 resolver
.pending_requests()[0]->url());
2269 // Complete the pending request.
2270 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2271 resolver
.pending_requests()[0]->CompleteNow(OK
);
2273 EXPECT_EQ(OK
, callback2
.WaitForResult());
2274 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2277 // Delete the ProxyService while InitProxyResolver has an outstanding
2278 // request to the script fetcher. When run under valgrind, should not
2279 // have any memory errors (used to be that the ProxyScriptFetcher was
2280 // being deleted prior to the InitProxyResolver).
2281 TEST_F(ProxyServiceTest
, DeleteWhileInitProxyResolverHasOutstandingFetch
) {
2282 ProxyConfig config
=
2283 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
2285 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2286 MockAsyncProxyResolverExpectsBytes resolver
;
2287 ProxyService
service(
2289 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
2291 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2292 service
.SetProxyScriptFetchers(fetcher
,
2293 new DoNothingDhcpProxyScriptFetcher());
2298 TestCompletionCallback callback1
;
2299 int rv
= service
.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL
,
2300 &info1
, callback1
.callback(), NULL
, NULL
,
2302 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2304 // Check that nothing has been sent to the proxy resolver yet.
2305 ASSERT_EQ(0u, resolver
.pending_requests().size());
2307 // InitProxyResolver should have issued a request to the ProxyScriptFetcher
2308 // and be waiting on that to complete.
2309 EXPECT_TRUE(fetcher
->has_pending_request());
2310 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2313 // Delete the ProxyService while InitProxyResolver has an outstanding
2314 // request to the proxy resolver. When run under valgrind, should not
2315 // have any memory errors (used to be that the ProxyResolver was
2316 // being deleted prior to the InitProxyResolver).
2317 TEST_F(ProxyServiceTest
, DeleteWhileInitProxyResolverHasOutstandingSet
) {
2318 MockProxyConfigService
* config_service
=
2319 new MockProxyConfigService("http://foopy/proxy.pac");
2321 MockAsyncProxyResolver resolver
;
2323 ProxyService
service(
2325 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
2327 GURL
url("http://www.google.com/");
2330 TestCompletionCallback callback
;
2331 int rv
= service
.ResolveProxy(
2332 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
2334 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2336 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
2337 resolver
.pending_set_pac_script_request()->script_data()->url());
2340 TEST_F(ProxyServiceTest
, ResetProxyConfigService
) {
2341 ProxyConfig config1
;
2342 config1
.proxy_rules().ParseFromString("foopy1:8080");
2343 config1
.set_auto_detect(false);
2344 ProxyService
service(new MockProxyConfigService(config1
), nullptr, NULL
);
2347 TestCompletionCallback callback1
;
2348 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2349 &info
, callback1
.callback(), NULL
, NULL
,
2352 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
2354 ProxyConfig config2
;
2355 config2
.proxy_rules().ParseFromString("foopy2:8080");
2356 config2
.set_auto_detect(false);
2357 service
.ResetConfigService(new MockProxyConfigService(config2
));
2358 TestCompletionCallback callback2
;
2359 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info
,
2360 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2362 EXPECT_EQ("foopy2:8080", info
.proxy_server().ToURI());
2365 // Test that when going from a configuration that required PAC to one
2366 // that does NOT, we unset the variable |should_use_proxy_resolver_|.
2367 TEST_F(ProxyServiceTest
, UpdateConfigFromPACToDirect
) {
2368 ProxyConfig config
= ProxyConfig::CreateAutoDetect();
2370 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2371 MockAsyncProxyResolver resolver
;
2372 ProxyService
service(
2374 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
2379 TestCompletionCallback callback1
;
2380 int rv
= service
.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL
,
2381 &info1
, callback1
.callback(), NULL
, NULL
,
2383 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2385 // Check that nothing has been sent to the proxy resolver yet.
2386 ASSERT_EQ(0u, resolver
.pending_requests().size());
2388 // Successfully set the autodetect script.
2389 EXPECT_EQ(ProxyResolverScriptData::TYPE_AUTO_DETECT
,
2390 resolver
.pending_set_pac_script_request()->script_data()->type());
2391 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
2393 // Complete the pending request.
2394 ASSERT_EQ(1u, resolver
.pending_requests().size());
2395 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2396 resolver
.pending_requests()[0]->CompleteNow(OK
);
2398 // Verify that request ran as expected.
2399 EXPECT_EQ(OK
, callback1
.WaitForResult());
2400 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2402 // Force the ProxyService to pull down a new proxy configuration.
2403 // (Even though the configuration isn't old/bad).
2405 // This new configuration no longer has auto_detect set, so
2406 // requests should complete synchronously now as direct-connect.
2407 config_service
->SetConfig(ProxyConfig::CreateDirect());
2409 // Start another request -- the effective configuration has changed.
2411 TestCompletionCallback callback2
;
2412 rv
= service
.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL
,
2413 &info2
, callback2
.callback(), NULL
, NULL
,
2417 EXPECT_TRUE(info2
.is_direct());
2420 TEST_F(ProxyServiceTest
, NetworkChangeTriggersPacRefetch
) {
2421 MockProxyConfigService
* config_service
=
2422 new MockProxyConfigService("http://foopy/proxy.pac");
2424 MockAsyncProxyResolverExpectsBytes resolver
;
2426 CapturingNetLog log
;
2428 ProxyService
service(
2430 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), &log
);
2432 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2433 service
.SetProxyScriptFetchers(fetcher
,
2434 new DoNothingDhcpProxyScriptFetcher());
2436 // Disable the "wait after IP address changes" hack, so this unit-test can
2437 // complete quickly.
2438 service
.set_stall_proxy_auto_config_delay(base::TimeDelta());
2443 TestCompletionCallback callback1
;
2444 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2445 &info1
, callback1
.callback(), NULL
, NULL
,
2447 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2449 // The first request should have triggered initial download of PAC script.
2450 EXPECT_TRUE(fetcher
->has_pending_request());
2451 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2453 // Nothing has been sent to the resolver yet.
2454 EXPECT_TRUE(resolver
.pending_requests().empty());
2456 // At this point the ProxyService should be waiting for the
2457 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2458 // PAC script download completion.
2459 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2461 // Now that the PAC script is downloaded, the request will have been sent to
2462 // the proxy resolver.
2463 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2464 resolver
.pending_set_pac_script_request()->script_data()->utf16());
2465 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
2467 ASSERT_EQ(1u, resolver
.pending_requests().size());
2468 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
2470 // Complete the pending request.
2471 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2472 resolver
.pending_requests()[0]->CompleteNow(OK
);
2474 // Wait for completion callback, and verify that the request ran as expected.
2475 EXPECT_EQ(OK
, callback1
.WaitForResult());
2476 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2478 // Now simluate a change in the network. The ProxyConfigService is still
2479 // going to return the same PAC URL as before, but this URL needs to be
2480 // refetched on the new network.
2481 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
2482 base::MessageLoop::current()->RunUntilIdle(); // Notification happens async.
2484 // Start a second request.
2486 TestCompletionCallback callback2
;
2487 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
2488 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2489 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2491 // This second request should have triggered the re-download of the PAC
2492 // script (since we marked the network as having changed).
2493 EXPECT_TRUE(fetcher
->has_pending_request());
2494 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2496 // Nothing has been sent to the resolver yet.
2497 EXPECT_TRUE(resolver
.pending_requests().empty());
2499 // Simulate the PAC script fetch as having completed (this time with
2501 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript2
);
2503 // Now that the PAC script is downloaded, the second request will have been
2504 // sent to the proxy resolver.
2505 EXPECT_EQ(ASCIIToUTF16(kValidPacScript2
),
2506 resolver
.pending_set_pac_script_request()->script_data()->utf16());
2507 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
2509 ASSERT_EQ(1u, resolver
.pending_requests().size());
2510 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[0]->url());
2512 // Complete the pending second request.
2513 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2514 resolver
.pending_requests()[0]->CompleteNow(OK
);
2516 // Wait for completion callback, and verify that the request ran as expected.
2517 EXPECT_EQ(OK
, callback2
.WaitForResult());
2518 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2520 // Check that the expected events were output to the log stream. In particular
2521 // PROXY_CONFIG_CHANGED should have only been emitted once (for the initial
2522 // setup), and NOT a second time when the IP address changed.
2523 CapturingNetLog::CapturedEntryList entries
;
2524 log
.GetEntries(&entries
);
2526 EXPECT_TRUE(LogContainsEntryWithType(entries
, 0,
2527 NetLog::TYPE_PROXY_CONFIG_CHANGED
));
2528 ASSERT_EQ(9u, entries
.size());
2529 for (size_t i
= 1; i
< entries
.size(); ++i
)
2530 EXPECT_NE(NetLog::TYPE_PROXY_CONFIG_CHANGED
, entries
[i
].type
);
2533 // This test verifies that the PAC script specified by the settings is
2534 // periodically polled for changes. Specifically, if the initial fetch fails due
2535 // to a network error, we will eventually re-configure the service to use the
2536 // script once it becomes available.
2537 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterFailure
) {
2538 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2540 ImmediatePollPolicy poll_policy
;
2541 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2543 MockProxyConfigService
* config_service
=
2544 new MockProxyConfigService("http://foopy/proxy.pac");
2546 MockAsyncProxyResolverExpectsBytes resolver
;
2548 ProxyService
service(
2550 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
2552 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2553 service
.SetProxyScriptFetchers(fetcher
,
2554 new DoNothingDhcpProxyScriptFetcher());
2559 TestCompletionCallback callback1
;
2560 int rv
= service
.ResolveProxy(
2561 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2562 NULL
, NULL
, BoundNetLog());
2563 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2565 // The first request should have triggered initial download of PAC script.
2566 EXPECT_TRUE(fetcher
->has_pending_request());
2567 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2569 // Nothing has been sent to the resolver yet.
2570 EXPECT_TRUE(resolver
.pending_requests().empty());
2572 // At this point the ProxyService should be waiting for the
2573 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2574 // PAC script download completion.
2576 // We simulate a failed download attempt, the proxy service should now
2577 // fall-back to DIRECT connections.
2578 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2580 ASSERT_TRUE(resolver
.pending_requests().empty());
2582 // Wait for completion callback, and verify it used DIRECT.
2583 EXPECT_EQ(OK
, callback1
.WaitForResult());
2584 EXPECT_TRUE(info1
.is_direct());
2586 // At this point we have initialized the proxy service using a PAC script,
2587 // however it failed and fell-back to DIRECT.
2589 // A background task to periodically re-check the PAC script for validity will
2590 // have been started. We will now wait for the next download attempt to start.
2592 // Note that we shouldn't have to wait long here, since our test enables a
2593 // special unit-test mode.
2594 fetcher
->WaitUntilFetch();
2596 ASSERT_TRUE(resolver
.pending_requests().empty());
2598 // Make sure that our background checker is trying to download the expected
2599 // PAC script (same one as before). This time we will simulate a successful
2600 // download of the script.
2601 EXPECT_TRUE(fetcher
->has_pending_request());
2602 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2603 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2605 base::MessageLoop::current()->RunUntilIdle();
2607 // Now that the PAC script is downloaded, it should be used to initialize the
2608 // ProxyResolver. Simulate a successful parse.
2609 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2610 resolver
.pending_set_pac_script_request()->script_data()->utf16());
2611 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
2613 // At this point the ProxyService should have re-configured itself to use the
2614 // PAC script (thereby recovering from the initial fetch failure). We will
2615 // verify that the next Resolve request uses the resolver rather than
2618 // Start a second request.
2620 TestCompletionCallback callback2
;
2621 rv
= service
.ResolveProxy(
2622 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2623 NULL
, NULL
, BoundNetLog());
2624 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2626 // Check that it was sent to the resolver.
2627 ASSERT_EQ(1u, resolver
.pending_requests().size());
2628 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[0]->url());
2630 // Complete the pending second request.
2631 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2632 resolver
.pending_requests()[0]->CompleteNow(OK
);
2634 // Wait for completion callback, and verify that the request ran as expected.
2635 EXPECT_EQ(OK
, callback2
.WaitForResult());
2636 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2639 // This test verifies that the PAC script specified by the settings is
2640 // periodically polled for changes. Specifically, if the initial fetch succeeds,
2641 // however at a later time its *contents* change, we will eventually
2642 // re-configure the service to use the new script.
2643 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterContentChange
) {
2644 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2646 ImmediatePollPolicy poll_policy
;
2647 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2649 MockProxyConfigService
* config_service
=
2650 new MockProxyConfigService("http://foopy/proxy.pac");
2652 MockAsyncProxyResolverExpectsBytes resolver
;
2654 ProxyService
service(
2656 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
2658 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2659 service
.SetProxyScriptFetchers(fetcher
,
2660 new DoNothingDhcpProxyScriptFetcher());
2665 TestCompletionCallback callback1
;
2666 int rv
= service
.ResolveProxy(
2667 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2668 NULL
, NULL
, BoundNetLog());
2669 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2671 // The first request should have triggered initial download of PAC script.
2672 EXPECT_TRUE(fetcher
->has_pending_request());
2673 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2675 // Nothing has been sent to the resolver yet.
2676 EXPECT_TRUE(resolver
.pending_requests().empty());
2678 // At this point the ProxyService should be waiting for the
2679 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2680 // PAC script download completion.
2681 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2683 // Now that the PAC script is downloaded, the request will have been sent to
2684 // the proxy resolver.
2685 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2686 resolver
.pending_set_pac_script_request()->script_data()->utf16());
2687 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
2689 ASSERT_EQ(1u, resolver
.pending_requests().size());
2690 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
2692 // Complete the pending request.
2693 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2694 resolver
.pending_requests()[0]->CompleteNow(OK
);
2696 // Wait for completion callback, and verify that the request ran as expected.
2697 EXPECT_EQ(OK
, callback1
.WaitForResult());
2698 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2700 // At this point we have initialized the proxy service using a PAC script.
2702 // A background task to periodically re-check the PAC script for validity will
2703 // have been started. We will now wait for the next download attempt to start.
2705 // Note that we shouldn't have to wait long here, since our test enables a
2706 // special unit-test mode.
2707 fetcher
->WaitUntilFetch();
2709 ASSERT_TRUE(resolver
.pending_requests().empty());
2711 // Make sure that our background checker is trying to download the expected
2712 // PAC script (same one as before). This time we will simulate a successful
2713 // download of a DIFFERENT script.
2714 EXPECT_TRUE(fetcher
->has_pending_request());
2715 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2716 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript2
);
2718 base::MessageLoop::current()->RunUntilIdle();
2720 // Now that the PAC script is downloaded, it should be used to initialize the
2721 // ProxyResolver. Simulate a successful parse.
2722 EXPECT_EQ(ASCIIToUTF16(kValidPacScript2
),
2723 resolver
.pending_set_pac_script_request()->script_data()->utf16());
2724 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
2726 // At this point the ProxyService should have re-configured itself to use the
2729 // Start a second request.
2731 TestCompletionCallback callback2
;
2732 rv
= service
.ResolveProxy(
2733 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2734 NULL
, NULL
, BoundNetLog());
2735 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2737 // Check that it was sent to the resolver.
2738 ASSERT_EQ(1u, resolver
.pending_requests().size());
2739 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[0]->url());
2741 // Complete the pending second request.
2742 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2743 resolver
.pending_requests()[0]->CompleteNow(OK
);
2745 // Wait for completion callback, and verify that the request ran as expected.
2746 EXPECT_EQ(OK
, callback2
.WaitForResult());
2747 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2750 // This test verifies that the PAC script specified by the settings is
2751 // periodically polled for changes. Specifically, if the initial fetch succeeds
2752 // and so does the next poll, however the contents of the downloaded script
2753 // have NOT changed, then we do not bother to re-initialize the proxy resolver.
2754 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterContentUnchanged
) {
2755 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2757 ImmediatePollPolicy poll_policy
;
2758 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2760 MockProxyConfigService
* config_service
=
2761 new MockProxyConfigService("http://foopy/proxy.pac");
2763 MockAsyncProxyResolverExpectsBytes resolver
;
2765 ProxyService
service(
2767 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
2769 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2770 service
.SetProxyScriptFetchers(fetcher
,
2771 new DoNothingDhcpProxyScriptFetcher());
2776 TestCompletionCallback callback1
;
2777 int rv
= service
.ResolveProxy(
2778 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2779 NULL
, NULL
, BoundNetLog());
2780 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2782 // The first request should have triggered initial download of PAC script.
2783 EXPECT_TRUE(fetcher
->has_pending_request());
2784 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2786 // Nothing has been sent to the resolver yet.
2787 EXPECT_TRUE(resolver
.pending_requests().empty());
2789 // At this point the ProxyService should be waiting for the
2790 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2791 // PAC script download completion.
2792 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2794 // Now that the PAC script is downloaded, the request will have been sent to
2795 // the proxy resolver.
2796 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2797 resolver
.pending_set_pac_script_request()->script_data()->utf16());
2798 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
2800 ASSERT_EQ(1u, resolver
.pending_requests().size());
2801 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
2803 // Complete the pending request.
2804 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2805 resolver
.pending_requests()[0]->CompleteNow(OK
);
2807 // Wait for completion callback, and verify that the request ran as expected.
2808 EXPECT_EQ(OK
, callback1
.WaitForResult());
2809 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2811 // At this point we have initialized the proxy service using a PAC script.
2813 // A background task to periodically re-check the PAC script for validity will
2814 // have been started. We will now wait for the next download attempt to start.
2816 // Note that we shouldn't have to wait long here, since our test enables a
2817 // special unit-test mode.
2818 fetcher
->WaitUntilFetch();
2820 ASSERT_TRUE(resolver
.pending_requests().empty());
2822 // Make sure that our background checker is trying to download the expected
2823 // PAC script (same one as before). We will simulate the same response as
2824 // last time (i.e. the script is unchanged).
2825 EXPECT_TRUE(fetcher
->has_pending_request());
2826 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2827 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2829 base::MessageLoop::current()->RunUntilIdle();
2831 ASSERT_FALSE(resolver
.has_pending_set_pac_script_request());
2833 // At this point the ProxyService is still running the same PAC script as
2836 // Start a second request.
2838 TestCompletionCallback callback2
;
2839 rv
= service
.ResolveProxy(
2840 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2841 NULL
, NULL
, BoundNetLog());
2842 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2844 // Check that it was sent to the resolver.
2845 ASSERT_EQ(1u, resolver
.pending_requests().size());
2846 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[0]->url());
2848 // Complete the pending second request.
2849 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2850 resolver
.pending_requests()[0]->CompleteNow(OK
);
2852 // Wait for completion callback, and verify that the request ran as expected.
2853 EXPECT_EQ(OK
, callback2
.WaitForResult());
2854 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2857 // This test verifies that the PAC script specified by the settings is
2858 // periodically polled for changes. Specifically, if the initial fetch succeeds,
2859 // however at a later time it starts to fail, we should re-configure the
2860 // ProxyService to stop using that PAC script.
2861 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterSuccess
) {
2862 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2864 ImmediatePollPolicy poll_policy
;
2865 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2867 MockProxyConfigService
* config_service
=
2868 new MockProxyConfigService("http://foopy/proxy.pac");
2870 MockAsyncProxyResolverExpectsBytes resolver
;
2872 ProxyService
service(
2874 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
2876 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2877 service
.SetProxyScriptFetchers(fetcher
,
2878 new DoNothingDhcpProxyScriptFetcher());
2883 TestCompletionCallback callback1
;
2884 int rv
= service
.ResolveProxy(
2885 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2886 NULL
, NULL
, BoundNetLog());
2887 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2889 // The first request should have triggered initial download of PAC script.
2890 EXPECT_TRUE(fetcher
->has_pending_request());
2891 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2893 // Nothing has been sent to the resolver yet.
2894 EXPECT_TRUE(resolver
.pending_requests().empty());
2896 // At this point the ProxyService should be waiting for the
2897 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2898 // PAC script download completion.
2899 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2901 // Now that the PAC script is downloaded, the request will have been sent to
2902 // the proxy resolver.
2903 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2904 resolver
.pending_set_pac_script_request()->script_data()->utf16());
2905 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
2907 ASSERT_EQ(1u, resolver
.pending_requests().size());
2908 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
2910 // Complete the pending request.
2911 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2912 resolver
.pending_requests()[0]->CompleteNow(OK
);
2914 // Wait for completion callback, and verify that the request ran as expected.
2915 EXPECT_EQ(OK
, callback1
.WaitForResult());
2916 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2918 // At this point we have initialized the proxy service using a PAC script.
2920 // A background task to periodically re-check the PAC script for validity will
2921 // have been started. We will now wait for the next download attempt to start.
2923 // Note that we shouldn't have to wait long here, since our test enables a
2924 // special unit-test mode.
2925 fetcher
->WaitUntilFetch();
2927 ASSERT_TRUE(resolver
.pending_requests().empty());
2929 // Make sure that our background checker is trying to download the expected
2930 // PAC script (same one as before). This time we will simulate a failure
2931 // to download the script.
2932 EXPECT_TRUE(fetcher
->has_pending_request());
2933 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2934 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2936 base::MessageLoop::current()->RunUntilIdle();
2938 // At this point the ProxyService should have re-configured itself to use
2939 // DIRECT connections rather than the given proxy resolver.
2941 // Start a second request.
2943 TestCompletionCallback callback2
;
2944 rv
= service
.ResolveProxy(
2945 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2946 NULL
, NULL
, BoundNetLog());
2948 EXPECT_TRUE(info2
.is_direct());
2951 // Tests that the code which decides at what times to poll the PAC
2952 // script follows the expected policy.
2953 TEST_F(ProxyServiceTest
, PACScriptPollingPolicy
) {
2954 // Retrieve the internal polling policy implementation used by ProxyService.
2955 scoped_ptr
<ProxyService::PacPollPolicy
> policy
=
2956 ProxyService::CreateDefaultPacPollPolicy();
2959 ProxyService::PacPollPolicy::Mode mode
;
2960 const base::TimeDelta initial_delay
= base::TimeDelta::FromMilliseconds(-1);
2961 base::TimeDelta delay
= initial_delay
;
2963 // --------------------------------------------------
2964 // Test the poll sequence in response to a failure.
2965 // --------------------------------------------------
2966 error
= ERR_NAME_NOT_RESOLVED
;
2969 mode
= policy
->GetNextDelay(error
, initial_delay
, &delay
);
2970 EXPECT_EQ(8, delay
.InSeconds());
2971 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_USE_TIMER
, mode
);
2974 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2975 EXPECT_EQ(32, delay
.InSeconds());
2976 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2979 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2980 EXPECT_EQ(120, delay
.InSeconds());
2981 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2984 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2985 EXPECT_EQ(14400, delay
.InSeconds());
2986 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2989 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2990 EXPECT_EQ(14400, delay
.InSeconds());
2991 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2993 // --------------------------------------------------
2994 // Test the poll sequence in response to a success.
2995 // --------------------------------------------------
2999 mode
= policy
->GetNextDelay(error
, initial_delay
, &delay
);
3000 EXPECT_EQ(43200, delay
.InSeconds());
3001 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3004 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
3005 EXPECT_EQ(43200, delay
.InSeconds());
3006 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3009 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
3010 EXPECT_EQ(43200, delay
.InSeconds());
3011 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3014 // This tests the polling of the PAC script. Specifically, it tests that
3015 // polling occurs in response to user activity.
3016 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterActivity
) {
3017 ImmediateAfterActivityPollPolicy poll_policy
;
3018 ProxyService::set_pac_script_poll_policy(&poll_policy
);
3020 MockProxyConfigService
* config_service
=
3021 new MockProxyConfigService("http://foopy/proxy.pac");
3023 MockAsyncProxyResolverExpectsBytes resolver
;
3025 ProxyService
service(
3027 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
3029 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
3030 service
.SetProxyScriptFetchers(fetcher
,
3031 new DoNothingDhcpProxyScriptFetcher());
3036 TestCompletionCallback callback1
;
3037 int rv
= service
.ResolveProxy(
3038 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
3039 NULL
, NULL
, BoundNetLog());
3040 EXPECT_EQ(ERR_IO_PENDING
, rv
);
3042 // The first request should have triggered initial download of PAC script.
3043 EXPECT_TRUE(fetcher
->has_pending_request());
3044 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
3046 // Nothing has been sent to the resolver yet.
3047 EXPECT_TRUE(resolver
.pending_requests().empty());
3049 // At this point the ProxyService should be waiting for the
3050 // ProxyScriptFetcher to invoke its completion callback, notifying it of
3051 // PAC script download completion.
3052 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
3054 // Now that the PAC script is downloaded, the request will have been sent to
3055 // the proxy resolver.
3056 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
3057 resolver
.pending_set_pac_script_request()->script_data()->utf16());
3058 resolver
.pending_set_pac_script_request()->CompleteNow(OK
);
3060 ASSERT_EQ(1u, resolver
.pending_requests().size());
3061 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
3063 // Complete the pending request.
3064 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
3065 resolver
.pending_requests()[0]->CompleteNow(OK
);
3067 // Wait for completion callback, and verify that the request ran as expected.
3068 EXPECT_EQ(OK
, callback1
.WaitForResult());
3069 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
3071 // At this point we have initialized the proxy service using a PAC script.
3072 // Our PAC poller is set to update ONLY in response to network activity,
3073 // (i.e. another call to ResolveProxy()).
3075 ASSERT_FALSE(fetcher
->has_pending_request());
3076 ASSERT_TRUE(resolver
.pending_requests().empty());
3078 // Start a second request.
3080 TestCompletionCallback callback2
;
3081 rv
= service
.ResolveProxy(
3082 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
3083 NULL
, NULL
, BoundNetLog());
3084 EXPECT_EQ(ERR_IO_PENDING
, rv
);
3086 // This request should have sent work to the resolver; complete it.
3087 ASSERT_EQ(1u, resolver
.pending_requests().size());
3088 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[0]->url());
3089 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
3090 resolver
.pending_requests()[0]->CompleteNow(OK
);
3092 EXPECT_EQ(OK
, callback2
.WaitForResult());
3093 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
3095 // In response to getting that resolve request, the poller should have
3096 // started the next poll, and made it as far as to request the download.
3098 EXPECT_TRUE(fetcher
->has_pending_request());
3099 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
3101 // This time we will fail the download, to simulate a PAC script change.
3102 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
3104 // Drain the message loop, so ProxyService is notified of the change
3105 // and has a chance to re-configure itself.
3106 base::MessageLoop::current()->RunUntilIdle();
3108 // Start a third request -- this time we expect to get a direct connection
3109 // since the PAC script poller experienced a failure.
3111 TestCompletionCallback callback3
;
3112 rv
= service
.ResolveProxy(
3113 GURL("http://request3"), net::LOAD_NORMAL
, &info3
, callback3
.callback(),
3114 NULL
, NULL
, BoundNetLog());
3116 EXPECT_TRUE(info3
.is_direct());
3119 // Test that the synchronous resolution fails when a PAC script is active.
3120 TEST_F(ProxyServiceTest
, SynchronousWithPAC
) {
3121 MockProxyConfigService
* config_service
=
3122 new MockProxyConfigService("http://foopy/proxy.pac");
3124 MockAsyncProxyResolver resolver
;
3126 ProxyService
service(
3128 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
3130 GURL
url("http://www.google.com/");
3134 CapturingBoundNetLog log
;
3136 bool synchronous_success
= service
.TryResolveProxySynchronously(
3137 url
, net::LOAD_NORMAL
, &info
, NULL
, log
.bound());
3138 EXPECT_FALSE(synchronous_success
);
3140 // No request should have been queued.
3141 EXPECT_EQ(0u, resolver
.pending_requests().size());
3143 // |info| should not have been modified.
3144 EXPECT_TRUE(info
.is_direct());
3147 // Test that synchronous results are returned correctly if a fixed proxy
3148 // configuration is active.
3149 TEST_F(ProxyServiceTest
, SynchronousWithFixedConfiguration
) {
3151 config
.proxy_rules().ParseFromString("foopy1:8080");
3152 config
.set_auto_detect(false);
3154 MockAsyncProxyResolver resolver
;
3156 ProxyService
service(
3157 new MockProxyConfigService(config
),
3158 make_scoped_ptr(new ForwardingProxyResolverFactory(&resolver
)), NULL
);
3160 GURL
url("http://www.google.com/");
3163 CapturingBoundNetLog log
;
3165 bool synchronous_success
= service
.TryResolveProxySynchronously(
3166 url
, net::LOAD_NORMAL
, &info
, NULL
, log
.bound());
3167 EXPECT_TRUE(synchronous_success
);
3168 EXPECT_FALSE(info
.is_direct());
3169 EXPECT_EQ("foopy1", info
.proxy_server().host_port_pair().host());
3171 // No request should have been queued.
3172 EXPECT_EQ(0u, resolver
.pending_requests().size());