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