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.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 virtual Mode
GetNextDelay(int error
, base::TimeDelta current_delay
,
41 base::TimeDelta
* next_delay
) const override
{
42 *next_delay
= base::TimeDelta::FromMilliseconds(1);
43 return MODE_USE_TIMER
;
47 DISALLOW_COPY_AND_ASSIGN(ImmediatePollPolicy
);
50 // This polling policy chooses a fantastically large delay. In other words, it
51 // will never trigger a poll
52 class NeverPollPolicy
: public ProxyService::PacPollPolicy
{
56 virtual Mode
GetNextDelay(int error
, base::TimeDelta current_delay
,
57 base::TimeDelta
* next_delay
) const override
{
58 *next_delay
= base::TimeDelta::FromDays(60);
59 return MODE_USE_TIMER
;
63 DISALLOW_COPY_AND_ASSIGN(NeverPollPolicy
);
66 // This polling policy starts a poll immediately after network activity.
67 class ImmediateAfterActivityPollPolicy
: public ProxyService::PacPollPolicy
{
69 ImmediateAfterActivityPollPolicy() {}
71 virtual Mode
GetNextDelay(int error
, base::TimeDelta current_delay
,
72 base::TimeDelta
* next_delay
) const override
{
73 *next_delay
= base::TimeDelta();
74 return MODE_START_AFTER_ACTIVITY
;
78 DISALLOW_COPY_AND_ASSIGN(ImmediateAfterActivityPollPolicy
);
81 // This test fixture is used to partially disable the background polling done by
82 // the ProxyService (which it uses to detect whenever its PAC script contents or
83 // WPAD results have changed).
85 // We disable the feature by setting the poll interval to something really
86 // large, so it will never actually be reached even on the slowest bots that run
89 // We disable the polling in order to avoid any timing dependencies in the
90 // tests. If the bot were to run the tests very slowly and we hadn't disabled
91 // polling, then it might start a background re-try in the middle of our test
92 // and confuse our expectations leading to flaky failures.
94 // The tests which verify the polling code re-enable the polling behavior but
95 // are careful to avoid timing problems.
96 class ProxyServiceTest
: public testing::Test
{
98 virtual void SetUp() override
{
99 testing::Test::SetUp();
101 ProxyService::set_pac_script_poll_policy(&never_poll_policy_
);
104 virtual void TearDown() override
{
105 // Restore the original policy.
106 ProxyService::set_pac_script_poll_policy(previous_policy_
);
107 testing::Test::TearDown();
111 NeverPollPolicy never_poll_policy_
;
112 const ProxyService::PacPollPolicy
* previous_policy_
;
115 const char kValidPacScript1
[] = "pac-script-v1-FindProxyForURL";
116 const char kValidPacScript2
[] = "pac-script-v2-FindProxyForURL";
118 class MockProxyConfigService
: public ProxyConfigService
{
120 explicit MockProxyConfigService(const ProxyConfig
& config
)
121 : availability_(CONFIG_VALID
),
125 explicit MockProxyConfigService(const std::string
& pac_url
)
126 : availability_(CONFIG_VALID
),
127 config_(ProxyConfig::CreateFromCustomPacURL(GURL(pac_url
))) {
130 virtual void AddObserver(Observer
* observer
) override
{
131 observers_
.AddObserver(observer
);
134 virtual void RemoveObserver(Observer
* observer
) override
{
135 observers_
.RemoveObserver(observer
);
138 virtual ConfigAvailability
GetLatestProxyConfig(ProxyConfig
* results
)
140 if (availability_
== CONFIG_VALID
)
142 return availability_
;
145 void SetConfig(const ProxyConfig
& config
) {
146 availability_
= CONFIG_VALID
;
148 FOR_EACH_OBSERVER(Observer
, observers_
,
149 OnProxyConfigChanged(config_
, availability_
));
153 ConfigAvailability availability_
;
155 ObserverList
<Observer
, true> observers_
;
158 // A test network delegate that exercises the OnResolveProxy callback.
159 class TestResolveProxyNetworkDelegate
: public NetworkDelegate
{
161 TestResolveProxyNetworkDelegate()
162 : on_resolve_proxy_called_(false),
164 remove_proxy_(false),
165 proxy_service_(NULL
) {
168 virtual void OnResolveProxy(const GURL
& url
,
170 const ProxyService
& proxy_service
,
171 ProxyInfo
* result
) override
{
172 on_resolve_proxy_called_
= true;
173 proxy_service_
= &proxy_service
;
174 DCHECK(!add_proxy_
|| !remove_proxy_
);
176 result
->UseNamedProxy("delegate_proxy.com");
177 } else if (remove_proxy_
) {
182 bool on_resolve_proxy_called() const {
183 return on_resolve_proxy_called_
;
186 void set_add_proxy(bool add_proxy
) {
187 add_proxy_
= add_proxy
;
190 void set_remove_proxy(bool remove_proxy
) {
191 remove_proxy_
= remove_proxy
;
194 const ProxyService
* proxy_service() const {
195 return proxy_service_
;
199 bool on_resolve_proxy_called_
;
202 const ProxyService
* proxy_service_
;
205 // A test network delegate that exercises the OnProxyFallback callback.
206 class TestProxyFallbackNetworkDelegate
: public NetworkDelegate
{
208 TestProxyFallbackNetworkDelegate()
209 : on_proxy_fallback_called_(false),
210 proxy_fallback_net_error_(OK
) {
213 virtual void OnProxyFallback(const ProxyServer
& proxy_server
,
214 int net_error
) override
{
215 proxy_server_
= proxy_server
;
216 proxy_fallback_net_error_
= net_error
;
217 on_proxy_fallback_called_
= true;
220 bool on_proxy_fallback_called() const {
221 return on_proxy_fallback_called_
;
224 const ProxyServer
& proxy_server() const {
225 return proxy_server_
;
228 int proxy_fallback_net_error() const {
229 return proxy_fallback_net_error_
;
233 bool on_proxy_fallback_called_
;
234 ProxyServer proxy_server_
;
235 int proxy_fallback_net_error_
;
240 TEST_F(ProxyServiceTest
, Direct
) {
241 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
242 ProxyService
service(new MockProxyConfigService(
243 ProxyConfig::CreateDirect()), resolver
, NULL
);
245 GURL
url("http://www.google.com/");
248 TestCompletionCallback callback
;
249 CapturingBoundNetLog log
;
250 int rv
= service
.ResolveProxy(
251 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
254 EXPECT_TRUE(resolver
->pending_requests().empty());
256 EXPECT_TRUE(info
.is_direct());
257 EXPECT_TRUE(info
.proxy_resolve_start_time().is_null());
258 EXPECT_TRUE(info
.proxy_resolve_end_time().is_null());
260 // Check the NetLog was filled correctly.
261 CapturingNetLog::CapturedEntryList entries
;
262 log
.GetEntries(&entries
);
264 EXPECT_EQ(3u, entries
.size());
265 EXPECT_TRUE(LogContainsBeginEvent(
266 entries
, 0, NetLog::TYPE_PROXY_SERVICE
));
267 EXPECT_TRUE(LogContainsEvent(
268 entries
, 1, NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST
,
269 NetLog::PHASE_NONE
));
270 EXPECT_TRUE(LogContainsEndEvent(
271 entries
, 2, NetLog::TYPE_PROXY_SERVICE
));
274 TEST_F(ProxyServiceTest
, OnResolveProxyCallbackAddProxy
) {
276 config
.proxy_rules().ParseFromString("foopy1:8080");
277 config
.set_auto_detect(false);
278 config
.proxy_rules().bypass_rules
.ParseFromString("*.org");
280 ProxyService
service(
281 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
283 GURL
url("http://www.google.com/");
284 GURL
bypass_url("http://internet.org");
287 TestCompletionCallback callback
;
288 CapturingBoundNetLog log
;
290 // First, warm up the ProxyService.
291 int rv
= service
.ResolveProxy(
292 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
296 // Verify that network delegate is invoked.
297 TestResolveProxyNetworkDelegate delegate
;
298 rv
= service
.ResolveProxy(
299 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
301 EXPECT_TRUE(delegate
.on_resolve_proxy_called());
302 EXPECT_EQ(&service
, delegate
.proxy_service());
304 // Verify that the NetworkDelegate's behavior is stateless across
305 // invocations of ResolveProxy. Start by having the callback add a proxy
306 // and checking that subsequent requests are not affected.
307 delegate
.set_add_proxy(true);
309 // Callback should interpose:
310 rv
= service
.ResolveProxy(
311 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
313 EXPECT_FALSE(info
.is_direct());
314 EXPECT_EQ(info
.proxy_server().host_port_pair().host(), "delegate_proxy.com");
315 delegate
.set_add_proxy(false);
317 // Check non-bypassed URL:
318 rv
= service
.ResolveProxy(
319 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
321 EXPECT_FALSE(info
.is_direct());
322 EXPECT_EQ(info
.proxy_server().host_port_pair().host(), "foopy1");
324 // Check bypassed URL:
325 rv
= service
.ResolveProxy(
326 bypass_url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
,
327 &delegate
, log
.bound());
328 EXPECT_TRUE(info
.is_direct());
331 TEST_F(ProxyServiceTest
, OnResolveProxyCallbackRemoveProxy
) {
332 // Same as OnResolveProxyCallbackAddProxy, but verify that the
333 // NetworkDelegate's behavior is stateless across invocations after it
334 // *removes* a proxy.
336 config
.proxy_rules().ParseFromString("foopy1:8080");
337 config
.set_auto_detect(false);
338 config
.proxy_rules().bypass_rules
.ParseFromString("*.org");
340 ProxyService
service(
341 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
343 GURL
url("http://www.google.com/");
344 GURL
bypass_url("http://internet.org");
347 TestCompletionCallback callback
;
348 CapturingBoundNetLog log
;
350 // First, warm up the ProxyService.
351 int rv
= service
.ResolveProxy(
352 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
356 TestResolveProxyNetworkDelegate delegate
;
357 delegate
.set_remove_proxy(true);
359 // Callback should interpose:
360 rv
= service
.ResolveProxy(
361 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
363 EXPECT_TRUE(info
.is_direct());
364 delegate
.set_remove_proxy(false);
366 // Check non-bypassed URL:
367 rv
= service
.ResolveProxy(
368 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
370 EXPECT_FALSE(info
.is_direct());
371 EXPECT_EQ(info
.proxy_server().host_port_pair().host(), "foopy1");
373 // Check bypassed URL:
374 rv
= service
.ResolveProxy(
375 bypass_url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
,
376 &delegate
, log
.bound());
377 EXPECT_TRUE(info
.is_direct());
380 TEST_F(ProxyServiceTest
, PAC
) {
381 MockProxyConfigService
* config_service
=
382 new MockProxyConfigService("http://foopy/proxy.pac");
384 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
386 ProxyService
service(config_service
, resolver
, NULL
);
388 GURL
url("http://www.google.com/");
391 TestCompletionCallback callback
;
392 ProxyService::PacRequest
* request
;
393 CapturingBoundNetLog log
;
395 int rv
= service
.ResolveProxy(
396 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), &request
, NULL
,
398 EXPECT_EQ(ERR_IO_PENDING
, rv
);
400 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request
));
402 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
403 resolver
->pending_set_pac_script_request()->script_data()->url());
404 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
406 ASSERT_EQ(1u, resolver
->pending_requests().size());
407 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
409 // Set the result in proxy resolver.
410 resolver
->pending_requests()[0]->results()->UseNamedProxy("foopy");
411 resolver
->pending_requests()[0]->CompleteNow(OK
);
413 EXPECT_EQ(OK
, callback
.WaitForResult());
414 EXPECT_FALSE(info
.is_direct());
415 EXPECT_EQ("foopy:80", info
.proxy_server().ToURI());
416 EXPECT_TRUE(info
.did_use_pac_script());
418 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
419 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
420 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
422 // Check the NetLog was filled correctly.
423 CapturingNetLog::CapturedEntryList entries
;
424 log
.GetEntries(&entries
);
426 EXPECT_EQ(5u, entries
.size());
427 EXPECT_TRUE(LogContainsBeginEvent(
428 entries
, 0, NetLog::TYPE_PROXY_SERVICE
));
429 EXPECT_TRUE(LogContainsBeginEvent(
430 entries
, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
431 EXPECT_TRUE(LogContainsEndEvent(
432 entries
, 2, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
433 EXPECT_TRUE(LogContainsEndEvent(
434 entries
, 4, NetLog::TYPE_PROXY_SERVICE
));
437 // Test that the proxy resolver does not see the URL's username/password
438 // or its reference section.
439 TEST_F(ProxyServiceTest
, PAC_NoIdentityOrHash
) {
440 MockProxyConfigService
* config_service
=
441 new MockProxyConfigService("http://foopy/proxy.pac");
443 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
445 ProxyService
service(config_service
, resolver
, NULL
);
447 GURL
url("http://username:password@www.google.com/?ref#hash#hash");
450 TestCompletionCallback callback
;
451 int rv
= service
.ResolveProxy(
452 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
454 EXPECT_EQ(ERR_IO_PENDING
, rv
);
456 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
457 resolver
->pending_set_pac_script_request()->script_data()->url());
458 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
460 ASSERT_EQ(1u, resolver
->pending_requests().size());
461 // The URL should have been simplified, stripping the username/password/hash.
462 EXPECT_EQ(GURL("http://www.google.com/?ref"),
463 resolver
->pending_requests()[0]->url());
465 // We end here without ever completing the request -- destruction of
466 // ProxyService will cancel the outstanding request.
469 TEST_F(ProxyServiceTest
, PAC_FailoverWithoutDirect
) {
470 MockProxyConfigService
* config_service
=
471 new MockProxyConfigService("http://foopy/proxy.pac");
472 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
474 ProxyService
service(config_service
, resolver
, NULL
);
476 GURL
url("http://www.google.com/");
479 TestCompletionCallback callback1
;
480 int rv
= service
.ResolveProxy(
481 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
483 EXPECT_EQ(ERR_IO_PENDING
, rv
);
485 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
486 resolver
->pending_set_pac_script_request()->script_data()->url());
487 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
489 ASSERT_EQ(1u, resolver
->pending_requests().size());
490 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
492 // Set the result in proxy resolver.
493 resolver
->pending_requests()[0]->results()->UseNamedProxy("foopy:8080");
494 resolver
->pending_requests()[0]->CompleteNow(OK
);
496 EXPECT_EQ(OK
, callback1
.WaitForResult());
497 EXPECT_FALSE(info
.is_direct());
498 EXPECT_EQ("foopy:8080", info
.proxy_server().ToURI());
499 EXPECT_TRUE(info
.did_use_pac_script());
501 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
502 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
503 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
505 // Now, imagine that connecting to foopy:8080 fails: there is nothing
506 // left to fallback to, since our proxy list was NOT terminated by
508 NetworkDelegate network_delegate
;
509 TestCompletionCallback callback2
;
510 ProxyServer expected_proxy_server
= info
.proxy_server();
511 rv
= service
.ReconsiderProxyAfterError(
512 url
, net::LOAD_NORMAL
, net::ERR_PROXY_CONNECTION_FAILED
,
513 &info
, callback2
.callback(), NULL
, &network_delegate
, BoundNetLog());
514 // ReconsiderProxyAfterError returns error indicating nothing left.
515 EXPECT_EQ(ERR_FAILED
, rv
);
516 EXPECT_TRUE(info
.is_empty());
519 // Test that if the execution of the PAC script fails (i.e. javascript runtime
520 // error), and the PAC settings are non-mandatory, that we fall-back to direct.
521 TEST_F(ProxyServiceTest
, PAC_RuntimeError
) {
522 MockProxyConfigService
* config_service
=
523 new MockProxyConfigService("http://foopy/proxy.pac");
524 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
526 ProxyService
service(config_service
, resolver
, NULL
);
528 GURL
url("http://this-causes-js-error/");
531 TestCompletionCallback callback1
;
532 int rv
= service
.ResolveProxy(
533 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
535 EXPECT_EQ(ERR_IO_PENDING
, rv
);
537 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
538 resolver
->pending_set_pac_script_request()->script_data()->url());
539 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
541 ASSERT_EQ(1u, resolver
->pending_requests().size());
542 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
544 // Simulate a failure in the PAC executor.
545 resolver
->pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_FAILED
);
547 EXPECT_EQ(OK
, callback1
.WaitForResult());
549 // Since the PAC script was non-mandatory, we should have fallen-back to
551 EXPECT_TRUE(info
.is_direct());
552 EXPECT_TRUE(info
.did_use_pac_script());
553 EXPECT_EQ(1, info
.config_id());
555 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
556 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
557 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
560 // The proxy list could potentially contain the DIRECT fallback choice
561 // in a location other than the very end of the list, and could even
562 // specify it multiple times.
564 // This is not a typical usage, but we will obey it.
565 // (If we wanted to disallow this type of input, the right place to
566 // enforce it would be in parsing the PAC result string).
568 // This test will use the PAC result string:
570 // "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20"
572 // For which we expect it to try DIRECT, then foobar:10, then DIRECT again,
573 // then foobar:20, and then give up and error.
575 // The important check of this test is to make sure that DIRECT is not somehow
576 // cached as being a bad proxy.
577 TEST_F(ProxyServiceTest
, PAC_FailoverAfterDirect
) {
578 MockProxyConfigService
* config_service
=
579 new MockProxyConfigService("http://foopy/proxy.pac");
580 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
582 ProxyService
service(config_service
, resolver
, NULL
);
584 GURL
url("http://www.google.com/");
587 TestCompletionCallback callback1
;
588 int rv
= service
.ResolveProxy(
589 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
591 EXPECT_EQ(ERR_IO_PENDING
, rv
);
593 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
594 resolver
->pending_set_pac_script_request()->script_data()->url());
595 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
597 ASSERT_EQ(1u, resolver
->pending_requests().size());
598 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
600 // Set the result in proxy resolver.
601 resolver
->pending_requests()[0]->results()->UsePacString(
602 "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20");
603 resolver
->pending_requests()[0]->CompleteNow(OK
);
605 EXPECT_EQ(OK
, callback1
.WaitForResult());
606 EXPECT_TRUE(info
.is_direct());
609 TestCompletionCallback callback2
;
610 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
611 net::ERR_PROXY_CONNECTION_FAILED
,
612 &info
, callback2
.callback(), NULL
,
613 NULL
, BoundNetLog());
615 EXPECT_FALSE(info
.is_direct());
616 EXPECT_EQ("foobar:10", info
.proxy_server().ToURI());
619 NetworkDelegate network_delegate
;
620 ProxyServer expected_proxy_server3
= info
.proxy_server();
621 TestCompletionCallback callback3
;
622 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
623 net::ERR_PROXY_CONNECTION_FAILED
,
624 &info
, callback3
.callback(), NULL
,
625 &network_delegate
, BoundNetLog());
627 EXPECT_TRUE(info
.is_direct());
630 ProxyServer expected_proxy_server4
= info
.proxy_server();
631 TestCompletionCallback callback4
;
632 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
633 net::ERR_PROXY_CONNECTION_FAILED
,
634 &info
, callback4
.callback(), NULL
,
635 &network_delegate
, BoundNetLog());
637 EXPECT_FALSE(info
.is_direct());
638 EXPECT_EQ("foobar:20", info
.proxy_server().ToURI());
640 // Fallback 4 -- Nothing to fall back to!
641 ProxyServer expected_proxy_server5
= info
.proxy_server();
642 TestCompletionCallback callback5
;
643 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
644 net::ERR_PROXY_CONNECTION_FAILED
,
645 &info
, callback5
.callback(), NULL
,
646 &network_delegate
, BoundNetLog());
647 EXPECT_EQ(ERR_FAILED
, rv
);
648 EXPECT_TRUE(info
.is_empty());
651 TEST_F(ProxyServiceTest
, PAC_ConfigSourcePropagates
) {
652 // Test whether the ProxyConfigSource set by the ProxyConfigService is applied
653 // to ProxyInfo after the proxy is resolved via a PAC script.
655 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
656 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
658 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
659 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
660 ProxyService
service(config_service
, resolver
, NULL
);
662 // Resolve something.
663 GURL
url("http://www.google.com/");
665 TestCompletionCallback callback
;
666 int rv
= service
.ResolveProxy(
667 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
669 ASSERT_EQ(ERR_IO_PENDING
, rv
);
670 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
671 ASSERT_EQ(1u, resolver
->pending_requests().size());
673 // Set the result in proxy resolver.
674 resolver
->pending_requests()[0]->results()->UseNamedProxy("foopy");
675 resolver
->pending_requests()[0]->CompleteNow(OK
);
677 EXPECT_EQ(OK
, callback
.WaitForResult());
678 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
679 EXPECT_TRUE(info
.did_use_pac_script());
681 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
682 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
683 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
686 TEST_F(ProxyServiceTest
, ProxyResolverFails
) {
687 // Test what happens when the ProxyResolver fails. The download and setting
688 // of the PAC script have already succeeded, so this corresponds with a
689 // javascript runtime error while calling FindProxyForURL().
691 MockProxyConfigService
* config_service
=
692 new MockProxyConfigService("http://foopy/proxy.pac");
694 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
696 ProxyService
service(config_service
, resolver
, NULL
);
698 // Start first resolve request.
699 GURL
url("http://www.google.com/");
701 TestCompletionCallback callback1
;
702 int rv
= service
.ResolveProxy(
703 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
705 EXPECT_EQ(ERR_IO_PENDING
, rv
);
707 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
708 resolver
->pending_set_pac_script_request()->script_data()->url());
709 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
711 ASSERT_EQ(1u, resolver
->pending_requests().size());
712 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
714 // Fail the first resolve request in MockAsyncProxyResolver.
715 resolver
->pending_requests()[0]->CompleteNow(ERR_FAILED
);
717 // Although the proxy resolver failed the request, ProxyService implicitly
718 // falls-back to DIRECT.
719 EXPECT_EQ(OK
, callback1
.WaitForResult());
720 EXPECT_TRUE(info
.is_direct());
722 // Failed PAC executions still have proxy resolution times.
723 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
724 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
725 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
727 // The second resolve request will try to run through the proxy resolver,
728 // regardless of whether the first request failed in it.
729 TestCompletionCallback callback2
;
730 rv
= service
.ResolveProxy(
731 url
, net::LOAD_NORMAL
, &info
, callback2
.callback(), NULL
, NULL
,
733 EXPECT_EQ(ERR_IO_PENDING
, rv
);
735 ASSERT_EQ(1u, resolver
->pending_requests().size());
736 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
738 // This time we will have the resolver succeed (perhaps the PAC script has
739 // a dependency on the current time).
740 resolver
->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
741 resolver
->pending_requests()[0]->CompleteNow(OK
);
743 EXPECT_EQ(OK
, callback2
.WaitForResult());
744 EXPECT_FALSE(info
.is_direct());
745 EXPECT_EQ("foopy_valid:8080", info
.proxy_server().ToURI());
748 TEST_F(ProxyServiceTest
, ProxyScriptFetcherFailsDownloadingMandatoryPac
) {
749 // Test what happens when the ProxyScriptResolver fails to download a
750 // mandatory PAC script.
753 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
754 config
.set_pac_mandatory(true);
756 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
758 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
760 ProxyService
service(config_service
, resolver
, NULL
);
762 // Start first resolve request.
763 GURL
url("http://www.google.com/");
765 TestCompletionCallback callback1
;
766 int rv
= service
.ResolveProxy(
767 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
769 EXPECT_EQ(ERR_IO_PENDING
, rv
);
771 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
772 resolver
->pending_set_pac_script_request()->script_data()->url());
773 resolver
->pending_set_pac_script_request()->CompleteNow(ERR_FAILED
);
775 ASSERT_EQ(0u, resolver
->pending_requests().size());
777 // As the proxy resolver failed the request and is configured for a mandatory
778 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
779 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
780 callback1
.WaitForResult());
781 EXPECT_FALSE(info
.is_direct());
783 // As the proxy resolver failed the request and is configured for a mandatory
784 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
785 TestCompletionCallback callback2
;
786 rv
= service
.ResolveProxy(
787 url
, net::LOAD_NORMAL
, &info
, callback2
.callback(), NULL
, NULL
,
789 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
, rv
);
790 EXPECT_FALSE(info
.is_direct());
793 TEST_F(ProxyServiceTest
, ProxyResolverFailsParsingJavaScriptMandatoryPac
) {
794 // Test what happens when the ProxyResolver fails that is configured to use a
795 // mandatory PAC script. The download of the PAC script has already
796 // succeeded but the PAC script contains no valid javascript.
799 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
800 config
.set_pac_mandatory(true);
802 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
804 MockAsyncProxyResolverExpectsBytes
* resolver
=
805 new MockAsyncProxyResolverExpectsBytes
;
807 ProxyService
service(config_service
, resolver
, NULL
);
809 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
810 DhcpProxyScriptFetcher
* dhcp_fetcher
= new DoNothingDhcpProxyScriptFetcher();
811 service
.SetProxyScriptFetchers(fetcher
, dhcp_fetcher
);
813 // Start resolve request.
814 GURL
url("http://www.google.com/");
816 TestCompletionCallback callback
;
817 int rv
= service
.ResolveProxy(
818 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
820 EXPECT_EQ(ERR_IO_PENDING
, rv
);
822 // Check that nothing has been sent to the proxy resolver yet.
823 ASSERT_EQ(0u, resolver
->pending_requests().size());
825 // Downloading the PAC script succeeds.
826 EXPECT_TRUE(fetcher
->has_pending_request());
827 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
828 fetcher
->NotifyFetchCompletion(OK
, "invalid-script-contents");
830 EXPECT_FALSE(fetcher
->has_pending_request());
831 ASSERT_EQ(0u, resolver
->pending_requests().size());
833 // Since ProxyScriptDecider failed to identify a valid PAC and PAC was
834 // mandatory for this configuration, the ProxyService must not implicitly
835 // fall-back to DIRECT.
836 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
837 callback
.WaitForResult());
838 EXPECT_FALSE(info
.is_direct());
841 TEST_F(ProxyServiceTest
, ProxyResolverFailsInJavaScriptMandatoryPac
) {
842 // Test what happens when the ProxyResolver fails that is configured to use a
843 // mandatory PAC script. The download and setting of the PAC script have
844 // already succeeded, so this corresponds with a javascript runtime error
845 // while calling FindProxyForURL().
848 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
849 config
.set_pac_mandatory(true);
851 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
853 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
855 ProxyService
service(config_service
, resolver
, NULL
);
857 // Start first resolve request.
858 GURL
url("http://www.google.com/");
860 TestCompletionCallback callback1
;
861 int rv
= service
.ResolveProxy(
862 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
864 EXPECT_EQ(ERR_IO_PENDING
, rv
);
866 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
867 resolver
->pending_set_pac_script_request()->script_data()->url());
868 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
870 ASSERT_EQ(1u, resolver
->pending_requests().size());
871 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
873 // Fail the first resolve request in MockAsyncProxyResolver.
874 resolver
->pending_requests()[0]->CompleteNow(ERR_FAILED
);
876 // As the proxy resolver failed the request and is configured for a mandatory
877 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
878 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
879 callback1
.WaitForResult());
880 EXPECT_FALSE(info
.is_direct());
882 // The second resolve request will try to run through the proxy resolver,
883 // regardless of whether the first request failed in it.
884 TestCompletionCallback callback2
;
885 rv
= service
.ResolveProxy(
886 url
, net::LOAD_NORMAL
, &info
, callback2
.callback(), NULL
, NULL
,
888 EXPECT_EQ(ERR_IO_PENDING
, rv
);
890 ASSERT_EQ(1u, resolver
->pending_requests().size());
891 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
893 // This time we will have the resolver succeed (perhaps the PAC script has
894 // a dependency on the current time).
895 resolver
->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
896 resolver
->pending_requests()[0]->CompleteNow(OK
);
898 EXPECT_EQ(OK
, callback2
.WaitForResult());
899 EXPECT_FALSE(info
.is_direct());
900 EXPECT_EQ("foopy_valid:8080", info
.proxy_server().ToURI());
903 TEST_F(ProxyServiceTest
, ProxyFallback
) {
904 // Test what happens when we specify multiple proxy servers and some of them
907 MockProxyConfigService
* config_service
=
908 new MockProxyConfigService("http://foopy/proxy.pac");
910 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
912 ProxyService
service(config_service
, resolver
, NULL
);
914 GURL
url("http://www.google.com/");
916 // Get the proxy information.
918 TestCompletionCallback callback1
;
919 int rv
= service
.ResolveProxy(
920 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
922 EXPECT_EQ(ERR_IO_PENDING
, rv
);
924 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
925 resolver
->pending_set_pac_script_request()->script_data()->url());
926 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
928 ASSERT_EQ(1u, resolver
->pending_requests().size());
929 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
931 // Set the result in proxy resolver.
932 resolver
->pending_requests()[0]->results()->UseNamedProxy(
933 "foopy1:8080;foopy2:9090");
934 resolver
->pending_requests()[0]->CompleteNow(OK
);
936 // The first item is valid.
937 EXPECT_EQ(OK
, callback1
.WaitForResult());
938 EXPECT_FALSE(info
.is_direct());
939 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
941 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
942 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
943 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
944 base::TimeTicks proxy_resolve_start_time
= info
.proxy_resolve_start_time();
945 base::TimeTicks proxy_resolve_end_time
= info
.proxy_resolve_end_time();
947 // Fake an error on the proxy.
948 TestCompletionCallback callback2
;
949 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
950 net::ERR_PROXY_CONNECTION_FAILED
,
951 &info
, callback2
.callback(), NULL
,
952 NULL
, BoundNetLog());
955 // Proxy times should not have been modified by fallback.
956 EXPECT_EQ(proxy_resolve_start_time
, info
.proxy_resolve_start_time());
957 EXPECT_EQ(proxy_resolve_end_time
, info
.proxy_resolve_end_time());
959 // The second proxy should be specified.
960 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
961 // Report back that the second proxy worked. This will globally mark the
962 // first proxy as bad.
963 TestProxyFallbackNetworkDelegate test_delegate
;
964 service
.ReportSuccess(info
, &test_delegate
);
965 EXPECT_EQ("foopy1:8080", test_delegate
.proxy_server().ToURI());
966 EXPECT_EQ(net::ERR_PROXY_CONNECTION_FAILED
,
967 test_delegate
.proxy_fallback_net_error());
969 TestCompletionCallback callback3
;
970 rv
= service
.ResolveProxy(
971 url
, net::LOAD_NORMAL
, &info
, callback3
.callback(), NULL
, NULL
,
973 EXPECT_EQ(ERR_IO_PENDING
, rv
);
975 ASSERT_EQ(1u, resolver
->pending_requests().size());
976 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
978 // Set the result in proxy resolver -- the second result is already known
979 // to be bad, so we will not try to use it initially.
980 resolver
->pending_requests()[0]->results()->UseNamedProxy(
981 "foopy3:7070;foopy1:8080;foopy2:9090");
982 resolver
->pending_requests()[0]->CompleteNow(OK
);
984 EXPECT_EQ(OK
, callback3
.WaitForResult());
985 EXPECT_FALSE(info
.is_direct());
986 EXPECT_EQ("foopy3:7070", info
.proxy_server().ToURI());
988 // Proxy times should have been updated, so get them again.
989 EXPECT_LE(proxy_resolve_end_time
, info
.proxy_resolve_start_time());
990 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
991 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
992 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
993 proxy_resolve_start_time
= info
.proxy_resolve_start_time();
994 proxy_resolve_end_time
= info
.proxy_resolve_end_time();
996 // We fake another error. It should now try the third one.
997 TestCompletionCallback callback4
;
998 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
999 net::ERR_PROXY_CONNECTION_FAILED
,
1000 &info
, callback4
.callback(), NULL
,
1001 NULL
, BoundNetLog());
1003 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1005 // We fake another error. At this point we have tried all of the
1006 // proxy servers we thought were valid; next we try the proxy server
1007 // that was in our bad proxies map (foopy1:8080).
1008 TestCompletionCallback callback5
;
1009 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1010 net::ERR_PROXY_CONNECTION_FAILED
,
1011 &info
, callback5
.callback(), NULL
,
1012 NULL
, BoundNetLog());
1014 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1016 // Fake another error, the last proxy is gone, the list should now be empty,
1017 // so there is nothing left to try.
1018 TestCompletionCallback callback6
;
1019 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1020 net::ERR_PROXY_CONNECTION_FAILED
,
1021 &info
, callback6
.callback(), NULL
,
1022 NULL
, BoundNetLog());
1023 EXPECT_EQ(ERR_FAILED
, rv
);
1024 EXPECT_FALSE(info
.is_direct());
1025 EXPECT_TRUE(info
.is_empty());
1027 // Proxy times should not have been modified by fallback.
1028 EXPECT_EQ(proxy_resolve_start_time
, info
.proxy_resolve_start_time());
1029 EXPECT_EQ(proxy_resolve_end_time
, info
.proxy_resolve_end_time());
1031 // Look up proxies again
1032 TestCompletionCallback callback7
;
1033 rv
= service
.ResolveProxy(url
, net::LOAD_NORMAL
, &info
, callback7
.callback(),
1034 NULL
, NULL
, BoundNetLog());
1035 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1037 ASSERT_EQ(1u, resolver
->pending_requests().size());
1038 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1040 // This time, the first 3 results have been found to be bad, but only the
1041 // first proxy has been confirmed ...
1042 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1043 "foopy1:8080;foopy3:7070;foopy2:9090;foopy4:9091");
1044 resolver
->pending_requests()[0]->CompleteNow(OK
);
1046 // ... therefore, we should see the second proxy first.
1047 EXPECT_EQ(OK
, callback7
.WaitForResult());
1048 EXPECT_FALSE(info
.is_direct());
1049 EXPECT_EQ("foopy3:7070", info
.proxy_server().ToURI());
1051 EXPECT_LE(proxy_resolve_end_time
, info
.proxy_resolve_start_time());
1052 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1053 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1054 // TODO(nsylvain): Test that the proxy can be retried after the delay.
1057 // This test is similar to ProxyFallback, but this time we have an explicit
1058 // fallback choice to DIRECT.
1059 TEST_F(ProxyServiceTest
, ProxyFallbackToDirect
) {
1060 MockProxyConfigService
* config_service
=
1061 new MockProxyConfigService("http://foopy/proxy.pac");
1063 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
1065 ProxyService
service(config_service
, resolver
, NULL
);
1067 GURL
url("http://www.google.com/");
1069 // Get the proxy information.
1071 TestCompletionCallback callback1
;
1072 int rv
= service
.ResolveProxy(
1073 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
1075 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1077 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1078 resolver
->pending_set_pac_script_request()->script_data()->url());
1079 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1081 ASSERT_EQ(1u, resolver
->pending_requests().size());
1082 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1084 // Set the result in proxy resolver.
1085 resolver
->pending_requests()[0]->results()->UsePacString(
1086 "PROXY foopy1:8080; PROXY foopy2:9090; DIRECT");
1087 resolver
->pending_requests()[0]->CompleteNow(OK
);
1089 // Get the first result.
1090 EXPECT_EQ(OK
, callback1
.WaitForResult());
1091 EXPECT_FALSE(info
.is_direct());
1092 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1094 // Fake an error on the proxy.
1095 TestCompletionCallback callback2
;
1096 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1097 net::ERR_PROXY_CONNECTION_FAILED
,
1098 &info
, callback2
.callback(), NULL
,
1099 NULL
, BoundNetLog());
1102 // Now we get back the second proxy.
1103 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1105 // Fake an error on this proxy as well.
1106 TestCompletionCallback callback3
;
1107 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1108 net::ERR_PROXY_CONNECTION_FAILED
,
1109 &info
, callback3
.callback(), NULL
,
1110 NULL
, BoundNetLog());
1113 // Finally, we get back DIRECT.
1114 EXPECT_TRUE(info
.is_direct());
1116 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1117 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1118 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1120 // Now we tell the proxy service that even DIRECT failed.
1121 TestCompletionCallback callback4
;
1122 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1123 net::ERR_PROXY_CONNECTION_FAILED
,
1124 &info
, callback4
.callback(), NULL
,
1125 NULL
, BoundNetLog());
1126 // There was nothing left to try after DIRECT, so we are out of
1128 EXPECT_EQ(ERR_FAILED
, rv
);
1131 TEST_F(ProxyServiceTest
, ProxyFallback_NewSettings
) {
1132 // Test proxy failover when new settings are available.
1134 MockProxyConfigService
* config_service
=
1135 new MockProxyConfigService("http://foopy/proxy.pac");
1137 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
1139 ProxyService
service(config_service
, resolver
, NULL
);
1141 GURL
url("http://www.google.com/");
1143 // Get the proxy information.
1145 TestCompletionCallback callback1
;
1146 int rv
= service
.ResolveProxy(
1147 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
1149 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1151 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1152 resolver
->pending_set_pac_script_request()->script_data()->url());
1153 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1155 ASSERT_EQ(1u, resolver
->pending_requests().size());
1156 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1158 // Set the result in proxy resolver.
1159 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1160 "foopy1:8080;foopy2:9090");
1161 resolver
->pending_requests()[0]->CompleteNow(OK
);
1163 // The first item is valid.
1164 EXPECT_EQ(OK
, callback1
.WaitForResult());
1165 EXPECT_FALSE(info
.is_direct());
1166 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1168 // Fake an error on the proxy, and also a new configuration on the proxy.
1169 config_service
->SetConfig(
1170 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy-new/proxy.pac")));
1172 TestCompletionCallback callback2
;
1173 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1174 net::ERR_PROXY_CONNECTION_FAILED
,
1175 &info
, callback2
.callback(), NULL
,
1176 NULL
, BoundNetLog());
1177 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1179 EXPECT_EQ(GURL("http://foopy-new/proxy.pac"),
1180 resolver
->pending_set_pac_script_request()->script_data()->url());
1181 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1183 ASSERT_EQ(1u, resolver
->pending_requests().size());
1184 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1186 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1187 "foopy1:8080;foopy2:9090");
1188 resolver
->pending_requests()[0]->CompleteNow(OK
);
1190 // The first proxy is still there since the configuration changed.
1191 EXPECT_EQ(OK
, callback2
.WaitForResult());
1192 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1194 // We fake another error. It should now ignore the first one.
1195 TestCompletionCallback callback3
;
1196 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1197 net::ERR_PROXY_CONNECTION_FAILED
,
1198 &info
, callback3
.callback(), NULL
,
1199 NULL
, BoundNetLog());
1201 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1203 // We simulate a new configuration.
1204 config_service
->SetConfig(
1205 ProxyConfig::CreateFromCustomPacURL(
1206 GURL("http://foopy-new2/proxy.pac")));
1208 // We fake another error. It should go back to the first proxy.
1209 TestCompletionCallback callback4
;
1210 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1211 net::ERR_PROXY_CONNECTION_FAILED
,
1212 &info
, callback4
.callback(), NULL
,
1213 NULL
, BoundNetLog());
1214 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1216 EXPECT_EQ(GURL("http://foopy-new2/proxy.pac"),
1217 resolver
->pending_set_pac_script_request()->script_data()->url());
1218 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1220 ASSERT_EQ(1u, resolver
->pending_requests().size());
1221 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1223 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1224 "foopy1:8080;foopy2:9090");
1225 resolver
->pending_requests()[0]->CompleteNow(OK
);
1227 EXPECT_EQ(OK
, callback4
.WaitForResult());
1228 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1230 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1231 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1232 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1235 TEST_F(ProxyServiceTest
, ProxyFallback_BadConfig
) {
1236 // Test proxy failover when the configuration is bad.
1238 MockProxyConfigService
* config_service
=
1239 new MockProxyConfigService("http://foopy/proxy.pac");
1241 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
1243 ProxyService
service(config_service
, resolver
, NULL
);
1245 GURL
url("http://www.google.com/");
1247 // Get the proxy information.
1249 TestCompletionCallback callback1
;
1250 int rv
= service
.ResolveProxy(
1251 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
1253 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1255 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1256 resolver
->pending_set_pac_script_request()->script_data()->url());
1257 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1258 ASSERT_EQ(1u, resolver
->pending_requests().size());
1259 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1261 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1262 "foopy1:8080;foopy2:9090");
1263 resolver
->pending_requests()[0]->CompleteNow(OK
);
1265 // The first item is valid.
1266 EXPECT_EQ(OK
, callback1
.WaitForResult());
1267 EXPECT_FALSE(info
.is_direct());
1268 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1270 // Fake a proxy error.
1271 TestCompletionCallback callback2
;
1272 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1273 net::ERR_PROXY_CONNECTION_FAILED
,
1274 &info
, callback2
.callback(), NULL
,
1275 NULL
, BoundNetLog());
1278 // The first proxy is ignored, and the second one is selected.
1279 EXPECT_FALSE(info
.is_direct());
1280 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1282 // Fake a PAC failure.
1284 TestCompletionCallback callback3
;
1285 rv
= service
.ResolveProxy(
1286 url
, net::LOAD_NORMAL
, &info2
, callback3
.callback(), NULL
, NULL
,
1288 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1290 ASSERT_EQ(1u, resolver
->pending_requests().size());
1291 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1293 // This simulates a javascript runtime error in the PAC script.
1294 resolver
->pending_requests()[0]->CompleteNow(ERR_FAILED
);
1296 // Although the resolver failed, the ProxyService will implicitly fall-back
1297 // to a DIRECT connection.
1298 EXPECT_EQ(OK
, callback3
.WaitForResult());
1299 EXPECT_TRUE(info2
.is_direct());
1300 EXPECT_FALSE(info2
.is_empty());
1302 // The PAC script will work properly next time and successfully return a
1303 // proxy list. Since we have not marked the configuration as bad, it should
1304 // "just work" the next time we call it.
1306 TestCompletionCallback callback4
;
1307 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1308 net::ERR_PROXY_CONNECTION_FAILED
,
1309 &info3
, callback4
.callback(),
1310 NULL
, NULL
, BoundNetLog());
1311 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1313 ASSERT_EQ(1u, resolver
->pending_requests().size());
1314 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1316 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1317 "foopy1:8080;foopy2:9090");
1318 resolver
->pending_requests()[0]->CompleteNow(OK
);
1320 // The first proxy is not there since the it was added to the bad proxies
1321 // list by the earlier ReconsiderProxyAfterError().
1322 EXPECT_EQ(OK
, callback4
.WaitForResult());
1323 EXPECT_FALSE(info3
.is_direct());
1324 EXPECT_EQ("foopy1:8080", info3
.proxy_server().ToURI());
1326 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1327 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1328 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1331 TEST_F(ProxyServiceTest
, ProxyFallback_BadConfigMandatory
) {
1332 // Test proxy failover when the configuration is bad.
1335 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
1337 config
.set_pac_mandatory(true);
1338 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
1340 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
1342 ProxyService
service(config_service
, resolver
, NULL
);
1344 GURL
url("http://www.google.com/");
1346 // Get the proxy information.
1348 TestCompletionCallback callback1
;
1349 int rv
= service
.ResolveProxy(
1350 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
1352 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1354 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1355 resolver
->pending_set_pac_script_request()->script_data()->url());
1356 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1357 ASSERT_EQ(1u, resolver
->pending_requests().size());
1358 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1360 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1361 "foopy1:8080;foopy2:9090");
1362 resolver
->pending_requests()[0]->CompleteNow(OK
);
1364 // The first item is valid.
1365 EXPECT_EQ(OK
, callback1
.WaitForResult());
1366 EXPECT_FALSE(info
.is_direct());
1367 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1369 // Fake a proxy error.
1370 TestCompletionCallback callback2
;
1371 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1372 net::ERR_PROXY_CONNECTION_FAILED
,
1373 &info
, callback2
.callback(), NULL
,
1374 NULL
, BoundNetLog());
1377 // The first proxy is ignored, and the second one is selected.
1378 EXPECT_FALSE(info
.is_direct());
1379 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1381 // Fake a PAC failure.
1383 TestCompletionCallback callback3
;
1384 rv
= service
.ResolveProxy(
1385 url
, net::LOAD_NORMAL
, &info2
, callback3
.callback(), NULL
, NULL
,
1387 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1389 ASSERT_EQ(1u, resolver
->pending_requests().size());
1390 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1392 // This simulates a javascript runtime error in the PAC script.
1393 resolver
->pending_requests()[0]->CompleteNow(ERR_FAILED
);
1395 // Although the resolver failed, the ProxyService will NOT fall-back
1396 // to a DIRECT connection as it is configured as mandatory.
1397 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
1398 callback3
.WaitForResult());
1399 EXPECT_FALSE(info2
.is_direct());
1400 EXPECT_TRUE(info2
.is_empty());
1402 // The PAC script will work properly next time and successfully return a
1403 // proxy list. Since we have not marked the configuration as bad, it should
1404 // "just work" the next time we call it.
1406 TestCompletionCallback callback4
;
1407 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1408 net::ERR_PROXY_CONNECTION_FAILED
,
1409 &info3
, callback4
.callback(),
1410 NULL
, NULL
, BoundNetLog());
1411 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1413 ASSERT_EQ(1u, resolver
->pending_requests().size());
1414 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1416 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1417 "foopy1:8080;foopy2:9090");
1418 resolver
->pending_requests()[0]->CompleteNow(OK
);
1420 // The first proxy is not there since the it was added to the bad proxies
1421 // list by the earlier ReconsiderProxyAfterError().
1422 EXPECT_EQ(OK
, callback4
.WaitForResult());
1423 EXPECT_FALSE(info3
.is_direct());
1424 EXPECT_EQ("foopy1:8080", info3
.proxy_server().ToURI());
1427 TEST_F(ProxyServiceTest
, ProxyBypassList
) {
1428 // Test that the proxy bypass rules are consulted.
1430 TestCompletionCallback callback
[2];
1433 config
.proxy_rules().ParseFromString("foopy1:8080;foopy2:9090");
1434 config
.set_auto_detect(false);
1435 config
.proxy_rules().bypass_rules
.ParseFromString("*.org");
1437 ProxyService
service(
1438 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1441 GURL
url1("http://www.webkit.org");
1442 GURL
url2("http://www.webkit.com");
1444 // Request for a .org domain should bypass proxy.
1445 rv
= service
.ResolveProxy(
1446 url1
, net::LOAD_NORMAL
, &info
[0], callback
[0].callback(), NULL
, NULL
,
1449 EXPECT_TRUE(info
[0].is_direct());
1451 // Request for a .com domain hits the proxy.
1452 rv
= service
.ResolveProxy(
1453 url2
, net::LOAD_NORMAL
, &info
[1], callback
[1].callback(), NULL
, NULL
,
1456 EXPECT_EQ("foopy1:8080", info
[1].proxy_server().ToURI());
1460 TEST_F(ProxyServiceTest
, PerProtocolProxyTests
) {
1462 config
.proxy_rules().ParseFromString("http=foopy1:8080;https=foopy2:8080");
1463 config
.set_auto_detect(false);
1465 ProxyService
service(
1466 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1467 GURL
test_url("http://www.msn.com");
1469 TestCompletionCallback callback
;
1470 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1471 callback
.callback(), NULL
, NULL
,
1474 EXPECT_FALSE(info
.is_direct());
1475 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1478 ProxyService
service(
1479 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1480 GURL
test_url("ftp://ftp.google.com");
1482 TestCompletionCallback callback
;
1483 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1484 callback
.callback(), NULL
,
1485 NULL
, BoundNetLog());
1487 EXPECT_TRUE(info
.is_direct());
1488 EXPECT_EQ("direct://", info
.proxy_server().ToURI());
1491 ProxyService
service(
1492 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1493 GURL
test_url("https://webbranch.techcu.com");
1495 TestCompletionCallback callback
;
1496 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1497 callback
.callback(), NULL
,
1498 NULL
, BoundNetLog());
1500 EXPECT_FALSE(info
.is_direct());
1501 EXPECT_EQ("foopy2:8080", info
.proxy_server().ToURI());
1504 config
.proxy_rules().ParseFromString("foopy1:8080");
1505 ProxyService
service(
1506 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1507 GURL
test_url("http://www.microsoft.com");
1509 TestCompletionCallback callback
;
1510 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1511 callback
.callback(), NULL
,
1512 NULL
, BoundNetLog());
1514 EXPECT_FALSE(info
.is_direct());
1515 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1519 TEST_F(ProxyServiceTest
, ProxyConfigSourcePropagates
) {
1520 // Test that the proxy config source is set correctly when resolving proxies
1521 // using manual proxy rules. Namely, the config source should only be set if
1522 // any of the rules were applied.
1525 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1526 config
.proxy_rules().ParseFromString("https=foopy2:8080");
1527 ProxyService
service(
1528 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1529 GURL
test_url("http://www.google.com");
1531 TestCompletionCallback callback
;
1532 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1533 callback
.callback(), NULL
,
1534 NULL
, BoundNetLog());
1536 // Should be SOURCE_TEST, even if there are no HTTP proxies configured.
1537 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1541 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1542 config
.proxy_rules().ParseFromString("https=foopy2:8080");
1543 ProxyService
service(
1544 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1545 GURL
test_url("https://www.google.com");
1547 TestCompletionCallback callback
;
1548 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1549 callback
.callback(), NULL
,
1550 NULL
, BoundNetLog());
1552 // Used the HTTPS proxy. So source should be TEST.
1553 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1557 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1558 ProxyService
service(
1559 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1560 GURL
test_url("http://www.google.com");
1562 TestCompletionCallback callback
;
1563 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1564 callback
.callback(), NULL
,
1565 NULL
, BoundNetLog());
1567 // ProxyConfig is empty. Source should still be TEST.
1568 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1572 // If only HTTP and a SOCKS proxy are specified, check if ftp/https queries
1573 // fall back to the SOCKS proxy.
1574 TEST_F(ProxyServiceTest
, DefaultProxyFallbackToSOCKS
) {
1576 config
.proxy_rules().ParseFromString("http=foopy1:8080;socks=foopy2:1080");
1577 config
.set_auto_detect(false);
1578 EXPECT_EQ(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
1579 config
.proxy_rules().type
);
1582 ProxyService
service(
1583 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1584 GURL
test_url("http://www.msn.com");
1586 TestCompletionCallback callback
;
1587 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1588 callback
.callback(), NULL
,
1589 NULL
, BoundNetLog());
1591 EXPECT_FALSE(info
.is_direct());
1592 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1595 ProxyService
service(
1596 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1597 GURL
test_url("ftp://ftp.google.com");
1599 TestCompletionCallback callback
;
1600 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1601 callback
.callback(), NULL
,
1602 NULL
, BoundNetLog());
1604 EXPECT_FALSE(info
.is_direct());
1605 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1608 ProxyService
service(
1609 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1610 GURL
test_url("https://webbranch.techcu.com");
1612 TestCompletionCallback callback
;
1613 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1614 callback
.callback(), NULL
,
1615 NULL
, BoundNetLog());
1617 EXPECT_FALSE(info
.is_direct());
1618 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1621 ProxyService
service(
1622 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1623 GURL
test_url("unknown://www.microsoft.com");
1625 TestCompletionCallback callback
;
1626 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1627 callback
.callback(), NULL
,
1628 NULL
, BoundNetLog());
1630 EXPECT_FALSE(info
.is_direct());
1631 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1635 // Test cancellation of an in-progress request.
1636 TEST_F(ProxyServiceTest
, CancelInProgressRequest
) {
1637 MockProxyConfigService
* config_service
=
1638 new MockProxyConfigService("http://foopy/proxy.pac");
1640 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
1642 ProxyService
service(config_service
, resolver
, NULL
);
1644 // Start 3 requests.
1647 TestCompletionCallback callback1
;
1648 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1649 &info1
, callback1
.callback(), NULL
, NULL
,
1651 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1653 // Nothing has been sent to the proxy resolver yet, since the proxy
1654 // resolver has not been configured yet.
1655 ASSERT_EQ(0u, resolver
->pending_requests().size());
1657 // Successfully initialize the PAC script.
1658 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1659 resolver
->pending_set_pac_script_request()->script_data()->url());
1660 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1662 ASSERT_EQ(1u, resolver
->pending_requests().size());
1663 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
1666 TestCompletionCallback callback2
;
1667 ProxyService::PacRequest
* request2
;
1668 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1669 callback2
.callback(), &request2
, NULL
,
1671 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1672 ASSERT_EQ(2u, resolver
->pending_requests().size());
1673 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[1]->url());
1676 TestCompletionCallback callback3
;
1677 rv
= service
.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL
, &info3
,
1678 callback3
.callback(), NULL
, NULL
, BoundNetLog());
1679 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1680 ASSERT_EQ(3u, resolver
->pending_requests().size());
1681 EXPECT_EQ(GURL("http://request3"), resolver
->pending_requests()[2]->url());
1683 // Cancel the second request
1684 service
.CancelPacRequest(request2
);
1686 ASSERT_EQ(2u, resolver
->pending_requests().size());
1687 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
1688 EXPECT_EQ(GURL("http://request3"), resolver
->pending_requests()[1]->url());
1690 // Complete the two un-cancelled requests.
1691 // We complete the last one first, just to mix it up a bit.
1692 resolver
->pending_requests()[1]->results()->UseNamedProxy("request3:80");
1693 resolver
->pending_requests()[1]->CompleteNow(OK
);
1695 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1696 resolver
->pending_requests()[0]->CompleteNow(OK
);
1698 // Complete and verify that requests ran as expected.
1699 EXPECT_EQ(OK
, callback1
.WaitForResult());
1700 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
1702 EXPECT_FALSE(callback2
.have_result()); // Cancelled.
1703 ASSERT_EQ(1u, resolver
->cancelled_requests().size());
1704 EXPECT_EQ(GURL("http://request2"), resolver
->cancelled_requests()[0]->url());
1706 EXPECT_EQ(OK
, callback3
.WaitForResult());
1707 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
1710 // Test the initial PAC download for resolver that expects bytes.
1711 TEST_F(ProxyServiceTest
, InitialPACScriptDownload
) {
1712 MockProxyConfigService
* config_service
=
1713 new MockProxyConfigService("http://foopy/proxy.pac");
1715 MockAsyncProxyResolverExpectsBytes
* resolver
=
1716 new MockAsyncProxyResolverExpectsBytes
;
1718 ProxyService
service(config_service
, resolver
, NULL
);
1720 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1721 service
.SetProxyScriptFetchers(fetcher
,
1722 new DoNothingDhcpProxyScriptFetcher());
1724 // Start 3 requests.
1727 TestCompletionCallback callback1
;
1728 ProxyService::PacRequest
* request1
;
1729 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1730 &info1
, callback1
.callback(), &request1
, NULL
,
1732 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1734 // The first request should have triggered download of PAC script.
1735 EXPECT_TRUE(fetcher
->has_pending_request());
1736 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1739 TestCompletionCallback callback2
;
1740 ProxyService::PacRequest
* request2
;
1741 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1742 callback2
.callback(), &request2
, NULL
,
1744 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1747 TestCompletionCallback callback3
;
1748 ProxyService::PacRequest
* request3
;
1749 rv
= service
.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL
, &info3
,
1750 callback3
.callback(), &request3
, NULL
,
1752 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1754 // Nothing has been sent to the resolver yet.
1755 EXPECT_TRUE(resolver
->pending_requests().empty());
1757 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1758 service
.GetLoadState(request1
));
1759 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1760 service
.GetLoadState(request2
));
1761 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1762 service
.GetLoadState(request3
));
1764 // At this point the ProxyService should be waiting for the
1765 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1766 // PAC script download completion.
1767 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
1769 // Now that the PAC script is downloaded, it will have been sent to the proxy
1771 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
1772 resolver
->pending_set_pac_script_request()->script_data()->utf16());
1773 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1775 ASSERT_EQ(3u, resolver
->pending_requests().size());
1776 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
1777 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[1]->url());
1778 EXPECT_EQ(GURL("http://request3"), resolver
->pending_requests()[2]->url());
1780 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request1
));
1781 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request2
));
1782 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request3
));
1784 // Complete all the requests (in some order).
1785 // Note that as we complete requests, they shift up in |pending_requests()|.
1787 resolver
->pending_requests()[2]->results()->UseNamedProxy("request3:80");
1788 resolver
->pending_requests()[2]->CompleteNow(OK
);
1790 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1791 resolver
->pending_requests()[0]->CompleteNow(OK
);
1793 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
1794 resolver
->pending_requests()[0]->CompleteNow(OK
);
1796 // Complete and verify that requests ran as expected.
1797 EXPECT_EQ(OK
, callback1
.WaitForResult());
1798 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
1799 EXPECT_FALSE(info1
.proxy_resolve_start_time().is_null());
1800 EXPECT_FALSE(info1
.proxy_resolve_end_time().is_null());
1801 EXPECT_LE(info1
.proxy_resolve_start_time(), info1
.proxy_resolve_end_time());
1803 EXPECT_EQ(OK
, callback2
.WaitForResult());
1804 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
1805 EXPECT_FALSE(info2
.proxy_resolve_start_time().is_null());
1806 EXPECT_FALSE(info2
.proxy_resolve_end_time().is_null());
1807 EXPECT_LE(info2
.proxy_resolve_start_time(), info2
.proxy_resolve_end_time());
1809 EXPECT_EQ(OK
, callback3
.WaitForResult());
1810 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
1811 EXPECT_FALSE(info3
.proxy_resolve_start_time().is_null());
1812 EXPECT_FALSE(info3
.proxy_resolve_end_time().is_null());
1813 EXPECT_LE(info3
.proxy_resolve_start_time(), info3
.proxy_resolve_end_time());
1816 // Test changing the ProxyScriptFetcher while PAC download is in progress.
1817 TEST_F(ProxyServiceTest
, ChangeScriptFetcherWhilePACDownloadInProgress
) {
1818 MockProxyConfigService
* config_service
=
1819 new MockProxyConfigService("http://foopy/proxy.pac");
1821 MockAsyncProxyResolverExpectsBytes
* resolver
=
1822 new MockAsyncProxyResolverExpectsBytes
;
1824 ProxyService
service(config_service
, resolver
, NULL
);
1826 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1827 service
.SetProxyScriptFetchers(fetcher
,
1828 new DoNothingDhcpProxyScriptFetcher());
1830 // Start 2 requests.
1833 TestCompletionCallback callback1
;
1834 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1835 &info1
, callback1
.callback(), NULL
, NULL
,
1837 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1839 // The first request should have triggered download of PAC script.
1840 EXPECT_TRUE(fetcher
->has_pending_request());
1841 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1844 TestCompletionCallback callback2
;
1845 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1846 callback2
.callback(), NULL
, NULL
, BoundNetLog());
1847 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1849 // At this point the ProxyService should be waiting for the
1850 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1851 // PAC script download completion.
1853 // We now change out the ProxyService's script fetcher. We should restart
1854 // the initialization with the new fetcher.
1856 fetcher
= new MockProxyScriptFetcher
;
1857 service
.SetProxyScriptFetchers(fetcher
,
1858 new DoNothingDhcpProxyScriptFetcher());
1860 // Nothing has been sent to the resolver yet.
1861 EXPECT_TRUE(resolver
->pending_requests().empty());
1863 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
1865 // Now that the PAC script is downloaded, it will have been sent to the proxy
1867 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
1868 resolver
->pending_set_pac_script_request()->script_data()->utf16());
1869 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1871 ASSERT_EQ(2u, resolver
->pending_requests().size());
1872 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
1873 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[1]->url());
1876 // Test cancellation of a request, while the PAC script is being fetched.
1877 TEST_F(ProxyServiceTest
, CancelWhilePACFetching
) {
1878 MockProxyConfigService
* config_service
=
1879 new MockProxyConfigService("http://foopy/proxy.pac");
1881 MockAsyncProxyResolverExpectsBytes
* resolver
=
1882 new MockAsyncProxyResolverExpectsBytes
;
1884 ProxyService
service(config_service
, resolver
, NULL
);
1886 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1887 service
.SetProxyScriptFetchers(fetcher
,
1888 new DoNothingDhcpProxyScriptFetcher());
1890 // Start 3 requests.
1892 TestCompletionCallback callback1
;
1893 ProxyService::PacRequest
* request1
;
1894 CapturingBoundNetLog log1
;
1895 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1896 &info1
, callback1
.callback(), &request1
, NULL
,
1898 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1900 // The first request should have triggered download of PAC script.
1901 EXPECT_TRUE(fetcher
->has_pending_request());
1902 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1905 TestCompletionCallback callback2
;
1906 ProxyService::PacRequest
* request2
;
1907 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1908 callback2
.callback(), &request2
, NULL
,
1910 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1913 TestCompletionCallback callback3
;
1914 rv
= service
.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL
, &info3
,
1915 callback3
.callback(), NULL
, NULL
, BoundNetLog());
1916 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1918 // Nothing has been sent to the resolver yet.
1919 EXPECT_TRUE(resolver
->pending_requests().empty());
1921 // Cancel the first 2 requests.
1922 service
.CancelPacRequest(request1
);
1923 service
.CancelPacRequest(request2
);
1925 // At this point the ProxyService should be waiting for the
1926 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1927 // PAC script download completion.
1928 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
1930 // Now that the PAC script is downloaded, it will have been sent to the
1932 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
1933 resolver
->pending_set_pac_script_request()->script_data()->utf16());
1934 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1936 ASSERT_EQ(1u, resolver
->pending_requests().size());
1937 EXPECT_EQ(GURL("http://request3"), resolver
->pending_requests()[0]->url());
1939 // Complete all the requests.
1940 resolver
->pending_requests()[0]->results()->UseNamedProxy("request3:80");
1941 resolver
->pending_requests()[0]->CompleteNow(OK
);
1943 EXPECT_EQ(OK
, callback3
.WaitForResult());
1944 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
1946 EXPECT_TRUE(resolver
->cancelled_requests().empty());
1948 EXPECT_FALSE(callback1
.have_result()); // Cancelled.
1949 EXPECT_FALSE(callback2
.have_result()); // Cancelled.
1951 CapturingNetLog::CapturedEntryList entries1
;
1952 log1
.GetEntries(&entries1
);
1954 // Check the NetLog for request 1 (which was cancelled) got filled properly.
1955 EXPECT_EQ(4u, entries1
.size());
1956 EXPECT_TRUE(LogContainsBeginEvent(
1957 entries1
, 0, NetLog::TYPE_PROXY_SERVICE
));
1958 EXPECT_TRUE(LogContainsBeginEvent(
1959 entries1
, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
1960 // Note that TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC is never completed before
1961 // the cancellation occured.
1962 EXPECT_TRUE(LogContainsEvent(
1963 entries1
, 2, NetLog::TYPE_CANCELLED
, NetLog::PHASE_NONE
));
1964 EXPECT_TRUE(LogContainsEndEvent(
1965 entries1
, 3, NetLog::TYPE_PROXY_SERVICE
));
1968 // Test that if auto-detect fails, we fall-back to the custom pac.
1969 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomPac
) {
1971 config
.set_auto_detect(true);
1972 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
1973 config
.proxy_rules().ParseFromString("http=foopy:80"); // Won't be used.
1975 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
1976 MockAsyncProxyResolverExpectsBytes
* resolver
=
1977 new MockAsyncProxyResolverExpectsBytes
;
1978 ProxyService
service(config_service
, resolver
, NULL
);
1980 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1981 service
.SetProxyScriptFetchers(fetcher
,
1982 new DoNothingDhcpProxyScriptFetcher());
1984 // Start 2 requests.
1987 TestCompletionCallback callback1
;
1988 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1989 &info1
, callback1
.callback(), NULL
, NULL
,
1991 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1994 TestCompletionCallback callback2
;
1995 ProxyService::PacRequest
* request2
;
1996 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1997 callback2
.callback(), &request2
, NULL
,
1999 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2001 // Check that nothing has been sent to the proxy resolver yet.
2002 ASSERT_EQ(0u, resolver
->pending_requests().size());
2004 // It should be trying to auto-detect first -- FAIL the autodetect during
2005 // the script download.
2006 EXPECT_TRUE(fetcher
->has_pending_request());
2007 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2008 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2010 // Next it should be trying the custom PAC url.
2011 EXPECT_TRUE(fetcher
->has_pending_request());
2012 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2013 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2015 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2016 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2017 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2019 // Now finally, the pending requests should have been sent to the resolver
2020 // (which was initialized with custom PAC script).
2022 ASSERT_EQ(2u, resolver
->pending_requests().size());
2023 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2024 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[1]->url());
2026 // Complete the pending requests.
2027 resolver
->pending_requests()[1]->results()->UseNamedProxy("request2:80");
2028 resolver
->pending_requests()[1]->CompleteNow(OK
);
2029 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2030 resolver
->pending_requests()[0]->CompleteNow(OK
);
2032 // Verify that requests ran as expected.
2033 EXPECT_EQ(OK
, callback1
.WaitForResult());
2034 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2035 EXPECT_FALSE(info1
.proxy_resolve_start_time().is_null());
2036 EXPECT_FALSE(info1
.proxy_resolve_end_time().is_null());
2037 EXPECT_LE(info1
.proxy_resolve_start_time(), info1
.proxy_resolve_end_time());
2039 EXPECT_EQ(OK
, callback2
.WaitForResult());
2040 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2041 EXPECT_FALSE(info2
.proxy_resolve_start_time().is_null());
2042 EXPECT_FALSE(info2
.proxy_resolve_end_time().is_null());
2043 EXPECT_LE(info2
.proxy_resolve_start_time(), info2
.proxy_resolve_end_time());
2046 // This is the same test as FallbackFromAutodetectToCustomPac, except
2047 // the auto-detect script fails parsing rather than downloading.
2048 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomPac2
) {
2050 config
.set_auto_detect(true);
2051 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2052 config
.proxy_rules().ParseFromString("http=foopy:80"); // Won't be used.
2054 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2055 MockAsyncProxyResolverExpectsBytes
* resolver
=
2056 new MockAsyncProxyResolverExpectsBytes
;
2057 ProxyService
service(config_service
, resolver
, NULL
);
2059 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2060 service
.SetProxyScriptFetchers(fetcher
,
2061 new DoNothingDhcpProxyScriptFetcher());
2063 // Start 2 requests.
2066 TestCompletionCallback callback1
;
2067 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2068 &info1
, callback1
.callback(), NULL
, NULL
,
2070 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2073 TestCompletionCallback callback2
;
2074 ProxyService::PacRequest
* request2
;
2075 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
2076 callback2
.callback(), &request2
, NULL
,
2078 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2080 // Check that nothing has been sent to the proxy resolver yet.
2081 ASSERT_EQ(0u, resolver
->pending_requests().size());
2083 // It should be trying to auto-detect first -- succeed the download.
2084 EXPECT_TRUE(fetcher
->has_pending_request());
2085 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2086 fetcher
->NotifyFetchCompletion(OK
, "invalid-script-contents");
2088 // The script contents passed failed basic verification step (since didn't
2089 // contain token FindProxyForURL), so it was never passed to the resolver.
2091 // Next it should be trying the custom PAC url.
2092 EXPECT_TRUE(fetcher
->has_pending_request());
2093 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2094 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2096 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2097 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2098 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2100 // Now finally, the pending requests should have been sent to the resolver
2101 // (which was initialized with custom PAC script).
2103 ASSERT_EQ(2u, resolver
->pending_requests().size());
2104 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2105 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[1]->url());
2107 // Complete the pending requests.
2108 resolver
->pending_requests()[1]->results()->UseNamedProxy("request2:80");
2109 resolver
->pending_requests()[1]->CompleteNow(OK
);
2110 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2111 resolver
->pending_requests()[0]->CompleteNow(OK
);
2113 // Verify that requests ran as expected.
2114 EXPECT_EQ(OK
, callback1
.WaitForResult());
2115 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2117 EXPECT_EQ(OK
, callback2
.WaitForResult());
2118 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2121 // Test that if all of auto-detect, a custom PAC script, and manual settings
2122 // are given, then we will try them in that order.
2123 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomToManual
) {
2125 config
.set_auto_detect(true);
2126 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2127 config
.proxy_rules().ParseFromString("http=foopy:80");
2129 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2130 MockAsyncProxyResolverExpectsBytes
* resolver
=
2131 new MockAsyncProxyResolverExpectsBytes
;
2132 ProxyService
service(config_service
, resolver
, NULL
);
2134 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2135 service
.SetProxyScriptFetchers(fetcher
,
2136 new DoNothingDhcpProxyScriptFetcher());
2138 // Start 2 requests.
2141 TestCompletionCallback callback1
;
2142 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2143 &info1
, callback1
.callback(), NULL
, NULL
,
2145 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2148 TestCompletionCallback callback2
;
2149 ProxyService::PacRequest
* request2
;
2150 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
2151 callback2
.callback(), &request2
, NULL
,
2153 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2155 // Check that nothing has been sent to the proxy resolver yet.
2156 ASSERT_EQ(0u, resolver
->pending_requests().size());
2158 // It should be trying to auto-detect first -- fail the download.
2159 EXPECT_TRUE(fetcher
->has_pending_request());
2160 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2161 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2163 // Next it should be trying the custom PAC url -- fail the download.
2164 EXPECT_TRUE(fetcher
->has_pending_request());
2165 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2166 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2168 // Since we never managed to initialize a ProxyResolver, nothing should have
2170 ASSERT_EQ(0u, resolver
->pending_requests().size());
2172 // Verify that requests ran as expected -- they should have fallen back to
2173 // the manual proxy configuration for HTTP urls.
2174 EXPECT_EQ(OK
, callback1
.WaitForResult());
2175 EXPECT_EQ("foopy:80", info1
.proxy_server().ToURI());
2177 EXPECT_EQ(OK
, callback2
.WaitForResult());
2178 EXPECT_EQ("foopy:80", info2
.proxy_server().ToURI());
2181 // Test that the bypass rules are NOT applied when using autodetect.
2182 TEST_F(ProxyServiceTest
, BypassDoesntApplyToPac
) {
2184 config
.set_auto_detect(true);
2185 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2186 config
.proxy_rules().ParseFromString("http=foopy:80"); // Not used.
2187 config
.proxy_rules().bypass_rules
.ParseFromString("www.google.com");
2189 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2190 MockAsyncProxyResolverExpectsBytes
* resolver
=
2191 new MockAsyncProxyResolverExpectsBytes
;
2192 ProxyService
service(config_service
, resolver
, NULL
);
2194 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2195 service
.SetProxyScriptFetchers(fetcher
,
2196 new DoNothingDhcpProxyScriptFetcher());
2198 // Start 1 requests.
2201 TestCompletionCallback callback1
;
2202 int rv
= service
.ResolveProxy(
2203 GURL("http://www.google.com"), net::LOAD_NORMAL
, &info1
,
2204 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2205 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2207 // Check that nothing has been sent to the proxy resolver yet.
2208 ASSERT_EQ(0u, resolver
->pending_requests().size());
2210 // It should be trying to auto-detect first -- succeed the download.
2211 EXPECT_TRUE(fetcher
->has_pending_request());
2212 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2213 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2215 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2216 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2217 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2219 ASSERT_EQ(1u, resolver
->pending_requests().size());
2220 EXPECT_EQ(GURL("http://www.google.com"),
2221 resolver
->pending_requests()[0]->url());
2223 // Complete the pending request.
2224 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2225 resolver
->pending_requests()[0]->CompleteNow(OK
);
2227 // Verify that request ran as expected.
2228 EXPECT_EQ(OK
, callback1
.WaitForResult());
2229 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2231 // Start another request, it should pickup the bypass item.
2233 TestCompletionCallback callback2
;
2234 rv
= service
.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL
,
2235 &info2
, callback2
.callback(), NULL
, NULL
,
2237 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2239 ASSERT_EQ(1u, resolver
->pending_requests().size());
2240 EXPECT_EQ(GURL("http://www.google.com"),
2241 resolver
->pending_requests()[0]->url());
2243 // Complete the pending request.
2244 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
2245 resolver
->pending_requests()[0]->CompleteNow(OK
);
2247 EXPECT_EQ(OK
, callback2
.WaitForResult());
2248 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2251 // Delete the ProxyService while InitProxyResolver has an outstanding
2252 // request to the script fetcher. When run under valgrind, should not
2253 // have any memory errors (used to be that the ProxyScriptFetcher was
2254 // being deleted prior to the InitProxyResolver).
2255 TEST_F(ProxyServiceTest
, DeleteWhileInitProxyResolverHasOutstandingFetch
) {
2256 ProxyConfig config
=
2257 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
2259 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2260 MockAsyncProxyResolverExpectsBytes
* resolver
=
2261 new MockAsyncProxyResolverExpectsBytes
;
2262 ProxyService
service(config_service
, resolver
, NULL
);
2264 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2265 service
.SetProxyScriptFetchers(fetcher
,
2266 new DoNothingDhcpProxyScriptFetcher());
2271 TestCompletionCallback callback1
;
2272 int rv
= service
.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL
,
2273 &info1
, callback1
.callback(), NULL
, NULL
,
2275 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2277 // Check that nothing has been sent to the proxy resolver yet.
2278 ASSERT_EQ(0u, resolver
->pending_requests().size());
2280 // InitProxyResolver should have issued a request to the ProxyScriptFetcher
2281 // and be waiting on that to complete.
2282 EXPECT_TRUE(fetcher
->has_pending_request());
2283 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2286 // Delete the ProxyService while InitProxyResolver has an outstanding
2287 // request to the proxy resolver. When run under valgrind, should not
2288 // have any memory errors (used to be that the ProxyResolver was
2289 // being deleted prior to the InitProxyResolver).
2290 TEST_F(ProxyServiceTest
, DeleteWhileInitProxyResolverHasOutstandingSet
) {
2291 MockProxyConfigService
* config_service
=
2292 new MockProxyConfigService("http://foopy/proxy.pac");
2294 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
2296 ProxyService
service(config_service
, resolver
, NULL
);
2298 GURL
url("http://www.google.com/");
2301 TestCompletionCallback callback
;
2302 int rv
= service
.ResolveProxy(
2303 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
2305 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2307 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
2308 resolver
->pending_set_pac_script_request()->script_data()->url());
2311 TEST_F(ProxyServiceTest
, ResetProxyConfigService
) {
2312 ProxyConfig config1
;
2313 config1
.proxy_rules().ParseFromString("foopy1:8080");
2314 config1
.set_auto_detect(false);
2315 ProxyService
service(
2316 new MockProxyConfigService(config1
),
2317 new MockAsyncProxyResolverExpectsBytes
, NULL
);
2320 TestCompletionCallback callback1
;
2321 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2322 &info
, callback1
.callback(), NULL
, NULL
,
2325 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
2327 ProxyConfig config2
;
2328 config2
.proxy_rules().ParseFromString("foopy2:8080");
2329 config2
.set_auto_detect(false);
2330 service
.ResetConfigService(new MockProxyConfigService(config2
));
2331 TestCompletionCallback callback2
;
2332 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info
,
2333 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2335 EXPECT_EQ("foopy2:8080", info
.proxy_server().ToURI());
2338 // Test that when going from a configuration that required PAC to one
2339 // that does NOT, we unset the variable |should_use_proxy_resolver_|.
2340 TEST_F(ProxyServiceTest
, UpdateConfigFromPACToDirect
) {
2341 ProxyConfig config
= ProxyConfig::CreateAutoDetect();
2343 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2344 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
2345 ProxyService
service(config_service
, resolver
, NULL
);
2350 TestCompletionCallback callback1
;
2351 int rv
= service
.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL
,
2352 &info1
, callback1
.callback(), NULL
, NULL
,
2354 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2356 // Check that nothing has been sent to the proxy resolver yet.
2357 ASSERT_EQ(0u, resolver
->pending_requests().size());
2359 // Successfully set the autodetect script.
2360 EXPECT_EQ(ProxyResolverScriptData::TYPE_AUTO_DETECT
,
2361 resolver
->pending_set_pac_script_request()->script_data()->type());
2362 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2364 // Complete the pending request.
2365 ASSERT_EQ(1u, resolver
->pending_requests().size());
2366 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2367 resolver
->pending_requests()[0]->CompleteNow(OK
);
2369 // Verify that request ran as expected.
2370 EXPECT_EQ(OK
, callback1
.WaitForResult());
2371 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2373 // Force the ProxyService to pull down a new proxy configuration.
2374 // (Even though the configuration isn't old/bad).
2376 // This new configuration no longer has auto_detect set, so
2377 // requests should complete synchronously now as direct-connect.
2378 config_service
->SetConfig(ProxyConfig::CreateDirect());
2380 // Start another request -- the effective configuration has changed.
2382 TestCompletionCallback callback2
;
2383 rv
= service
.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL
,
2384 &info2
, callback2
.callback(), NULL
, NULL
,
2388 EXPECT_TRUE(info2
.is_direct());
2391 TEST_F(ProxyServiceTest
, NetworkChangeTriggersPacRefetch
) {
2392 MockProxyConfigService
* config_service
=
2393 new MockProxyConfigService("http://foopy/proxy.pac");
2395 MockAsyncProxyResolverExpectsBytes
* resolver
=
2396 new MockAsyncProxyResolverExpectsBytes
;
2398 CapturingNetLog log
;
2400 ProxyService
service(config_service
, resolver
, &log
);
2402 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2403 service
.SetProxyScriptFetchers(fetcher
,
2404 new DoNothingDhcpProxyScriptFetcher());
2406 // Disable the "wait after IP address changes" hack, so this unit-test can
2407 // complete quickly.
2408 service
.set_stall_proxy_auto_config_delay(base::TimeDelta());
2413 TestCompletionCallback callback1
;
2414 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2415 &info1
, callback1
.callback(), NULL
, NULL
,
2417 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2419 // The first request should have triggered initial download of PAC script.
2420 EXPECT_TRUE(fetcher
->has_pending_request());
2421 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2423 // Nothing has been sent to the resolver yet.
2424 EXPECT_TRUE(resolver
->pending_requests().empty());
2426 // At this point the ProxyService should be waiting for the
2427 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2428 // PAC script download completion.
2429 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2431 // Now that the PAC script is downloaded, the request will have been sent to
2432 // the proxy resolver.
2433 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2434 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2435 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2437 ASSERT_EQ(1u, resolver
->pending_requests().size());
2438 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2440 // Complete the pending request.
2441 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2442 resolver
->pending_requests()[0]->CompleteNow(OK
);
2444 // Wait for completion callback, and verify that the request ran as expected.
2445 EXPECT_EQ(OK
, callback1
.WaitForResult());
2446 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2448 // Now simluate a change in the network. The ProxyConfigService is still
2449 // going to return the same PAC URL as before, but this URL needs to be
2450 // refetched on the new network.
2451 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
2452 base::MessageLoop::current()->RunUntilIdle(); // Notification happens async.
2454 // Start a second request.
2456 TestCompletionCallback callback2
;
2457 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
2458 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2459 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2461 // This second request should have triggered the re-download of the PAC
2462 // script (since we marked the network as having changed).
2463 EXPECT_TRUE(fetcher
->has_pending_request());
2464 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2466 // Nothing has been sent to the resolver yet.
2467 EXPECT_TRUE(resolver
->pending_requests().empty());
2469 // Simulate the PAC script fetch as having completed (this time with
2471 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript2
);
2473 // Now that the PAC script is downloaded, the second request will have been
2474 // sent to the proxy resolver.
2475 EXPECT_EQ(ASCIIToUTF16(kValidPacScript2
),
2476 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2477 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2479 ASSERT_EQ(1u, resolver
->pending_requests().size());
2480 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[0]->url());
2482 // Complete the pending second request.
2483 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
2484 resolver
->pending_requests()[0]->CompleteNow(OK
);
2486 // Wait for completion callback, and verify that the request ran as expected.
2487 EXPECT_EQ(OK
, callback2
.WaitForResult());
2488 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2490 // Check that the expected events were output to the log stream. In particular
2491 // PROXY_CONFIG_CHANGED should have only been emitted once (for the initial
2492 // setup), and NOT a second time when the IP address changed.
2493 CapturingNetLog::CapturedEntryList entries
;
2494 log
.GetEntries(&entries
);
2496 EXPECT_TRUE(LogContainsEntryWithType(entries
, 0,
2497 NetLog::TYPE_PROXY_CONFIG_CHANGED
));
2498 ASSERT_EQ(9u, entries
.size());
2499 for (size_t i
= 1; i
< entries
.size(); ++i
)
2500 EXPECT_NE(NetLog::TYPE_PROXY_CONFIG_CHANGED
, entries
[i
].type
);
2503 // This test verifies that the PAC script specified by the settings is
2504 // periodically polled for changes. Specifically, if the initial fetch fails due
2505 // to a network error, we will eventually re-configure the service to use the
2506 // script once it becomes available.
2507 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterFailure
) {
2508 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2510 ImmediatePollPolicy poll_policy
;
2511 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2513 MockProxyConfigService
* config_service
=
2514 new MockProxyConfigService("http://foopy/proxy.pac");
2516 MockAsyncProxyResolverExpectsBytes
* resolver
=
2517 new MockAsyncProxyResolverExpectsBytes
;
2519 ProxyService
service(config_service
, resolver
, NULL
);
2521 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2522 service
.SetProxyScriptFetchers(fetcher
,
2523 new DoNothingDhcpProxyScriptFetcher());
2528 TestCompletionCallback callback1
;
2529 int rv
= service
.ResolveProxy(
2530 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2531 NULL
, NULL
, BoundNetLog());
2532 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2534 // The first request should have triggered initial download of PAC script.
2535 EXPECT_TRUE(fetcher
->has_pending_request());
2536 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2538 // Nothing has been sent to the resolver yet.
2539 EXPECT_TRUE(resolver
->pending_requests().empty());
2541 // At this point the ProxyService should be waiting for the
2542 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2543 // PAC script download completion.
2545 // We simulate a failed download attempt, the proxy service should now
2546 // fall-back to DIRECT connections.
2547 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2549 ASSERT_TRUE(resolver
->pending_requests().empty());
2551 // Wait for completion callback, and verify it used DIRECT.
2552 EXPECT_EQ(OK
, callback1
.WaitForResult());
2553 EXPECT_TRUE(info1
.is_direct());
2555 // At this point we have initialized the proxy service using a PAC script,
2556 // however it failed and fell-back to DIRECT.
2558 // A background task to periodically re-check the PAC script for validity will
2559 // have been started. We will now wait for the next download attempt to start.
2561 // Note that we shouldn't have to wait long here, since our test enables a
2562 // special unit-test mode.
2563 fetcher
->WaitUntilFetch();
2565 ASSERT_TRUE(resolver
->pending_requests().empty());
2567 // Make sure that our background checker is trying to download the expected
2568 // PAC script (same one as before). This time we will simulate a successful
2569 // download of the script.
2570 EXPECT_TRUE(fetcher
->has_pending_request());
2571 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2572 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2574 base::MessageLoop::current()->RunUntilIdle();
2576 // Now that the PAC script is downloaded, it should be used to initialize the
2577 // ProxyResolver. Simulate a successful parse.
2578 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2579 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2580 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2582 // At this point the ProxyService should have re-configured itself to use the
2583 // PAC script (thereby recovering from the initial fetch failure). We will
2584 // verify that the next Resolve request uses the resolver rather than
2587 // Start a second request.
2589 TestCompletionCallback callback2
;
2590 rv
= service
.ResolveProxy(
2591 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2592 NULL
, NULL
, BoundNetLog());
2593 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2595 // Check that it was sent to the resolver.
2596 ASSERT_EQ(1u, resolver
->pending_requests().size());
2597 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[0]->url());
2599 // Complete the pending second request.
2600 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
2601 resolver
->pending_requests()[0]->CompleteNow(OK
);
2603 // Wait for completion callback, and verify that the request ran as expected.
2604 EXPECT_EQ(OK
, callback2
.WaitForResult());
2605 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2608 // This test verifies that the PAC script specified by the settings is
2609 // periodically polled for changes. Specifically, if the initial fetch succeeds,
2610 // however at a later time its *contents* change, we will eventually
2611 // re-configure the service to use the new script.
2612 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterContentChange
) {
2613 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2615 ImmediatePollPolicy poll_policy
;
2616 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2618 MockProxyConfigService
* config_service
=
2619 new MockProxyConfigService("http://foopy/proxy.pac");
2621 MockAsyncProxyResolverExpectsBytes
* resolver
=
2622 new MockAsyncProxyResolverExpectsBytes
;
2624 ProxyService
service(config_service
, resolver
, NULL
);
2626 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2627 service
.SetProxyScriptFetchers(fetcher
,
2628 new DoNothingDhcpProxyScriptFetcher());
2633 TestCompletionCallback callback1
;
2634 int rv
= service
.ResolveProxy(
2635 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2636 NULL
, NULL
, BoundNetLog());
2637 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2639 // The first request should have triggered initial download of PAC script.
2640 EXPECT_TRUE(fetcher
->has_pending_request());
2641 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2643 // Nothing has been sent to the resolver yet.
2644 EXPECT_TRUE(resolver
->pending_requests().empty());
2646 // At this point the ProxyService should be waiting for the
2647 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2648 // PAC script download completion.
2649 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2651 // Now that the PAC script is downloaded, the request will have been sent to
2652 // the proxy resolver.
2653 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2654 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2655 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2657 ASSERT_EQ(1u, resolver
->pending_requests().size());
2658 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2660 // Complete the pending request.
2661 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2662 resolver
->pending_requests()[0]->CompleteNow(OK
);
2664 // Wait for completion callback, and verify that the request ran as expected.
2665 EXPECT_EQ(OK
, callback1
.WaitForResult());
2666 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2668 // At this point we have initialized the proxy service using a PAC script.
2670 // A background task to periodically re-check the PAC script for validity will
2671 // have been started. We will now wait for the next download attempt to start.
2673 // Note that we shouldn't have to wait long here, since our test enables a
2674 // special unit-test mode.
2675 fetcher
->WaitUntilFetch();
2677 ASSERT_TRUE(resolver
->pending_requests().empty());
2679 // Make sure that our background checker is trying to download the expected
2680 // PAC script (same one as before). This time we will simulate a successful
2681 // download of a DIFFERENT script.
2682 EXPECT_TRUE(fetcher
->has_pending_request());
2683 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2684 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript2
);
2686 base::MessageLoop::current()->RunUntilIdle();
2688 // Now that the PAC script is downloaded, it should be used to initialize the
2689 // ProxyResolver. Simulate a successful parse.
2690 EXPECT_EQ(ASCIIToUTF16(kValidPacScript2
),
2691 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2692 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2694 // At this point the ProxyService should have re-configured itself to use the
2697 // Start a second request.
2699 TestCompletionCallback callback2
;
2700 rv
= service
.ResolveProxy(
2701 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2702 NULL
, NULL
, BoundNetLog());
2703 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2705 // Check that it was sent to the resolver.
2706 ASSERT_EQ(1u, resolver
->pending_requests().size());
2707 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[0]->url());
2709 // Complete the pending second request.
2710 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
2711 resolver
->pending_requests()[0]->CompleteNow(OK
);
2713 // Wait for completion callback, and verify that the request ran as expected.
2714 EXPECT_EQ(OK
, callback2
.WaitForResult());
2715 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2718 // This test verifies that the PAC script specified by the settings is
2719 // periodically polled for changes. Specifically, if the initial fetch succeeds
2720 // and so does the next poll, however the contents of the downloaded script
2721 // have NOT changed, then we do not bother to re-initialize the proxy resolver.
2722 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterContentUnchanged
) {
2723 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2725 ImmediatePollPolicy poll_policy
;
2726 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2728 MockProxyConfigService
* config_service
=
2729 new MockProxyConfigService("http://foopy/proxy.pac");
2731 MockAsyncProxyResolverExpectsBytes
* resolver
=
2732 new MockAsyncProxyResolverExpectsBytes
;
2734 ProxyService
service(config_service
, resolver
, NULL
);
2736 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2737 service
.SetProxyScriptFetchers(fetcher
,
2738 new DoNothingDhcpProxyScriptFetcher());
2743 TestCompletionCallback callback1
;
2744 int rv
= service
.ResolveProxy(
2745 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2746 NULL
, NULL
, BoundNetLog());
2747 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2749 // The first request should have triggered initial download of PAC script.
2750 EXPECT_TRUE(fetcher
->has_pending_request());
2751 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2753 // Nothing has been sent to the resolver yet.
2754 EXPECT_TRUE(resolver
->pending_requests().empty());
2756 // At this point the ProxyService should be waiting for the
2757 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2758 // PAC script download completion.
2759 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2761 // Now that the PAC script is downloaded, the request will have been sent to
2762 // the proxy resolver.
2763 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2764 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2765 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2767 ASSERT_EQ(1u, resolver
->pending_requests().size());
2768 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2770 // Complete the pending request.
2771 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2772 resolver
->pending_requests()[0]->CompleteNow(OK
);
2774 // Wait for completion callback, and verify that the request ran as expected.
2775 EXPECT_EQ(OK
, callback1
.WaitForResult());
2776 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2778 // At this point we have initialized the proxy service using a PAC script.
2780 // A background task to periodically re-check the PAC script for validity will
2781 // have been started. We will now wait for the next download attempt to start.
2783 // Note that we shouldn't have to wait long here, since our test enables a
2784 // special unit-test mode.
2785 fetcher
->WaitUntilFetch();
2787 ASSERT_TRUE(resolver
->pending_requests().empty());
2789 // Make sure that our background checker is trying to download the expected
2790 // PAC script (same one as before). We will simulate the same response as
2791 // last time (i.e. the script is unchanged).
2792 EXPECT_TRUE(fetcher
->has_pending_request());
2793 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2794 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2796 base::MessageLoop::current()->RunUntilIdle();
2798 ASSERT_FALSE(resolver
->has_pending_set_pac_script_request());
2800 // At this point the ProxyService is still running the same PAC script as
2803 // Start a second request.
2805 TestCompletionCallback callback2
;
2806 rv
= service
.ResolveProxy(
2807 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2808 NULL
, NULL
, BoundNetLog());
2809 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2811 // Check that it was sent to the resolver.
2812 ASSERT_EQ(1u, resolver
->pending_requests().size());
2813 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[0]->url());
2815 // Complete the pending second request.
2816 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
2817 resolver
->pending_requests()[0]->CompleteNow(OK
);
2819 // Wait for completion callback, and verify that the request ran as expected.
2820 EXPECT_EQ(OK
, callback2
.WaitForResult());
2821 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2824 // This test verifies that the PAC script specified by the settings is
2825 // periodically polled for changes. Specifically, if the initial fetch succeeds,
2826 // however at a later time it starts to fail, we should re-configure the
2827 // ProxyService to stop using that PAC script.
2828 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterSuccess
) {
2829 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2831 ImmediatePollPolicy poll_policy
;
2832 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2834 MockProxyConfigService
* config_service
=
2835 new MockProxyConfigService("http://foopy/proxy.pac");
2837 MockAsyncProxyResolverExpectsBytes
* resolver
=
2838 new MockAsyncProxyResolverExpectsBytes
;
2840 ProxyService
service(config_service
, resolver
, NULL
);
2842 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2843 service
.SetProxyScriptFetchers(fetcher
,
2844 new DoNothingDhcpProxyScriptFetcher());
2849 TestCompletionCallback callback1
;
2850 int rv
= service
.ResolveProxy(
2851 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2852 NULL
, NULL
, BoundNetLog());
2853 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2855 // The first request should have triggered initial download of PAC script.
2856 EXPECT_TRUE(fetcher
->has_pending_request());
2857 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2859 // Nothing has been sent to the resolver yet.
2860 EXPECT_TRUE(resolver
->pending_requests().empty());
2862 // At this point the ProxyService should be waiting for the
2863 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2864 // PAC script download completion.
2865 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2867 // Now that the PAC script is downloaded, the request will have been sent to
2868 // the proxy resolver.
2869 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2870 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2871 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2873 ASSERT_EQ(1u, resolver
->pending_requests().size());
2874 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2876 // Complete the pending request.
2877 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2878 resolver
->pending_requests()[0]->CompleteNow(OK
);
2880 // Wait for completion callback, and verify that the request ran as expected.
2881 EXPECT_EQ(OK
, callback1
.WaitForResult());
2882 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2884 // At this point we have initialized the proxy service using a PAC script.
2886 // A background task to periodically re-check the PAC script for validity will
2887 // have been started. We will now wait for the next download attempt to start.
2889 // Note that we shouldn't have to wait long here, since our test enables a
2890 // special unit-test mode.
2891 fetcher
->WaitUntilFetch();
2893 ASSERT_TRUE(resolver
->pending_requests().empty());
2895 // Make sure that our background checker is trying to download the expected
2896 // PAC script (same one as before). This time we will simulate a failure
2897 // to download the script.
2898 EXPECT_TRUE(fetcher
->has_pending_request());
2899 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2900 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2902 base::MessageLoop::current()->RunUntilIdle();
2904 // At this point the ProxyService should have re-configured itself to use
2905 // DIRECT connections rather than the given proxy resolver.
2907 // Start a second request.
2909 TestCompletionCallback callback2
;
2910 rv
= service
.ResolveProxy(
2911 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2912 NULL
, NULL
, BoundNetLog());
2914 EXPECT_TRUE(info2
.is_direct());
2917 // Tests that the code which decides at what times to poll the PAC
2918 // script follows the expected policy.
2919 TEST_F(ProxyServiceTest
, PACScriptPollingPolicy
) {
2920 // Retrieve the internal polling policy implementation used by ProxyService.
2921 scoped_ptr
<ProxyService::PacPollPolicy
> policy
=
2922 ProxyService::CreateDefaultPacPollPolicy();
2925 ProxyService::PacPollPolicy::Mode mode
;
2926 const base::TimeDelta initial_delay
= base::TimeDelta::FromMilliseconds(-1);
2927 base::TimeDelta delay
= initial_delay
;
2929 // --------------------------------------------------
2930 // Test the poll sequence in response to a failure.
2931 // --------------------------------------------------
2932 error
= ERR_NAME_NOT_RESOLVED
;
2935 mode
= policy
->GetNextDelay(error
, initial_delay
, &delay
);
2936 EXPECT_EQ(8, delay
.InSeconds());
2937 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_USE_TIMER
, mode
);
2940 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2941 EXPECT_EQ(32, delay
.InSeconds());
2942 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2945 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2946 EXPECT_EQ(120, delay
.InSeconds());
2947 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2950 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2951 EXPECT_EQ(14400, delay
.InSeconds());
2952 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2955 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2956 EXPECT_EQ(14400, delay
.InSeconds());
2957 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2959 // --------------------------------------------------
2960 // Test the poll sequence in response to a success.
2961 // --------------------------------------------------
2965 mode
= policy
->GetNextDelay(error
, initial_delay
, &delay
);
2966 EXPECT_EQ(43200, delay
.InSeconds());
2967 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2970 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2971 EXPECT_EQ(43200, delay
.InSeconds());
2972 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2975 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2976 EXPECT_EQ(43200, delay
.InSeconds());
2977 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2980 // This tests the polling of the PAC script. Specifically, it tests that
2981 // polling occurs in response to user activity.
2982 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterActivity
) {
2983 ImmediateAfterActivityPollPolicy poll_policy
;
2984 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2986 MockProxyConfigService
* config_service
=
2987 new MockProxyConfigService("http://foopy/proxy.pac");
2989 MockAsyncProxyResolverExpectsBytes
* resolver
=
2990 new MockAsyncProxyResolverExpectsBytes
;
2992 ProxyService
service(config_service
, resolver
, NULL
);
2994 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2995 service
.SetProxyScriptFetchers(fetcher
,
2996 new DoNothingDhcpProxyScriptFetcher());
3001 TestCompletionCallback callback1
;
3002 int rv
= service
.ResolveProxy(
3003 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
3004 NULL
, NULL
, BoundNetLog());
3005 EXPECT_EQ(ERR_IO_PENDING
, rv
);
3007 // The first request should have triggered initial download of PAC script.
3008 EXPECT_TRUE(fetcher
->has_pending_request());
3009 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
3011 // Nothing has been sent to the resolver yet.
3012 EXPECT_TRUE(resolver
->pending_requests().empty());
3014 // At this point the ProxyService should be waiting for the
3015 // ProxyScriptFetcher to invoke its completion callback, notifying it of
3016 // PAC script download completion.
3017 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
3019 // Now that the PAC script is downloaded, the request will have been sent to
3020 // the proxy resolver.
3021 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
3022 resolver
->pending_set_pac_script_request()->script_data()->utf16());
3023 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
3025 ASSERT_EQ(1u, resolver
->pending_requests().size());
3026 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
3028 // Complete the pending request.
3029 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
3030 resolver
->pending_requests()[0]->CompleteNow(OK
);
3032 // Wait for completion callback, and verify that the request ran as expected.
3033 EXPECT_EQ(OK
, callback1
.WaitForResult());
3034 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
3036 // At this point we have initialized the proxy service using a PAC script.
3037 // Our PAC poller is set to update ONLY in response to network activity,
3038 // (i.e. another call to ResolveProxy()).
3040 ASSERT_FALSE(fetcher
->has_pending_request());
3041 ASSERT_TRUE(resolver
->pending_requests().empty());
3043 // Start a second request.
3045 TestCompletionCallback callback2
;
3046 rv
= service
.ResolveProxy(
3047 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
3048 NULL
, NULL
, BoundNetLog());
3049 EXPECT_EQ(ERR_IO_PENDING
, rv
);
3051 // This request should have sent work to the resolver; complete it.
3052 ASSERT_EQ(1u, resolver
->pending_requests().size());
3053 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[0]->url());
3054 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
3055 resolver
->pending_requests()[0]->CompleteNow(OK
);
3057 EXPECT_EQ(OK
, callback2
.WaitForResult());
3058 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
3060 // In response to getting that resolve request, the poller should have
3061 // started the next poll, and made it as far as to request the download.
3063 EXPECT_TRUE(fetcher
->has_pending_request());
3064 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
3066 // This time we will fail the download, to simulate a PAC script change.
3067 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
3069 // Drain the message loop, so ProxyService is notified of the change
3070 // and has a chance to re-configure itself.
3071 base::MessageLoop::current()->RunUntilIdle();
3073 // Start a third request -- this time we expect to get a direct connection
3074 // since the PAC script poller experienced a failure.
3076 TestCompletionCallback callback3
;
3077 rv
= service
.ResolveProxy(
3078 GURL("http://request3"), net::LOAD_NORMAL
, &info3
, callback3
.callback(),
3079 NULL
, NULL
, BoundNetLog());
3081 EXPECT_TRUE(info3
.is_direct());