1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/proxy/proxy_service.h"
9 #include "base/format_macros.h"
10 #include "base/logging.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "net/base/load_flags.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/net_log.h"
16 #include "net/base/net_log_unittest.h"
17 #include "net/base/network_delegate_impl.h"
18 #include "net/base/test_completion_callback.h"
19 #include "net/proxy/dhcp_proxy_script_fetcher.h"
20 #include "net/proxy/mock_proxy_resolver.h"
21 #include "net/proxy/mock_proxy_script_fetcher.h"
22 #include "net/proxy/proxy_config_service.h"
23 #include "net/proxy/proxy_resolver.h"
24 #include "net/proxy/proxy_script_fetcher.h"
25 #include "testing/gtest/include/gtest/gtest.h"
28 using base::ASCIIToUTF16
;
30 // TODO(eroman): Write a test which exercises
31 // ProxyService::SuspendAllPendingRequests().
35 // This polling policy will decide to poll every 1 ms.
36 class ImmediatePollPolicy
: public ProxyService::PacPollPolicy
{
38 ImmediatePollPolicy() {}
40 Mode
GetNextDelay(int error
,
41 base::TimeDelta current_delay
,
42 base::TimeDelta
* next_delay
) const override
{
43 *next_delay
= base::TimeDelta::FromMilliseconds(1);
44 return MODE_USE_TIMER
;
48 DISALLOW_COPY_AND_ASSIGN(ImmediatePollPolicy
);
51 // This polling policy chooses a fantastically large delay. In other words, it
52 // will never trigger a poll
53 class NeverPollPolicy
: public ProxyService::PacPollPolicy
{
57 Mode
GetNextDelay(int error
,
58 base::TimeDelta current_delay
,
59 base::TimeDelta
* next_delay
) const override
{
60 *next_delay
= base::TimeDelta::FromDays(60);
61 return MODE_USE_TIMER
;
65 DISALLOW_COPY_AND_ASSIGN(NeverPollPolicy
);
68 // This polling policy starts a poll immediately after network activity.
69 class ImmediateAfterActivityPollPolicy
: public ProxyService::PacPollPolicy
{
71 ImmediateAfterActivityPollPolicy() {}
73 Mode
GetNextDelay(int error
,
74 base::TimeDelta current_delay
,
75 base::TimeDelta
* next_delay
) const override
{
76 *next_delay
= base::TimeDelta();
77 return MODE_START_AFTER_ACTIVITY
;
81 DISALLOW_COPY_AND_ASSIGN(ImmediateAfterActivityPollPolicy
);
84 // This test fixture is used to partially disable the background polling done by
85 // the ProxyService (which it uses to detect whenever its PAC script contents or
86 // WPAD results have changed).
88 // We disable the feature by setting the poll interval to something really
89 // large, so it will never actually be reached even on the slowest bots that run
92 // We disable the polling in order to avoid any timing dependencies in the
93 // tests. If the bot were to run the tests very slowly and we hadn't disabled
94 // polling, then it might start a background re-try in the middle of our test
95 // and confuse our expectations leading to flaky failures.
97 // The tests which verify the polling code re-enable the polling behavior but
98 // are careful to avoid timing problems.
99 class ProxyServiceTest
: public testing::Test
{
101 void SetUp() override
{
102 testing::Test::SetUp();
104 ProxyService::set_pac_script_poll_policy(&never_poll_policy_
);
107 void TearDown() override
{
108 // Restore the original policy.
109 ProxyService::set_pac_script_poll_policy(previous_policy_
);
110 testing::Test::TearDown();
114 NeverPollPolicy never_poll_policy_
;
115 const ProxyService::PacPollPolicy
* previous_policy_
;
118 const char kValidPacScript1
[] = "pac-script-v1-FindProxyForURL";
119 const char kValidPacScript2
[] = "pac-script-v2-FindProxyForURL";
121 class MockProxyConfigService
: public ProxyConfigService
{
123 explicit MockProxyConfigService(const ProxyConfig
& config
)
124 : availability_(CONFIG_VALID
),
128 explicit MockProxyConfigService(const std::string
& pac_url
)
129 : availability_(CONFIG_VALID
),
130 config_(ProxyConfig::CreateFromCustomPacURL(GURL(pac_url
))) {
133 void AddObserver(Observer
* observer
) override
{
134 observers_
.AddObserver(observer
);
137 void RemoveObserver(Observer
* observer
) override
{
138 observers_
.RemoveObserver(observer
);
141 ConfigAvailability
GetLatestProxyConfig(ProxyConfig
* results
) override
{
142 if (availability_
== CONFIG_VALID
)
144 return availability_
;
147 void SetConfig(const ProxyConfig
& config
) {
148 availability_
= CONFIG_VALID
;
150 FOR_EACH_OBSERVER(Observer
, observers_
,
151 OnProxyConfigChanged(config_
, availability_
));
155 ConfigAvailability availability_
;
157 ObserverList
<Observer
, true> observers_
;
160 // A test network delegate that exercises the OnResolveProxy callback.
161 class TestResolveProxyNetworkDelegate
: public NetworkDelegateImpl
{
163 TestResolveProxyNetworkDelegate()
164 : on_resolve_proxy_called_(false),
166 remove_proxy_(false),
167 proxy_service_(NULL
) {
170 void OnResolveProxy(const GURL
& url
,
172 const ProxyService
& proxy_service
,
173 ProxyInfo
* result
) override
{
174 on_resolve_proxy_called_
= true;
175 proxy_service_
= &proxy_service
;
176 DCHECK(!add_proxy_
|| !remove_proxy_
);
178 result
->UseNamedProxy("delegate_proxy.com");
179 } else if (remove_proxy_
) {
184 bool on_resolve_proxy_called() const {
185 return on_resolve_proxy_called_
;
188 void set_add_proxy(bool add_proxy
) {
189 add_proxy_
= add_proxy
;
192 void set_remove_proxy(bool remove_proxy
) {
193 remove_proxy_
= remove_proxy
;
196 const ProxyService
* proxy_service() const {
197 return proxy_service_
;
201 bool on_resolve_proxy_called_
;
204 const ProxyService
* proxy_service_
;
207 // A test network delegate that exercises the OnProxyFallback callback.
208 class TestProxyFallbackNetworkDelegate
: public NetworkDelegateImpl
{
210 TestProxyFallbackNetworkDelegate()
211 : on_proxy_fallback_called_(false),
212 proxy_fallback_net_error_(OK
) {
215 void OnProxyFallback(const ProxyServer
& proxy_server
,
216 int net_error
) override
{
217 proxy_server_
= proxy_server
;
218 proxy_fallback_net_error_
= net_error
;
219 on_proxy_fallback_called_
= true;
222 bool on_proxy_fallback_called() const {
223 return on_proxy_fallback_called_
;
226 const ProxyServer
& proxy_server() const {
227 return proxy_server_
;
230 int proxy_fallback_net_error() const {
231 return proxy_fallback_net_error_
;
235 bool on_proxy_fallback_called_
;
236 ProxyServer proxy_server_
;
237 int proxy_fallback_net_error_
;
242 TEST_F(ProxyServiceTest
, Direct
) {
243 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
244 ProxyService
service(new MockProxyConfigService(
245 ProxyConfig::CreateDirect()), resolver
, NULL
);
247 GURL
url("http://www.google.com/");
250 TestCompletionCallback callback
;
251 CapturingBoundNetLog log
;
252 int rv
= service
.ResolveProxy(
253 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
256 EXPECT_TRUE(resolver
->pending_requests().empty());
258 EXPECT_TRUE(info
.is_direct());
259 EXPECT_TRUE(info
.proxy_resolve_start_time().is_null());
260 EXPECT_TRUE(info
.proxy_resolve_end_time().is_null());
262 // Check the NetLog was filled correctly.
263 CapturingNetLog::CapturedEntryList entries
;
264 log
.GetEntries(&entries
);
266 EXPECT_EQ(3u, entries
.size());
267 EXPECT_TRUE(LogContainsBeginEvent(
268 entries
, 0, NetLog::TYPE_PROXY_SERVICE
));
269 EXPECT_TRUE(LogContainsEvent(
270 entries
, 1, NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST
,
271 NetLog::PHASE_NONE
));
272 EXPECT_TRUE(LogContainsEndEvent(
273 entries
, 2, NetLog::TYPE_PROXY_SERVICE
));
276 TEST_F(ProxyServiceTest
, OnResolveProxyCallbackAddProxy
) {
278 config
.proxy_rules().ParseFromString("foopy1:8080");
279 config
.set_auto_detect(false);
280 config
.proxy_rules().bypass_rules
.ParseFromString("*.org");
282 ProxyService
service(
283 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
285 GURL
url("http://www.google.com/");
286 GURL
bypass_url("http://internet.org");
289 TestCompletionCallback callback
;
290 CapturingBoundNetLog log
;
292 // First, warm up the ProxyService.
293 int rv
= service
.ResolveProxy(
294 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
298 // Verify that network delegate is invoked.
299 TestResolveProxyNetworkDelegate delegate
;
300 rv
= service
.ResolveProxy(
301 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
303 EXPECT_TRUE(delegate
.on_resolve_proxy_called());
304 EXPECT_EQ(&service
, delegate
.proxy_service());
306 // Verify that the NetworkDelegate's behavior is stateless across
307 // invocations of ResolveProxy. Start by having the callback add a proxy
308 // and checking that subsequent requests are not affected.
309 delegate
.set_add_proxy(true);
311 // Callback should interpose:
312 rv
= service
.ResolveProxy(
313 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
315 EXPECT_FALSE(info
.is_direct());
316 EXPECT_EQ(info
.proxy_server().host_port_pair().host(), "delegate_proxy.com");
317 delegate
.set_add_proxy(false);
319 // Check non-bypassed URL:
320 rv
= service
.ResolveProxy(
321 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
323 EXPECT_FALSE(info
.is_direct());
324 EXPECT_EQ(info
.proxy_server().host_port_pair().host(), "foopy1");
326 // Check bypassed URL:
327 rv
= service
.ResolveProxy(
328 bypass_url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
,
329 &delegate
, log
.bound());
330 EXPECT_TRUE(info
.is_direct());
333 TEST_F(ProxyServiceTest
, OnResolveProxyCallbackRemoveProxy
) {
334 // Same as OnResolveProxyCallbackAddProxy, but verify that the
335 // NetworkDelegate's behavior is stateless across invocations after it
336 // *removes* a proxy.
338 config
.proxy_rules().ParseFromString("foopy1:8080");
339 config
.set_auto_detect(false);
340 config
.proxy_rules().bypass_rules
.ParseFromString("*.org");
342 ProxyService
service(
343 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
345 GURL
url("http://www.google.com/");
346 GURL
bypass_url("http://internet.org");
349 TestCompletionCallback callback
;
350 CapturingBoundNetLog log
;
352 // First, warm up the ProxyService.
353 int rv
= service
.ResolveProxy(
354 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
358 TestResolveProxyNetworkDelegate delegate
;
359 delegate
.set_remove_proxy(true);
361 // Callback should interpose:
362 rv
= service
.ResolveProxy(
363 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
365 EXPECT_TRUE(info
.is_direct());
366 delegate
.set_remove_proxy(false);
368 // Check non-bypassed URL:
369 rv
= service
.ResolveProxy(
370 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
372 EXPECT_FALSE(info
.is_direct());
373 EXPECT_EQ(info
.proxy_server().host_port_pair().host(), "foopy1");
375 // Check bypassed URL:
376 rv
= service
.ResolveProxy(
377 bypass_url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
,
378 &delegate
, log
.bound());
379 EXPECT_TRUE(info
.is_direct());
382 TEST_F(ProxyServiceTest
, PAC
) {
383 MockProxyConfigService
* config_service
=
384 new MockProxyConfigService("http://foopy/proxy.pac");
386 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
388 ProxyService
service(config_service
, resolver
, NULL
);
390 GURL
url("http://www.google.com/");
393 TestCompletionCallback callback
;
394 ProxyService::PacRequest
* request
;
395 CapturingBoundNetLog log
;
397 int rv
= service
.ResolveProxy(
398 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), &request
, NULL
,
400 EXPECT_EQ(ERR_IO_PENDING
, rv
);
402 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request
));
404 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
405 resolver
->pending_set_pac_script_request()->script_data()->url());
406 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
408 ASSERT_EQ(1u, resolver
->pending_requests().size());
409 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
411 // Set the result in proxy resolver.
412 resolver
->pending_requests()[0]->results()->UseNamedProxy("foopy");
413 resolver
->pending_requests()[0]->CompleteNow(OK
);
415 EXPECT_EQ(OK
, callback
.WaitForResult());
416 EXPECT_FALSE(info
.is_direct());
417 EXPECT_EQ("foopy:80", info
.proxy_server().ToURI());
418 EXPECT_TRUE(info
.did_use_pac_script());
420 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
421 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
422 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
424 // Check the NetLog was filled correctly.
425 CapturingNetLog::CapturedEntryList entries
;
426 log
.GetEntries(&entries
);
428 EXPECT_EQ(5u, entries
.size());
429 EXPECT_TRUE(LogContainsBeginEvent(
430 entries
, 0, NetLog::TYPE_PROXY_SERVICE
));
431 EXPECT_TRUE(LogContainsBeginEvent(
432 entries
, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
433 EXPECT_TRUE(LogContainsEndEvent(
434 entries
, 2, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
435 EXPECT_TRUE(LogContainsEndEvent(
436 entries
, 4, NetLog::TYPE_PROXY_SERVICE
));
439 // Test that the proxy resolver does not see the URL's username/password
440 // or its reference section.
441 TEST_F(ProxyServiceTest
, PAC_NoIdentityOrHash
) {
442 MockProxyConfigService
* config_service
=
443 new MockProxyConfigService("http://foopy/proxy.pac");
445 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
447 ProxyService
service(config_service
, resolver
, NULL
);
449 GURL
url("http://username:password@www.google.com/?ref#hash#hash");
452 TestCompletionCallback callback
;
453 int rv
= service
.ResolveProxy(
454 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
456 EXPECT_EQ(ERR_IO_PENDING
, rv
);
458 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
459 resolver
->pending_set_pac_script_request()->script_data()->url());
460 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
462 ASSERT_EQ(1u, resolver
->pending_requests().size());
463 // The URL should have been simplified, stripping the username/password/hash.
464 EXPECT_EQ(GURL("http://www.google.com/?ref"),
465 resolver
->pending_requests()[0]->url());
467 // We end here without ever completing the request -- destruction of
468 // ProxyService will cancel the outstanding request.
471 TEST_F(ProxyServiceTest
, PAC_FailoverWithoutDirect
) {
472 MockProxyConfigService
* config_service
=
473 new MockProxyConfigService("http://foopy/proxy.pac");
474 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
476 ProxyService
service(config_service
, resolver
, NULL
);
478 GURL
url("http://www.google.com/");
481 TestCompletionCallback callback1
;
482 int rv
= service
.ResolveProxy(
483 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
485 EXPECT_EQ(ERR_IO_PENDING
, rv
);
487 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
488 resolver
->pending_set_pac_script_request()->script_data()->url());
489 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
491 ASSERT_EQ(1u, resolver
->pending_requests().size());
492 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
494 // Set the result in proxy resolver.
495 resolver
->pending_requests()[0]->results()->UseNamedProxy("foopy:8080");
496 resolver
->pending_requests()[0]->CompleteNow(OK
);
498 EXPECT_EQ(OK
, callback1
.WaitForResult());
499 EXPECT_FALSE(info
.is_direct());
500 EXPECT_EQ("foopy:8080", info
.proxy_server().ToURI());
501 EXPECT_TRUE(info
.did_use_pac_script());
503 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
504 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
505 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
507 // Now, imagine that connecting to foopy:8080 fails: there is nothing
508 // left to fallback to, since our proxy list was NOT terminated by
510 NetworkDelegateImpl network_delegate
;
511 TestCompletionCallback callback2
;
512 ProxyServer expected_proxy_server
= info
.proxy_server();
513 rv
= service
.ReconsiderProxyAfterError(
514 url
, net::LOAD_NORMAL
, net::ERR_PROXY_CONNECTION_FAILED
,
515 &info
, callback2
.callback(), NULL
, &network_delegate
, BoundNetLog());
516 // ReconsiderProxyAfterError returns error indicating nothing left.
517 EXPECT_EQ(ERR_FAILED
, rv
);
518 EXPECT_TRUE(info
.is_empty());
521 // Test that if the execution of the PAC script fails (i.e. javascript runtime
522 // error), and the PAC settings are non-mandatory, that we fall-back to direct.
523 TEST_F(ProxyServiceTest
, PAC_RuntimeError
) {
524 MockProxyConfigService
* config_service
=
525 new MockProxyConfigService("http://foopy/proxy.pac");
526 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
528 ProxyService
service(config_service
, resolver
, NULL
);
530 GURL
url("http://this-causes-js-error/");
533 TestCompletionCallback callback1
;
534 int rv
= service
.ResolveProxy(
535 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
537 EXPECT_EQ(ERR_IO_PENDING
, rv
);
539 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
540 resolver
->pending_set_pac_script_request()->script_data()->url());
541 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
543 ASSERT_EQ(1u, resolver
->pending_requests().size());
544 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
546 // Simulate a failure in the PAC executor.
547 resolver
->pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_FAILED
);
549 EXPECT_EQ(OK
, callback1
.WaitForResult());
551 // Since the PAC script was non-mandatory, we should have fallen-back to
553 EXPECT_TRUE(info
.is_direct());
554 EXPECT_TRUE(info
.did_use_pac_script());
555 EXPECT_EQ(1, info
.config_id());
557 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
558 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
559 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
562 // The proxy list could potentially contain the DIRECT fallback choice
563 // in a location other than the very end of the list, and could even
564 // specify it multiple times.
566 // This is not a typical usage, but we will obey it.
567 // (If we wanted to disallow this type of input, the right place to
568 // enforce it would be in parsing the PAC result string).
570 // This test will use the PAC result string:
572 // "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20"
574 // For which we expect it to try DIRECT, then foobar:10, then DIRECT again,
575 // then foobar:20, and then give up and error.
577 // The important check of this test is to make sure that DIRECT is not somehow
578 // cached as being a bad proxy.
579 TEST_F(ProxyServiceTest
, PAC_FailoverAfterDirect
) {
580 MockProxyConfigService
* config_service
=
581 new MockProxyConfigService("http://foopy/proxy.pac");
582 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
584 ProxyService
service(config_service
, resolver
, NULL
);
586 GURL
url("http://www.google.com/");
589 TestCompletionCallback callback1
;
590 int rv
= service
.ResolveProxy(
591 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
593 EXPECT_EQ(ERR_IO_PENDING
, rv
);
595 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
596 resolver
->pending_set_pac_script_request()->script_data()->url());
597 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
599 ASSERT_EQ(1u, resolver
->pending_requests().size());
600 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
602 // Set the result in proxy resolver.
603 resolver
->pending_requests()[0]->results()->UsePacString(
604 "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20");
605 resolver
->pending_requests()[0]->CompleteNow(OK
);
607 EXPECT_EQ(OK
, callback1
.WaitForResult());
608 EXPECT_TRUE(info
.is_direct());
611 TestCompletionCallback callback2
;
612 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
613 net::ERR_PROXY_CONNECTION_FAILED
,
614 &info
, callback2
.callback(), NULL
,
615 NULL
, BoundNetLog());
617 EXPECT_FALSE(info
.is_direct());
618 EXPECT_EQ("foobar:10", info
.proxy_server().ToURI());
621 NetworkDelegateImpl network_delegate
;
622 ProxyServer expected_proxy_server3
= info
.proxy_server();
623 TestCompletionCallback callback3
;
624 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
625 net::ERR_PROXY_CONNECTION_FAILED
,
626 &info
, callback3
.callback(), NULL
,
627 &network_delegate
, BoundNetLog());
629 EXPECT_TRUE(info
.is_direct());
632 ProxyServer expected_proxy_server4
= info
.proxy_server();
633 TestCompletionCallback callback4
;
634 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
635 net::ERR_PROXY_CONNECTION_FAILED
,
636 &info
, callback4
.callback(), NULL
,
637 &network_delegate
, BoundNetLog());
639 EXPECT_FALSE(info
.is_direct());
640 EXPECT_EQ("foobar:20", info
.proxy_server().ToURI());
642 // Fallback 4 -- Nothing to fall back to!
643 ProxyServer expected_proxy_server5
= info
.proxy_server();
644 TestCompletionCallback callback5
;
645 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
646 net::ERR_PROXY_CONNECTION_FAILED
,
647 &info
, callback5
.callback(), NULL
,
648 &network_delegate
, BoundNetLog());
649 EXPECT_EQ(ERR_FAILED
, rv
);
650 EXPECT_TRUE(info
.is_empty());
653 TEST_F(ProxyServiceTest
, PAC_ConfigSourcePropagates
) {
654 // Test whether the ProxyConfigSource set by the ProxyConfigService is applied
655 // to ProxyInfo after the proxy is resolved via a PAC script.
657 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
658 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
660 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
661 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
662 ProxyService
service(config_service
, resolver
, NULL
);
664 // Resolve something.
665 GURL
url("http://www.google.com/");
667 TestCompletionCallback callback
;
668 int rv
= service
.ResolveProxy(
669 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
671 ASSERT_EQ(ERR_IO_PENDING
, rv
);
672 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
673 ASSERT_EQ(1u, resolver
->pending_requests().size());
675 // Set the result in proxy resolver.
676 resolver
->pending_requests()[0]->results()->UseNamedProxy("foopy");
677 resolver
->pending_requests()[0]->CompleteNow(OK
);
679 EXPECT_EQ(OK
, callback
.WaitForResult());
680 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
681 EXPECT_TRUE(info
.did_use_pac_script());
683 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
684 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
685 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
688 TEST_F(ProxyServiceTest
, ProxyResolverFails
) {
689 // Test what happens when the ProxyResolver fails. The download and setting
690 // of the PAC script have already succeeded, so this corresponds with a
691 // javascript runtime error while calling FindProxyForURL().
693 MockProxyConfigService
* config_service
=
694 new MockProxyConfigService("http://foopy/proxy.pac");
696 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
698 ProxyService
service(config_service
, resolver
, NULL
);
700 // Start first resolve request.
701 GURL
url("http://www.google.com/");
703 TestCompletionCallback callback1
;
704 int rv
= service
.ResolveProxy(
705 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
707 EXPECT_EQ(ERR_IO_PENDING
, rv
);
709 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
710 resolver
->pending_set_pac_script_request()->script_data()->url());
711 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
713 ASSERT_EQ(1u, resolver
->pending_requests().size());
714 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
716 // Fail the first resolve request in MockAsyncProxyResolver.
717 resolver
->pending_requests()[0]->CompleteNow(ERR_FAILED
);
719 // Although the proxy resolver failed the request, ProxyService implicitly
720 // falls-back to DIRECT.
721 EXPECT_EQ(OK
, callback1
.WaitForResult());
722 EXPECT_TRUE(info
.is_direct());
724 // Failed PAC executions still have proxy resolution times.
725 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
726 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
727 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
729 // The second resolve request will try to run through the proxy resolver,
730 // regardless of whether the first request failed in it.
731 TestCompletionCallback callback2
;
732 rv
= service
.ResolveProxy(
733 url
, net::LOAD_NORMAL
, &info
, callback2
.callback(), NULL
, NULL
,
735 EXPECT_EQ(ERR_IO_PENDING
, rv
);
737 ASSERT_EQ(1u, resolver
->pending_requests().size());
738 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
740 // This time we will have the resolver succeed (perhaps the PAC script has
741 // a dependency on the current time).
742 resolver
->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
743 resolver
->pending_requests()[0]->CompleteNow(OK
);
745 EXPECT_EQ(OK
, callback2
.WaitForResult());
746 EXPECT_FALSE(info
.is_direct());
747 EXPECT_EQ("foopy_valid:8080", info
.proxy_server().ToURI());
750 TEST_F(ProxyServiceTest
, ProxyScriptFetcherFailsDownloadingMandatoryPac
) {
751 // Test what happens when the ProxyScriptResolver fails to download a
752 // mandatory PAC script.
755 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
756 config
.set_pac_mandatory(true);
758 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
760 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
762 ProxyService
service(config_service
, resolver
, NULL
);
764 // Start first resolve request.
765 GURL
url("http://www.google.com/");
767 TestCompletionCallback callback1
;
768 int rv
= service
.ResolveProxy(
769 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
771 EXPECT_EQ(ERR_IO_PENDING
, rv
);
773 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
774 resolver
->pending_set_pac_script_request()->script_data()->url());
775 resolver
->pending_set_pac_script_request()->CompleteNow(ERR_FAILED
);
777 ASSERT_EQ(0u, resolver
->pending_requests().size());
779 // As the proxy resolver failed the request and is configured for a mandatory
780 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
781 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
782 callback1
.WaitForResult());
783 EXPECT_FALSE(info
.is_direct());
785 // As the proxy resolver failed the request and is configured for a mandatory
786 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
787 TestCompletionCallback callback2
;
788 rv
= service
.ResolveProxy(
789 url
, net::LOAD_NORMAL
, &info
, callback2
.callback(), NULL
, NULL
,
791 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
, rv
);
792 EXPECT_FALSE(info
.is_direct());
795 TEST_F(ProxyServiceTest
, ProxyResolverFailsParsingJavaScriptMandatoryPac
) {
796 // Test what happens when the ProxyResolver fails that is configured to use a
797 // mandatory PAC script. The download of the PAC script has already
798 // succeeded but the PAC script contains no valid javascript.
801 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
802 config
.set_pac_mandatory(true);
804 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
806 MockAsyncProxyResolverExpectsBytes
* resolver
=
807 new MockAsyncProxyResolverExpectsBytes
;
809 ProxyService
service(config_service
, resolver
, NULL
);
811 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
812 DhcpProxyScriptFetcher
* dhcp_fetcher
= new DoNothingDhcpProxyScriptFetcher();
813 service
.SetProxyScriptFetchers(fetcher
, dhcp_fetcher
);
815 // Start resolve request.
816 GURL
url("http://www.google.com/");
818 TestCompletionCallback callback
;
819 int rv
= service
.ResolveProxy(
820 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
822 EXPECT_EQ(ERR_IO_PENDING
, rv
);
824 // Check that nothing has been sent to the proxy resolver yet.
825 ASSERT_EQ(0u, resolver
->pending_requests().size());
827 // Downloading the PAC script succeeds.
828 EXPECT_TRUE(fetcher
->has_pending_request());
829 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
830 fetcher
->NotifyFetchCompletion(OK
, "invalid-script-contents");
832 EXPECT_FALSE(fetcher
->has_pending_request());
833 ASSERT_EQ(0u, resolver
->pending_requests().size());
835 // Since ProxyScriptDecider failed to identify a valid PAC and PAC was
836 // mandatory for this configuration, the ProxyService must not implicitly
837 // fall-back to DIRECT.
838 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
839 callback
.WaitForResult());
840 EXPECT_FALSE(info
.is_direct());
843 TEST_F(ProxyServiceTest
, ProxyResolverFailsInJavaScriptMandatoryPac
) {
844 // Test what happens when the ProxyResolver fails that is configured to use a
845 // mandatory PAC script. The download and setting of the PAC script have
846 // already succeeded, so this corresponds with a javascript runtime error
847 // while calling FindProxyForURL().
850 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
851 config
.set_pac_mandatory(true);
853 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
855 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
857 ProxyService
service(config_service
, resolver
, NULL
);
859 // Start first resolve request.
860 GURL
url("http://www.google.com/");
862 TestCompletionCallback callback1
;
863 int rv
= service
.ResolveProxy(
864 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
866 EXPECT_EQ(ERR_IO_PENDING
, rv
);
868 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
869 resolver
->pending_set_pac_script_request()->script_data()->url());
870 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
872 ASSERT_EQ(1u, resolver
->pending_requests().size());
873 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
875 // Fail the first resolve request in MockAsyncProxyResolver.
876 resolver
->pending_requests()[0]->CompleteNow(ERR_FAILED
);
878 // As the proxy resolver failed the request and is configured for a mandatory
879 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
880 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
881 callback1
.WaitForResult());
882 EXPECT_FALSE(info
.is_direct());
884 // The second resolve request will try to run through the proxy resolver,
885 // regardless of whether the first request failed in it.
886 TestCompletionCallback callback2
;
887 rv
= service
.ResolveProxy(
888 url
, net::LOAD_NORMAL
, &info
, callback2
.callback(), NULL
, NULL
,
890 EXPECT_EQ(ERR_IO_PENDING
, rv
);
892 ASSERT_EQ(1u, resolver
->pending_requests().size());
893 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
895 // This time we will have the resolver succeed (perhaps the PAC script has
896 // a dependency on the current time).
897 resolver
->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
898 resolver
->pending_requests()[0]->CompleteNow(OK
);
900 EXPECT_EQ(OK
, callback2
.WaitForResult());
901 EXPECT_FALSE(info
.is_direct());
902 EXPECT_EQ("foopy_valid:8080", info
.proxy_server().ToURI());
905 TEST_F(ProxyServiceTest
, ProxyFallback
) {
906 // Test what happens when we specify multiple proxy servers and some of them
909 MockProxyConfigService
* config_service
=
910 new MockProxyConfigService("http://foopy/proxy.pac");
912 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
914 ProxyService
service(config_service
, resolver
, NULL
);
916 GURL
url("http://www.google.com/");
918 // Get the proxy information.
920 TestCompletionCallback callback1
;
921 int rv
= service
.ResolveProxy(
922 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
924 EXPECT_EQ(ERR_IO_PENDING
, rv
);
926 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
927 resolver
->pending_set_pac_script_request()->script_data()->url());
928 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
930 ASSERT_EQ(1u, resolver
->pending_requests().size());
931 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
933 // Set the result in proxy resolver.
934 resolver
->pending_requests()[0]->results()->UseNamedProxy(
935 "foopy1:8080;foopy2:9090");
936 resolver
->pending_requests()[0]->CompleteNow(OK
);
938 // The first item is valid.
939 EXPECT_EQ(OK
, callback1
.WaitForResult());
940 EXPECT_FALSE(info
.is_direct());
941 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
943 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
944 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
945 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
946 base::TimeTicks proxy_resolve_start_time
= info
.proxy_resolve_start_time();
947 base::TimeTicks proxy_resolve_end_time
= info
.proxy_resolve_end_time();
949 // Fake an error on the proxy.
950 TestCompletionCallback callback2
;
951 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
952 net::ERR_PROXY_CONNECTION_FAILED
,
953 &info
, callback2
.callback(), NULL
,
954 NULL
, BoundNetLog());
957 // Proxy times should not have been modified by fallback.
958 EXPECT_EQ(proxy_resolve_start_time
, info
.proxy_resolve_start_time());
959 EXPECT_EQ(proxy_resolve_end_time
, info
.proxy_resolve_end_time());
961 // The second proxy should be specified.
962 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
963 // Report back that the second proxy worked. This will globally mark the
964 // first proxy as bad.
965 TestProxyFallbackNetworkDelegate test_delegate
;
966 service
.ReportSuccess(info
, &test_delegate
);
967 EXPECT_EQ("foopy1:8080", test_delegate
.proxy_server().ToURI());
968 EXPECT_EQ(net::ERR_PROXY_CONNECTION_FAILED
,
969 test_delegate
.proxy_fallback_net_error());
971 TestCompletionCallback callback3
;
972 rv
= service
.ResolveProxy(
973 url
, net::LOAD_NORMAL
, &info
, callback3
.callback(), NULL
, NULL
,
975 EXPECT_EQ(ERR_IO_PENDING
, rv
);
977 ASSERT_EQ(1u, resolver
->pending_requests().size());
978 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
980 // Set the result in proxy resolver -- the second result is already known
981 // to be bad, so we will not try to use it initially.
982 resolver
->pending_requests()[0]->results()->UseNamedProxy(
983 "foopy3:7070;foopy1:8080;foopy2:9090");
984 resolver
->pending_requests()[0]->CompleteNow(OK
);
986 EXPECT_EQ(OK
, callback3
.WaitForResult());
987 EXPECT_FALSE(info
.is_direct());
988 EXPECT_EQ("foopy3:7070", info
.proxy_server().ToURI());
990 // Proxy times should have been updated, so get them again.
991 EXPECT_LE(proxy_resolve_end_time
, info
.proxy_resolve_start_time());
992 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
993 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
994 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
995 proxy_resolve_start_time
= info
.proxy_resolve_start_time();
996 proxy_resolve_end_time
= info
.proxy_resolve_end_time();
998 // We fake another error. It should now try the third one.
999 TestCompletionCallback callback4
;
1000 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1001 net::ERR_PROXY_CONNECTION_FAILED
,
1002 &info
, callback4
.callback(), NULL
,
1003 NULL
, BoundNetLog());
1005 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1007 // We fake another error. At this point we have tried all of the
1008 // proxy servers we thought were valid; next we try the proxy server
1009 // that was in our bad proxies map (foopy1:8080).
1010 TestCompletionCallback callback5
;
1011 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1012 net::ERR_PROXY_CONNECTION_FAILED
,
1013 &info
, callback5
.callback(), NULL
,
1014 NULL
, BoundNetLog());
1016 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1018 // Fake another error, the last proxy is gone, the list should now be empty,
1019 // so there is nothing left to try.
1020 TestCompletionCallback callback6
;
1021 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1022 net::ERR_PROXY_CONNECTION_FAILED
,
1023 &info
, callback6
.callback(), NULL
,
1024 NULL
, BoundNetLog());
1025 EXPECT_EQ(ERR_FAILED
, rv
);
1026 EXPECT_FALSE(info
.is_direct());
1027 EXPECT_TRUE(info
.is_empty());
1029 // Proxy times should not have been modified by fallback.
1030 EXPECT_EQ(proxy_resolve_start_time
, info
.proxy_resolve_start_time());
1031 EXPECT_EQ(proxy_resolve_end_time
, info
.proxy_resolve_end_time());
1033 // Look up proxies again
1034 TestCompletionCallback callback7
;
1035 rv
= service
.ResolveProxy(url
, net::LOAD_NORMAL
, &info
, callback7
.callback(),
1036 NULL
, NULL
, BoundNetLog());
1037 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1039 ASSERT_EQ(1u, resolver
->pending_requests().size());
1040 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1042 // This time, the first 3 results have been found to be bad, but only the
1043 // first proxy has been confirmed ...
1044 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1045 "foopy1:8080;foopy3:7070;foopy2:9090;foopy4:9091");
1046 resolver
->pending_requests()[0]->CompleteNow(OK
);
1048 // ... therefore, we should see the second proxy first.
1049 EXPECT_EQ(OK
, callback7
.WaitForResult());
1050 EXPECT_FALSE(info
.is_direct());
1051 EXPECT_EQ("foopy3:7070", info
.proxy_server().ToURI());
1053 EXPECT_LE(proxy_resolve_end_time
, info
.proxy_resolve_start_time());
1054 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1055 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1056 // TODO(nsylvain): Test that the proxy can be retried after the delay.
1059 // This test is similar to ProxyFallback, but this time we have an explicit
1060 // fallback choice to DIRECT.
1061 TEST_F(ProxyServiceTest
, ProxyFallbackToDirect
) {
1062 MockProxyConfigService
* config_service
=
1063 new MockProxyConfigService("http://foopy/proxy.pac");
1065 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
1067 ProxyService
service(config_service
, resolver
, NULL
);
1069 GURL
url("http://www.google.com/");
1071 // Get the proxy information.
1073 TestCompletionCallback callback1
;
1074 int rv
= service
.ResolveProxy(
1075 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
1077 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1079 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1080 resolver
->pending_set_pac_script_request()->script_data()->url());
1081 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1083 ASSERT_EQ(1u, resolver
->pending_requests().size());
1084 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1086 // Set the result in proxy resolver.
1087 resolver
->pending_requests()[0]->results()->UsePacString(
1088 "PROXY foopy1:8080; PROXY foopy2:9090; DIRECT");
1089 resolver
->pending_requests()[0]->CompleteNow(OK
);
1091 // Get the first result.
1092 EXPECT_EQ(OK
, callback1
.WaitForResult());
1093 EXPECT_FALSE(info
.is_direct());
1094 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1096 // Fake an error on the proxy.
1097 TestCompletionCallback callback2
;
1098 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1099 net::ERR_PROXY_CONNECTION_FAILED
,
1100 &info
, callback2
.callback(), NULL
,
1101 NULL
, BoundNetLog());
1104 // Now we get back the second proxy.
1105 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1107 // Fake an error on this proxy as well.
1108 TestCompletionCallback callback3
;
1109 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1110 net::ERR_PROXY_CONNECTION_FAILED
,
1111 &info
, callback3
.callback(), NULL
,
1112 NULL
, BoundNetLog());
1115 // Finally, we get back DIRECT.
1116 EXPECT_TRUE(info
.is_direct());
1118 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1119 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1120 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1122 // Now we tell the proxy service that even DIRECT failed.
1123 TestCompletionCallback callback4
;
1124 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1125 net::ERR_PROXY_CONNECTION_FAILED
,
1126 &info
, callback4
.callback(), NULL
,
1127 NULL
, BoundNetLog());
1128 // There was nothing left to try after DIRECT, so we are out of
1130 EXPECT_EQ(ERR_FAILED
, rv
);
1133 TEST_F(ProxyServiceTest
, ProxyFallback_NewSettings
) {
1134 // Test proxy failover when new settings are available.
1136 MockProxyConfigService
* config_service
=
1137 new MockProxyConfigService("http://foopy/proxy.pac");
1139 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
1141 ProxyService
service(config_service
, resolver
, NULL
);
1143 GURL
url("http://www.google.com/");
1145 // Get the proxy information.
1147 TestCompletionCallback callback1
;
1148 int rv
= service
.ResolveProxy(
1149 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
1151 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1153 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1154 resolver
->pending_set_pac_script_request()->script_data()->url());
1155 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1157 ASSERT_EQ(1u, resolver
->pending_requests().size());
1158 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1160 // Set the result in proxy resolver.
1161 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1162 "foopy1:8080;foopy2:9090");
1163 resolver
->pending_requests()[0]->CompleteNow(OK
);
1165 // The first item is valid.
1166 EXPECT_EQ(OK
, callback1
.WaitForResult());
1167 EXPECT_FALSE(info
.is_direct());
1168 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1170 // Fake an error on the proxy, and also a new configuration on the proxy.
1171 config_service
->SetConfig(
1172 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy-new/proxy.pac")));
1174 TestCompletionCallback callback2
;
1175 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1176 net::ERR_PROXY_CONNECTION_FAILED
,
1177 &info
, callback2
.callback(), NULL
,
1178 NULL
, BoundNetLog());
1179 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1181 EXPECT_EQ(GURL("http://foopy-new/proxy.pac"),
1182 resolver
->pending_set_pac_script_request()->script_data()->url());
1183 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1185 ASSERT_EQ(1u, resolver
->pending_requests().size());
1186 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1188 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1189 "foopy1:8080;foopy2:9090");
1190 resolver
->pending_requests()[0]->CompleteNow(OK
);
1192 // The first proxy is still there since the configuration changed.
1193 EXPECT_EQ(OK
, callback2
.WaitForResult());
1194 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1196 // We fake another error. It should now ignore the first one.
1197 TestCompletionCallback callback3
;
1198 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1199 net::ERR_PROXY_CONNECTION_FAILED
,
1200 &info
, callback3
.callback(), NULL
,
1201 NULL
, BoundNetLog());
1203 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1205 // We simulate a new configuration.
1206 config_service
->SetConfig(
1207 ProxyConfig::CreateFromCustomPacURL(
1208 GURL("http://foopy-new2/proxy.pac")));
1210 // We fake another error. It should go back to the first proxy.
1211 TestCompletionCallback callback4
;
1212 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1213 net::ERR_PROXY_CONNECTION_FAILED
,
1214 &info
, callback4
.callback(), NULL
,
1215 NULL
, BoundNetLog());
1216 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1218 EXPECT_EQ(GURL("http://foopy-new2/proxy.pac"),
1219 resolver
->pending_set_pac_script_request()->script_data()->url());
1220 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1222 ASSERT_EQ(1u, resolver
->pending_requests().size());
1223 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1225 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1226 "foopy1:8080;foopy2:9090");
1227 resolver
->pending_requests()[0]->CompleteNow(OK
);
1229 EXPECT_EQ(OK
, callback4
.WaitForResult());
1230 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1232 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1233 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1234 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1237 TEST_F(ProxyServiceTest
, ProxyFallback_BadConfig
) {
1238 // Test proxy failover when the configuration is bad.
1240 MockProxyConfigService
* config_service
=
1241 new MockProxyConfigService("http://foopy/proxy.pac");
1243 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
1245 ProxyService
service(config_service
, resolver
, NULL
);
1247 GURL
url("http://www.google.com/");
1249 // Get the proxy information.
1251 TestCompletionCallback callback1
;
1252 int rv
= service
.ResolveProxy(
1253 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
1255 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1257 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1258 resolver
->pending_set_pac_script_request()->script_data()->url());
1259 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1260 ASSERT_EQ(1u, resolver
->pending_requests().size());
1261 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1263 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1264 "foopy1:8080;foopy2:9090");
1265 resolver
->pending_requests()[0]->CompleteNow(OK
);
1267 // The first item is valid.
1268 EXPECT_EQ(OK
, callback1
.WaitForResult());
1269 EXPECT_FALSE(info
.is_direct());
1270 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1272 // Fake a proxy error.
1273 TestCompletionCallback callback2
;
1274 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1275 net::ERR_PROXY_CONNECTION_FAILED
,
1276 &info
, callback2
.callback(), NULL
,
1277 NULL
, BoundNetLog());
1280 // The first proxy is ignored, and the second one is selected.
1281 EXPECT_FALSE(info
.is_direct());
1282 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1284 // Fake a PAC failure.
1286 TestCompletionCallback callback3
;
1287 rv
= service
.ResolveProxy(
1288 url
, net::LOAD_NORMAL
, &info2
, callback3
.callback(), NULL
, NULL
,
1290 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1292 ASSERT_EQ(1u, resolver
->pending_requests().size());
1293 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1295 // This simulates a javascript runtime error in the PAC script.
1296 resolver
->pending_requests()[0]->CompleteNow(ERR_FAILED
);
1298 // Although the resolver failed, the ProxyService will implicitly fall-back
1299 // to a DIRECT connection.
1300 EXPECT_EQ(OK
, callback3
.WaitForResult());
1301 EXPECT_TRUE(info2
.is_direct());
1302 EXPECT_FALSE(info2
.is_empty());
1304 // The PAC script will work properly next time and successfully return a
1305 // proxy list. Since we have not marked the configuration as bad, it should
1306 // "just work" the next time we call it.
1308 TestCompletionCallback callback4
;
1309 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1310 net::ERR_PROXY_CONNECTION_FAILED
,
1311 &info3
, callback4
.callback(),
1312 NULL
, NULL
, BoundNetLog());
1313 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1315 ASSERT_EQ(1u, resolver
->pending_requests().size());
1316 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1318 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1319 "foopy1:8080;foopy2:9090");
1320 resolver
->pending_requests()[0]->CompleteNow(OK
);
1322 // The first proxy is not there since the it was added to the bad proxies
1323 // list by the earlier ReconsiderProxyAfterError().
1324 EXPECT_EQ(OK
, callback4
.WaitForResult());
1325 EXPECT_FALSE(info3
.is_direct());
1326 EXPECT_EQ("foopy1:8080", info3
.proxy_server().ToURI());
1328 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1329 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1330 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1333 TEST_F(ProxyServiceTest
, ProxyFallback_BadConfigMandatory
) {
1334 // Test proxy failover when the configuration is bad.
1337 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
1339 config
.set_pac_mandatory(true);
1340 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
1342 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
1344 ProxyService
service(config_service
, resolver
, NULL
);
1346 GURL
url("http://www.google.com/");
1348 // Get the proxy information.
1350 TestCompletionCallback callback1
;
1351 int rv
= service
.ResolveProxy(
1352 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
1354 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1356 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1357 resolver
->pending_set_pac_script_request()->script_data()->url());
1358 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1359 ASSERT_EQ(1u, resolver
->pending_requests().size());
1360 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1362 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1363 "foopy1:8080;foopy2:9090");
1364 resolver
->pending_requests()[0]->CompleteNow(OK
);
1366 // The first item is valid.
1367 EXPECT_EQ(OK
, callback1
.WaitForResult());
1368 EXPECT_FALSE(info
.is_direct());
1369 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1371 // Fake a proxy error.
1372 TestCompletionCallback callback2
;
1373 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1374 net::ERR_PROXY_CONNECTION_FAILED
,
1375 &info
, callback2
.callback(), NULL
,
1376 NULL
, BoundNetLog());
1379 // The first proxy is ignored, and the second one is selected.
1380 EXPECT_FALSE(info
.is_direct());
1381 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1383 // Fake a PAC failure.
1385 TestCompletionCallback callback3
;
1386 rv
= service
.ResolveProxy(
1387 url
, net::LOAD_NORMAL
, &info2
, callback3
.callback(), NULL
, NULL
,
1389 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1391 ASSERT_EQ(1u, resolver
->pending_requests().size());
1392 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1394 // This simulates a javascript runtime error in the PAC script.
1395 resolver
->pending_requests()[0]->CompleteNow(ERR_FAILED
);
1397 // Although the resolver failed, the ProxyService will NOT fall-back
1398 // to a DIRECT connection as it is configured as mandatory.
1399 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
1400 callback3
.WaitForResult());
1401 EXPECT_FALSE(info2
.is_direct());
1402 EXPECT_TRUE(info2
.is_empty());
1404 // The PAC script will work properly next time and successfully return a
1405 // proxy list. Since we have not marked the configuration as bad, it should
1406 // "just work" the next time we call it.
1408 TestCompletionCallback callback4
;
1409 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1410 net::ERR_PROXY_CONNECTION_FAILED
,
1411 &info3
, callback4
.callback(),
1412 NULL
, NULL
, BoundNetLog());
1413 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1415 ASSERT_EQ(1u, resolver
->pending_requests().size());
1416 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1418 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1419 "foopy1:8080;foopy2:9090");
1420 resolver
->pending_requests()[0]->CompleteNow(OK
);
1422 // The first proxy is not there since the it was added to the bad proxies
1423 // list by the earlier ReconsiderProxyAfterError().
1424 EXPECT_EQ(OK
, callback4
.WaitForResult());
1425 EXPECT_FALSE(info3
.is_direct());
1426 EXPECT_EQ("foopy1:8080", info3
.proxy_server().ToURI());
1429 TEST_F(ProxyServiceTest
, ProxyBypassList
) {
1430 // Test that the proxy bypass rules are consulted.
1432 TestCompletionCallback callback
[2];
1435 config
.proxy_rules().ParseFromString("foopy1:8080;foopy2:9090");
1436 config
.set_auto_detect(false);
1437 config
.proxy_rules().bypass_rules
.ParseFromString("*.org");
1439 ProxyService
service(
1440 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1443 GURL
url1("http://www.webkit.org");
1444 GURL
url2("http://www.webkit.com");
1446 // Request for a .org domain should bypass proxy.
1447 rv
= service
.ResolveProxy(
1448 url1
, net::LOAD_NORMAL
, &info
[0], callback
[0].callback(), NULL
, NULL
,
1451 EXPECT_TRUE(info
[0].is_direct());
1453 // Request for a .com domain hits the proxy.
1454 rv
= service
.ResolveProxy(
1455 url2
, net::LOAD_NORMAL
, &info
[1], callback
[1].callback(), NULL
, NULL
,
1458 EXPECT_EQ("foopy1:8080", info
[1].proxy_server().ToURI());
1462 TEST_F(ProxyServiceTest
, PerProtocolProxyTests
) {
1464 config
.proxy_rules().ParseFromString("http=foopy1:8080;https=foopy2:8080");
1465 config
.set_auto_detect(false);
1467 ProxyService
service(
1468 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1469 GURL
test_url("http://www.msn.com");
1471 TestCompletionCallback callback
;
1472 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1473 callback
.callback(), NULL
, NULL
,
1476 EXPECT_FALSE(info
.is_direct());
1477 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1480 ProxyService
service(
1481 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1482 GURL
test_url("ftp://ftp.google.com");
1484 TestCompletionCallback callback
;
1485 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1486 callback
.callback(), NULL
,
1487 NULL
, BoundNetLog());
1489 EXPECT_TRUE(info
.is_direct());
1490 EXPECT_EQ("direct://", info
.proxy_server().ToURI());
1493 ProxyService
service(
1494 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1495 GURL
test_url("https://webbranch.techcu.com");
1497 TestCompletionCallback callback
;
1498 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1499 callback
.callback(), NULL
,
1500 NULL
, BoundNetLog());
1502 EXPECT_FALSE(info
.is_direct());
1503 EXPECT_EQ("foopy2:8080", info
.proxy_server().ToURI());
1506 config
.proxy_rules().ParseFromString("foopy1:8080");
1507 ProxyService
service(
1508 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1509 GURL
test_url("http://www.microsoft.com");
1511 TestCompletionCallback callback
;
1512 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1513 callback
.callback(), NULL
,
1514 NULL
, BoundNetLog());
1516 EXPECT_FALSE(info
.is_direct());
1517 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1521 TEST_F(ProxyServiceTest
, ProxyConfigSourcePropagates
) {
1522 // Test that the proxy config source is set correctly when resolving proxies
1523 // using manual proxy rules. Namely, the config source should only be set if
1524 // any of the rules were applied.
1527 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1528 config
.proxy_rules().ParseFromString("https=foopy2:8080");
1529 ProxyService
service(
1530 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1531 GURL
test_url("http://www.google.com");
1533 TestCompletionCallback callback
;
1534 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1535 callback
.callback(), NULL
,
1536 NULL
, BoundNetLog());
1538 // Should be SOURCE_TEST, even if there are no HTTP proxies configured.
1539 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1543 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1544 config
.proxy_rules().ParseFromString("https=foopy2:8080");
1545 ProxyService
service(
1546 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1547 GURL
test_url("https://www.google.com");
1549 TestCompletionCallback callback
;
1550 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1551 callback
.callback(), NULL
,
1552 NULL
, BoundNetLog());
1554 // Used the HTTPS proxy. So source should be TEST.
1555 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1559 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1560 ProxyService
service(
1561 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1562 GURL
test_url("http://www.google.com");
1564 TestCompletionCallback callback
;
1565 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1566 callback
.callback(), NULL
,
1567 NULL
, BoundNetLog());
1569 // ProxyConfig is empty. Source should still be TEST.
1570 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1574 // If only HTTP and a SOCKS proxy are specified, check if ftp/https queries
1575 // fall back to the SOCKS proxy.
1576 TEST_F(ProxyServiceTest
, DefaultProxyFallbackToSOCKS
) {
1578 config
.proxy_rules().ParseFromString("http=foopy1:8080;socks=foopy2:1080");
1579 config
.set_auto_detect(false);
1580 EXPECT_EQ(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
1581 config
.proxy_rules().type
);
1584 ProxyService
service(
1585 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1586 GURL
test_url("http://www.msn.com");
1588 TestCompletionCallback callback
;
1589 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1590 callback
.callback(), NULL
,
1591 NULL
, BoundNetLog());
1593 EXPECT_FALSE(info
.is_direct());
1594 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1597 ProxyService
service(
1598 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1599 GURL
test_url("ftp://ftp.google.com");
1601 TestCompletionCallback callback
;
1602 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1603 callback
.callback(), NULL
,
1604 NULL
, BoundNetLog());
1606 EXPECT_FALSE(info
.is_direct());
1607 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1610 ProxyService
service(
1611 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1612 GURL
test_url("https://webbranch.techcu.com");
1614 TestCompletionCallback callback
;
1615 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1616 callback
.callback(), NULL
,
1617 NULL
, BoundNetLog());
1619 EXPECT_FALSE(info
.is_direct());
1620 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1623 ProxyService
service(
1624 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1625 GURL
test_url("unknown://www.microsoft.com");
1627 TestCompletionCallback callback
;
1628 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1629 callback
.callback(), NULL
,
1630 NULL
, BoundNetLog());
1632 EXPECT_FALSE(info
.is_direct());
1633 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1637 // Test cancellation of an in-progress request.
1638 TEST_F(ProxyServiceTest
, CancelInProgressRequest
) {
1639 MockProxyConfigService
* config_service
=
1640 new MockProxyConfigService("http://foopy/proxy.pac");
1642 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
1644 ProxyService
service(config_service
, resolver
, NULL
);
1646 // Start 3 requests.
1649 TestCompletionCallback callback1
;
1650 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1651 &info1
, callback1
.callback(), NULL
, NULL
,
1653 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1655 // Nothing has been sent to the proxy resolver yet, since the proxy
1656 // resolver has not been configured yet.
1657 ASSERT_EQ(0u, resolver
->pending_requests().size());
1659 // Successfully initialize the PAC script.
1660 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1661 resolver
->pending_set_pac_script_request()->script_data()->url());
1662 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1664 ASSERT_EQ(1u, resolver
->pending_requests().size());
1665 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
1668 TestCompletionCallback callback2
;
1669 ProxyService::PacRequest
* request2
;
1670 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1671 callback2
.callback(), &request2
, NULL
,
1673 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1674 ASSERT_EQ(2u, resolver
->pending_requests().size());
1675 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[1]->url());
1678 TestCompletionCallback callback3
;
1679 rv
= service
.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL
, &info3
,
1680 callback3
.callback(), NULL
, NULL
, BoundNetLog());
1681 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1682 ASSERT_EQ(3u, resolver
->pending_requests().size());
1683 EXPECT_EQ(GURL("http://request3"), resolver
->pending_requests()[2]->url());
1685 // Cancel the second request
1686 service
.CancelPacRequest(request2
);
1688 ASSERT_EQ(2u, resolver
->pending_requests().size());
1689 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
1690 EXPECT_EQ(GURL("http://request3"), resolver
->pending_requests()[1]->url());
1692 // Complete the two un-cancelled requests.
1693 // We complete the last one first, just to mix it up a bit.
1694 resolver
->pending_requests()[1]->results()->UseNamedProxy("request3:80");
1695 resolver
->pending_requests()[1]->CompleteNow(OK
);
1697 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1698 resolver
->pending_requests()[0]->CompleteNow(OK
);
1700 // Complete and verify that requests ran as expected.
1701 EXPECT_EQ(OK
, callback1
.WaitForResult());
1702 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
1704 EXPECT_FALSE(callback2
.have_result()); // Cancelled.
1705 ASSERT_EQ(1u, resolver
->cancelled_requests().size());
1706 EXPECT_EQ(GURL("http://request2"), resolver
->cancelled_requests()[0]->url());
1708 EXPECT_EQ(OK
, callback3
.WaitForResult());
1709 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
1712 // Test the initial PAC download for resolver that expects bytes.
1713 TEST_F(ProxyServiceTest
, InitialPACScriptDownload
) {
1714 MockProxyConfigService
* config_service
=
1715 new MockProxyConfigService("http://foopy/proxy.pac");
1717 MockAsyncProxyResolverExpectsBytes
* resolver
=
1718 new MockAsyncProxyResolverExpectsBytes
;
1720 ProxyService
service(config_service
, resolver
, NULL
);
1722 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1723 service
.SetProxyScriptFetchers(fetcher
,
1724 new DoNothingDhcpProxyScriptFetcher());
1726 // Start 3 requests.
1729 TestCompletionCallback callback1
;
1730 ProxyService::PacRequest
* request1
;
1731 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1732 &info1
, callback1
.callback(), &request1
, NULL
,
1734 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1736 // The first request should have triggered download of PAC script.
1737 EXPECT_TRUE(fetcher
->has_pending_request());
1738 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1741 TestCompletionCallback callback2
;
1742 ProxyService::PacRequest
* request2
;
1743 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1744 callback2
.callback(), &request2
, NULL
,
1746 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1749 TestCompletionCallback callback3
;
1750 ProxyService::PacRequest
* request3
;
1751 rv
= service
.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL
, &info3
,
1752 callback3
.callback(), &request3
, NULL
,
1754 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1756 // Nothing has been sent to the resolver yet.
1757 EXPECT_TRUE(resolver
->pending_requests().empty());
1759 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1760 service
.GetLoadState(request1
));
1761 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1762 service
.GetLoadState(request2
));
1763 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1764 service
.GetLoadState(request3
));
1766 // At this point the ProxyService should be waiting for the
1767 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1768 // PAC script download completion.
1769 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
1771 // Now that the PAC script is downloaded, it will have been sent to the proxy
1773 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
1774 resolver
->pending_set_pac_script_request()->script_data()->utf16());
1775 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1777 ASSERT_EQ(3u, resolver
->pending_requests().size());
1778 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
1779 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[1]->url());
1780 EXPECT_EQ(GURL("http://request3"), resolver
->pending_requests()[2]->url());
1782 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request1
));
1783 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request2
));
1784 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request3
));
1786 // Complete all the requests (in some order).
1787 // Note that as we complete requests, they shift up in |pending_requests()|.
1789 resolver
->pending_requests()[2]->results()->UseNamedProxy("request3:80");
1790 resolver
->pending_requests()[2]->CompleteNow(OK
);
1792 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1793 resolver
->pending_requests()[0]->CompleteNow(OK
);
1795 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
1796 resolver
->pending_requests()[0]->CompleteNow(OK
);
1798 // Complete and verify that requests ran as expected.
1799 EXPECT_EQ(OK
, callback1
.WaitForResult());
1800 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
1801 EXPECT_FALSE(info1
.proxy_resolve_start_time().is_null());
1802 EXPECT_FALSE(info1
.proxy_resolve_end_time().is_null());
1803 EXPECT_LE(info1
.proxy_resolve_start_time(), info1
.proxy_resolve_end_time());
1805 EXPECT_EQ(OK
, callback2
.WaitForResult());
1806 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
1807 EXPECT_FALSE(info2
.proxy_resolve_start_time().is_null());
1808 EXPECT_FALSE(info2
.proxy_resolve_end_time().is_null());
1809 EXPECT_LE(info2
.proxy_resolve_start_time(), info2
.proxy_resolve_end_time());
1811 EXPECT_EQ(OK
, callback3
.WaitForResult());
1812 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
1813 EXPECT_FALSE(info3
.proxy_resolve_start_time().is_null());
1814 EXPECT_FALSE(info3
.proxy_resolve_end_time().is_null());
1815 EXPECT_LE(info3
.proxy_resolve_start_time(), info3
.proxy_resolve_end_time());
1818 // Test changing the ProxyScriptFetcher while PAC download is in progress.
1819 TEST_F(ProxyServiceTest
, ChangeScriptFetcherWhilePACDownloadInProgress
) {
1820 MockProxyConfigService
* config_service
=
1821 new MockProxyConfigService("http://foopy/proxy.pac");
1823 MockAsyncProxyResolverExpectsBytes
* resolver
=
1824 new MockAsyncProxyResolverExpectsBytes
;
1826 ProxyService
service(config_service
, resolver
, NULL
);
1828 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1829 service
.SetProxyScriptFetchers(fetcher
,
1830 new DoNothingDhcpProxyScriptFetcher());
1832 // Start 2 requests.
1835 TestCompletionCallback callback1
;
1836 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1837 &info1
, callback1
.callback(), NULL
, NULL
,
1839 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1841 // The first request should have triggered download of PAC script.
1842 EXPECT_TRUE(fetcher
->has_pending_request());
1843 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1846 TestCompletionCallback callback2
;
1847 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1848 callback2
.callback(), NULL
, NULL
, BoundNetLog());
1849 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1851 // At this point the ProxyService should be waiting for the
1852 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1853 // PAC script download completion.
1855 // We now change out the ProxyService's script fetcher. We should restart
1856 // the initialization with the new fetcher.
1858 fetcher
= new MockProxyScriptFetcher
;
1859 service
.SetProxyScriptFetchers(fetcher
,
1860 new DoNothingDhcpProxyScriptFetcher());
1862 // Nothing has been sent to the resolver yet.
1863 EXPECT_TRUE(resolver
->pending_requests().empty());
1865 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
1867 // Now that the PAC script is downloaded, it will have been sent to the proxy
1869 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
1870 resolver
->pending_set_pac_script_request()->script_data()->utf16());
1871 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1873 ASSERT_EQ(2u, resolver
->pending_requests().size());
1874 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
1875 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[1]->url());
1878 // Test cancellation of a request, while the PAC script is being fetched.
1879 TEST_F(ProxyServiceTest
, CancelWhilePACFetching
) {
1880 MockProxyConfigService
* config_service
=
1881 new MockProxyConfigService("http://foopy/proxy.pac");
1883 MockAsyncProxyResolverExpectsBytes
* resolver
=
1884 new MockAsyncProxyResolverExpectsBytes
;
1886 ProxyService
service(config_service
, resolver
, NULL
);
1888 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1889 service
.SetProxyScriptFetchers(fetcher
,
1890 new DoNothingDhcpProxyScriptFetcher());
1892 // Start 3 requests.
1894 TestCompletionCallback callback1
;
1895 ProxyService::PacRequest
* request1
;
1896 CapturingBoundNetLog log1
;
1897 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1898 &info1
, callback1
.callback(), &request1
, NULL
,
1900 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1902 // The first request should have triggered download of PAC script.
1903 EXPECT_TRUE(fetcher
->has_pending_request());
1904 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1907 TestCompletionCallback callback2
;
1908 ProxyService::PacRequest
* request2
;
1909 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1910 callback2
.callback(), &request2
, NULL
,
1912 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1915 TestCompletionCallback callback3
;
1916 rv
= service
.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL
, &info3
,
1917 callback3
.callback(), NULL
, NULL
, BoundNetLog());
1918 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1920 // Nothing has been sent to the resolver yet.
1921 EXPECT_TRUE(resolver
->pending_requests().empty());
1923 // Cancel the first 2 requests.
1924 service
.CancelPacRequest(request1
);
1925 service
.CancelPacRequest(request2
);
1927 // At this point the ProxyService should be waiting for the
1928 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1929 // PAC script download completion.
1930 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
1932 // Now that the PAC script is downloaded, it will have been sent to the
1934 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
1935 resolver
->pending_set_pac_script_request()->script_data()->utf16());
1936 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1938 ASSERT_EQ(1u, resolver
->pending_requests().size());
1939 EXPECT_EQ(GURL("http://request3"), resolver
->pending_requests()[0]->url());
1941 // Complete all the requests.
1942 resolver
->pending_requests()[0]->results()->UseNamedProxy("request3:80");
1943 resolver
->pending_requests()[0]->CompleteNow(OK
);
1945 EXPECT_EQ(OK
, callback3
.WaitForResult());
1946 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
1948 EXPECT_TRUE(resolver
->cancelled_requests().empty());
1950 EXPECT_FALSE(callback1
.have_result()); // Cancelled.
1951 EXPECT_FALSE(callback2
.have_result()); // Cancelled.
1953 CapturingNetLog::CapturedEntryList entries1
;
1954 log1
.GetEntries(&entries1
);
1956 // Check the NetLog for request 1 (which was cancelled) got filled properly.
1957 EXPECT_EQ(4u, entries1
.size());
1958 EXPECT_TRUE(LogContainsBeginEvent(
1959 entries1
, 0, NetLog::TYPE_PROXY_SERVICE
));
1960 EXPECT_TRUE(LogContainsBeginEvent(
1961 entries1
, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
1962 // Note that TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC is never completed before
1963 // the cancellation occured.
1964 EXPECT_TRUE(LogContainsEvent(
1965 entries1
, 2, NetLog::TYPE_CANCELLED
, NetLog::PHASE_NONE
));
1966 EXPECT_TRUE(LogContainsEndEvent(
1967 entries1
, 3, NetLog::TYPE_PROXY_SERVICE
));
1970 // Test that if auto-detect fails, we fall-back to the custom pac.
1971 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomPac
) {
1973 config
.set_auto_detect(true);
1974 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
1975 config
.proxy_rules().ParseFromString("http=foopy:80"); // Won't be used.
1977 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
1978 MockAsyncProxyResolverExpectsBytes
* resolver
=
1979 new MockAsyncProxyResolverExpectsBytes
;
1980 ProxyService
service(config_service
, resolver
, NULL
);
1982 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1983 service
.SetProxyScriptFetchers(fetcher
,
1984 new DoNothingDhcpProxyScriptFetcher());
1986 // Start 2 requests.
1989 TestCompletionCallback callback1
;
1990 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1991 &info1
, callback1
.callback(), NULL
, NULL
,
1993 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1996 TestCompletionCallback callback2
;
1997 ProxyService::PacRequest
* request2
;
1998 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1999 callback2
.callback(), &request2
, NULL
,
2001 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2003 // Check that nothing has been sent to the proxy resolver yet.
2004 ASSERT_EQ(0u, resolver
->pending_requests().size());
2006 // It should be trying to auto-detect first -- FAIL the autodetect during
2007 // the script download.
2008 EXPECT_TRUE(fetcher
->has_pending_request());
2009 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2010 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2012 // Next it should be trying the custom PAC url.
2013 EXPECT_TRUE(fetcher
->has_pending_request());
2014 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2015 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2017 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2018 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2019 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2021 // Now finally, the pending requests should have been sent to the resolver
2022 // (which was initialized with custom PAC script).
2024 ASSERT_EQ(2u, resolver
->pending_requests().size());
2025 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2026 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[1]->url());
2028 // Complete the pending requests.
2029 resolver
->pending_requests()[1]->results()->UseNamedProxy("request2:80");
2030 resolver
->pending_requests()[1]->CompleteNow(OK
);
2031 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2032 resolver
->pending_requests()[0]->CompleteNow(OK
);
2034 // Verify that requests ran as expected.
2035 EXPECT_EQ(OK
, callback1
.WaitForResult());
2036 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2037 EXPECT_FALSE(info1
.proxy_resolve_start_time().is_null());
2038 EXPECT_FALSE(info1
.proxy_resolve_end_time().is_null());
2039 EXPECT_LE(info1
.proxy_resolve_start_time(), info1
.proxy_resolve_end_time());
2041 EXPECT_EQ(OK
, callback2
.WaitForResult());
2042 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2043 EXPECT_FALSE(info2
.proxy_resolve_start_time().is_null());
2044 EXPECT_FALSE(info2
.proxy_resolve_end_time().is_null());
2045 EXPECT_LE(info2
.proxy_resolve_start_time(), info2
.proxy_resolve_end_time());
2048 // This is the same test as FallbackFromAutodetectToCustomPac, except
2049 // the auto-detect script fails parsing rather than downloading.
2050 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomPac2
) {
2052 config
.set_auto_detect(true);
2053 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2054 config
.proxy_rules().ParseFromString("http=foopy:80"); // Won't be used.
2056 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2057 MockAsyncProxyResolverExpectsBytes
* resolver
=
2058 new MockAsyncProxyResolverExpectsBytes
;
2059 ProxyService
service(config_service
, resolver
, NULL
);
2061 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2062 service
.SetProxyScriptFetchers(fetcher
,
2063 new DoNothingDhcpProxyScriptFetcher());
2065 // Start 2 requests.
2068 TestCompletionCallback callback1
;
2069 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2070 &info1
, callback1
.callback(), NULL
, NULL
,
2072 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2075 TestCompletionCallback callback2
;
2076 ProxyService::PacRequest
* request2
;
2077 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
2078 callback2
.callback(), &request2
, NULL
,
2080 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2082 // Check that nothing has been sent to the proxy resolver yet.
2083 ASSERT_EQ(0u, resolver
->pending_requests().size());
2085 // It should be trying to auto-detect first -- succeed the download.
2086 EXPECT_TRUE(fetcher
->has_pending_request());
2087 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2088 fetcher
->NotifyFetchCompletion(OK
, "invalid-script-contents");
2090 // The script contents passed failed basic verification step (since didn't
2091 // contain token FindProxyForURL), so it was never passed to the resolver.
2093 // Next it should be trying the custom PAC url.
2094 EXPECT_TRUE(fetcher
->has_pending_request());
2095 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2096 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2098 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2099 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2100 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2102 // Now finally, the pending requests should have been sent to the resolver
2103 // (which was initialized with custom PAC script).
2105 ASSERT_EQ(2u, resolver
->pending_requests().size());
2106 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2107 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[1]->url());
2109 // Complete the pending requests.
2110 resolver
->pending_requests()[1]->results()->UseNamedProxy("request2:80");
2111 resolver
->pending_requests()[1]->CompleteNow(OK
);
2112 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2113 resolver
->pending_requests()[0]->CompleteNow(OK
);
2115 // Verify that requests ran as expected.
2116 EXPECT_EQ(OK
, callback1
.WaitForResult());
2117 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2119 EXPECT_EQ(OK
, callback2
.WaitForResult());
2120 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2123 // Test that if all of auto-detect, a custom PAC script, and manual settings
2124 // are given, then we will try them in that order.
2125 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomToManual
) {
2127 config
.set_auto_detect(true);
2128 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2129 config
.proxy_rules().ParseFromString("http=foopy:80");
2131 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2132 MockAsyncProxyResolverExpectsBytes
* resolver
=
2133 new MockAsyncProxyResolverExpectsBytes
;
2134 ProxyService
service(config_service
, resolver
, NULL
);
2136 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2137 service
.SetProxyScriptFetchers(fetcher
,
2138 new DoNothingDhcpProxyScriptFetcher());
2140 // Start 2 requests.
2143 TestCompletionCallback callback1
;
2144 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2145 &info1
, callback1
.callback(), NULL
, NULL
,
2147 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2150 TestCompletionCallback callback2
;
2151 ProxyService::PacRequest
* request2
;
2152 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
2153 callback2
.callback(), &request2
, NULL
,
2155 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2157 // Check that nothing has been sent to the proxy resolver yet.
2158 ASSERT_EQ(0u, resolver
->pending_requests().size());
2160 // It should be trying to auto-detect first -- fail the download.
2161 EXPECT_TRUE(fetcher
->has_pending_request());
2162 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2163 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2165 // Next it should be trying the custom PAC url -- fail the download.
2166 EXPECT_TRUE(fetcher
->has_pending_request());
2167 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2168 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2170 // Since we never managed to initialize a ProxyResolver, nothing should have
2172 ASSERT_EQ(0u, resolver
->pending_requests().size());
2174 // Verify that requests ran as expected -- they should have fallen back to
2175 // the manual proxy configuration for HTTP urls.
2176 EXPECT_EQ(OK
, callback1
.WaitForResult());
2177 EXPECT_EQ("foopy:80", info1
.proxy_server().ToURI());
2179 EXPECT_EQ(OK
, callback2
.WaitForResult());
2180 EXPECT_EQ("foopy:80", info2
.proxy_server().ToURI());
2183 // Test that the bypass rules are NOT applied when using autodetect.
2184 TEST_F(ProxyServiceTest
, BypassDoesntApplyToPac
) {
2186 config
.set_auto_detect(true);
2187 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2188 config
.proxy_rules().ParseFromString("http=foopy:80"); // Not used.
2189 config
.proxy_rules().bypass_rules
.ParseFromString("www.google.com");
2191 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2192 MockAsyncProxyResolverExpectsBytes
* resolver
=
2193 new MockAsyncProxyResolverExpectsBytes
;
2194 ProxyService
service(config_service
, resolver
, NULL
);
2196 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2197 service
.SetProxyScriptFetchers(fetcher
,
2198 new DoNothingDhcpProxyScriptFetcher());
2200 // Start 1 requests.
2203 TestCompletionCallback callback1
;
2204 int rv
= service
.ResolveProxy(
2205 GURL("http://www.google.com"), net::LOAD_NORMAL
, &info1
,
2206 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2207 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2209 // Check that nothing has been sent to the proxy resolver yet.
2210 ASSERT_EQ(0u, resolver
->pending_requests().size());
2212 // It should be trying to auto-detect first -- succeed the download.
2213 EXPECT_TRUE(fetcher
->has_pending_request());
2214 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2215 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2217 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2218 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2219 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2221 ASSERT_EQ(1u, resolver
->pending_requests().size());
2222 EXPECT_EQ(GURL("http://www.google.com"),
2223 resolver
->pending_requests()[0]->url());
2225 // Complete the pending request.
2226 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2227 resolver
->pending_requests()[0]->CompleteNow(OK
);
2229 // Verify that request ran as expected.
2230 EXPECT_EQ(OK
, callback1
.WaitForResult());
2231 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2233 // Start another request, it should pickup the bypass item.
2235 TestCompletionCallback callback2
;
2236 rv
= service
.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL
,
2237 &info2
, callback2
.callback(), NULL
, NULL
,
2239 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2241 ASSERT_EQ(1u, resolver
->pending_requests().size());
2242 EXPECT_EQ(GURL("http://www.google.com"),
2243 resolver
->pending_requests()[0]->url());
2245 // Complete the pending request.
2246 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
2247 resolver
->pending_requests()[0]->CompleteNow(OK
);
2249 EXPECT_EQ(OK
, callback2
.WaitForResult());
2250 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2253 // Delete the ProxyService while InitProxyResolver has an outstanding
2254 // request to the script fetcher. When run under valgrind, should not
2255 // have any memory errors (used to be that the ProxyScriptFetcher was
2256 // being deleted prior to the InitProxyResolver).
2257 TEST_F(ProxyServiceTest
, DeleteWhileInitProxyResolverHasOutstandingFetch
) {
2258 ProxyConfig config
=
2259 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
2261 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2262 MockAsyncProxyResolverExpectsBytes
* resolver
=
2263 new MockAsyncProxyResolverExpectsBytes
;
2264 ProxyService
service(config_service
, resolver
, NULL
);
2266 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2267 service
.SetProxyScriptFetchers(fetcher
,
2268 new DoNothingDhcpProxyScriptFetcher());
2273 TestCompletionCallback callback1
;
2274 int rv
= service
.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL
,
2275 &info1
, callback1
.callback(), NULL
, NULL
,
2277 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2279 // Check that nothing has been sent to the proxy resolver yet.
2280 ASSERT_EQ(0u, resolver
->pending_requests().size());
2282 // InitProxyResolver should have issued a request to the ProxyScriptFetcher
2283 // and be waiting on that to complete.
2284 EXPECT_TRUE(fetcher
->has_pending_request());
2285 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2288 // Delete the ProxyService while InitProxyResolver has an outstanding
2289 // request to the proxy resolver. When run under valgrind, should not
2290 // have any memory errors (used to be that the ProxyResolver was
2291 // being deleted prior to the InitProxyResolver).
2292 TEST_F(ProxyServiceTest
, DeleteWhileInitProxyResolverHasOutstandingSet
) {
2293 MockProxyConfigService
* config_service
=
2294 new MockProxyConfigService("http://foopy/proxy.pac");
2296 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
2298 ProxyService
service(config_service
, resolver
, NULL
);
2300 GURL
url("http://www.google.com/");
2303 TestCompletionCallback callback
;
2304 int rv
= service
.ResolveProxy(
2305 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
2307 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2309 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
2310 resolver
->pending_set_pac_script_request()->script_data()->url());
2313 TEST_F(ProxyServiceTest
, ResetProxyConfigService
) {
2314 ProxyConfig config1
;
2315 config1
.proxy_rules().ParseFromString("foopy1:8080");
2316 config1
.set_auto_detect(false);
2317 ProxyService
service(
2318 new MockProxyConfigService(config1
),
2319 new MockAsyncProxyResolverExpectsBytes
, NULL
);
2322 TestCompletionCallback callback1
;
2323 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2324 &info
, callback1
.callback(), NULL
, NULL
,
2327 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
2329 ProxyConfig config2
;
2330 config2
.proxy_rules().ParseFromString("foopy2:8080");
2331 config2
.set_auto_detect(false);
2332 service
.ResetConfigService(new MockProxyConfigService(config2
));
2333 TestCompletionCallback callback2
;
2334 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info
,
2335 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2337 EXPECT_EQ("foopy2:8080", info
.proxy_server().ToURI());
2340 // Test that when going from a configuration that required PAC to one
2341 // that does NOT, we unset the variable |should_use_proxy_resolver_|.
2342 TEST_F(ProxyServiceTest
, UpdateConfigFromPACToDirect
) {
2343 ProxyConfig config
= ProxyConfig::CreateAutoDetect();
2345 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2346 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
2347 ProxyService
service(config_service
, resolver
, NULL
);
2352 TestCompletionCallback callback1
;
2353 int rv
= service
.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL
,
2354 &info1
, callback1
.callback(), NULL
, NULL
,
2356 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2358 // Check that nothing has been sent to the proxy resolver yet.
2359 ASSERT_EQ(0u, resolver
->pending_requests().size());
2361 // Successfully set the autodetect script.
2362 EXPECT_EQ(ProxyResolverScriptData::TYPE_AUTO_DETECT
,
2363 resolver
->pending_set_pac_script_request()->script_data()->type());
2364 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2366 // Complete the pending request.
2367 ASSERT_EQ(1u, resolver
->pending_requests().size());
2368 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2369 resolver
->pending_requests()[0]->CompleteNow(OK
);
2371 // Verify that request ran as expected.
2372 EXPECT_EQ(OK
, callback1
.WaitForResult());
2373 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2375 // Force the ProxyService to pull down a new proxy configuration.
2376 // (Even though the configuration isn't old/bad).
2378 // This new configuration no longer has auto_detect set, so
2379 // requests should complete synchronously now as direct-connect.
2380 config_service
->SetConfig(ProxyConfig::CreateDirect());
2382 // Start another request -- the effective configuration has changed.
2384 TestCompletionCallback callback2
;
2385 rv
= service
.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL
,
2386 &info2
, callback2
.callback(), NULL
, NULL
,
2390 EXPECT_TRUE(info2
.is_direct());
2393 TEST_F(ProxyServiceTest
, NetworkChangeTriggersPacRefetch
) {
2394 MockProxyConfigService
* config_service
=
2395 new MockProxyConfigService("http://foopy/proxy.pac");
2397 MockAsyncProxyResolverExpectsBytes
* resolver
=
2398 new MockAsyncProxyResolverExpectsBytes
;
2400 CapturingNetLog log
;
2402 ProxyService
service(config_service
, resolver
, &log
);
2404 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2405 service
.SetProxyScriptFetchers(fetcher
,
2406 new DoNothingDhcpProxyScriptFetcher());
2408 // Disable the "wait after IP address changes" hack, so this unit-test can
2409 // complete quickly.
2410 service
.set_stall_proxy_auto_config_delay(base::TimeDelta());
2415 TestCompletionCallback callback1
;
2416 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2417 &info1
, callback1
.callback(), NULL
, NULL
,
2419 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2421 // The first request should have triggered initial download of PAC script.
2422 EXPECT_TRUE(fetcher
->has_pending_request());
2423 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2425 // Nothing has been sent to the resolver yet.
2426 EXPECT_TRUE(resolver
->pending_requests().empty());
2428 // At this point the ProxyService should be waiting for the
2429 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2430 // PAC script download completion.
2431 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2433 // Now that the PAC script is downloaded, the request will have been sent to
2434 // the proxy resolver.
2435 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2436 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2437 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2439 ASSERT_EQ(1u, resolver
->pending_requests().size());
2440 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2442 // Complete the pending request.
2443 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2444 resolver
->pending_requests()[0]->CompleteNow(OK
);
2446 // Wait for completion callback, and verify that the request ran as expected.
2447 EXPECT_EQ(OK
, callback1
.WaitForResult());
2448 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2450 // Now simluate a change in the network. The ProxyConfigService is still
2451 // going to return the same PAC URL as before, but this URL needs to be
2452 // refetched on the new network.
2453 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
2454 base::MessageLoop::current()->RunUntilIdle(); // Notification happens async.
2456 // Start a second request.
2458 TestCompletionCallback callback2
;
2459 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
2460 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2461 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2463 // This second request should have triggered the re-download of the PAC
2464 // script (since we marked the network as having changed).
2465 EXPECT_TRUE(fetcher
->has_pending_request());
2466 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2468 // Nothing has been sent to the resolver yet.
2469 EXPECT_TRUE(resolver
->pending_requests().empty());
2471 // Simulate the PAC script fetch as having completed (this time with
2473 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript2
);
2475 // Now that the PAC script is downloaded, the second request will have been
2476 // sent to the proxy resolver.
2477 EXPECT_EQ(ASCIIToUTF16(kValidPacScript2
),
2478 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2479 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2481 ASSERT_EQ(1u, resolver
->pending_requests().size());
2482 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[0]->url());
2484 // Complete the pending second request.
2485 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
2486 resolver
->pending_requests()[0]->CompleteNow(OK
);
2488 // Wait for completion callback, and verify that the request ran as expected.
2489 EXPECT_EQ(OK
, callback2
.WaitForResult());
2490 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2492 // Check that the expected events were output to the log stream. In particular
2493 // PROXY_CONFIG_CHANGED should have only been emitted once (for the initial
2494 // setup), and NOT a second time when the IP address changed.
2495 CapturingNetLog::CapturedEntryList entries
;
2496 log
.GetEntries(&entries
);
2498 EXPECT_TRUE(LogContainsEntryWithType(entries
, 0,
2499 NetLog::TYPE_PROXY_CONFIG_CHANGED
));
2500 ASSERT_EQ(9u, entries
.size());
2501 for (size_t i
= 1; i
< entries
.size(); ++i
)
2502 EXPECT_NE(NetLog::TYPE_PROXY_CONFIG_CHANGED
, entries
[i
].type
);
2505 // This test verifies that the PAC script specified by the settings is
2506 // periodically polled for changes. Specifically, if the initial fetch fails due
2507 // to a network error, we will eventually re-configure the service to use the
2508 // script once it becomes available.
2509 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterFailure
) {
2510 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2512 ImmediatePollPolicy poll_policy
;
2513 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2515 MockProxyConfigService
* config_service
=
2516 new MockProxyConfigService("http://foopy/proxy.pac");
2518 MockAsyncProxyResolverExpectsBytes
* resolver
=
2519 new MockAsyncProxyResolverExpectsBytes
;
2521 ProxyService
service(config_service
, resolver
, NULL
);
2523 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2524 service
.SetProxyScriptFetchers(fetcher
,
2525 new DoNothingDhcpProxyScriptFetcher());
2530 TestCompletionCallback callback1
;
2531 int rv
= service
.ResolveProxy(
2532 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2533 NULL
, NULL
, BoundNetLog());
2534 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2536 // The first request should have triggered initial download of PAC script.
2537 EXPECT_TRUE(fetcher
->has_pending_request());
2538 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2540 // Nothing has been sent to the resolver yet.
2541 EXPECT_TRUE(resolver
->pending_requests().empty());
2543 // At this point the ProxyService should be waiting for the
2544 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2545 // PAC script download completion.
2547 // We simulate a failed download attempt, the proxy service should now
2548 // fall-back to DIRECT connections.
2549 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2551 ASSERT_TRUE(resolver
->pending_requests().empty());
2553 // Wait for completion callback, and verify it used DIRECT.
2554 EXPECT_EQ(OK
, callback1
.WaitForResult());
2555 EXPECT_TRUE(info1
.is_direct());
2557 // At this point we have initialized the proxy service using a PAC script,
2558 // however it failed and fell-back to DIRECT.
2560 // A background task to periodically re-check the PAC script for validity will
2561 // have been started. We will now wait for the next download attempt to start.
2563 // Note that we shouldn't have to wait long here, since our test enables a
2564 // special unit-test mode.
2565 fetcher
->WaitUntilFetch();
2567 ASSERT_TRUE(resolver
->pending_requests().empty());
2569 // Make sure that our background checker is trying to download the expected
2570 // PAC script (same one as before). This time we will simulate a successful
2571 // download of the script.
2572 EXPECT_TRUE(fetcher
->has_pending_request());
2573 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2574 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2576 base::MessageLoop::current()->RunUntilIdle();
2578 // Now that the PAC script is downloaded, it should be used to initialize the
2579 // ProxyResolver. Simulate a successful parse.
2580 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2581 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2582 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2584 // At this point the ProxyService should have re-configured itself to use the
2585 // PAC script (thereby recovering from the initial fetch failure). We will
2586 // verify that the next Resolve request uses the resolver rather than
2589 // Start a second request.
2591 TestCompletionCallback callback2
;
2592 rv
= service
.ResolveProxy(
2593 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2594 NULL
, NULL
, BoundNetLog());
2595 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2597 // Check that it was sent to the resolver.
2598 ASSERT_EQ(1u, resolver
->pending_requests().size());
2599 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[0]->url());
2601 // Complete the pending second request.
2602 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
2603 resolver
->pending_requests()[0]->CompleteNow(OK
);
2605 // Wait for completion callback, and verify that the request ran as expected.
2606 EXPECT_EQ(OK
, callback2
.WaitForResult());
2607 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2610 // This test verifies that the PAC script specified by the settings is
2611 // periodically polled for changes. Specifically, if the initial fetch succeeds,
2612 // however at a later time its *contents* change, we will eventually
2613 // re-configure the service to use the new script.
2614 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterContentChange
) {
2615 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2617 ImmediatePollPolicy poll_policy
;
2618 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2620 MockProxyConfigService
* config_service
=
2621 new MockProxyConfigService("http://foopy/proxy.pac");
2623 MockAsyncProxyResolverExpectsBytes
* resolver
=
2624 new MockAsyncProxyResolverExpectsBytes
;
2626 ProxyService
service(config_service
, resolver
, NULL
);
2628 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2629 service
.SetProxyScriptFetchers(fetcher
,
2630 new DoNothingDhcpProxyScriptFetcher());
2635 TestCompletionCallback callback1
;
2636 int rv
= service
.ResolveProxy(
2637 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2638 NULL
, NULL
, BoundNetLog());
2639 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2641 // The first request should have triggered initial download of PAC script.
2642 EXPECT_TRUE(fetcher
->has_pending_request());
2643 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2645 // Nothing has been sent to the resolver yet.
2646 EXPECT_TRUE(resolver
->pending_requests().empty());
2648 // At this point the ProxyService should be waiting for the
2649 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2650 // PAC script download completion.
2651 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2653 // Now that the PAC script is downloaded, the request will have been sent to
2654 // the proxy resolver.
2655 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2656 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2657 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2659 ASSERT_EQ(1u, resolver
->pending_requests().size());
2660 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2662 // Complete the pending request.
2663 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2664 resolver
->pending_requests()[0]->CompleteNow(OK
);
2666 // Wait for completion callback, and verify that the request ran as expected.
2667 EXPECT_EQ(OK
, callback1
.WaitForResult());
2668 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2670 // At this point we have initialized the proxy service using a PAC script.
2672 // A background task to periodically re-check the PAC script for validity will
2673 // have been started. We will now wait for the next download attempt to start.
2675 // Note that we shouldn't have to wait long here, since our test enables a
2676 // special unit-test mode.
2677 fetcher
->WaitUntilFetch();
2679 ASSERT_TRUE(resolver
->pending_requests().empty());
2681 // Make sure that our background checker is trying to download the expected
2682 // PAC script (same one as before). This time we will simulate a successful
2683 // download of a DIFFERENT script.
2684 EXPECT_TRUE(fetcher
->has_pending_request());
2685 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2686 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript2
);
2688 base::MessageLoop::current()->RunUntilIdle();
2690 // Now that the PAC script is downloaded, it should be used to initialize the
2691 // ProxyResolver. Simulate a successful parse.
2692 EXPECT_EQ(ASCIIToUTF16(kValidPacScript2
),
2693 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2694 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2696 // At this point the ProxyService should have re-configured itself to use the
2699 // Start a second request.
2701 TestCompletionCallback callback2
;
2702 rv
= service
.ResolveProxy(
2703 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2704 NULL
, NULL
, BoundNetLog());
2705 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2707 // Check that it was sent to the resolver.
2708 ASSERT_EQ(1u, resolver
->pending_requests().size());
2709 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[0]->url());
2711 // Complete the pending second request.
2712 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
2713 resolver
->pending_requests()[0]->CompleteNow(OK
);
2715 // Wait for completion callback, and verify that the request ran as expected.
2716 EXPECT_EQ(OK
, callback2
.WaitForResult());
2717 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2720 // This test verifies that the PAC script specified by the settings is
2721 // periodically polled for changes. Specifically, if the initial fetch succeeds
2722 // and so does the next poll, however the contents of the downloaded script
2723 // have NOT changed, then we do not bother to re-initialize the proxy resolver.
2724 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterContentUnchanged
) {
2725 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2727 ImmediatePollPolicy poll_policy
;
2728 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2730 MockProxyConfigService
* config_service
=
2731 new MockProxyConfigService("http://foopy/proxy.pac");
2733 MockAsyncProxyResolverExpectsBytes
* resolver
=
2734 new MockAsyncProxyResolverExpectsBytes
;
2736 ProxyService
service(config_service
, resolver
, NULL
);
2738 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2739 service
.SetProxyScriptFetchers(fetcher
,
2740 new DoNothingDhcpProxyScriptFetcher());
2745 TestCompletionCallback callback1
;
2746 int rv
= service
.ResolveProxy(
2747 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2748 NULL
, NULL
, BoundNetLog());
2749 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2751 // The first request should have triggered initial download of PAC script.
2752 EXPECT_TRUE(fetcher
->has_pending_request());
2753 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2755 // Nothing has been sent to the resolver yet.
2756 EXPECT_TRUE(resolver
->pending_requests().empty());
2758 // At this point the ProxyService should be waiting for the
2759 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2760 // PAC script download completion.
2761 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2763 // Now that the PAC script is downloaded, the request will have been sent to
2764 // the proxy resolver.
2765 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2766 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2767 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2769 ASSERT_EQ(1u, resolver
->pending_requests().size());
2770 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2772 // Complete the pending request.
2773 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2774 resolver
->pending_requests()[0]->CompleteNow(OK
);
2776 // Wait for completion callback, and verify that the request ran as expected.
2777 EXPECT_EQ(OK
, callback1
.WaitForResult());
2778 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2780 // At this point we have initialized the proxy service using a PAC script.
2782 // A background task to periodically re-check the PAC script for validity will
2783 // have been started. We will now wait for the next download attempt to start.
2785 // Note that we shouldn't have to wait long here, since our test enables a
2786 // special unit-test mode.
2787 fetcher
->WaitUntilFetch();
2789 ASSERT_TRUE(resolver
->pending_requests().empty());
2791 // Make sure that our background checker is trying to download the expected
2792 // PAC script (same one as before). We will simulate the same response as
2793 // last time (i.e. the script is unchanged).
2794 EXPECT_TRUE(fetcher
->has_pending_request());
2795 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2796 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2798 base::MessageLoop::current()->RunUntilIdle();
2800 ASSERT_FALSE(resolver
->has_pending_set_pac_script_request());
2802 // At this point the ProxyService is still running the same PAC script as
2805 // Start a second request.
2807 TestCompletionCallback callback2
;
2808 rv
= service
.ResolveProxy(
2809 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2810 NULL
, NULL
, BoundNetLog());
2811 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2813 // Check that it was sent to the resolver.
2814 ASSERT_EQ(1u, resolver
->pending_requests().size());
2815 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[0]->url());
2817 // Complete the pending second request.
2818 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
2819 resolver
->pending_requests()[0]->CompleteNow(OK
);
2821 // Wait for completion callback, and verify that the request ran as expected.
2822 EXPECT_EQ(OK
, callback2
.WaitForResult());
2823 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2826 // This test verifies that the PAC script specified by the settings is
2827 // periodically polled for changes. Specifically, if the initial fetch succeeds,
2828 // however at a later time it starts to fail, we should re-configure the
2829 // ProxyService to stop using that PAC script.
2830 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterSuccess
) {
2831 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2833 ImmediatePollPolicy poll_policy
;
2834 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2836 MockProxyConfigService
* config_service
=
2837 new MockProxyConfigService("http://foopy/proxy.pac");
2839 MockAsyncProxyResolverExpectsBytes
* resolver
=
2840 new MockAsyncProxyResolverExpectsBytes
;
2842 ProxyService
service(config_service
, resolver
, NULL
);
2844 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2845 service
.SetProxyScriptFetchers(fetcher
,
2846 new DoNothingDhcpProxyScriptFetcher());
2851 TestCompletionCallback callback1
;
2852 int rv
= service
.ResolveProxy(
2853 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2854 NULL
, NULL
, BoundNetLog());
2855 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2857 // The first request should have triggered initial download of PAC script.
2858 EXPECT_TRUE(fetcher
->has_pending_request());
2859 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2861 // Nothing has been sent to the resolver yet.
2862 EXPECT_TRUE(resolver
->pending_requests().empty());
2864 // At this point the ProxyService should be waiting for the
2865 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2866 // PAC script download completion.
2867 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2869 // Now that the PAC script is downloaded, the request will have been sent to
2870 // the proxy resolver.
2871 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2872 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2873 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2875 ASSERT_EQ(1u, resolver
->pending_requests().size());
2876 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2878 // Complete the pending request.
2879 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2880 resolver
->pending_requests()[0]->CompleteNow(OK
);
2882 // Wait for completion callback, and verify that the request ran as expected.
2883 EXPECT_EQ(OK
, callback1
.WaitForResult());
2884 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2886 // At this point we have initialized the proxy service using a PAC script.
2888 // A background task to periodically re-check the PAC script for validity will
2889 // have been started. We will now wait for the next download attempt to start.
2891 // Note that we shouldn't have to wait long here, since our test enables a
2892 // special unit-test mode.
2893 fetcher
->WaitUntilFetch();
2895 ASSERT_TRUE(resolver
->pending_requests().empty());
2897 // Make sure that our background checker is trying to download the expected
2898 // PAC script (same one as before). This time we will simulate a failure
2899 // to download the script.
2900 EXPECT_TRUE(fetcher
->has_pending_request());
2901 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2902 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2904 base::MessageLoop::current()->RunUntilIdle();
2906 // At this point the ProxyService should have re-configured itself to use
2907 // DIRECT connections rather than the given proxy resolver.
2909 // Start a second request.
2911 TestCompletionCallback callback2
;
2912 rv
= service
.ResolveProxy(
2913 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2914 NULL
, NULL
, BoundNetLog());
2916 EXPECT_TRUE(info2
.is_direct());
2919 // Tests that the code which decides at what times to poll the PAC
2920 // script follows the expected policy.
2921 TEST_F(ProxyServiceTest
, PACScriptPollingPolicy
) {
2922 // Retrieve the internal polling policy implementation used by ProxyService.
2923 scoped_ptr
<ProxyService::PacPollPolicy
> policy
=
2924 ProxyService::CreateDefaultPacPollPolicy();
2927 ProxyService::PacPollPolicy::Mode mode
;
2928 const base::TimeDelta initial_delay
= base::TimeDelta::FromMilliseconds(-1);
2929 base::TimeDelta delay
= initial_delay
;
2931 // --------------------------------------------------
2932 // Test the poll sequence in response to a failure.
2933 // --------------------------------------------------
2934 error
= ERR_NAME_NOT_RESOLVED
;
2937 mode
= policy
->GetNextDelay(error
, initial_delay
, &delay
);
2938 EXPECT_EQ(8, delay
.InSeconds());
2939 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_USE_TIMER
, mode
);
2942 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2943 EXPECT_EQ(32, delay
.InSeconds());
2944 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2947 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2948 EXPECT_EQ(120, delay
.InSeconds());
2949 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2952 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2953 EXPECT_EQ(14400, delay
.InSeconds());
2954 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2957 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2958 EXPECT_EQ(14400, delay
.InSeconds());
2959 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2961 // --------------------------------------------------
2962 // Test the poll sequence in response to a success.
2963 // --------------------------------------------------
2967 mode
= policy
->GetNextDelay(error
, initial_delay
, &delay
);
2968 EXPECT_EQ(43200, delay
.InSeconds());
2969 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2972 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2973 EXPECT_EQ(43200, delay
.InSeconds());
2974 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2977 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2978 EXPECT_EQ(43200, delay
.InSeconds());
2979 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2982 // This tests the polling of the PAC script. Specifically, it tests that
2983 // polling occurs in response to user activity.
2984 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterActivity
) {
2985 ImmediateAfterActivityPollPolicy poll_policy
;
2986 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2988 MockProxyConfigService
* config_service
=
2989 new MockProxyConfigService("http://foopy/proxy.pac");
2991 MockAsyncProxyResolverExpectsBytes
* resolver
=
2992 new MockAsyncProxyResolverExpectsBytes
;
2994 ProxyService
service(config_service
, resolver
, NULL
);
2996 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2997 service
.SetProxyScriptFetchers(fetcher
,
2998 new DoNothingDhcpProxyScriptFetcher());
3003 TestCompletionCallback callback1
;
3004 int rv
= service
.ResolveProxy(
3005 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
3006 NULL
, NULL
, BoundNetLog());
3007 EXPECT_EQ(ERR_IO_PENDING
, rv
);
3009 // The first request should have triggered initial download of PAC script.
3010 EXPECT_TRUE(fetcher
->has_pending_request());
3011 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
3013 // Nothing has been sent to the resolver yet.
3014 EXPECT_TRUE(resolver
->pending_requests().empty());
3016 // At this point the ProxyService should be waiting for the
3017 // ProxyScriptFetcher to invoke its completion callback, notifying it of
3018 // PAC script download completion.
3019 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
3021 // Now that the PAC script is downloaded, the request will have been sent to
3022 // the proxy resolver.
3023 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
3024 resolver
->pending_set_pac_script_request()->script_data()->utf16());
3025 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
3027 ASSERT_EQ(1u, resolver
->pending_requests().size());
3028 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
3030 // Complete the pending request.
3031 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
3032 resolver
->pending_requests()[0]->CompleteNow(OK
);
3034 // Wait for completion callback, and verify that the request ran as expected.
3035 EXPECT_EQ(OK
, callback1
.WaitForResult());
3036 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
3038 // At this point we have initialized the proxy service using a PAC script.
3039 // Our PAC poller is set to update ONLY in response to network activity,
3040 // (i.e. another call to ResolveProxy()).
3042 ASSERT_FALSE(fetcher
->has_pending_request());
3043 ASSERT_TRUE(resolver
->pending_requests().empty());
3045 // Start a second request.
3047 TestCompletionCallback callback2
;
3048 rv
= service
.ResolveProxy(
3049 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
3050 NULL
, NULL
, BoundNetLog());
3051 EXPECT_EQ(ERR_IO_PENDING
, rv
);
3053 // This request should have sent work to the resolver; complete it.
3054 ASSERT_EQ(1u, resolver
->pending_requests().size());
3055 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[0]->url());
3056 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
3057 resolver
->pending_requests()[0]->CompleteNow(OK
);
3059 EXPECT_EQ(OK
, callback2
.WaitForResult());
3060 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
3062 // In response to getting that resolve request, the poller should have
3063 // started the next poll, and made it as far as to request the download.
3065 EXPECT_TRUE(fetcher
->has_pending_request());
3066 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
3068 // This time we will fail the download, to simulate a PAC script change.
3069 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
3071 // Drain the message loop, so ProxyService is notified of the change
3072 // and has a chance to re-configure itself.
3073 base::MessageLoop::current()->RunUntilIdle();
3075 // Start a third request -- this time we expect to get a direct connection
3076 // since the PAC script poller experienced a failure.
3078 TestCompletionCallback callback3
;
3079 rv
= service
.ResolveProxy(
3080 GURL("http://request3"), net::LOAD_NORMAL
, &info3
, callback3
.callback(),
3081 NULL
, NULL
, BoundNetLog());
3083 EXPECT_TRUE(info3
.is_direct());
3086 // Test that the synchronous resolution fails when a PAC script is active.
3087 TEST_F(ProxyServiceTest
, SynchronousWithPAC
) {
3088 MockProxyConfigService
* config_service
=
3089 new MockProxyConfigService("http://foopy/proxy.pac");
3091 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver();
3093 ProxyService
service(config_service
, resolver
, NULL
);
3095 GURL
url("http://www.google.com/");
3099 CapturingBoundNetLog log
;
3101 bool synchronous_success
= service
.TryResolveProxySynchronously(
3102 url
, net::LOAD_NORMAL
, &info
, NULL
, log
.bound());
3103 EXPECT_FALSE(synchronous_success
);
3105 // No request should have been queued.
3106 EXPECT_EQ(0u, resolver
->pending_requests().size());
3108 // |info| should not have been modified.
3109 EXPECT_TRUE(info
.is_direct());
3112 // Test that synchronous results are returned correctly if a fixed proxy
3113 // configuration is active.
3114 TEST_F(ProxyServiceTest
, SynchronousWithFixedConfiguration
) {
3116 config
.proxy_rules().ParseFromString("foopy1:8080");
3117 config
.set_auto_detect(false);
3119 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver();
3121 ProxyService
service(new MockProxyConfigService(config
), resolver
, NULL
);
3123 GURL
url("http://www.google.com/");
3126 CapturingBoundNetLog log
;
3128 bool synchronous_success
= service
.TryResolveProxySynchronously(
3129 url
, net::LOAD_NORMAL
, &info
, NULL
, log
.bound());
3130 EXPECT_TRUE(synchronous_success
);
3131 EXPECT_FALSE(info
.is_direct());
3132 EXPECT_EQ("foopy1", info
.proxy_server().host_port_pair().host());
3134 // No request should have been queued.
3135 EXPECT_EQ(0u, resolver
->pending_requests().size());