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"
10 #include "base/format_macros.h"
11 #include "base/logging.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "net/base/load_flags.h"
15 #include "net/base/net_errors.h"
16 #include "net/base/network_delegate_impl.h"
17 #include "net/base/test_completion_callback.h"
18 #include "net/log/net_log.h"
19 #include "net/log/test_net_log.h"
20 #include "net/log/test_net_log_entry.h"
21 #include "net/log/test_net_log_util.h"
22 #include "net/proxy/dhcp_proxy_script_fetcher.h"
23 #include "net/proxy/mock_proxy_resolver.h"
24 #include "net/proxy/mock_proxy_script_fetcher.h"
25 #include "net/proxy/proxy_config_service.h"
26 #include "net/proxy/proxy_resolver.h"
27 #include "net/proxy/proxy_script_fetcher.h"
28 #include "testing/gtest/include/gtest/gtest.h"
31 using base::ASCIIToUTF16
;
33 // TODO(eroman): Write a test which exercises
34 // ProxyService::SuspendAllPendingRequests().
38 // This polling policy will decide to poll every 1 ms.
39 class ImmediatePollPolicy
: public ProxyService::PacPollPolicy
{
41 ImmediatePollPolicy() {}
43 Mode
GetNextDelay(int error
,
44 base::TimeDelta current_delay
,
45 base::TimeDelta
* next_delay
) const override
{
46 *next_delay
= base::TimeDelta::FromMilliseconds(1);
47 return MODE_USE_TIMER
;
51 DISALLOW_COPY_AND_ASSIGN(ImmediatePollPolicy
);
54 // This polling policy chooses a fantastically large delay. In other words, it
55 // will never trigger a poll
56 class NeverPollPolicy
: public ProxyService::PacPollPolicy
{
60 Mode
GetNextDelay(int error
,
61 base::TimeDelta current_delay
,
62 base::TimeDelta
* next_delay
) const override
{
63 *next_delay
= base::TimeDelta::FromDays(60);
64 return MODE_USE_TIMER
;
68 DISALLOW_COPY_AND_ASSIGN(NeverPollPolicy
);
71 // This polling policy starts a poll immediately after network activity.
72 class ImmediateAfterActivityPollPolicy
: public ProxyService::PacPollPolicy
{
74 ImmediateAfterActivityPollPolicy() {}
76 Mode
GetNextDelay(int error
,
77 base::TimeDelta current_delay
,
78 base::TimeDelta
* next_delay
) const override
{
79 *next_delay
= base::TimeDelta();
80 return MODE_START_AFTER_ACTIVITY
;
84 DISALLOW_COPY_AND_ASSIGN(ImmediateAfterActivityPollPolicy
);
87 // This test fixture is used to partially disable the background polling done by
88 // the ProxyService (which it uses to detect whenever its PAC script contents or
89 // WPAD results have changed).
91 // We disable the feature by setting the poll interval to something really
92 // large, so it will never actually be reached even on the slowest bots that run
95 // We disable the polling in order to avoid any timing dependencies in the
96 // tests. If the bot were to run the tests very slowly and we hadn't disabled
97 // polling, then it might start a background re-try in the middle of our test
98 // and confuse our expectations leading to flaky failures.
100 // The tests which verify the polling code re-enable the polling behavior but
101 // are careful to avoid timing problems.
102 class ProxyServiceTest
: public testing::Test
{
104 void SetUp() override
{
105 testing::Test::SetUp();
107 ProxyService::set_pac_script_poll_policy(&never_poll_policy_
);
110 void TearDown() override
{
111 // Restore the original policy.
112 ProxyService::set_pac_script_poll_policy(previous_policy_
);
113 testing::Test::TearDown();
117 NeverPollPolicy never_poll_policy_
;
118 const ProxyService::PacPollPolicy
* previous_policy_
;
121 const char kValidPacScript1
[] = "pac-script-v1-FindProxyForURL";
122 const char kValidPacScript2
[] = "pac-script-v2-FindProxyForURL";
124 class MockProxyConfigService
: public ProxyConfigService
{
126 explicit MockProxyConfigService(const ProxyConfig
& config
)
127 : availability_(CONFIG_VALID
),
131 explicit MockProxyConfigService(const std::string
& pac_url
)
132 : availability_(CONFIG_VALID
),
133 config_(ProxyConfig::CreateFromCustomPacURL(GURL(pac_url
))) {
136 void AddObserver(Observer
* observer
) override
{
137 observers_
.AddObserver(observer
);
140 void RemoveObserver(Observer
* observer
) override
{
141 observers_
.RemoveObserver(observer
);
144 ConfigAvailability
GetLatestProxyConfig(ProxyConfig
* results
) override
{
145 if (availability_
== CONFIG_VALID
)
147 return availability_
;
150 void SetConfig(const ProxyConfig
& config
) {
151 availability_
= CONFIG_VALID
;
153 FOR_EACH_OBSERVER(Observer
, observers_
,
154 OnProxyConfigChanged(config_
, availability_
));
158 ConfigAvailability availability_
;
160 base::ObserverList
<Observer
, true> observers_
;
163 // A test network delegate that exercises the OnResolveProxy callback.
164 class TestResolveProxyNetworkDelegate
: public NetworkDelegateImpl
{
166 TestResolveProxyNetworkDelegate()
167 : on_resolve_proxy_called_(false),
169 remove_proxy_(false),
170 proxy_service_(NULL
) {
173 void OnResolveProxy(const GURL
& url
,
175 const ProxyService
& proxy_service
,
176 ProxyInfo
* result
) override
{
177 on_resolve_proxy_called_
= true;
178 proxy_service_
= &proxy_service
;
179 DCHECK(!add_proxy_
|| !remove_proxy_
);
181 result
->UseNamedProxy("delegate_proxy.com");
182 } else if (remove_proxy_
) {
187 bool on_resolve_proxy_called() const {
188 return on_resolve_proxy_called_
;
191 void set_add_proxy(bool add_proxy
) {
192 add_proxy_
= add_proxy
;
195 void set_remove_proxy(bool remove_proxy
) {
196 remove_proxy_
= remove_proxy
;
199 const ProxyService
* proxy_service() const {
200 return proxy_service_
;
204 bool on_resolve_proxy_called_
;
207 const ProxyService
* proxy_service_
;
210 // A test network delegate that exercises the OnProxyFallback callback.
211 class TestProxyFallbackNetworkDelegate
: public NetworkDelegateImpl
{
213 TestProxyFallbackNetworkDelegate()
214 : on_proxy_fallback_called_(false),
215 proxy_fallback_net_error_(OK
) {
218 void OnProxyFallback(const ProxyServer
& proxy_server
,
219 int net_error
) override
{
220 proxy_server_
= proxy_server
;
221 proxy_fallback_net_error_
= net_error
;
222 on_proxy_fallback_called_
= true;
225 bool on_proxy_fallback_called() const {
226 return on_proxy_fallback_called_
;
229 const ProxyServer
& proxy_server() const {
230 return proxy_server_
;
233 int proxy_fallback_net_error() const {
234 return proxy_fallback_net_error_
;
238 bool on_proxy_fallback_called_
;
239 ProxyServer proxy_server_
;
240 int proxy_fallback_net_error_
;
244 std::map
<GURL
, scoped_refptr
<MockAsyncProxyResolver::Request
>>;
246 // Given a list of requests |list| from a MockAsyncProxyResolver and a list of
247 // target URLs |_urls|, asserts that the set of URLs of the requests appearing
248 // in |list| is exactly the set of URLs in |_urls|, and produces a RequestMap in
249 // |*map| containing the requests corresponding to those target |_urls|.
251 // Note that this function must return void to allow use of gtest's ASSERT_*
253 RequestMap
GetRequestsForURLs(
254 const MockAsyncProxyResolver::RequestsList
& requests
,
255 const std::vector
<GURL
>& urls
) {
258 for (const auto& it
: requests
)
261 if (urls
.size() != map
.size()) {
262 ADD_FAILURE() << "map size (" << map
.size() << ") != urls size ("
263 << urls
.size() << ")";
266 for (const auto& it
: urls
) {
267 if (map
.count(it
) != 1U) {
268 ADD_FAILURE() << "url not in map: " << it
.spec();
275 // Given a MockAsyncProxyResolver |resolver| and some GURLs, validates that the
276 // set of pending request URLs for |resolver| is exactly the supplied list of
277 // URLs and returns a map from URLs to the corresponding pending requests.
278 RequestMap
GetPendingRequestsForURLs(const MockAsyncProxyResolver
& resolver
,
279 const GURL
& url1
= GURL(),
280 const GURL
& url2
= GURL(),
281 const GURL
& url3
= GURL()) {
282 std::vector
<GURL
> urls
;
283 if (!url1
.is_empty())
284 urls
.push_back(url1
);
285 if (!url2
.is_empty())
286 urls
.push_back(url2
);
287 if (!url3
.is_empty())
288 urls
.push_back(url3
);
289 return GetRequestsForURLs(resolver
.pending_requests(), urls
);
292 // Given a MockAsyncProxyResolver |resolver| and some GURLs, validates that the
293 // set of cancelled request URLs for |resolver| is exactly the supplied list of
294 // URLs and returns a map from URLs to the corresponding cancelled requests.
295 RequestMap
GetCancelledRequestsForURLs(const MockAsyncProxyResolver
& resolver
,
296 const GURL
& url1
= GURL(),
297 const GURL
& url2
= GURL(),
298 const GURL
& url3
= GURL()) {
299 std::vector
<GURL
> urls
;
300 if (!url1
.is_empty())
301 urls
.push_back(url1
);
302 if (!url2
.is_empty())
303 urls
.push_back(url2
);
304 if (!url3
.is_empty())
305 urls
.push_back(url3
);
306 return GetRequestsForURLs(resolver
.cancelled_requests(), urls
);
311 TEST_F(ProxyServiceTest
, Direct
) {
312 MockAsyncProxyResolverFactory
* factory
=
313 new MockAsyncProxyResolverFactory(false);
314 ProxyService
service(new MockProxyConfigService(ProxyConfig::CreateDirect()),
315 make_scoped_ptr(factory
), NULL
);
317 GURL
url("http://www.google.com/");
320 TestCompletionCallback callback
;
322 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(),
323 NULL
, NULL
, log
.bound());
325 EXPECT_TRUE(factory
->pending_requests().empty());
327 EXPECT_TRUE(info
.is_direct());
328 EXPECT_TRUE(info
.proxy_resolve_start_time().is_null());
329 EXPECT_TRUE(info
.proxy_resolve_end_time().is_null());
331 // Check the NetLog was filled correctly.
332 TestNetLogEntry::List entries
;
333 log
.GetEntries(&entries
);
335 EXPECT_EQ(3u, entries
.size());
336 EXPECT_TRUE(LogContainsBeginEvent(
337 entries
, 0, NetLog::TYPE_PROXY_SERVICE
));
338 EXPECT_TRUE(LogContainsEvent(
339 entries
, 1, NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST
,
340 NetLog::PHASE_NONE
));
341 EXPECT_TRUE(LogContainsEndEvent(
342 entries
, 2, NetLog::TYPE_PROXY_SERVICE
));
345 TEST_F(ProxyServiceTest
, OnResolveProxyCallbackAddProxy
) {
347 config
.proxy_rules().ParseFromString("foopy1:8080");
348 config
.set_auto_detect(false);
349 config
.proxy_rules().bypass_rules
.ParseFromString("*.org");
351 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
353 GURL
url("http://www.google.com/");
354 GURL
bypass_url("http://internet.org");
357 TestCompletionCallback callback
;
360 // First, warm up the ProxyService.
361 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(),
362 NULL
, NULL
, log
.bound());
365 // Verify that network delegate is invoked.
366 TestResolveProxyNetworkDelegate delegate
;
367 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(), NULL
,
368 &delegate
, log
.bound());
369 EXPECT_TRUE(delegate
.on_resolve_proxy_called());
370 EXPECT_EQ(&service
, delegate
.proxy_service());
372 // Verify that the NetworkDelegate's behavior is stateless across
373 // invocations of ResolveProxy. Start by having the callback add a proxy
374 // and checking that subsequent requests are not affected.
375 delegate
.set_add_proxy(true);
377 // Callback should interpose:
378 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(), NULL
,
379 &delegate
, log
.bound());
380 EXPECT_FALSE(info
.is_direct());
381 EXPECT_EQ(info
.proxy_server().host_port_pair().host(), "delegate_proxy.com");
382 delegate
.set_add_proxy(false);
384 // Check non-bypassed URL:
385 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(), NULL
,
386 &delegate
, log
.bound());
387 EXPECT_FALSE(info
.is_direct());
388 EXPECT_EQ(info
.proxy_server().host_port_pair().host(), "foopy1");
390 // Check bypassed URL:
391 rv
= service
.ResolveProxy(bypass_url
, LOAD_NORMAL
, &info
, callback
.callback(),
392 NULL
, &delegate
, log
.bound());
393 EXPECT_TRUE(info
.is_direct());
396 TEST_F(ProxyServiceTest
, OnResolveProxyCallbackRemoveProxy
) {
397 // Same as OnResolveProxyCallbackAddProxy, but verify that the
398 // NetworkDelegate's behavior is stateless across invocations after it
399 // *removes* a proxy.
401 config
.proxy_rules().ParseFromString("foopy1:8080");
402 config
.set_auto_detect(false);
403 config
.proxy_rules().bypass_rules
.ParseFromString("*.org");
405 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
407 GURL
url("http://www.google.com/");
408 GURL
bypass_url("http://internet.org");
411 TestCompletionCallback callback
;
414 // First, warm up the ProxyService.
415 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(),
416 NULL
, NULL
, log
.bound());
419 TestResolveProxyNetworkDelegate delegate
;
420 delegate
.set_remove_proxy(true);
422 // Callback should interpose:
423 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(), NULL
,
424 &delegate
, log
.bound());
425 EXPECT_TRUE(info
.is_direct());
426 delegate
.set_remove_proxy(false);
428 // Check non-bypassed URL:
429 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(), NULL
,
430 &delegate
, log
.bound());
431 EXPECT_FALSE(info
.is_direct());
432 EXPECT_EQ(info
.proxy_server().host_port_pair().host(), "foopy1");
434 // Check bypassed URL:
435 rv
= service
.ResolveProxy(bypass_url
, LOAD_NORMAL
, &info
, callback
.callback(),
436 NULL
, &delegate
, log
.bound());
437 EXPECT_TRUE(info
.is_direct());
440 TEST_F(ProxyServiceTest
, PAC
) {
441 MockProxyConfigService
* config_service
=
442 new MockProxyConfigService("http://foopy/proxy.pac");
444 MockAsyncProxyResolver resolver
;
445 MockAsyncProxyResolverFactory
* factory
=
446 new MockAsyncProxyResolverFactory(false);
448 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
450 GURL
url("http://www.google.com/");
453 TestCompletionCallback callback
;
454 ProxyService::PacRequest
* request
;
457 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(),
458 &request
, NULL
, log
.bound());
459 EXPECT_EQ(ERR_IO_PENDING
, rv
);
461 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request
));
463 ASSERT_EQ(1u, factory
->pending_requests().size());
464 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
465 factory
->pending_requests()[0]->script_data()->url());
466 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
468 ASSERT_EQ(1u, resolver
.pending_requests().size());
469 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
471 // Set the result in proxy resolver.
472 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy");
473 resolver
.pending_requests()[0]->CompleteNow(OK
);
475 EXPECT_EQ(OK
, callback
.WaitForResult());
476 EXPECT_FALSE(info
.is_direct());
477 EXPECT_EQ("foopy:80", info
.proxy_server().ToURI());
478 EXPECT_TRUE(info
.did_use_pac_script());
480 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
481 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
482 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
484 // Check the NetLog was filled correctly.
485 TestNetLogEntry::List entries
;
486 log
.GetEntries(&entries
);
488 EXPECT_EQ(5u, entries
.size());
489 EXPECT_TRUE(LogContainsBeginEvent(
490 entries
, 0, NetLog::TYPE_PROXY_SERVICE
));
491 EXPECT_TRUE(LogContainsBeginEvent(
492 entries
, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
493 EXPECT_TRUE(LogContainsEndEvent(
494 entries
, 2, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
495 EXPECT_TRUE(LogContainsEndEvent(
496 entries
, 4, NetLog::TYPE_PROXY_SERVICE
));
499 // Test that the proxy resolver does not see the URL's username/password
500 // or its reference section.
501 TEST_F(ProxyServiceTest
, PAC_NoIdentityOrHash
) {
502 MockProxyConfigService
* config_service
=
503 new MockProxyConfigService("http://foopy/proxy.pac");
505 MockAsyncProxyResolver resolver
;
506 MockAsyncProxyResolverFactory
* factory
=
507 new MockAsyncProxyResolverFactory(false);
509 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
511 GURL
url("http://username:password@www.google.com/?ref#hash#hash");
514 TestCompletionCallback callback
;
515 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(),
516 NULL
, NULL
, BoundNetLog());
517 EXPECT_EQ(ERR_IO_PENDING
, rv
);
519 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
520 factory
->pending_requests()[0]->script_data()->url());
521 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
523 ASSERT_EQ(1u, resolver
.pending_requests().size());
524 // The URL should have been simplified, stripping the username/password/hash.
525 EXPECT_EQ(GURL("http://www.google.com/?ref"),
526 resolver
.pending_requests()[0]->url());
528 // We end here without ever completing the request -- destruction of
529 // ProxyService will cancel the outstanding request.
532 TEST_F(ProxyServiceTest
, PAC_FailoverWithoutDirect
) {
533 MockProxyConfigService
* config_service
=
534 new MockProxyConfigService("http://foopy/proxy.pac");
535 MockAsyncProxyResolver resolver
;
536 MockAsyncProxyResolverFactory
* factory
=
537 new MockAsyncProxyResolverFactory(false);
539 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
541 GURL
url("http://www.google.com/");
544 TestCompletionCallback callback1
;
545 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
546 NULL
, NULL
, BoundNetLog());
547 EXPECT_EQ(ERR_IO_PENDING
, rv
);
549 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
550 factory
->pending_requests()[0]->script_data()->url());
551 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
553 ASSERT_EQ(1u, resolver
.pending_requests().size());
554 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
556 // Set the result in proxy resolver.
557 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy:8080");
558 resolver
.pending_requests()[0]->CompleteNow(OK
);
560 EXPECT_EQ(OK
, callback1
.WaitForResult());
561 EXPECT_FALSE(info
.is_direct());
562 EXPECT_EQ("foopy:8080", info
.proxy_server().ToURI());
563 EXPECT_TRUE(info
.did_use_pac_script());
565 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
566 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
567 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
569 // Now, imagine that connecting to foopy:8080 fails: there is nothing
570 // left to fallback to, since our proxy list was NOT terminated by
572 NetworkDelegateImpl network_delegate
;
573 TestCompletionCallback callback2
;
574 ProxyServer expected_proxy_server
= info
.proxy_server();
575 rv
= service
.ReconsiderProxyAfterError(
576 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
577 callback2
.callback(), NULL
, &network_delegate
, BoundNetLog());
578 // ReconsiderProxyAfterError returns error indicating nothing left.
579 EXPECT_EQ(ERR_FAILED
, rv
);
580 EXPECT_TRUE(info
.is_empty());
583 // Test that if the execution of the PAC script fails (i.e. javascript runtime
584 // error), and the PAC settings are non-mandatory, that we fall-back to direct.
585 TEST_F(ProxyServiceTest
, PAC_RuntimeError
) {
586 MockProxyConfigService
* config_service
=
587 new MockProxyConfigService("http://foopy/proxy.pac");
588 MockAsyncProxyResolver resolver
;
589 MockAsyncProxyResolverFactory
* factory
=
590 new MockAsyncProxyResolverFactory(false);
592 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
594 GURL
url("http://this-causes-js-error/");
597 TestCompletionCallback callback1
;
598 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
599 NULL
, NULL
, BoundNetLog());
600 EXPECT_EQ(ERR_IO_PENDING
, rv
);
602 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
603 factory
->pending_requests()[0]->script_data()->url());
604 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
606 ASSERT_EQ(1u, resolver
.pending_requests().size());
607 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
609 // Simulate a failure in the PAC executor.
610 resolver
.pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_FAILED
);
612 EXPECT_EQ(OK
, callback1
.WaitForResult());
614 // Since the PAC script was non-mandatory, we should have fallen-back to
616 EXPECT_TRUE(info
.is_direct());
617 EXPECT_TRUE(info
.did_use_pac_script());
618 EXPECT_EQ(1, info
.config_id());
620 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
621 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
622 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
625 // The proxy list could potentially contain the DIRECT fallback choice
626 // in a location other than the very end of the list, and could even
627 // specify it multiple times.
629 // This is not a typical usage, but we will obey it.
630 // (If we wanted to disallow this type of input, the right place to
631 // enforce it would be in parsing the PAC result string).
633 // This test will use the PAC result string:
635 // "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20"
637 // For which we expect it to try DIRECT, then foobar:10, then DIRECT again,
638 // then foobar:20, and then give up and error.
640 // The important check of this test is to make sure that DIRECT is not somehow
641 // cached as being a bad proxy.
642 TEST_F(ProxyServiceTest
, PAC_FailoverAfterDirect
) {
643 MockProxyConfigService
* config_service
=
644 new MockProxyConfigService("http://foopy/proxy.pac");
645 MockAsyncProxyResolver resolver
;
646 MockAsyncProxyResolverFactory
* factory
=
647 new MockAsyncProxyResolverFactory(false);
649 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
651 GURL
url("http://www.google.com/");
654 TestCompletionCallback callback1
;
655 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
656 NULL
, NULL
, BoundNetLog());
657 EXPECT_EQ(ERR_IO_PENDING
, rv
);
659 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
660 factory
->pending_requests()[0]->script_data()->url());
661 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
663 ASSERT_EQ(1u, resolver
.pending_requests().size());
664 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
666 // Set the result in proxy resolver.
667 resolver
.pending_requests()[0]->results()->UsePacString(
668 "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20");
669 resolver
.pending_requests()[0]->CompleteNow(OK
);
671 EXPECT_EQ(OK
, callback1
.WaitForResult());
672 EXPECT_TRUE(info
.is_direct());
675 TestCompletionCallback callback2
;
676 rv
= service
.ReconsiderProxyAfterError(
677 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
678 callback2
.callback(), NULL
, NULL
, BoundNetLog());
680 EXPECT_FALSE(info
.is_direct());
681 EXPECT_EQ("foobar:10", info
.proxy_server().ToURI());
684 NetworkDelegateImpl network_delegate
;
685 ProxyServer expected_proxy_server3
= info
.proxy_server();
686 TestCompletionCallback callback3
;
687 rv
= service
.ReconsiderProxyAfterError(
688 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
689 callback3
.callback(), NULL
, &network_delegate
, BoundNetLog());
691 EXPECT_TRUE(info
.is_direct());
694 ProxyServer expected_proxy_server4
= info
.proxy_server();
695 TestCompletionCallback callback4
;
696 rv
= service
.ReconsiderProxyAfterError(
697 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
698 callback4
.callback(), NULL
, &network_delegate
, BoundNetLog());
700 EXPECT_FALSE(info
.is_direct());
701 EXPECT_EQ("foobar:20", info
.proxy_server().ToURI());
703 // Fallback 4 -- Nothing to fall back to!
704 ProxyServer expected_proxy_server5
= info
.proxy_server();
705 TestCompletionCallback callback5
;
706 rv
= service
.ReconsiderProxyAfterError(
707 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
708 callback5
.callback(), NULL
, &network_delegate
, BoundNetLog());
709 EXPECT_EQ(ERR_FAILED
, rv
);
710 EXPECT_TRUE(info
.is_empty());
713 TEST_F(ProxyServiceTest
, PAC_ConfigSourcePropagates
) {
714 // Test whether the ProxyConfigSource set by the ProxyConfigService is applied
715 // to ProxyInfo after the proxy is resolved via a PAC script.
717 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
718 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
720 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
721 MockAsyncProxyResolver resolver
;
722 MockAsyncProxyResolverFactory
* factory
=
723 new MockAsyncProxyResolverFactory(false);
724 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
726 // Resolve something.
727 GURL
url("http://www.google.com/");
729 TestCompletionCallback callback
;
730 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(),
731 NULL
, NULL
, BoundNetLog());
732 ASSERT_EQ(ERR_IO_PENDING
, rv
);
733 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
734 ASSERT_EQ(1u, resolver
.pending_requests().size());
736 // Set the result in proxy resolver.
737 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy");
738 resolver
.pending_requests()[0]->CompleteNow(OK
);
740 EXPECT_EQ(OK
, callback
.WaitForResult());
741 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
742 EXPECT_TRUE(info
.did_use_pac_script());
744 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
745 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
746 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
749 TEST_F(ProxyServiceTest
, ProxyResolverFails
) {
750 // Test what happens when the ProxyResolver fails. The download and setting
751 // of the PAC script have already succeeded, so this corresponds with a
752 // javascript runtime error while calling FindProxyForURL().
754 MockProxyConfigService
* config_service
=
755 new MockProxyConfigService("http://foopy/proxy.pac");
757 MockAsyncProxyResolver resolver
;
758 MockAsyncProxyResolverFactory
* factory
=
759 new MockAsyncProxyResolverFactory(false);
761 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
763 // Start first resolve request.
764 GURL
url("http://www.google.com/");
766 TestCompletionCallback callback1
;
767 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
768 NULL
, NULL
, BoundNetLog());
769 EXPECT_EQ(ERR_IO_PENDING
, rv
);
771 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
772 factory
->pending_requests()[0]->script_data()->url());
773 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
775 ASSERT_EQ(1u, resolver
.pending_requests().size());
776 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
778 // Fail the first resolve request in MockAsyncProxyResolver.
779 resolver
.pending_requests()[0]->CompleteNow(ERR_FAILED
);
781 // Although the proxy resolver failed the request, ProxyService implicitly
782 // falls-back to DIRECT.
783 EXPECT_EQ(OK
, callback1
.WaitForResult());
784 EXPECT_TRUE(info
.is_direct());
786 // Failed PAC executions still have proxy resolution times.
787 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
788 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
789 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
791 // The second resolve request will try to run through the proxy resolver,
792 // regardless of whether the first request failed in it.
793 TestCompletionCallback callback2
;
794 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback2
.callback(), NULL
,
795 NULL
, BoundNetLog());
796 EXPECT_EQ(ERR_IO_PENDING
, rv
);
798 ASSERT_EQ(1u, resolver
.pending_requests().size());
799 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
801 // This time we will have the resolver succeed (perhaps the PAC script has
802 // a dependency on the current time).
803 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
804 resolver
.pending_requests()[0]->CompleteNow(OK
);
806 EXPECT_EQ(OK
, callback2
.WaitForResult());
807 EXPECT_FALSE(info
.is_direct());
808 EXPECT_EQ("foopy_valid:8080", info
.proxy_server().ToURI());
811 TEST_F(ProxyServiceTest
, ProxyResolverTerminatedDuringRequest
) {
812 // Test what happens when the ProxyResolver fails with a fatal error while
813 // a GetProxyForURL() call is in progress.
815 MockProxyConfigService
* config_service
=
816 new MockProxyConfigService("http://foopy/proxy.pac");
818 MockAsyncProxyResolver resolver
;
819 MockAsyncProxyResolverFactory
* factory
=
820 new MockAsyncProxyResolverFactory(false);
822 ProxyService
service(config_service
, make_scoped_ptr(factory
), nullptr);
824 // Start first resolve request.
825 GURL
url("http://www.google.com/");
827 TestCompletionCallback callback1
;
829 service
.ResolveProxy(url
, net::LOAD_NORMAL
, &info
, callback1
.callback(),
830 nullptr, nullptr, BoundNetLog());
831 EXPECT_EQ(ERR_IO_PENDING
, rv
);
833 ASSERT_EQ(1u, factory
->pending_requests().size());
834 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
835 factory
->pending_requests()[0]->script_data()->url());
836 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
838 ASSERT_EQ(1u, resolver
.pending_requests().size());
839 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
841 // Fail the first resolve request in MockAsyncProxyResolver.
842 resolver
.pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_TERMINATED
);
844 // Although the proxy resolver failed the request, ProxyService implicitly
845 // falls-back to DIRECT.
846 EXPECT_EQ(OK
, callback1
.WaitForResult());
847 EXPECT_TRUE(info
.is_direct());
849 // Failed PAC executions still have proxy resolution times.
850 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
851 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
852 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
854 // With no other requests, the ProxyService waits for a new request before
855 // initializing a new ProxyResolver.
856 EXPECT_TRUE(factory
->pending_requests().empty());
858 TestCompletionCallback callback2
;
859 rv
= service
.ResolveProxy(url
, net::LOAD_NORMAL
, &info
, callback2
.callback(),
860 nullptr, nullptr, BoundNetLog());
861 EXPECT_EQ(ERR_IO_PENDING
, rv
);
863 ASSERT_EQ(1u, factory
->pending_requests().size());
864 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
865 factory
->pending_requests()[0]->script_data()->url());
866 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
868 ASSERT_EQ(1u, resolver
.pending_requests().size());
869 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
871 // This time we will have the resolver succeed.
872 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
873 resolver
.pending_requests()[0]->CompleteNow(OK
);
875 EXPECT_EQ(OK
, callback2
.WaitForResult());
876 EXPECT_FALSE(info
.is_direct());
877 EXPECT_EQ("foopy_valid:8080", info
.proxy_server().ToURI());
880 TEST_F(ProxyServiceTest
,
881 ProxyResolverTerminatedDuringRequestWithConcurrentRequest
) {
882 // Test what happens when the ProxyResolver fails with a fatal error while
883 // a GetProxyForURL() call is in progress.
885 MockProxyConfigService
* config_service
=
886 new MockProxyConfigService("http://foopy/proxy.pac");
888 MockAsyncProxyResolver resolver
;
889 MockAsyncProxyResolverFactory
* factory
=
890 new MockAsyncProxyResolverFactory(false);
892 ProxyService
service(config_service
, make_scoped_ptr(factory
), nullptr);
894 // Start two resolve requests.
895 GURL
url1("http://www.google.com/");
896 GURL
url2("https://www.google.com/");
898 TestCompletionCallback callback1
;
900 service
.ResolveProxy(url1
, net::LOAD_NORMAL
, &info
, callback1
.callback(),
901 nullptr, nullptr, BoundNetLog());
902 EXPECT_EQ(ERR_IO_PENDING
, rv
);
903 TestCompletionCallback callback2
;
904 rv
= service
.ResolveProxy(url2
, net::LOAD_NORMAL
, &info
, callback2
.callback(),
905 nullptr, nullptr, BoundNetLog());
906 EXPECT_EQ(ERR_IO_PENDING
, rv
);
908 ASSERT_EQ(1u, factory
->pending_requests().size());
909 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
910 factory
->pending_requests()[0]->script_data()->url());
911 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
913 RequestMap requests
= GetPendingRequestsForURLs(resolver
, url1
, url2
);
915 // Fail the first resolve request in MockAsyncProxyResolver.
916 requests
[url1
]->CompleteNow(ERR_PAC_SCRIPT_TERMINATED
);
918 // Although the proxy resolver failed the request, ProxyService implicitly
919 // falls-back to DIRECT.
920 EXPECT_EQ(OK
, callback1
.WaitForResult());
921 EXPECT_TRUE(info
.is_direct());
923 // Failed PAC executions still have proxy resolution times.
924 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
925 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
926 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
928 // The second request is cancelled when the proxy resolver terminates.
929 requests
= GetCancelledRequestsForURLs(resolver
, url2
);
931 // Since a second request was in progress, the ProxyService starts
932 // initializating a new ProxyResolver.
933 ASSERT_EQ(1u, factory
->pending_requests().size());
934 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
935 factory
->pending_requests()[0]->script_data()->url());
936 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
938 requests
= GetPendingRequestsForURLs(resolver
, url2
);
940 // This request succeeds.
941 requests
[url2
]->results()->UseNamedProxy("foopy_valid:8080");
942 requests
[url2
]->CompleteNow(OK
);
944 EXPECT_EQ(OK
, callback2
.WaitForResult());
945 EXPECT_FALSE(info
.is_direct());
946 EXPECT_EQ("foopy_valid:8080", info
.proxy_server().ToURI());
949 TEST_F(ProxyServiceTest
, ProxyScriptFetcherFailsDownloadingMandatoryPac
) {
950 // Test what happens when the ProxyScriptResolver fails to download a
951 // mandatory PAC script.
954 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
955 config
.set_pac_mandatory(true);
957 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
959 MockAsyncProxyResolverFactory
* factory
=
960 new MockAsyncProxyResolverFactory(false);
962 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
964 // Start first resolve request.
965 GURL
url("http://www.google.com/");
967 TestCompletionCallback callback1
;
968 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
969 NULL
, NULL
, BoundNetLog());
970 EXPECT_EQ(ERR_IO_PENDING
, rv
);
972 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
973 factory
->pending_requests()[0]->script_data()->url());
974 factory
->pending_requests()[0]->CompleteNow(ERR_FAILED
, nullptr);
976 ASSERT_EQ(0u, factory
->pending_requests().size());
977 // As the proxy resolver factory failed the request and is configured for a
978 // mandatory PAC script, ProxyService must not implicitly fall-back to DIRECT.
979 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
980 callback1
.WaitForResult());
981 EXPECT_FALSE(info
.is_direct());
983 // As the proxy resolver factory failed the request and is configured for a
984 // mandatory PAC script, ProxyService must not implicitly fall-back to DIRECT.
985 TestCompletionCallback callback2
;
986 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback2
.callback(), NULL
,
987 NULL
, BoundNetLog());
988 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
, rv
);
989 EXPECT_FALSE(info
.is_direct());
992 TEST_F(ProxyServiceTest
, ProxyResolverFailsParsingJavaScriptMandatoryPac
) {
993 // Test what happens when the ProxyResolver fails that is configured to use a
994 // mandatory PAC script. The download of the PAC script has already
995 // succeeded but the PAC script contains no valid javascript.
998 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
999 config
.set_pac_mandatory(true);
1001 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
1003 MockAsyncProxyResolverFactory
* factory
=
1004 new MockAsyncProxyResolverFactory(true);
1006 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1008 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1009 service
.SetProxyScriptFetchers(
1010 fetcher
, make_scoped_ptr(new DoNothingDhcpProxyScriptFetcher()));
1012 // Start resolve request.
1013 GURL
url("http://www.google.com/");
1015 TestCompletionCallback callback
;
1016 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(),
1017 NULL
, NULL
, BoundNetLog());
1018 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1020 // Check that nothing has been sent to the proxy resolver factory yet.
1021 ASSERT_EQ(0u, factory
->pending_requests().size());
1023 // Downloading the PAC script succeeds.
1024 EXPECT_TRUE(fetcher
->has_pending_request());
1025 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1026 fetcher
->NotifyFetchCompletion(OK
, "invalid-script-contents");
1028 EXPECT_FALSE(fetcher
->has_pending_request());
1029 ASSERT_EQ(0u, factory
->pending_requests().size());
1031 // Since ProxyScriptDecider failed to identify a valid PAC and PAC was
1032 // mandatory for this configuration, the ProxyService must not implicitly
1033 // fall-back to DIRECT.
1034 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
1035 callback
.WaitForResult());
1036 EXPECT_FALSE(info
.is_direct());
1039 TEST_F(ProxyServiceTest
, ProxyResolverFailsInJavaScriptMandatoryPac
) {
1040 // Test what happens when the ProxyResolver fails that is configured to use a
1041 // mandatory PAC script. The download and setting of the PAC script have
1042 // already succeeded, so this corresponds with a javascript runtime error
1043 // while calling FindProxyForURL().
1046 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
1047 config
.set_pac_mandatory(true);
1049 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
1051 MockAsyncProxyResolver resolver
;
1052 MockAsyncProxyResolverFactory
* factory
=
1053 new MockAsyncProxyResolverFactory(false);
1055 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1057 // Start first resolve request.
1058 GURL
url("http://www.google.com/");
1060 TestCompletionCallback callback1
;
1061 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
1062 NULL
, NULL
, BoundNetLog());
1063 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1065 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1066 factory
->pending_requests()[0]->script_data()->url());
1067 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1069 ASSERT_EQ(1u, resolver
.pending_requests().size());
1070 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1072 // Fail the first resolve request in MockAsyncProxyResolver.
1073 resolver
.pending_requests()[0]->CompleteNow(ERR_FAILED
);
1075 // As the proxy resolver failed the request and is configured for a mandatory
1076 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
1077 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
1078 callback1
.WaitForResult());
1079 EXPECT_FALSE(info
.is_direct());
1081 // The second resolve request will try to run through the proxy resolver,
1082 // regardless of whether the first request failed in it.
1083 TestCompletionCallback callback2
;
1084 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback2
.callback(), NULL
,
1085 NULL
, BoundNetLog());
1086 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1088 ASSERT_EQ(1u, resolver
.pending_requests().size());
1089 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1091 // This time we will have the resolver succeed (perhaps the PAC script has
1092 // a dependency on the current time).
1093 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
1094 resolver
.pending_requests()[0]->CompleteNow(OK
);
1096 EXPECT_EQ(OK
, callback2
.WaitForResult());
1097 EXPECT_FALSE(info
.is_direct());
1098 EXPECT_EQ("foopy_valid:8080", info
.proxy_server().ToURI());
1101 TEST_F(ProxyServiceTest
, ProxyFallback
) {
1102 // Test what happens when we specify multiple proxy servers and some of them
1105 MockProxyConfigService
* config_service
=
1106 new MockProxyConfigService("http://foopy/proxy.pac");
1108 MockAsyncProxyResolver resolver
;
1109 MockAsyncProxyResolverFactory
* factory
=
1110 new MockAsyncProxyResolverFactory(false);
1112 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1114 GURL
url("http://www.google.com/");
1116 // Get the proxy information.
1118 TestCompletionCallback callback1
;
1119 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
1120 NULL
, NULL
, BoundNetLog());
1121 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1123 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1124 factory
->pending_requests()[0]->script_data()->url());
1125 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1127 ASSERT_EQ(1u, resolver
.pending_requests().size());
1128 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1130 // Set the result in proxy resolver.
1131 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1132 "foopy1:8080;foopy2:9090");
1133 resolver
.pending_requests()[0]->CompleteNow(OK
);
1135 // The first item is valid.
1136 EXPECT_EQ(OK
, callback1
.WaitForResult());
1137 EXPECT_FALSE(info
.is_direct());
1138 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1140 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1141 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1142 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1143 base::TimeTicks proxy_resolve_start_time
= info
.proxy_resolve_start_time();
1144 base::TimeTicks proxy_resolve_end_time
= info
.proxy_resolve_end_time();
1146 // Fake an error on the proxy.
1147 TestCompletionCallback callback2
;
1148 rv
= service
.ReconsiderProxyAfterError(
1149 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1150 callback2
.callback(), NULL
, NULL
, BoundNetLog());
1153 // Proxy times should not have been modified by fallback.
1154 EXPECT_EQ(proxy_resolve_start_time
, info
.proxy_resolve_start_time());
1155 EXPECT_EQ(proxy_resolve_end_time
, info
.proxy_resolve_end_time());
1157 // The second proxy should be specified.
1158 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1159 // Report back that the second proxy worked. This will globally mark the
1160 // first proxy as bad.
1161 TestProxyFallbackNetworkDelegate test_delegate
;
1162 service
.ReportSuccess(info
, &test_delegate
);
1163 EXPECT_EQ("foopy1:8080", test_delegate
.proxy_server().ToURI());
1164 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED
,
1165 test_delegate
.proxy_fallback_net_error());
1167 TestCompletionCallback callback3
;
1168 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback3
.callback(), NULL
,
1169 NULL
, BoundNetLog());
1170 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1172 ASSERT_EQ(1u, resolver
.pending_requests().size());
1173 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1175 // Set the result in proxy resolver -- the second result is already known
1176 // to be bad, so we will not try to use it initially.
1177 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1178 "foopy3:7070;foopy1:8080;foopy2:9090");
1179 resolver
.pending_requests()[0]->CompleteNow(OK
);
1181 EXPECT_EQ(OK
, callback3
.WaitForResult());
1182 EXPECT_FALSE(info
.is_direct());
1183 EXPECT_EQ("foopy3:7070", info
.proxy_server().ToURI());
1185 // Proxy times should have been updated, so get them again.
1186 EXPECT_LE(proxy_resolve_end_time
, info
.proxy_resolve_start_time());
1187 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1188 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1189 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1190 proxy_resolve_start_time
= info
.proxy_resolve_start_time();
1191 proxy_resolve_end_time
= info
.proxy_resolve_end_time();
1193 // We fake another error. It should now try the third one.
1194 TestCompletionCallback callback4
;
1195 rv
= service
.ReconsiderProxyAfterError(
1196 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1197 callback4
.callback(), NULL
, NULL
, BoundNetLog());
1199 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1201 // We fake another error. At this point we have tried all of the
1202 // proxy servers we thought were valid; next we try the proxy server
1203 // that was in our bad proxies map (foopy1:8080).
1204 TestCompletionCallback callback5
;
1205 rv
= service
.ReconsiderProxyAfterError(
1206 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1207 callback5
.callback(), NULL
, NULL
, BoundNetLog());
1209 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1211 // Fake another error, the last proxy is gone, the list should now be empty,
1212 // so there is nothing left to try.
1213 TestCompletionCallback callback6
;
1214 rv
= service
.ReconsiderProxyAfterError(
1215 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1216 callback6
.callback(), NULL
, NULL
, BoundNetLog());
1217 EXPECT_EQ(ERR_FAILED
, rv
);
1218 EXPECT_FALSE(info
.is_direct());
1219 EXPECT_TRUE(info
.is_empty());
1221 // Proxy times should not have been modified by fallback.
1222 EXPECT_EQ(proxy_resolve_start_time
, info
.proxy_resolve_start_time());
1223 EXPECT_EQ(proxy_resolve_end_time
, info
.proxy_resolve_end_time());
1225 // Look up proxies again
1226 TestCompletionCallback callback7
;
1227 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback7
.callback(), NULL
,
1228 NULL
, BoundNetLog());
1229 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1231 ASSERT_EQ(1u, resolver
.pending_requests().size());
1232 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1234 // This time, the first 3 results have been found to be bad, but only the
1235 // first proxy has been confirmed ...
1236 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1237 "foopy1:8080;foopy3:7070;foopy2:9090;foopy4:9091");
1238 resolver
.pending_requests()[0]->CompleteNow(OK
);
1240 // ... therefore, we should see the second proxy first.
1241 EXPECT_EQ(OK
, callback7
.WaitForResult());
1242 EXPECT_FALSE(info
.is_direct());
1243 EXPECT_EQ("foopy3:7070", info
.proxy_server().ToURI());
1245 EXPECT_LE(proxy_resolve_end_time
, info
.proxy_resolve_start_time());
1246 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1247 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1248 // TODO(nsylvain): Test that the proxy can be retried after the delay.
1251 // This test is similar to ProxyFallback, but this time we have an explicit
1252 // fallback choice to DIRECT.
1253 TEST_F(ProxyServiceTest
, ProxyFallbackToDirect
) {
1254 MockProxyConfigService
* config_service
=
1255 new MockProxyConfigService("http://foopy/proxy.pac");
1257 MockAsyncProxyResolver resolver
;
1258 MockAsyncProxyResolverFactory
* factory
=
1259 new MockAsyncProxyResolverFactory(false);
1261 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1263 GURL
url("http://www.google.com/");
1265 // Get the proxy information.
1267 TestCompletionCallback callback1
;
1268 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
1269 NULL
, NULL
, BoundNetLog());
1270 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1272 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1273 factory
->pending_requests()[0]->script_data()->url());
1274 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1276 ASSERT_EQ(1u, resolver
.pending_requests().size());
1277 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1279 // Set the result in proxy resolver.
1280 resolver
.pending_requests()[0]->results()->UsePacString(
1281 "PROXY foopy1:8080; PROXY foopy2:9090; DIRECT");
1282 resolver
.pending_requests()[0]->CompleteNow(OK
);
1284 // Get the first result.
1285 EXPECT_EQ(OK
, callback1
.WaitForResult());
1286 EXPECT_FALSE(info
.is_direct());
1287 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1289 // Fake an error on the proxy.
1290 TestCompletionCallback callback2
;
1291 rv
= service
.ReconsiderProxyAfterError(
1292 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1293 callback2
.callback(), NULL
, NULL
, BoundNetLog());
1296 // Now we get back the second proxy.
1297 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1299 // Fake an error on this proxy as well.
1300 TestCompletionCallback callback3
;
1301 rv
= service
.ReconsiderProxyAfterError(
1302 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1303 callback3
.callback(), NULL
, NULL
, BoundNetLog());
1306 // Finally, we get back DIRECT.
1307 EXPECT_TRUE(info
.is_direct());
1309 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1310 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1311 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1313 // Now we tell the proxy service that even DIRECT failed.
1314 TestCompletionCallback callback4
;
1315 rv
= service
.ReconsiderProxyAfterError(
1316 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1317 callback4
.callback(), NULL
, NULL
, BoundNetLog());
1318 // There was nothing left to try after DIRECT, so we are out of
1320 EXPECT_EQ(ERR_FAILED
, rv
);
1323 TEST_F(ProxyServiceTest
, ProxyFallback_NewSettings
) {
1324 // Test proxy failover when new settings are available.
1326 MockProxyConfigService
* config_service
=
1327 new MockProxyConfigService("http://foopy/proxy.pac");
1329 MockAsyncProxyResolver resolver
;
1330 MockAsyncProxyResolverFactory
* factory
=
1331 new MockAsyncProxyResolverFactory(false);
1333 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1335 GURL
url("http://www.google.com/");
1337 // Get the proxy information.
1339 TestCompletionCallback callback1
;
1340 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
1341 NULL
, NULL
, BoundNetLog());
1342 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1344 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1345 factory
->pending_requests()[0]->script_data()->url());
1346 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1348 ASSERT_EQ(1u, resolver
.pending_requests().size());
1349 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1351 // Set the result in proxy resolver.
1352 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1353 "foopy1:8080;foopy2:9090");
1354 resolver
.pending_requests()[0]->CompleteNow(OK
);
1356 // The first item is valid.
1357 EXPECT_EQ(OK
, callback1
.WaitForResult());
1358 EXPECT_FALSE(info
.is_direct());
1359 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1361 // Fake an error on the proxy, and also a new configuration on the proxy.
1362 config_service
->SetConfig(
1363 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy-new/proxy.pac")));
1365 TestCompletionCallback callback2
;
1366 rv
= service
.ReconsiderProxyAfterError(
1367 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1368 callback2
.callback(), NULL
, NULL
, BoundNetLog());
1369 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1371 EXPECT_EQ(GURL("http://foopy-new/proxy.pac"),
1372 factory
->pending_requests()[0]->script_data()->url());
1373 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1375 ASSERT_EQ(1u, resolver
.pending_requests().size());
1376 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1378 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1379 "foopy1:8080;foopy2:9090");
1380 resolver
.pending_requests()[0]->CompleteNow(OK
);
1382 // The first proxy is still there since the configuration changed.
1383 EXPECT_EQ(OK
, callback2
.WaitForResult());
1384 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1386 // We fake another error. It should now ignore the first one.
1387 TestCompletionCallback callback3
;
1388 rv
= service
.ReconsiderProxyAfterError(
1389 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1390 callback3
.callback(), NULL
, NULL
, BoundNetLog());
1392 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1394 // We simulate a new configuration.
1395 config_service
->SetConfig(
1396 ProxyConfig::CreateFromCustomPacURL(
1397 GURL("http://foopy-new2/proxy.pac")));
1399 // We fake another error. It should go back to the first proxy.
1400 TestCompletionCallback callback4
;
1401 rv
= service
.ReconsiderProxyAfterError(
1402 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1403 callback4
.callback(), NULL
, NULL
, BoundNetLog());
1404 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1406 EXPECT_EQ(GURL("http://foopy-new2/proxy.pac"),
1407 factory
->pending_requests()[0]->script_data()->url());
1408 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1410 ASSERT_EQ(1u, resolver
.pending_requests().size());
1411 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1413 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1414 "foopy1:8080;foopy2:9090");
1415 resolver
.pending_requests()[0]->CompleteNow(OK
);
1417 EXPECT_EQ(OK
, callback4
.WaitForResult());
1418 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1420 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1421 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1422 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1425 TEST_F(ProxyServiceTest
, ProxyFallback_BadConfig
) {
1426 // Test proxy failover when the configuration is bad.
1428 MockProxyConfigService
* config_service
=
1429 new MockProxyConfigService("http://foopy/proxy.pac");
1431 MockAsyncProxyResolver resolver
;
1432 MockAsyncProxyResolverFactory
* factory
=
1433 new MockAsyncProxyResolverFactory(false);
1435 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1437 GURL
url("http://www.google.com/");
1439 // Get the proxy information.
1441 TestCompletionCallback callback1
;
1442 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
1443 NULL
, NULL
, BoundNetLog());
1444 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1446 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1447 factory
->pending_requests()[0]->script_data()->url());
1448 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1449 ASSERT_EQ(1u, resolver
.pending_requests().size());
1450 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1452 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1453 "foopy1:8080;foopy2:9090");
1454 resolver
.pending_requests()[0]->CompleteNow(OK
);
1456 // The first item is valid.
1457 EXPECT_EQ(OK
, callback1
.WaitForResult());
1458 EXPECT_FALSE(info
.is_direct());
1459 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1461 // Fake a proxy error.
1462 TestCompletionCallback callback2
;
1463 rv
= service
.ReconsiderProxyAfterError(
1464 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1465 callback2
.callback(), NULL
, NULL
, BoundNetLog());
1468 // The first proxy is ignored, and the second one is selected.
1469 EXPECT_FALSE(info
.is_direct());
1470 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1472 // Fake a PAC failure.
1474 TestCompletionCallback callback3
;
1475 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info2
, callback3
.callback(),
1476 NULL
, NULL
, BoundNetLog());
1477 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1479 ASSERT_EQ(1u, resolver
.pending_requests().size());
1480 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1482 // This simulates a javascript runtime error in the PAC script.
1483 resolver
.pending_requests()[0]->CompleteNow(ERR_FAILED
);
1485 // Although the resolver failed, the ProxyService will implicitly fall-back
1486 // to a DIRECT connection.
1487 EXPECT_EQ(OK
, callback3
.WaitForResult());
1488 EXPECT_TRUE(info2
.is_direct());
1489 EXPECT_FALSE(info2
.is_empty());
1491 // The PAC script will work properly next time and successfully return a
1492 // proxy list. Since we have not marked the configuration as bad, it should
1493 // "just work" the next time we call it.
1495 TestCompletionCallback callback4
;
1496 rv
= service
.ReconsiderProxyAfterError(
1497 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info3
,
1498 callback4
.callback(), NULL
, NULL
, BoundNetLog());
1499 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1501 ASSERT_EQ(1u, resolver
.pending_requests().size());
1502 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1504 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1505 "foopy1:8080;foopy2:9090");
1506 resolver
.pending_requests()[0]->CompleteNow(OK
);
1508 // The first proxy is not there since the it was added to the bad proxies
1509 // list by the earlier ReconsiderProxyAfterError().
1510 EXPECT_EQ(OK
, callback4
.WaitForResult());
1511 EXPECT_FALSE(info3
.is_direct());
1512 EXPECT_EQ("foopy1:8080", info3
.proxy_server().ToURI());
1514 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1515 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1516 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1519 TEST_F(ProxyServiceTest
, ProxyFallback_BadConfigMandatory
) {
1520 // Test proxy failover when the configuration is bad.
1523 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
1525 config
.set_pac_mandatory(true);
1526 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
1528 MockAsyncProxyResolver resolver
;
1529 MockAsyncProxyResolverFactory
* factory
=
1530 new MockAsyncProxyResolverFactory(false);
1532 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1534 GURL
url("http://www.google.com/");
1536 // Get the proxy information.
1538 TestCompletionCallback callback1
;
1539 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
1540 NULL
, NULL
, BoundNetLog());
1541 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1543 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1544 factory
->pending_requests()[0]->script_data()->url());
1545 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1546 ASSERT_EQ(1u, resolver
.pending_requests().size());
1547 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1549 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1550 "foopy1:8080;foopy2:9090");
1551 resolver
.pending_requests()[0]->CompleteNow(OK
);
1553 // The first item is valid.
1554 EXPECT_EQ(OK
, callback1
.WaitForResult());
1555 EXPECT_FALSE(info
.is_direct());
1556 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1558 // Fake a proxy error.
1559 TestCompletionCallback callback2
;
1560 rv
= service
.ReconsiderProxyAfterError(
1561 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1562 callback2
.callback(), NULL
, NULL
, BoundNetLog());
1565 // The first proxy is ignored, and the second one is selected.
1566 EXPECT_FALSE(info
.is_direct());
1567 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1569 // Fake a PAC failure.
1571 TestCompletionCallback callback3
;
1572 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info2
, callback3
.callback(),
1573 NULL
, NULL
, BoundNetLog());
1574 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1576 ASSERT_EQ(1u, resolver
.pending_requests().size());
1577 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1579 // This simulates a javascript runtime error in the PAC script.
1580 resolver
.pending_requests()[0]->CompleteNow(ERR_FAILED
);
1582 // Although the resolver failed, the ProxyService will NOT fall-back
1583 // to a DIRECT connection as it is configured as mandatory.
1584 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
1585 callback3
.WaitForResult());
1586 EXPECT_FALSE(info2
.is_direct());
1587 EXPECT_TRUE(info2
.is_empty());
1589 // The PAC script will work properly next time and successfully return a
1590 // proxy list. Since we have not marked the configuration as bad, it should
1591 // "just work" the next time we call it.
1593 TestCompletionCallback callback4
;
1594 rv
= service
.ReconsiderProxyAfterError(
1595 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info3
,
1596 callback4
.callback(), NULL
, NULL
, BoundNetLog());
1597 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1599 ASSERT_EQ(1u, resolver
.pending_requests().size());
1600 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1602 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1603 "foopy1:8080;foopy2:9090");
1604 resolver
.pending_requests()[0]->CompleteNow(OK
);
1606 // The first proxy is not there since the it was added to the bad proxies
1607 // list by the earlier ReconsiderProxyAfterError().
1608 EXPECT_EQ(OK
, callback4
.WaitForResult());
1609 EXPECT_FALSE(info3
.is_direct());
1610 EXPECT_EQ("foopy1:8080", info3
.proxy_server().ToURI());
1613 TEST_F(ProxyServiceTest
, ProxyBypassList
) {
1614 // Test that the proxy bypass rules are consulted.
1616 TestCompletionCallback callback
[2];
1619 config
.proxy_rules().ParseFromString("foopy1:8080;foopy2:9090");
1620 config
.set_auto_detect(false);
1621 config
.proxy_rules().bypass_rules
.ParseFromString("*.org");
1623 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1626 GURL
url1("http://www.webkit.org");
1627 GURL
url2("http://www.webkit.com");
1629 // Request for a .org domain should bypass proxy.
1630 rv
= service
.ResolveProxy(url1
, LOAD_NORMAL
, &info
[0], callback
[0].callback(),
1631 NULL
, NULL
, BoundNetLog());
1633 EXPECT_TRUE(info
[0].is_direct());
1635 // Request for a .com domain hits the proxy.
1636 rv
= service
.ResolveProxy(url2
, LOAD_NORMAL
, &info
[1], callback
[1].callback(),
1637 NULL
, NULL
, BoundNetLog());
1639 EXPECT_EQ("foopy1:8080", info
[1].proxy_server().ToURI());
1642 TEST_F(ProxyServiceTest
, MarkProxiesAsBadTests
) {
1644 config
.proxy_rules().ParseFromString(
1645 "http=foopy1:8080;http=foopy2:8080;http=foopy3.8080;http=foopy4:8080");
1646 config
.set_auto_detect(false);
1648 ProxyList proxy_list
;
1649 std::vector
<ProxyServer
> additional_bad_proxies
;
1650 for (const ProxyServer
& proxy_server
:
1651 config
.proxy_rules().proxies_for_http
.GetAll()) {
1652 proxy_list
.AddProxyServer(proxy_server
);
1653 if (proxy_server
== config
.proxy_rules().proxies_for_http
.Get())
1656 additional_bad_proxies
.push_back(proxy_server
);
1659 EXPECT_EQ(3u, additional_bad_proxies
.size());
1661 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1662 ProxyInfo proxy_info
;
1663 proxy_info
.UseProxyList(proxy_list
);
1664 const ProxyRetryInfoMap
& retry_info
= service
.proxy_retry_info();
1665 service
.MarkProxiesAsBadUntil(proxy_info
, base::TimeDelta::FromSeconds(1),
1666 additional_bad_proxies
, BoundNetLog());
1667 ASSERT_EQ(4u, retry_info
.size());
1668 for (const ProxyServer
& proxy_server
:
1669 config
.proxy_rules().proxies_for_http
.GetAll()) {
1670 ProxyRetryInfoMap::const_iterator i
=
1671 retry_info
.find(proxy_server
.host_port_pair().ToString());
1672 ASSERT_TRUE(i
!= retry_info
.end());
1676 TEST_F(ProxyServiceTest
, PerProtocolProxyTests
) {
1678 config
.proxy_rules().ParseFromString("http=foopy1:8080;https=foopy2:8080");
1679 config
.set_auto_detect(false);
1681 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1682 GURL
test_url("http://www.msn.com");
1684 TestCompletionCallback callback
;
1686 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1687 NULL
, NULL
, BoundNetLog());
1689 EXPECT_FALSE(info
.is_direct());
1690 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1693 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1694 GURL
test_url("ftp://ftp.google.com");
1696 TestCompletionCallback callback
;
1698 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1699 NULL
, NULL
, BoundNetLog());
1701 EXPECT_TRUE(info
.is_direct());
1702 EXPECT_EQ("direct://", info
.proxy_server().ToURI());
1705 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1706 GURL
test_url("https://webbranch.techcu.com");
1708 TestCompletionCallback callback
;
1710 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1711 NULL
, NULL
, BoundNetLog());
1713 EXPECT_FALSE(info
.is_direct());
1714 EXPECT_EQ("foopy2:8080", info
.proxy_server().ToURI());
1717 config
.proxy_rules().ParseFromString("foopy1:8080");
1718 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1719 GURL
test_url("http://www.microsoft.com");
1721 TestCompletionCallback callback
;
1723 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1724 NULL
, NULL
, BoundNetLog());
1726 EXPECT_FALSE(info
.is_direct());
1727 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1731 TEST_F(ProxyServiceTest
, ProxyConfigSourcePropagates
) {
1732 // Test that the proxy config source is set correctly when resolving proxies
1733 // using manual proxy rules. Namely, the config source should only be set if
1734 // any of the rules were applied.
1737 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1738 config
.proxy_rules().ParseFromString("https=foopy2:8080");
1739 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1740 GURL
test_url("http://www.google.com");
1742 TestCompletionCallback callback
;
1744 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1745 NULL
, NULL
, BoundNetLog());
1747 // Should be SOURCE_TEST, even if there are no HTTP proxies configured.
1748 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1752 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1753 config
.proxy_rules().ParseFromString("https=foopy2:8080");
1754 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1755 GURL
test_url("https://www.google.com");
1757 TestCompletionCallback callback
;
1759 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1760 NULL
, NULL
, BoundNetLog());
1762 // Used the HTTPS proxy. So source should be TEST.
1763 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1767 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1768 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1769 GURL
test_url("http://www.google.com");
1771 TestCompletionCallback callback
;
1773 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1774 NULL
, NULL
, BoundNetLog());
1776 // ProxyConfig is empty. Source should still be TEST.
1777 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1781 // If only HTTP and a SOCKS proxy are specified, check if ftp/https queries
1782 // fall back to the SOCKS proxy.
1783 TEST_F(ProxyServiceTest
, DefaultProxyFallbackToSOCKS
) {
1785 config
.proxy_rules().ParseFromString("http=foopy1:8080;socks=foopy2:1080");
1786 config
.set_auto_detect(false);
1787 EXPECT_EQ(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
1788 config
.proxy_rules().type
);
1791 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1792 GURL
test_url("http://www.msn.com");
1794 TestCompletionCallback callback
;
1796 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1797 NULL
, NULL
, BoundNetLog());
1799 EXPECT_FALSE(info
.is_direct());
1800 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1803 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1804 GURL
test_url("ftp://ftp.google.com");
1806 TestCompletionCallback callback
;
1808 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1809 NULL
, NULL
, BoundNetLog());
1811 EXPECT_FALSE(info
.is_direct());
1812 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1815 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1816 GURL
test_url("https://webbranch.techcu.com");
1818 TestCompletionCallback callback
;
1820 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1821 NULL
, NULL
, BoundNetLog());
1823 EXPECT_FALSE(info
.is_direct());
1824 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1827 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1828 GURL
test_url("unknown://www.microsoft.com");
1830 TestCompletionCallback callback
;
1832 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1833 NULL
, NULL
, BoundNetLog());
1835 EXPECT_FALSE(info
.is_direct());
1836 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1840 // Test cancellation of an in-progress request.
1841 TEST_F(ProxyServiceTest
, CancelInProgressRequest
) {
1842 const GURL
url1("http://request1");
1843 const GURL
url2("http://request2");
1844 const GURL
url3("http://request3");
1845 MockProxyConfigService
* config_service
=
1846 new MockProxyConfigService("http://foopy/proxy.pac");
1848 MockAsyncProxyResolver resolver
;
1849 MockAsyncProxyResolverFactory
* factory
=
1850 new MockAsyncProxyResolverFactory(false);
1852 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1854 // Start 3 requests.
1857 TestCompletionCallback callback1
;
1858 int rv
= service
.ResolveProxy(url1
, LOAD_NORMAL
, &info1
, callback1
.callback(),
1859 NULL
, NULL
, BoundNetLog());
1860 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1862 // Successfully initialize the PAC script.
1863 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1864 factory
->pending_requests()[0]->script_data()->url());
1865 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1867 GetPendingRequestsForURLs(resolver
, url1
);
1870 TestCompletionCallback callback2
;
1871 ProxyService::PacRequest
* request2
;
1872 rv
= service
.ResolveProxy(url2
, LOAD_NORMAL
, &info2
, callback2
.callback(),
1873 &request2
, NULL
, BoundNetLog());
1874 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1876 GetPendingRequestsForURLs(resolver
, url1
, url2
);
1879 TestCompletionCallback callback3
;
1880 rv
= service
.ResolveProxy(url3
, LOAD_NORMAL
, &info3
, callback3
.callback(),
1881 NULL
, NULL
, BoundNetLog());
1882 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1883 GetPendingRequestsForURLs(resolver
, url1
, url2
, url3
);
1885 // Cancel the second request
1886 service
.CancelPacRequest(request2
);
1888 RequestMap requests
= GetPendingRequestsForURLs(resolver
, url1
, url3
);
1890 // Complete the two un-cancelled requests.
1891 // We complete the last one first, just to mix it up a bit.
1892 requests
[url3
]->results()->UseNamedProxy("request3:80");
1893 requests
[url3
]->CompleteNow(OK
);
1895 requests
[url1
]->results()->UseNamedProxy("request1:80");
1896 requests
[url1
]->CompleteNow(OK
);
1898 // Complete and verify that requests ran as expected.
1899 EXPECT_EQ(OK
, callback1
.WaitForResult());
1900 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
1902 EXPECT_FALSE(callback2
.have_result()); // Cancelled.
1903 GetCancelledRequestsForURLs(resolver
, url2
);
1905 EXPECT_EQ(OK
, callback3
.WaitForResult());
1906 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
1909 // Test the initial PAC download for resolver that expects bytes.
1910 TEST_F(ProxyServiceTest
, InitialPACScriptDownload
) {
1911 const GURL
url1("http://request1");
1912 const GURL
url2("http://request2");
1913 const GURL
url3("http://request3");
1915 MockProxyConfigService
* config_service
=
1916 new MockProxyConfigService("http://foopy/proxy.pac");
1918 MockAsyncProxyResolver resolver
;
1919 MockAsyncProxyResolverFactory
* factory
=
1920 new MockAsyncProxyResolverFactory(true);
1922 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1924 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1925 service
.SetProxyScriptFetchers(
1926 fetcher
, make_scoped_ptr(new DoNothingDhcpProxyScriptFetcher()));
1928 // Start 3 requests.
1931 TestCompletionCallback callback1
;
1932 ProxyService::PacRequest
* request1
;
1933 int rv
= service
.ResolveProxy(url1
, LOAD_NORMAL
, &info1
, callback1
.callback(),
1934 &request1
, NULL
, BoundNetLog());
1935 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1937 // The first request should have triggered download of PAC script.
1938 EXPECT_TRUE(fetcher
->has_pending_request());
1939 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1942 TestCompletionCallback callback2
;
1943 ProxyService::PacRequest
* request2
;
1944 rv
= service
.ResolveProxy(url2
, LOAD_NORMAL
, &info2
, callback2
.callback(),
1945 &request2
, NULL
, BoundNetLog());
1946 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1949 TestCompletionCallback callback3
;
1950 ProxyService::PacRequest
* request3
;
1951 rv
= service
.ResolveProxy(url3
, LOAD_NORMAL
, &info3
, callback3
.callback(),
1952 &request3
, NULL
, BoundNetLog());
1953 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1955 // Nothing has been sent to the factory yet.
1956 EXPECT_TRUE(factory
->pending_requests().empty());
1958 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1959 service
.GetLoadState(request1
));
1960 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1961 service
.GetLoadState(request2
));
1962 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1963 service
.GetLoadState(request3
));
1965 // At this point the ProxyService should be waiting for the
1966 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1967 // PAC script download completion.
1968 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
1970 // Now that the PAC script is downloaded, it will have been sent to the proxy
1972 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
1973 factory
->pending_requests()[0]->script_data()->utf16());
1974 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1976 RequestMap requests
= GetPendingRequestsForURLs(resolver
, url1
, url2
, url3
);
1978 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request1
));
1979 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request2
));
1980 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request3
));
1982 // Complete all the requests (in some order).
1984 requests
[url3
]->results()->UseNamedProxy("request3:80");
1985 requests
[url3
]->CompleteNow(OK
);
1987 requests
[url1
]->results()->UseNamedProxy("request1:80");
1988 requests
[url1
]->CompleteNow(OK
);
1990 requests
[url2
]->results()->UseNamedProxy("request2:80");
1991 requests
[url2
]->CompleteNow(OK
);
1993 // Complete and verify that requests ran as expected.
1994 EXPECT_EQ(OK
, callback1
.WaitForResult());
1995 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
1996 EXPECT_FALSE(info1
.proxy_resolve_start_time().is_null());
1997 EXPECT_FALSE(info1
.proxy_resolve_end_time().is_null());
1998 EXPECT_LE(info1
.proxy_resolve_start_time(), info1
.proxy_resolve_end_time());
2000 EXPECT_EQ(OK
, callback2
.WaitForResult());
2001 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2002 EXPECT_FALSE(info2
.proxy_resolve_start_time().is_null());
2003 EXPECT_FALSE(info2
.proxy_resolve_end_time().is_null());
2004 EXPECT_LE(info2
.proxy_resolve_start_time(), info2
.proxy_resolve_end_time());
2006 EXPECT_EQ(OK
, callback3
.WaitForResult());
2007 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
2008 EXPECT_FALSE(info3
.proxy_resolve_start_time().is_null());
2009 EXPECT_FALSE(info3
.proxy_resolve_end_time().is_null());
2010 EXPECT_LE(info3
.proxy_resolve_start_time(), info3
.proxy_resolve_end_time());
2013 // Test changing the ProxyScriptFetcher while PAC download is in progress.
2014 TEST_F(ProxyServiceTest
, ChangeScriptFetcherWhilePACDownloadInProgress
) {
2015 const GURL
url1("http://request1");
2016 const GURL
url2("http://request2");
2017 MockProxyConfigService
* config_service
=
2018 new MockProxyConfigService("http://foopy/proxy.pac");
2020 MockAsyncProxyResolver resolver
;
2021 MockAsyncProxyResolverFactory
* factory
=
2022 new MockAsyncProxyResolverFactory(true);
2024 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2026 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2027 service
.SetProxyScriptFetchers(
2028 fetcher
, make_scoped_ptr(new DoNothingDhcpProxyScriptFetcher()));
2030 // Start 2 requests.
2033 TestCompletionCallback callback1
;
2034 int rv
= service
.ResolveProxy(url1
, LOAD_NORMAL
, &info1
, callback1
.callback(),
2035 NULL
, NULL
, BoundNetLog());
2036 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2038 // The first request should have triggered download of PAC script.
2039 EXPECT_TRUE(fetcher
->has_pending_request());
2040 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2043 TestCompletionCallback callback2
;
2044 rv
= service
.ResolveProxy(url2
, LOAD_NORMAL
, &info2
, callback2
.callback(),
2045 NULL
, NULL
, BoundNetLog());
2046 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2048 // At this point the ProxyService should be waiting for the
2049 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2050 // PAC script download completion.
2052 // We now change out the ProxyService's script fetcher. We should restart
2053 // the initialization with the new fetcher.
2055 fetcher
= new MockProxyScriptFetcher
;
2056 service
.SetProxyScriptFetchers(
2057 fetcher
, make_scoped_ptr(new DoNothingDhcpProxyScriptFetcher()));
2059 // Nothing has been sent to the factory yet.
2060 EXPECT_TRUE(factory
->pending_requests().empty());
2062 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2064 // Now that the PAC script is downloaded, it will have been sent to the proxy
2066 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2067 factory
->pending_requests()[0]->script_data()->utf16());
2068 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2070 GetPendingRequestsForURLs(resolver
, url1
, url2
);
2073 // Test cancellation of a request, while the PAC script is being fetched.
2074 TEST_F(ProxyServiceTest
, CancelWhilePACFetching
) {
2075 MockProxyConfigService
* config_service
=
2076 new MockProxyConfigService("http://foopy/proxy.pac");
2078 MockAsyncProxyResolver resolver
;
2079 MockAsyncProxyResolverFactory
* factory
=
2080 new MockAsyncProxyResolverFactory(true);
2082 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2084 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2085 service
.SetProxyScriptFetchers(
2086 fetcher
, make_scoped_ptr(new DoNothingDhcpProxyScriptFetcher()));
2088 // Start 3 requests.
2090 TestCompletionCallback callback1
;
2091 ProxyService::PacRequest
* request1
;
2092 BoundTestNetLog log1
;
2094 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
2095 callback1
.callback(), &request1
, NULL
, log1
.bound());
2096 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2098 // The first request should have triggered download of PAC script.
2099 EXPECT_TRUE(fetcher
->has_pending_request());
2100 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2103 TestCompletionCallback callback2
;
2104 ProxyService::PacRequest
* request2
;
2105 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
2106 callback2
.callback(), &request2
, NULL
,
2108 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2111 TestCompletionCallback callback3
;
2112 rv
= service
.ResolveProxy(GURL("http://request3"), LOAD_NORMAL
, &info3
,
2113 callback3
.callback(), NULL
, NULL
, BoundNetLog());
2114 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2116 // Nothing has been sent to the factory yet.
2117 EXPECT_TRUE(factory
->pending_requests().empty());
2119 // Cancel the first 2 requests.
2120 service
.CancelPacRequest(request1
);
2121 service
.CancelPacRequest(request2
);
2123 // At this point the ProxyService should be waiting for the
2124 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2125 // PAC script download completion.
2126 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2128 // Now that the PAC script is downloaded, it will have been sent to the
2130 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2131 factory
->pending_requests()[0]->script_data()->utf16());
2132 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2134 ASSERT_EQ(1u, resolver
.pending_requests().size());
2135 EXPECT_EQ(GURL("http://request3"), resolver
.pending_requests()[0]->url());
2137 // Complete all the requests.
2138 resolver
.pending_requests()[0]->results()->UseNamedProxy("request3:80");
2139 resolver
.pending_requests()[0]->CompleteNow(OK
);
2141 EXPECT_EQ(OK
, callback3
.WaitForResult());
2142 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
2144 EXPECT_TRUE(resolver
.cancelled_requests().empty());
2146 EXPECT_FALSE(callback1
.have_result()); // Cancelled.
2147 EXPECT_FALSE(callback2
.have_result()); // Cancelled.
2149 TestNetLogEntry::List entries1
;
2150 log1
.GetEntries(&entries1
);
2152 // Check the NetLog for request 1 (which was cancelled) got filled properly.
2153 EXPECT_EQ(4u, entries1
.size());
2154 EXPECT_TRUE(LogContainsBeginEvent(
2155 entries1
, 0, NetLog::TYPE_PROXY_SERVICE
));
2156 EXPECT_TRUE(LogContainsBeginEvent(
2157 entries1
, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
2158 // Note that TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC is never completed before
2159 // the cancellation occured.
2160 EXPECT_TRUE(LogContainsEvent(
2161 entries1
, 2, NetLog::TYPE_CANCELLED
, NetLog::PHASE_NONE
));
2162 EXPECT_TRUE(LogContainsEndEvent(
2163 entries1
, 3, NetLog::TYPE_PROXY_SERVICE
));
2166 // Test that if auto-detect fails, we fall-back to the custom pac.
2167 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomPac
) {
2168 const GURL
url1("http://request1");
2169 const GURL
url2("http://request2");
2171 config
.set_auto_detect(true);
2172 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2173 config
.proxy_rules().ParseFromString("http=foopy:80"); // Won't be used.
2175 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2176 MockAsyncProxyResolver resolver
;
2177 MockAsyncProxyResolverFactory
* factory
=
2178 new MockAsyncProxyResolverFactory(true);
2179 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2181 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2182 service
.SetProxyScriptFetchers(
2183 fetcher
, make_scoped_ptr(new DoNothingDhcpProxyScriptFetcher()));
2185 // Start 2 requests.
2188 TestCompletionCallback callback1
;
2189 int rv
= service
.ResolveProxy(url1
, LOAD_NORMAL
, &info1
, callback1
.callback(),
2190 NULL
, NULL
, BoundNetLog());
2191 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2194 TestCompletionCallback callback2
;
2195 ProxyService::PacRequest
* request2
;
2196 rv
= service
.ResolveProxy(url2
, LOAD_NORMAL
, &info2
, callback2
.callback(),
2197 &request2
, NULL
, BoundNetLog());
2198 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2200 // Check that nothing has been sent to the proxy resolver factory yet.
2201 ASSERT_EQ(0u, factory
->pending_requests().size());
2203 // It should be trying to auto-detect first -- FAIL the autodetect during
2204 // the script download.
2205 EXPECT_TRUE(fetcher
->has_pending_request());
2206 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2207 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2209 // Next it should be trying the custom PAC url.
2210 EXPECT_TRUE(fetcher
->has_pending_request());
2211 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2212 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2214 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2215 factory
->pending_requests()[0]->script_data()->utf16());
2216 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2218 // Now finally, the pending requests should have been sent to the resolver
2219 // (which was initialized with custom PAC script).
2221 RequestMap requests
= GetPendingRequestsForURLs(resolver
, url1
, url2
);
2223 // Complete the pending requests.
2224 requests
[url2
]->results()->UseNamedProxy("request2:80");
2225 requests
[url2
]->CompleteNow(OK
);
2226 requests
[url1
]->results()->UseNamedProxy("request1:80");
2227 requests
[url1
]->CompleteNow(OK
);
2229 // Verify that requests ran as expected.
2230 EXPECT_EQ(OK
, callback1
.WaitForResult());
2231 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2232 EXPECT_FALSE(info1
.proxy_resolve_start_time().is_null());
2233 EXPECT_FALSE(info1
.proxy_resolve_end_time().is_null());
2234 EXPECT_LE(info1
.proxy_resolve_start_time(), info1
.proxy_resolve_end_time());
2236 EXPECT_EQ(OK
, callback2
.WaitForResult());
2237 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2238 EXPECT_FALSE(info2
.proxy_resolve_start_time().is_null());
2239 EXPECT_FALSE(info2
.proxy_resolve_end_time().is_null());
2240 EXPECT_LE(info2
.proxy_resolve_start_time(), info2
.proxy_resolve_end_time());
2243 // This is the same test as FallbackFromAutodetectToCustomPac, except
2244 // the auto-detect script fails parsing rather than downloading.
2245 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomPac2
) {
2246 const GURL
url1("http://request1");
2247 const GURL
url2("http://request2");
2249 config
.set_auto_detect(true);
2250 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2251 config
.proxy_rules().ParseFromString("http=foopy:80"); // Won't be used.
2253 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2254 MockAsyncProxyResolver resolver
;
2255 MockAsyncProxyResolverFactory
* factory
=
2256 new MockAsyncProxyResolverFactory(true);
2257 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2259 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2260 service
.SetProxyScriptFetchers(
2261 fetcher
, make_scoped_ptr(new DoNothingDhcpProxyScriptFetcher()));
2263 // Start 2 requests.
2266 TestCompletionCallback callback1
;
2267 int rv
= service
.ResolveProxy(url1
, LOAD_NORMAL
, &info1
, callback1
.callback(),
2268 NULL
, NULL
, BoundNetLog());
2269 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2272 TestCompletionCallback callback2
;
2273 ProxyService::PacRequest
* request2
;
2274 rv
= service
.ResolveProxy(url2
, LOAD_NORMAL
, &info2
, callback2
.callback(),
2275 &request2
, NULL
, BoundNetLog());
2276 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2278 // Check that nothing has been sent to the proxy resolver factory yet.
2279 ASSERT_EQ(0u, factory
->pending_requests().size());
2281 // It should be trying to auto-detect first -- succeed the download.
2282 EXPECT_TRUE(fetcher
->has_pending_request());
2283 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2284 fetcher
->NotifyFetchCompletion(OK
, "invalid-script-contents");
2286 // The script contents passed failed basic verification step (since didn't
2287 // contain token FindProxyForURL), so it was never passed to the resolver.
2289 // Next it should be trying the custom PAC url.
2290 EXPECT_TRUE(fetcher
->has_pending_request());
2291 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2292 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2294 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2295 factory
->pending_requests()[0]->script_data()->utf16());
2296 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2298 // Now finally, the pending requests should have been sent to the resolver
2299 // (which was initialized with custom PAC script).
2301 RequestMap requests
= GetPendingRequestsForURLs(resolver
, url1
, url2
);
2303 // Complete the pending requests.
2304 requests
[url2
]->results()->UseNamedProxy("request2:80");
2305 requests
[url2
]->CompleteNow(OK
);
2306 requests
[url1
]->results()->UseNamedProxy("request1:80");
2307 requests
[url1
]->CompleteNow(OK
);
2309 // Verify that requests ran as expected.
2310 EXPECT_EQ(OK
, callback1
.WaitForResult());
2311 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2313 EXPECT_EQ(OK
, callback2
.WaitForResult());
2314 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2317 // Test that if all of auto-detect, a custom PAC script, and manual settings
2318 // are given, then we will try them in that order.
2319 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomToManual
) {
2321 config
.set_auto_detect(true);
2322 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2323 config
.proxy_rules().ParseFromString("http=foopy:80");
2325 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2326 MockAsyncProxyResolverFactory
* factory
=
2327 new MockAsyncProxyResolverFactory(true);
2328 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2330 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2331 service
.SetProxyScriptFetchers(
2332 fetcher
, make_scoped_ptr(new DoNothingDhcpProxyScriptFetcher()));
2334 // Start 2 requests.
2337 TestCompletionCallback callback1
;
2339 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
2340 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2341 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2344 TestCompletionCallback callback2
;
2345 ProxyService::PacRequest
* request2
;
2346 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
2347 callback2
.callback(), &request2
, NULL
,
2349 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2351 // Check that nothing has been sent to the proxy resolver factory yet.
2352 ASSERT_EQ(0u, factory
->pending_requests().size());
2354 // It should be trying to auto-detect first -- fail the download.
2355 EXPECT_TRUE(fetcher
->has_pending_request());
2356 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2357 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2359 // Next it should be trying the custom PAC url -- fail the download.
2360 EXPECT_TRUE(fetcher
->has_pending_request());
2361 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2362 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2364 // Since we never managed to initialize a resolver, nothing should have been
2366 ASSERT_EQ(0u, factory
->pending_requests().size());
2368 // Verify that requests ran as expected -- they should have fallen back to
2369 // the manual proxy configuration for HTTP urls.
2370 EXPECT_EQ(OK
, callback1
.WaitForResult());
2371 EXPECT_EQ("foopy:80", info1
.proxy_server().ToURI());
2373 EXPECT_EQ(OK
, callback2
.WaitForResult());
2374 EXPECT_EQ("foopy:80", info2
.proxy_server().ToURI());
2377 // Test that the bypass rules are NOT applied when using autodetect.
2378 TEST_F(ProxyServiceTest
, BypassDoesntApplyToPac
) {
2380 config
.set_auto_detect(true);
2381 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2382 config
.proxy_rules().ParseFromString("http=foopy:80"); // Not used.
2383 config
.proxy_rules().bypass_rules
.ParseFromString("www.google.com");
2385 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2386 MockAsyncProxyResolver resolver
;
2387 MockAsyncProxyResolverFactory
* factory
=
2388 new MockAsyncProxyResolverFactory(true);
2389 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2391 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2392 service
.SetProxyScriptFetchers(
2393 fetcher
, make_scoped_ptr(new DoNothingDhcpProxyScriptFetcher()));
2395 // Start 1 requests.
2398 TestCompletionCallback callback1
;
2400 service
.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL
, &info1
,
2401 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2402 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2404 // Check that nothing has been sent to the proxy resolver factory yet.
2405 ASSERT_EQ(0u, factory
->pending_requests().size());
2407 // It should be trying to auto-detect first -- succeed the download.
2408 EXPECT_TRUE(fetcher
->has_pending_request());
2409 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2410 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2412 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2413 factory
->pending_requests()[0]->script_data()->utf16());
2414 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2416 ASSERT_EQ(1u, resolver
.pending_requests().size());
2417 EXPECT_EQ(GURL("http://www.google.com"),
2418 resolver
.pending_requests()[0]->url());
2420 // Complete the pending request.
2421 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2422 resolver
.pending_requests()[0]->CompleteNow(OK
);
2424 // Verify that request ran as expected.
2425 EXPECT_EQ(OK
, callback1
.WaitForResult());
2426 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2428 // Start another request, it should pickup the bypass item.
2430 TestCompletionCallback callback2
;
2431 rv
= service
.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL
, &info2
,
2432 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2433 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2435 ASSERT_EQ(1u, resolver
.pending_requests().size());
2436 EXPECT_EQ(GURL("http://www.google.com"),
2437 resolver
.pending_requests()[0]->url());
2439 // Complete the pending request.
2440 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2441 resolver
.pending_requests()[0]->CompleteNow(OK
);
2443 EXPECT_EQ(OK
, callback2
.WaitForResult());
2444 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2447 // Delete the ProxyService while InitProxyResolver has an outstanding
2448 // request to the script fetcher. When run under valgrind, should not
2449 // have any memory errors (used to be that the ProxyScriptFetcher was
2450 // being deleted prior to the InitProxyResolver).
2451 TEST_F(ProxyServiceTest
, DeleteWhileInitProxyResolverHasOutstandingFetch
) {
2452 ProxyConfig config
=
2453 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
2455 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2456 MockAsyncProxyResolverFactory
* factory
=
2457 new MockAsyncProxyResolverFactory(true);
2458 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2460 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2461 service
.SetProxyScriptFetchers(
2462 fetcher
, make_scoped_ptr(new DoNothingDhcpProxyScriptFetcher()));
2467 TestCompletionCallback callback1
;
2469 service
.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL
, &info1
,
2470 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2471 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2473 // Check that nothing has been sent to the proxy resolver factory yet.
2474 ASSERT_EQ(0u, factory
->pending_requests().size());
2476 // InitProxyResolver should have issued a request to the ProxyScriptFetcher
2477 // and be waiting on that to complete.
2478 EXPECT_TRUE(fetcher
->has_pending_request());
2479 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2482 // Delete the ProxyService while InitProxyResolver has an outstanding
2483 // request to the proxy resolver. When run under valgrind, should not
2484 // have any memory errors (used to be that the ProxyResolver was
2485 // being deleted prior to the InitProxyResolver).
2486 TEST_F(ProxyServiceTest
, DeleteWhileInitProxyResolverHasOutstandingSet
) {
2487 MockProxyConfigService
* config_service
=
2488 new MockProxyConfigService("http://foopy/proxy.pac");
2490 MockAsyncProxyResolverFactory
* factory
=
2491 new MockAsyncProxyResolverFactory(false);
2493 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2495 GURL
url("http://www.google.com/");
2498 TestCompletionCallback callback
;
2499 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(),
2500 NULL
, NULL
, BoundNetLog());
2501 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2503 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
2504 factory
->pending_requests()[0]->script_data()->url());
2507 TEST_F(ProxyServiceTest
, ResetProxyConfigService
) {
2508 ProxyConfig config1
;
2509 config1
.proxy_rules().ParseFromString("foopy1:8080");
2510 config1
.set_auto_detect(false);
2511 ProxyService
service(new MockProxyConfigService(config1
), nullptr, NULL
);
2514 TestCompletionCallback callback1
;
2516 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info
,
2517 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2519 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
2521 ProxyConfig config2
;
2522 config2
.proxy_rules().ParseFromString("foopy2:8080");
2523 config2
.set_auto_detect(false);
2524 service
.ResetConfigService(new MockProxyConfigService(config2
));
2525 TestCompletionCallback callback2
;
2526 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info
,
2527 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2529 EXPECT_EQ("foopy2:8080", info
.proxy_server().ToURI());
2532 // Test that when going from a configuration that required PAC to one
2533 // that does NOT, we unset the variable |should_use_proxy_resolver_|.
2534 TEST_F(ProxyServiceTest
, UpdateConfigFromPACToDirect
) {
2535 ProxyConfig config
= ProxyConfig::CreateAutoDetect();
2537 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2538 MockAsyncProxyResolver resolver
;
2539 MockAsyncProxyResolverFactory
* factory
=
2540 new MockAsyncProxyResolverFactory(false);
2541 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2546 TestCompletionCallback callback1
;
2548 service
.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL
, &info1
,
2549 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2550 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2552 // Successfully set the autodetect script.
2553 EXPECT_EQ(ProxyResolverScriptData::TYPE_AUTO_DETECT
,
2554 factory
->pending_requests()[0]->script_data()->type());
2555 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2557 // Complete the pending request.
2558 ASSERT_EQ(1u, resolver
.pending_requests().size());
2559 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2560 resolver
.pending_requests()[0]->CompleteNow(OK
);
2562 // Verify that request ran as expected.
2563 EXPECT_EQ(OK
, callback1
.WaitForResult());
2564 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2566 // Force the ProxyService to pull down a new proxy configuration.
2567 // (Even though the configuration isn't old/bad).
2569 // This new configuration no longer has auto_detect set, so
2570 // requests should complete synchronously now as direct-connect.
2571 config_service
->SetConfig(ProxyConfig::CreateDirect());
2573 // Start another request -- the effective configuration has changed.
2575 TestCompletionCallback callback2
;
2576 rv
= service
.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL
, &info2
,
2577 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2580 EXPECT_TRUE(info2
.is_direct());
2583 TEST_F(ProxyServiceTest
, NetworkChangeTriggersPacRefetch
) {
2584 MockProxyConfigService
* config_service
=
2585 new MockProxyConfigService("http://foopy/proxy.pac");
2587 MockAsyncProxyResolver resolver
;
2588 MockAsyncProxyResolverFactory
* factory
=
2589 new MockAsyncProxyResolverFactory(true);
2593 ProxyService
service(config_service
, make_scoped_ptr(factory
), &log
);
2595 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2596 service
.SetProxyScriptFetchers(
2597 fetcher
, make_scoped_ptr(new DoNothingDhcpProxyScriptFetcher()));
2599 // Disable the "wait after IP address changes" hack, so this unit-test can
2600 // complete quickly.
2601 service
.set_stall_proxy_auto_config_delay(base::TimeDelta());
2606 TestCompletionCallback callback1
;
2608 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
2609 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2610 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2612 // The first request should have triggered initial download of PAC script.
2613 EXPECT_TRUE(fetcher
->has_pending_request());
2614 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2616 // Nothing has been sent to the factory yet.
2617 EXPECT_TRUE(factory
->pending_requests().empty());
2619 // At this point the ProxyService should be waiting for the
2620 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2621 // PAC script download completion.
2622 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2624 // Now that the PAC script is downloaded, the request will have been sent to
2625 // the proxy resolver.
2626 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2627 factory
->pending_requests()[0]->script_data()->utf16());
2628 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2630 ASSERT_EQ(1u, resolver
.pending_requests().size());
2631 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
2633 // Complete the pending request.
2634 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2635 resolver
.pending_requests()[0]->CompleteNow(OK
);
2637 // Wait for completion callback, and verify that the request ran as expected.
2638 EXPECT_EQ(OK
, callback1
.WaitForResult());
2639 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2641 // Now simluate a change in the network. The ProxyConfigService is still
2642 // going to return the same PAC URL as before, but this URL needs to be
2643 // refetched on the new network.
2644 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
2645 base::MessageLoop::current()->RunUntilIdle(); // Notification happens async.
2647 // Start a second request.
2649 TestCompletionCallback callback2
;
2650 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
2651 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2652 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2654 // This second request should have triggered the re-download of the PAC
2655 // script (since we marked the network as having changed).
2656 EXPECT_TRUE(fetcher
->has_pending_request());
2657 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2659 // Nothing has been sent to the factory yet.
2660 EXPECT_TRUE(factory
->pending_requests().empty());
2662 // Simulate the PAC script fetch as having completed (this time with
2664 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript2
);
2666 // Now that the PAC script is downloaded, the second request will have been
2667 // sent to the proxy resolver.
2668 EXPECT_EQ(ASCIIToUTF16(kValidPacScript2
),
2669 factory
->pending_requests()[0]->script_data()->utf16());
2670 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2672 ASSERT_EQ(1u, resolver
.pending_requests().size());
2673 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[0]->url());
2675 // Complete the pending second request.
2676 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2677 resolver
.pending_requests()[0]->CompleteNow(OK
);
2679 // Wait for completion callback, and verify that the request ran as expected.
2680 EXPECT_EQ(OK
, callback2
.WaitForResult());
2681 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2683 // Check that the expected events were output to the log stream. In particular
2684 // PROXY_CONFIG_CHANGED should have only been emitted once (for the initial
2685 // setup), and NOT a second time when the IP address changed.
2686 TestNetLogEntry::List entries
;
2687 log
.GetEntries(&entries
);
2689 EXPECT_TRUE(LogContainsEntryWithType(entries
, 0,
2690 NetLog::TYPE_PROXY_CONFIG_CHANGED
));
2691 ASSERT_EQ(9u, entries
.size());
2692 for (size_t i
= 1; i
< entries
.size(); ++i
)
2693 EXPECT_NE(NetLog::TYPE_PROXY_CONFIG_CHANGED
, entries
[i
].type
);
2696 // This test verifies that the PAC script specified by the settings is
2697 // periodically polled for changes. Specifically, if the initial fetch fails due
2698 // to a network error, we will eventually re-configure the service to use the
2699 // script once it becomes available.
2700 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterFailure
) {
2701 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2703 ImmediatePollPolicy poll_policy
;
2704 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2706 MockProxyConfigService
* config_service
=
2707 new MockProxyConfigService("http://foopy/proxy.pac");
2709 MockAsyncProxyResolver resolver
;
2710 MockAsyncProxyResolverFactory
* factory
=
2711 new MockAsyncProxyResolverFactory(true);
2713 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2715 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2716 service
.SetProxyScriptFetchers(
2717 fetcher
, make_scoped_ptr(new DoNothingDhcpProxyScriptFetcher()));
2722 TestCompletionCallback callback1
;
2724 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
2725 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2726 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2728 // The first request should have triggered initial download of PAC script.
2729 EXPECT_TRUE(fetcher
->has_pending_request());
2730 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2732 // Nothing has been sent to the factory yet.
2733 EXPECT_TRUE(factory
->pending_requests().empty());
2735 // At this point the ProxyService should be waiting for the
2736 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2737 // PAC script download completion.
2739 // We simulate a failed download attempt, the proxy service should now
2740 // fall-back to DIRECT connections.
2741 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2743 ASSERT_TRUE(factory
->pending_requests().empty());
2745 // Wait for completion callback, and verify it used DIRECT.
2746 EXPECT_EQ(OK
, callback1
.WaitForResult());
2747 EXPECT_TRUE(info1
.is_direct());
2749 // At this point we have initialized the proxy service using a PAC script,
2750 // however it failed and fell-back to DIRECT.
2752 // A background task to periodically re-check the PAC script for validity will
2753 // have been started. We will now wait for the next download attempt to start.
2755 // Note that we shouldn't have to wait long here, since our test enables a
2756 // special unit-test mode.
2757 fetcher
->WaitUntilFetch();
2759 ASSERT_TRUE(factory
->pending_requests().empty());
2761 // Make sure that our background checker is trying to download the expected
2762 // PAC script (same one as before). This time we will simulate a successful
2763 // download of the script.
2764 EXPECT_TRUE(fetcher
->has_pending_request());
2765 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2766 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2768 base::MessageLoop::current()->RunUntilIdle();
2770 // Now that the PAC script is downloaded, it should be used to initialize the
2771 // ProxyResolver. Simulate a successful parse.
2772 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2773 factory
->pending_requests()[0]->script_data()->utf16());
2774 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2776 // At this point the ProxyService should have re-configured itself to use the
2777 // PAC script (thereby recovering from the initial fetch failure). We will
2778 // verify that the next Resolve request uses the resolver rather than
2781 // Start a second request.
2783 TestCompletionCallback callback2
;
2784 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
2785 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2786 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2788 // Check that it was sent to the resolver.
2789 ASSERT_EQ(1u, resolver
.pending_requests().size());
2790 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[0]->url());
2792 // Complete the pending second request.
2793 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2794 resolver
.pending_requests()[0]->CompleteNow(OK
);
2796 // Wait for completion callback, and verify that the request ran as expected.
2797 EXPECT_EQ(OK
, callback2
.WaitForResult());
2798 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2801 // This test verifies that the PAC script specified by the settings is
2802 // periodically polled for changes. Specifically, if the initial fetch succeeds,
2803 // however at a later time its *contents* change, we will eventually
2804 // re-configure the service to use the new script.
2805 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterContentChange
) {
2806 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2808 ImmediatePollPolicy poll_policy
;
2809 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2811 MockProxyConfigService
* config_service
=
2812 new MockProxyConfigService("http://foopy/proxy.pac");
2814 MockAsyncProxyResolver resolver
;
2815 MockAsyncProxyResolverFactory
* factory
=
2816 new MockAsyncProxyResolverFactory(true);
2818 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2820 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2821 service
.SetProxyScriptFetchers(
2822 fetcher
, make_scoped_ptr(new DoNothingDhcpProxyScriptFetcher()));
2827 TestCompletionCallback callback1
;
2829 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
2830 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2831 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2833 // The first request should have triggered initial download of PAC script.
2834 EXPECT_TRUE(fetcher
->has_pending_request());
2835 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2837 // Nothing has been sent to the factory yet.
2838 EXPECT_TRUE(factory
->pending_requests().empty());
2840 // At this point the ProxyService should be waiting for the
2841 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2842 // PAC script download completion.
2843 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2845 // Now that the PAC script is downloaded, the request will have been sent to
2846 // the proxy resolver.
2847 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2848 factory
->pending_requests()[0]->script_data()->utf16());
2849 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2851 ASSERT_EQ(1u, resolver
.pending_requests().size());
2852 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
2854 // Complete the pending request.
2855 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2856 resolver
.pending_requests()[0]->CompleteNow(OK
);
2858 // Wait for completion callback, and verify that the request ran as expected.
2859 EXPECT_EQ(OK
, callback1
.WaitForResult());
2860 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2862 // At this point we have initialized the proxy service using a PAC script.
2864 // A background task to periodically re-check the PAC script for validity will
2865 // have been started. We will now wait for the next download attempt to start.
2867 // Note that we shouldn't have to wait long here, since our test enables a
2868 // special unit-test mode.
2869 fetcher
->WaitUntilFetch();
2871 ASSERT_TRUE(factory
->pending_requests().empty());
2872 ASSERT_TRUE(resolver
.pending_requests().empty());
2874 // Make sure that our background checker is trying to download the expected
2875 // PAC script (same one as before). This time we will simulate a successful
2876 // download of a DIFFERENT script.
2877 EXPECT_TRUE(fetcher
->has_pending_request());
2878 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2879 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript2
);
2881 base::MessageLoop::current()->RunUntilIdle();
2883 // Now that the PAC script is downloaded, it should be used to initialize the
2884 // ProxyResolver. Simulate a successful parse.
2885 EXPECT_EQ(ASCIIToUTF16(kValidPacScript2
),
2886 factory
->pending_requests()[0]->script_data()->utf16());
2887 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2889 // At this point the ProxyService should have re-configured itself to use the
2892 // Start a second request.
2894 TestCompletionCallback callback2
;
2895 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
2896 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2897 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2899 // Check that it was sent to the resolver.
2900 ASSERT_EQ(1u, resolver
.pending_requests().size());
2901 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[0]->url());
2903 // Complete the pending second request.
2904 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2905 resolver
.pending_requests()[0]->CompleteNow(OK
);
2907 // Wait for completion callback, and verify that the request ran as expected.
2908 EXPECT_EQ(OK
, callback2
.WaitForResult());
2909 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2912 // This test verifies that the PAC script specified by the settings is
2913 // periodically polled for changes. Specifically, if the initial fetch succeeds
2914 // and so does the next poll, however the contents of the downloaded script
2915 // have NOT changed, then we do not bother to re-initialize the proxy resolver.
2916 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterContentUnchanged
) {
2917 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2919 ImmediatePollPolicy poll_policy
;
2920 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2922 MockProxyConfigService
* config_service
=
2923 new MockProxyConfigService("http://foopy/proxy.pac");
2925 MockAsyncProxyResolver resolver
;
2926 MockAsyncProxyResolverFactory
* factory
=
2927 new MockAsyncProxyResolverFactory(true);
2929 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2931 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2932 service
.SetProxyScriptFetchers(
2933 fetcher
, make_scoped_ptr(new DoNothingDhcpProxyScriptFetcher()));
2938 TestCompletionCallback callback1
;
2940 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
2941 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2942 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2944 // The first request should have triggered initial download of PAC script.
2945 EXPECT_TRUE(fetcher
->has_pending_request());
2946 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2948 // Nothing has been sent to the factory yet.
2949 EXPECT_TRUE(factory
->pending_requests().empty());
2951 // At this point the ProxyService should be waiting for the
2952 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2953 // PAC script download completion.
2954 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2956 // Now that the PAC script is downloaded, the request will have been sent to
2957 // the proxy resolver.
2958 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2959 factory
->pending_requests()[0]->script_data()->utf16());
2960 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2962 ASSERT_EQ(1u, resolver
.pending_requests().size());
2963 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
2965 // Complete the pending request.
2966 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2967 resolver
.pending_requests()[0]->CompleteNow(OK
);
2969 // Wait for completion callback, and verify that the request ran as expected.
2970 EXPECT_EQ(OK
, callback1
.WaitForResult());
2971 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2973 // At this point we have initialized the proxy service using a PAC script.
2975 // A background task to periodically re-check the PAC script for validity will
2976 // have been started. We will now wait for the next download attempt to start.
2978 // Note that we shouldn't have to wait long here, since our test enables a
2979 // special unit-test mode.
2980 fetcher
->WaitUntilFetch();
2982 ASSERT_TRUE(factory
->pending_requests().empty());
2983 ASSERT_TRUE(resolver
.pending_requests().empty());
2985 // Make sure that our background checker is trying to download the expected
2986 // PAC script (same one as before). We will simulate the same response as
2987 // last time (i.e. the script is unchanged).
2988 EXPECT_TRUE(fetcher
->has_pending_request());
2989 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2990 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2992 base::MessageLoop::current()->RunUntilIdle();
2994 ASSERT_TRUE(factory
->pending_requests().empty());
2995 ASSERT_TRUE(resolver
.pending_requests().empty());
2997 // At this point the ProxyService is still running the same PAC script as
3000 // Start a second request.
3002 TestCompletionCallback callback2
;
3003 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
3004 callback2
.callback(), NULL
, NULL
, BoundNetLog());
3005 EXPECT_EQ(ERR_IO_PENDING
, rv
);
3007 // Check that it was sent to the resolver.
3008 ASSERT_EQ(1u, resolver
.pending_requests().size());
3009 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[0]->url());
3011 // Complete the pending second request.
3012 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
3013 resolver
.pending_requests()[0]->CompleteNow(OK
);
3015 // Wait for completion callback, and verify that the request ran as expected.
3016 EXPECT_EQ(OK
, callback2
.WaitForResult());
3017 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
3020 // This test verifies that the PAC script specified by the settings is
3021 // periodically polled for changes. Specifically, if the initial fetch succeeds,
3022 // however at a later time it starts to fail, we should re-configure the
3023 // ProxyService to stop using that PAC script.
3024 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterSuccess
) {
3025 // Change the retry policy to wait a mere 1 ms before retrying, so the test
3027 ImmediatePollPolicy poll_policy
;
3028 ProxyService::set_pac_script_poll_policy(&poll_policy
);
3030 MockProxyConfigService
* config_service
=
3031 new MockProxyConfigService("http://foopy/proxy.pac");
3033 MockAsyncProxyResolver resolver
;
3034 MockAsyncProxyResolverFactory
* factory
=
3035 new MockAsyncProxyResolverFactory(true);
3037 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
3039 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
3040 service
.SetProxyScriptFetchers(
3041 fetcher
, make_scoped_ptr(new DoNothingDhcpProxyScriptFetcher()));
3046 TestCompletionCallback callback1
;
3048 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
3049 callback1
.callback(), NULL
, NULL
, BoundNetLog());
3050 EXPECT_EQ(ERR_IO_PENDING
, rv
);
3052 // The first request should have triggered initial download of PAC script.
3053 EXPECT_TRUE(fetcher
->has_pending_request());
3054 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
3056 // Nothing has been sent to the factory yet.
3057 EXPECT_TRUE(factory
->pending_requests().empty());
3059 // At this point the ProxyService should be waiting for the
3060 // ProxyScriptFetcher to invoke its completion callback, notifying it of
3061 // PAC script download completion.
3062 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
3064 // Now that the PAC script is downloaded, the request will have been sent to
3065 // the proxy resolver.
3066 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
3067 factory
->pending_requests()[0]->script_data()->utf16());
3068 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
3070 ASSERT_EQ(1u, resolver
.pending_requests().size());
3071 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
3073 // Complete the pending request.
3074 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
3075 resolver
.pending_requests()[0]->CompleteNow(OK
);
3077 // Wait for completion callback, and verify that the request ran as expected.
3078 EXPECT_EQ(OK
, callback1
.WaitForResult());
3079 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
3081 // At this point we have initialized the proxy service using a PAC script.
3083 // A background task to periodically re-check the PAC script for validity will
3084 // have been started. We will now wait for the next download attempt to start.
3086 // Note that we shouldn't have to wait long here, since our test enables a
3087 // special unit-test mode.
3088 fetcher
->WaitUntilFetch();
3090 ASSERT_TRUE(factory
->pending_requests().empty());
3091 ASSERT_TRUE(resolver
.pending_requests().empty());
3093 // Make sure that our background checker is trying to download the expected
3094 // PAC script (same one as before). This time we will simulate a failure
3095 // to download the script.
3096 EXPECT_TRUE(fetcher
->has_pending_request());
3097 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
3098 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
3100 base::MessageLoop::current()->RunUntilIdle();
3102 // At this point the ProxyService should have re-configured itself to use
3103 // DIRECT connections rather than the given proxy resolver.
3105 // Start a second request.
3107 TestCompletionCallback callback2
;
3108 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
3109 callback2
.callback(), NULL
, NULL
, BoundNetLog());
3111 EXPECT_TRUE(info2
.is_direct());
3114 // Tests that the code which decides at what times to poll the PAC
3115 // script follows the expected policy.
3116 TEST_F(ProxyServiceTest
, PACScriptPollingPolicy
) {
3117 // Retrieve the internal polling policy implementation used by ProxyService.
3118 scoped_ptr
<ProxyService::PacPollPolicy
> policy
=
3119 ProxyService::CreateDefaultPacPollPolicy();
3122 ProxyService::PacPollPolicy::Mode mode
;
3123 const base::TimeDelta initial_delay
= base::TimeDelta::FromMilliseconds(-1);
3124 base::TimeDelta delay
= initial_delay
;
3126 // --------------------------------------------------
3127 // Test the poll sequence in response to a failure.
3128 // --------------------------------------------------
3129 error
= ERR_NAME_NOT_RESOLVED
;
3132 mode
= policy
->GetNextDelay(error
, initial_delay
, &delay
);
3133 EXPECT_EQ(8, delay
.InSeconds());
3134 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_USE_TIMER
, mode
);
3137 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
3138 EXPECT_EQ(32, delay
.InSeconds());
3139 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3142 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
3143 EXPECT_EQ(120, delay
.InSeconds());
3144 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3147 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
3148 EXPECT_EQ(14400, delay
.InSeconds());
3149 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3152 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
3153 EXPECT_EQ(14400, delay
.InSeconds());
3154 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3156 // --------------------------------------------------
3157 // Test the poll sequence in response to a success.
3158 // --------------------------------------------------
3162 mode
= policy
->GetNextDelay(error
, initial_delay
, &delay
);
3163 EXPECT_EQ(43200, delay
.InSeconds());
3164 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3167 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
3168 EXPECT_EQ(43200, delay
.InSeconds());
3169 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3172 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
3173 EXPECT_EQ(43200, delay
.InSeconds());
3174 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3177 // This tests the polling of the PAC script. Specifically, it tests that
3178 // polling occurs in response to user activity.
3179 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterActivity
) {
3180 ImmediateAfterActivityPollPolicy poll_policy
;
3181 ProxyService::set_pac_script_poll_policy(&poll_policy
);
3183 MockProxyConfigService
* config_service
=
3184 new MockProxyConfigService("http://foopy/proxy.pac");
3186 MockAsyncProxyResolver resolver
;
3187 MockAsyncProxyResolverFactory
* factory
=
3188 new MockAsyncProxyResolverFactory(true);
3190 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
3192 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
3193 service
.SetProxyScriptFetchers(
3194 fetcher
, make_scoped_ptr(new DoNothingDhcpProxyScriptFetcher()));
3199 TestCompletionCallback callback1
;
3201 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
3202 callback1
.callback(), NULL
, NULL
, BoundNetLog());
3203 EXPECT_EQ(ERR_IO_PENDING
, rv
);
3205 // The first request should have triggered initial download of PAC script.
3206 EXPECT_TRUE(fetcher
->has_pending_request());
3207 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
3209 // Nothing has been sent to the factory yet.
3210 EXPECT_TRUE(factory
->pending_requests().empty());
3212 // At this point the ProxyService should be waiting for the
3213 // ProxyScriptFetcher to invoke its completion callback, notifying it of
3214 // PAC script download completion.
3215 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
3217 // Now that the PAC script is downloaded, the request will have been sent to
3218 // the proxy resolver.
3219 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
3220 factory
->pending_requests()[0]->script_data()->utf16());
3221 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
3223 ASSERT_EQ(1u, resolver
.pending_requests().size());
3224 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
3226 // Complete the pending request.
3227 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
3228 resolver
.pending_requests()[0]->CompleteNow(OK
);
3230 // Wait for completion callback, and verify that the request ran as expected.
3231 EXPECT_EQ(OK
, callback1
.WaitForResult());
3232 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
3234 // At this point we have initialized the proxy service using a PAC script.
3235 // Our PAC poller is set to update ONLY in response to network activity,
3236 // (i.e. another call to ResolveProxy()).
3238 ASSERT_FALSE(fetcher
->has_pending_request());
3239 ASSERT_TRUE(factory
->pending_requests().empty());
3240 ASSERT_TRUE(resolver
.pending_requests().empty());
3242 // Start a second request.
3244 TestCompletionCallback callback2
;
3245 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
3246 callback2
.callback(), NULL
, NULL
, BoundNetLog());
3247 EXPECT_EQ(ERR_IO_PENDING
, rv
);
3249 // This request should have sent work to the resolver; complete it.
3250 ASSERT_EQ(1u, resolver
.pending_requests().size());
3251 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[0]->url());
3252 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
3253 resolver
.pending_requests()[0]->CompleteNow(OK
);
3255 EXPECT_EQ(OK
, callback2
.WaitForResult());
3256 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
3258 // In response to getting that resolve request, the poller should have
3259 // started the next poll, and made it as far as to request the download.
3261 EXPECT_TRUE(fetcher
->has_pending_request());
3262 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
3264 // This time we will fail the download, to simulate a PAC script change.
3265 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
3267 // Drain the message loop, so ProxyService is notified of the change
3268 // and has a chance to re-configure itself.
3269 base::MessageLoop::current()->RunUntilIdle();
3271 // Start a third request -- this time we expect to get a direct connection
3272 // since the PAC script poller experienced a failure.
3274 TestCompletionCallback callback3
;
3275 rv
= service
.ResolveProxy(GURL("http://request3"), LOAD_NORMAL
, &info3
,
3276 callback3
.callback(), NULL
, NULL
, BoundNetLog());
3278 EXPECT_TRUE(info3
.is_direct());
3281 // Test that the synchronous resolution fails when a PAC script is active.
3282 TEST_F(ProxyServiceTest
, SynchronousWithPAC
) {
3283 MockProxyConfigService
* config_service
=
3284 new MockProxyConfigService("http://foopy/proxy.pac");
3286 MockAsyncProxyResolverFactory
* factory
=
3287 new MockAsyncProxyResolverFactory(false);
3289 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
3291 GURL
url("http://www.google.com/");
3295 BoundTestNetLog log
;
3297 bool synchronous_success
= service
.TryResolveProxySynchronously(
3298 url
, LOAD_NORMAL
, &info
, NULL
, log
.bound());
3299 EXPECT_FALSE(synchronous_success
);
3301 // |info| should not have been modified.
3302 EXPECT_TRUE(info
.is_direct());
3305 // Test that synchronous results are returned correctly if a fixed proxy
3306 // configuration is active.
3307 TEST_F(ProxyServiceTest
, SynchronousWithFixedConfiguration
) {
3309 config
.proxy_rules().ParseFromString("foopy1:8080");
3310 config
.set_auto_detect(false);
3312 MockAsyncProxyResolverFactory
* factory
=
3313 new MockAsyncProxyResolverFactory(false);
3315 ProxyService
service(new MockProxyConfigService(config
),
3316 make_scoped_ptr(factory
), NULL
);
3318 GURL
url("http://www.google.com/");
3321 BoundTestNetLog log
;
3323 bool synchronous_success
= service
.TryResolveProxySynchronously(
3324 url
, LOAD_NORMAL
, &info
, NULL
, log
.bound());
3325 EXPECT_TRUE(synchronous_success
);
3326 EXPECT_FALSE(info
.is_direct());
3327 EXPECT_EQ("foopy1", info
.proxy_server().host_port_pair().host());
3329 // No request should have been queued.
3330 EXPECT_EQ(0u, factory
->pending_requests().size());