1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/proxy/proxy_service.h"
9 #include "base/format_macros.h"
10 #include "base/logging.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "net/base/load_flags.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/network_delegate_impl.h"
16 #include "net/base/test_completion_callback.h"
17 #include "net/log/net_log.h"
18 #include "net/log/test_net_log.h"
19 #include "net/log/test_net_log_entry.h"
20 #include "net/log/test_net_log_util.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 base::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 MockAsyncProxyResolverFactory
* factory
=
246 new MockAsyncProxyResolverFactory(false);
247 ProxyService
service(new MockProxyConfigService(ProxyConfig::CreateDirect()),
248 make_scoped_ptr(factory
), 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(factory
->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 TestNetLogEntry::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
;
378 MockAsyncProxyResolverFactory
* factory
=
379 new MockAsyncProxyResolverFactory(false);
381 ProxyService
service(config_service
, make_scoped_ptr(factory
), 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 ASSERT_EQ(1u, factory
->pending_requests().size());
397 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
398 factory
->pending_requests()[0]->script_data()->url());
399 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
401 ASSERT_EQ(1u, resolver
.pending_requests().size());
402 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
404 // Set the result in proxy resolver.
405 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy");
406 resolver
.pending_requests()[0]->CompleteNow(OK
);
408 EXPECT_EQ(OK
, callback
.WaitForResult());
409 EXPECT_FALSE(info
.is_direct());
410 EXPECT_EQ("foopy:80", info
.proxy_server().ToURI());
411 EXPECT_TRUE(info
.did_use_pac_script());
413 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
414 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
415 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
417 // Check the NetLog was filled correctly.
418 TestNetLogEntry::List entries
;
419 log
.GetEntries(&entries
);
421 EXPECT_EQ(5u, entries
.size());
422 EXPECT_TRUE(LogContainsBeginEvent(
423 entries
, 0, NetLog::TYPE_PROXY_SERVICE
));
424 EXPECT_TRUE(LogContainsBeginEvent(
425 entries
, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
426 EXPECT_TRUE(LogContainsEndEvent(
427 entries
, 2, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
428 EXPECT_TRUE(LogContainsEndEvent(
429 entries
, 4, NetLog::TYPE_PROXY_SERVICE
));
432 // Test that the proxy resolver does not see the URL's username/password
433 // or its reference section.
434 TEST_F(ProxyServiceTest
, PAC_NoIdentityOrHash
) {
435 MockProxyConfigService
* config_service
=
436 new MockProxyConfigService("http://foopy/proxy.pac");
438 MockAsyncProxyResolver resolver
;
439 MockAsyncProxyResolverFactory
* factory
=
440 new MockAsyncProxyResolverFactory(false);
442 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
444 GURL
url("http://username:password@www.google.com/?ref#hash#hash");
447 TestCompletionCallback callback
;
448 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(),
449 NULL
, NULL
, BoundNetLog());
450 EXPECT_EQ(ERR_IO_PENDING
, rv
);
452 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
453 factory
->pending_requests()[0]->script_data()->url());
454 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
456 ASSERT_EQ(1u, resolver
.pending_requests().size());
457 // The URL should have been simplified, stripping the username/password/hash.
458 EXPECT_EQ(GURL("http://www.google.com/?ref"),
459 resolver
.pending_requests()[0]->url());
461 // We end here without ever completing the request -- destruction of
462 // ProxyService will cancel the outstanding request.
465 TEST_F(ProxyServiceTest
, PAC_FailoverWithoutDirect
) {
466 MockProxyConfigService
* config_service
=
467 new MockProxyConfigService("http://foopy/proxy.pac");
468 MockAsyncProxyResolver resolver
;
469 MockAsyncProxyResolverFactory
* factory
=
470 new MockAsyncProxyResolverFactory(false);
472 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
474 GURL
url("http://www.google.com/");
477 TestCompletionCallback callback1
;
478 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
479 NULL
, NULL
, BoundNetLog());
480 EXPECT_EQ(ERR_IO_PENDING
, rv
);
482 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
483 factory
->pending_requests()[0]->script_data()->url());
484 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
486 ASSERT_EQ(1u, resolver
.pending_requests().size());
487 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
489 // Set the result in proxy resolver.
490 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy:8080");
491 resolver
.pending_requests()[0]->CompleteNow(OK
);
493 EXPECT_EQ(OK
, callback1
.WaitForResult());
494 EXPECT_FALSE(info
.is_direct());
495 EXPECT_EQ("foopy:8080", info
.proxy_server().ToURI());
496 EXPECT_TRUE(info
.did_use_pac_script());
498 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
499 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
500 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
502 // Now, imagine that connecting to foopy:8080 fails: there is nothing
503 // left to fallback to, since our proxy list was NOT terminated by
505 NetworkDelegateImpl network_delegate
;
506 TestCompletionCallback callback2
;
507 ProxyServer expected_proxy_server
= info
.proxy_server();
508 rv
= service
.ReconsiderProxyAfterError(
509 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
510 callback2
.callback(), NULL
, &network_delegate
, BoundNetLog());
511 // ReconsiderProxyAfterError returns error indicating nothing left.
512 EXPECT_EQ(ERR_FAILED
, rv
);
513 EXPECT_TRUE(info
.is_empty());
516 // Test that if the execution of the PAC script fails (i.e. javascript runtime
517 // error), and the PAC settings are non-mandatory, that we fall-back to direct.
518 TEST_F(ProxyServiceTest
, PAC_RuntimeError
) {
519 MockProxyConfigService
* config_service
=
520 new MockProxyConfigService("http://foopy/proxy.pac");
521 MockAsyncProxyResolver resolver
;
522 MockAsyncProxyResolverFactory
* factory
=
523 new MockAsyncProxyResolverFactory(false);
525 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
527 GURL
url("http://this-causes-js-error/");
530 TestCompletionCallback callback1
;
531 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
532 NULL
, NULL
, BoundNetLog());
533 EXPECT_EQ(ERR_IO_PENDING
, rv
);
535 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
536 factory
->pending_requests()[0]->script_data()->url());
537 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
539 ASSERT_EQ(1u, resolver
.pending_requests().size());
540 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
542 // Simulate a failure in the PAC executor.
543 resolver
.pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_FAILED
);
545 EXPECT_EQ(OK
, callback1
.WaitForResult());
547 // Since the PAC script was non-mandatory, we should have fallen-back to
549 EXPECT_TRUE(info
.is_direct());
550 EXPECT_TRUE(info
.did_use_pac_script());
551 EXPECT_EQ(1, info
.config_id());
553 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
554 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
555 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
558 // The proxy list could potentially contain the DIRECT fallback choice
559 // in a location other than the very end of the list, and could even
560 // specify it multiple times.
562 // This is not a typical usage, but we will obey it.
563 // (If we wanted to disallow this type of input, the right place to
564 // enforce it would be in parsing the PAC result string).
566 // This test will use the PAC result string:
568 // "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20"
570 // For which we expect it to try DIRECT, then foobar:10, then DIRECT again,
571 // then foobar:20, and then give up and error.
573 // The important check of this test is to make sure that DIRECT is not somehow
574 // cached as being a bad proxy.
575 TEST_F(ProxyServiceTest
, PAC_FailoverAfterDirect
) {
576 MockProxyConfigService
* config_service
=
577 new MockProxyConfigService("http://foopy/proxy.pac");
578 MockAsyncProxyResolver resolver
;
579 MockAsyncProxyResolverFactory
* factory
=
580 new MockAsyncProxyResolverFactory(false);
582 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
584 GURL
url("http://www.google.com/");
587 TestCompletionCallback callback1
;
588 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
589 NULL
, NULL
, BoundNetLog());
590 EXPECT_EQ(ERR_IO_PENDING
, rv
);
592 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
593 factory
->pending_requests()[0]->script_data()->url());
594 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
596 ASSERT_EQ(1u, resolver
.pending_requests().size());
597 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
599 // Set the result in proxy resolver.
600 resolver
.pending_requests()[0]->results()->UsePacString(
601 "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20");
602 resolver
.pending_requests()[0]->CompleteNow(OK
);
604 EXPECT_EQ(OK
, callback1
.WaitForResult());
605 EXPECT_TRUE(info
.is_direct());
608 TestCompletionCallback callback2
;
609 rv
= service
.ReconsiderProxyAfterError(
610 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
611 callback2
.callback(), NULL
, NULL
, BoundNetLog());
613 EXPECT_FALSE(info
.is_direct());
614 EXPECT_EQ("foobar:10", info
.proxy_server().ToURI());
617 NetworkDelegateImpl network_delegate
;
618 ProxyServer expected_proxy_server3
= info
.proxy_server();
619 TestCompletionCallback callback3
;
620 rv
= service
.ReconsiderProxyAfterError(
621 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
622 callback3
.callback(), NULL
, &network_delegate
, BoundNetLog());
624 EXPECT_TRUE(info
.is_direct());
627 ProxyServer expected_proxy_server4
= info
.proxy_server();
628 TestCompletionCallback callback4
;
629 rv
= service
.ReconsiderProxyAfterError(
630 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
631 callback4
.callback(), NULL
, &network_delegate
, BoundNetLog());
633 EXPECT_FALSE(info
.is_direct());
634 EXPECT_EQ("foobar:20", info
.proxy_server().ToURI());
636 // Fallback 4 -- Nothing to fall back to!
637 ProxyServer expected_proxy_server5
= info
.proxy_server();
638 TestCompletionCallback callback5
;
639 rv
= service
.ReconsiderProxyAfterError(
640 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
641 callback5
.callback(), NULL
, &network_delegate
, BoundNetLog());
642 EXPECT_EQ(ERR_FAILED
, rv
);
643 EXPECT_TRUE(info
.is_empty());
646 TEST_F(ProxyServiceTest
, PAC_ConfigSourcePropagates
) {
647 // Test whether the ProxyConfigSource set by the ProxyConfigService is applied
648 // to ProxyInfo after the proxy is resolved via a PAC script.
650 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
651 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
653 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
654 MockAsyncProxyResolver resolver
;
655 MockAsyncProxyResolverFactory
* factory
=
656 new MockAsyncProxyResolverFactory(false);
657 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
659 // Resolve something.
660 GURL
url("http://www.google.com/");
662 TestCompletionCallback callback
;
663 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(),
664 NULL
, NULL
, BoundNetLog());
665 ASSERT_EQ(ERR_IO_PENDING
, rv
);
666 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
667 ASSERT_EQ(1u, resolver
.pending_requests().size());
669 // Set the result in proxy resolver.
670 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy");
671 resolver
.pending_requests()[0]->CompleteNow(OK
);
673 EXPECT_EQ(OK
, callback
.WaitForResult());
674 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
675 EXPECT_TRUE(info
.did_use_pac_script());
677 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
678 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
679 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
682 TEST_F(ProxyServiceTest
, ProxyResolverFails
) {
683 // Test what happens when the ProxyResolver fails. The download and setting
684 // of the PAC script have already succeeded, so this corresponds with a
685 // javascript runtime error while calling FindProxyForURL().
687 MockProxyConfigService
* config_service
=
688 new MockProxyConfigService("http://foopy/proxy.pac");
690 MockAsyncProxyResolver resolver
;
691 MockAsyncProxyResolverFactory
* factory
=
692 new MockAsyncProxyResolverFactory(false);
694 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
696 // Start first resolve request.
697 GURL
url("http://www.google.com/");
699 TestCompletionCallback callback1
;
700 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
701 NULL
, NULL
, BoundNetLog());
702 EXPECT_EQ(ERR_IO_PENDING
, rv
);
704 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
705 factory
->pending_requests()[0]->script_data()->url());
706 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
708 ASSERT_EQ(1u, resolver
.pending_requests().size());
709 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
711 // Fail the first resolve request in MockAsyncProxyResolver.
712 resolver
.pending_requests()[0]->CompleteNow(ERR_FAILED
);
714 // Although the proxy resolver failed the request, ProxyService implicitly
715 // falls-back to DIRECT.
716 EXPECT_EQ(OK
, callback1
.WaitForResult());
717 EXPECT_TRUE(info
.is_direct());
719 // Failed PAC executions still have proxy resolution times.
720 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
721 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
722 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
724 // The second resolve request will try to run through the proxy resolver,
725 // regardless of whether the first request failed in it.
726 TestCompletionCallback callback2
;
727 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback2
.callback(), NULL
,
728 NULL
, BoundNetLog());
729 EXPECT_EQ(ERR_IO_PENDING
, rv
);
731 ASSERT_EQ(1u, resolver
.pending_requests().size());
732 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
734 // This time we will have the resolver succeed (perhaps the PAC script has
735 // a dependency on the current time).
736 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
737 resolver
.pending_requests()[0]->CompleteNow(OK
);
739 EXPECT_EQ(OK
, callback2
.WaitForResult());
740 EXPECT_FALSE(info
.is_direct());
741 EXPECT_EQ("foopy_valid:8080", info
.proxy_server().ToURI());
744 TEST_F(ProxyServiceTest
, ProxyResolverTerminatedDuringRequest
) {
745 // Test what happens when the ProxyResolver fails with a fatal error while
746 // a GetProxyForURL() call is in progress.
748 MockProxyConfigService
* config_service
=
749 new MockProxyConfigService("http://foopy/proxy.pac");
751 MockAsyncProxyResolver resolver
;
752 MockAsyncProxyResolverFactory
* factory
=
753 new MockAsyncProxyResolverFactory(false);
755 ProxyService
service(config_service
, make_scoped_ptr(factory
), nullptr);
757 // Start first resolve request.
758 GURL
url("http://www.google.com/");
760 TestCompletionCallback callback1
;
762 service
.ResolveProxy(url
, net::LOAD_NORMAL
, &info
, callback1
.callback(),
763 nullptr, nullptr, BoundNetLog());
764 EXPECT_EQ(ERR_IO_PENDING
, rv
);
766 ASSERT_EQ(1u, factory
->pending_requests().size());
767 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
768 factory
->pending_requests()[0]->script_data()->url());
769 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
771 ASSERT_EQ(1u, resolver
.pending_requests().size());
772 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
774 // Fail the first resolve request in MockAsyncProxyResolver.
775 resolver
.pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_TERMINATED
);
777 // Although the proxy resolver failed the request, ProxyService implicitly
778 // falls-back to DIRECT.
779 EXPECT_EQ(OK
, callback1
.WaitForResult());
780 EXPECT_TRUE(info
.is_direct());
782 // Failed PAC executions still have proxy resolution times.
783 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
784 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
785 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
787 // With no other requests, the ProxyService waits for a new request before
788 // initializing a new ProxyResolver.
789 EXPECT_TRUE(factory
->pending_requests().empty());
791 TestCompletionCallback callback2
;
792 rv
= service
.ResolveProxy(url
, net::LOAD_NORMAL
, &info
, callback2
.callback(),
793 nullptr, nullptr, BoundNetLog());
794 EXPECT_EQ(ERR_IO_PENDING
, rv
);
796 ASSERT_EQ(1u, factory
->pending_requests().size());
797 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
798 factory
->pending_requests()[0]->script_data()->url());
799 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
801 ASSERT_EQ(1u, resolver
.pending_requests().size());
802 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
804 // This time we will have the resolver succeed.
805 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
806 resolver
.pending_requests()[0]->CompleteNow(OK
);
808 EXPECT_EQ(OK
, callback2
.WaitForResult());
809 EXPECT_FALSE(info
.is_direct());
810 EXPECT_EQ("foopy_valid:8080", info
.proxy_server().ToURI());
813 TEST_F(ProxyServiceTest
,
814 ProxyResolverTerminatedDuringRequestWithConcurrentRequest
) {
815 // Test what happens when the ProxyResolver fails with a fatal error while
816 // a GetProxyForURL() call is in progress.
818 MockProxyConfigService
* config_service
=
819 new MockProxyConfigService("http://foopy/proxy.pac");
821 MockAsyncProxyResolver resolver
;
822 MockAsyncProxyResolverFactory
* factory
=
823 new MockAsyncProxyResolverFactory(false);
825 ProxyService
service(config_service
, make_scoped_ptr(factory
), nullptr);
827 // Start two resolve requests.
828 GURL
url1("http://www.google.com/");
829 GURL
url2("https://www.google.com/");
831 TestCompletionCallback callback1
;
833 service
.ResolveProxy(url1
, net::LOAD_NORMAL
, &info
, callback1
.callback(),
834 nullptr, nullptr, BoundNetLog());
835 EXPECT_EQ(ERR_IO_PENDING
, rv
);
836 TestCompletionCallback callback2
;
837 rv
= service
.ResolveProxy(url2
, net::LOAD_NORMAL
, &info
, callback2
.callback(),
838 nullptr, nullptr, BoundNetLog());
839 EXPECT_EQ(ERR_IO_PENDING
, rv
);
841 ASSERT_EQ(1u, factory
->pending_requests().size());
842 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
843 factory
->pending_requests()[0]->script_data()->url());
844 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
846 ASSERT_EQ(2u, resolver
.pending_requests().size());
847 EXPECT_EQ(url1
, resolver
.pending_requests()[0]->url());
848 EXPECT_EQ(url2
, resolver
.pending_requests()[1]->url());
850 // Fail the first resolve request in MockAsyncProxyResolver.
851 resolver
.pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_TERMINATED
);
853 // Although the proxy resolver failed the request, ProxyService implicitly
854 // falls-back to DIRECT.
855 EXPECT_EQ(OK
, callback1
.WaitForResult());
856 EXPECT_TRUE(info
.is_direct());
858 // Failed PAC executions still have proxy resolution times.
859 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
860 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
861 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
863 // The second request is cancelled when the proxy resolver terminates.
864 ASSERT_EQ(1u, resolver
.cancelled_requests().size());
865 EXPECT_EQ(url2
, resolver
.cancelled_requests()[0]->url());
867 // Since a second request was in progress, the ProxyService starts
868 // initializating a new ProxyResolver.
869 ASSERT_EQ(1u, factory
->pending_requests().size());
870 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
871 factory
->pending_requests()[0]->script_data()->url());
872 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
874 ASSERT_EQ(1u, resolver
.pending_requests().size());
875 EXPECT_EQ(url2
, resolver
.pending_requests()[0]->url());
877 // This request succeeds.
878 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
879 resolver
.pending_requests()[0]->CompleteNow(OK
);
881 EXPECT_EQ(OK
, callback2
.WaitForResult());
882 EXPECT_FALSE(info
.is_direct());
883 EXPECT_EQ("foopy_valid:8080", info
.proxy_server().ToURI());
886 TEST_F(ProxyServiceTest
, ProxyScriptFetcherFailsDownloadingMandatoryPac
) {
887 // Test what happens when the ProxyScriptResolver fails to download a
888 // mandatory PAC script.
891 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
892 config
.set_pac_mandatory(true);
894 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
896 MockAsyncProxyResolverFactory
* factory
=
897 new MockAsyncProxyResolverFactory(false);
899 ProxyService
service(config_service
, make_scoped_ptr(factory
), 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 factory
->pending_requests()[0]->script_data()->url());
911 factory
->pending_requests()[0]->CompleteNow(ERR_FAILED
, nullptr);
913 ASSERT_EQ(0u, factory
->pending_requests().size());
914 // As the proxy resolver factory failed the request and is configured for a
915 // mandatory 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 factory failed the request and is configured for a
921 // mandatory 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 MockAsyncProxyResolverFactory
* factory
=
941 new MockAsyncProxyResolverFactory(true);
943 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
945 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
946 DhcpProxyScriptFetcher
* dhcp_fetcher
= new DoNothingDhcpProxyScriptFetcher();
947 service
.SetProxyScriptFetchers(fetcher
, dhcp_fetcher
);
949 // Start resolve request.
950 GURL
url("http://www.google.com/");
952 TestCompletionCallback callback
;
953 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(),
954 NULL
, NULL
, BoundNetLog());
955 EXPECT_EQ(ERR_IO_PENDING
, rv
);
957 // Check that nothing has been sent to the proxy resolver factory yet.
958 ASSERT_EQ(0u, factory
->pending_requests().size());
960 // Downloading the PAC script succeeds.
961 EXPECT_TRUE(fetcher
->has_pending_request());
962 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
963 fetcher
->NotifyFetchCompletion(OK
, "invalid-script-contents");
965 EXPECT_FALSE(fetcher
->has_pending_request());
966 ASSERT_EQ(0u, factory
->pending_requests().size());
968 // Since ProxyScriptDecider failed to identify a valid PAC and PAC was
969 // mandatory for this configuration, the ProxyService must not implicitly
970 // fall-back to DIRECT.
971 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
972 callback
.WaitForResult());
973 EXPECT_FALSE(info
.is_direct());
976 TEST_F(ProxyServiceTest
, ProxyResolverFailsInJavaScriptMandatoryPac
) {
977 // Test what happens when the ProxyResolver fails that is configured to use a
978 // mandatory PAC script. The download and setting of the PAC script have
979 // already succeeded, so this corresponds with a javascript runtime error
980 // while calling FindProxyForURL().
983 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
984 config
.set_pac_mandatory(true);
986 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
988 MockAsyncProxyResolver resolver
;
989 MockAsyncProxyResolverFactory
* factory
=
990 new MockAsyncProxyResolverFactory(false);
992 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
994 // Start first resolve request.
995 GURL
url("http://www.google.com/");
997 TestCompletionCallback callback1
;
998 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
999 NULL
, NULL
, BoundNetLog());
1000 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1002 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1003 factory
->pending_requests()[0]->script_data()->url());
1004 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1006 ASSERT_EQ(1u, resolver
.pending_requests().size());
1007 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1009 // Fail the first resolve request in MockAsyncProxyResolver.
1010 resolver
.pending_requests()[0]->CompleteNow(ERR_FAILED
);
1012 // As the proxy resolver failed the request and is configured for a mandatory
1013 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
1014 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
1015 callback1
.WaitForResult());
1016 EXPECT_FALSE(info
.is_direct());
1018 // The second resolve request will try to run through the proxy resolver,
1019 // regardless of whether the first request failed in it.
1020 TestCompletionCallback callback2
;
1021 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback2
.callback(), NULL
,
1022 NULL
, BoundNetLog());
1023 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1025 ASSERT_EQ(1u, resolver
.pending_requests().size());
1026 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1028 // This time we will have the resolver succeed (perhaps the PAC script has
1029 // a dependency on the current time).
1030 resolver
.pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
1031 resolver
.pending_requests()[0]->CompleteNow(OK
);
1033 EXPECT_EQ(OK
, callback2
.WaitForResult());
1034 EXPECT_FALSE(info
.is_direct());
1035 EXPECT_EQ("foopy_valid:8080", info
.proxy_server().ToURI());
1038 TEST_F(ProxyServiceTest
, ProxyFallback
) {
1039 // Test what happens when we specify multiple proxy servers and some of them
1042 MockProxyConfigService
* config_service
=
1043 new MockProxyConfigService("http://foopy/proxy.pac");
1045 MockAsyncProxyResolver resolver
;
1046 MockAsyncProxyResolverFactory
* factory
=
1047 new MockAsyncProxyResolverFactory(false);
1049 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1051 GURL
url("http://www.google.com/");
1053 // Get the proxy information.
1055 TestCompletionCallback callback1
;
1056 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
1057 NULL
, NULL
, BoundNetLog());
1058 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1060 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1061 factory
->pending_requests()[0]->script_data()->url());
1062 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1064 ASSERT_EQ(1u, resolver
.pending_requests().size());
1065 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1067 // Set the result in proxy resolver.
1068 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1069 "foopy1:8080;foopy2:9090");
1070 resolver
.pending_requests()[0]->CompleteNow(OK
);
1072 // The first item is valid.
1073 EXPECT_EQ(OK
, callback1
.WaitForResult());
1074 EXPECT_FALSE(info
.is_direct());
1075 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1077 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1078 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1079 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1080 base::TimeTicks proxy_resolve_start_time
= info
.proxy_resolve_start_time();
1081 base::TimeTicks proxy_resolve_end_time
= info
.proxy_resolve_end_time();
1083 // Fake an error on the proxy.
1084 TestCompletionCallback callback2
;
1085 rv
= service
.ReconsiderProxyAfterError(
1086 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1087 callback2
.callback(), NULL
, NULL
, BoundNetLog());
1090 // Proxy times should not have been modified by fallback.
1091 EXPECT_EQ(proxy_resolve_start_time
, info
.proxy_resolve_start_time());
1092 EXPECT_EQ(proxy_resolve_end_time
, info
.proxy_resolve_end_time());
1094 // The second proxy should be specified.
1095 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1096 // Report back that the second proxy worked. This will globally mark the
1097 // first proxy as bad.
1098 TestProxyFallbackNetworkDelegate test_delegate
;
1099 service
.ReportSuccess(info
, &test_delegate
);
1100 EXPECT_EQ("foopy1:8080", test_delegate
.proxy_server().ToURI());
1101 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED
,
1102 test_delegate
.proxy_fallback_net_error());
1104 TestCompletionCallback callback3
;
1105 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback3
.callback(), NULL
,
1106 NULL
, BoundNetLog());
1107 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1109 ASSERT_EQ(1u, resolver
.pending_requests().size());
1110 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1112 // Set the result in proxy resolver -- the second result is already known
1113 // to be bad, so we will not try to use it initially.
1114 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1115 "foopy3:7070;foopy1:8080;foopy2:9090");
1116 resolver
.pending_requests()[0]->CompleteNow(OK
);
1118 EXPECT_EQ(OK
, callback3
.WaitForResult());
1119 EXPECT_FALSE(info
.is_direct());
1120 EXPECT_EQ("foopy3:7070", info
.proxy_server().ToURI());
1122 // Proxy times should have been updated, so get them again.
1123 EXPECT_LE(proxy_resolve_end_time
, info
.proxy_resolve_start_time());
1124 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1125 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1126 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1127 proxy_resolve_start_time
= info
.proxy_resolve_start_time();
1128 proxy_resolve_end_time
= info
.proxy_resolve_end_time();
1130 // We fake another error. It should now try the third one.
1131 TestCompletionCallback callback4
;
1132 rv
= service
.ReconsiderProxyAfterError(
1133 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1134 callback4
.callback(), NULL
, NULL
, BoundNetLog());
1136 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1138 // We fake another error. At this point we have tried all of the
1139 // proxy servers we thought were valid; next we try the proxy server
1140 // that was in our bad proxies map (foopy1:8080).
1141 TestCompletionCallback callback5
;
1142 rv
= service
.ReconsiderProxyAfterError(
1143 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1144 callback5
.callback(), NULL
, NULL
, BoundNetLog());
1146 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1148 // Fake another error, the last proxy is gone, the list should now be empty,
1149 // so there is nothing left to try.
1150 TestCompletionCallback callback6
;
1151 rv
= service
.ReconsiderProxyAfterError(
1152 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1153 callback6
.callback(), NULL
, NULL
, BoundNetLog());
1154 EXPECT_EQ(ERR_FAILED
, rv
);
1155 EXPECT_FALSE(info
.is_direct());
1156 EXPECT_TRUE(info
.is_empty());
1158 // Proxy times should not have been modified by fallback.
1159 EXPECT_EQ(proxy_resolve_start_time
, info
.proxy_resolve_start_time());
1160 EXPECT_EQ(proxy_resolve_end_time
, info
.proxy_resolve_end_time());
1162 // Look up proxies again
1163 TestCompletionCallback callback7
;
1164 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback7
.callback(), NULL
,
1165 NULL
, BoundNetLog());
1166 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1168 ASSERT_EQ(1u, resolver
.pending_requests().size());
1169 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1171 // This time, the first 3 results have been found to be bad, but only the
1172 // first proxy has been confirmed ...
1173 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1174 "foopy1:8080;foopy3:7070;foopy2:9090;foopy4:9091");
1175 resolver
.pending_requests()[0]->CompleteNow(OK
);
1177 // ... therefore, we should see the second proxy first.
1178 EXPECT_EQ(OK
, callback7
.WaitForResult());
1179 EXPECT_FALSE(info
.is_direct());
1180 EXPECT_EQ("foopy3:7070", info
.proxy_server().ToURI());
1182 EXPECT_LE(proxy_resolve_end_time
, info
.proxy_resolve_start_time());
1183 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1184 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1185 // TODO(nsylvain): Test that the proxy can be retried after the delay.
1188 // This test is similar to ProxyFallback, but this time we have an explicit
1189 // fallback choice to DIRECT.
1190 TEST_F(ProxyServiceTest
, ProxyFallbackToDirect
) {
1191 MockProxyConfigService
* config_service
=
1192 new MockProxyConfigService("http://foopy/proxy.pac");
1194 MockAsyncProxyResolver resolver
;
1195 MockAsyncProxyResolverFactory
* factory
=
1196 new MockAsyncProxyResolverFactory(false);
1198 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1200 GURL
url("http://www.google.com/");
1202 // Get the proxy information.
1204 TestCompletionCallback callback1
;
1205 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
1206 NULL
, NULL
, BoundNetLog());
1207 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1209 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1210 factory
->pending_requests()[0]->script_data()->url());
1211 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1213 ASSERT_EQ(1u, resolver
.pending_requests().size());
1214 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1216 // Set the result in proxy resolver.
1217 resolver
.pending_requests()[0]->results()->UsePacString(
1218 "PROXY foopy1:8080; PROXY foopy2:9090; DIRECT");
1219 resolver
.pending_requests()[0]->CompleteNow(OK
);
1221 // Get the first result.
1222 EXPECT_EQ(OK
, callback1
.WaitForResult());
1223 EXPECT_FALSE(info
.is_direct());
1224 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1226 // Fake an error on the proxy.
1227 TestCompletionCallback callback2
;
1228 rv
= service
.ReconsiderProxyAfterError(
1229 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1230 callback2
.callback(), NULL
, NULL
, BoundNetLog());
1233 // Now we get back the second proxy.
1234 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1236 // Fake an error on this proxy as well.
1237 TestCompletionCallback callback3
;
1238 rv
= service
.ReconsiderProxyAfterError(
1239 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1240 callback3
.callback(), NULL
, NULL
, BoundNetLog());
1243 // Finally, we get back DIRECT.
1244 EXPECT_TRUE(info
.is_direct());
1246 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1247 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1248 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1250 // Now we tell the proxy service that even DIRECT failed.
1251 TestCompletionCallback callback4
;
1252 rv
= service
.ReconsiderProxyAfterError(
1253 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1254 callback4
.callback(), NULL
, NULL
, BoundNetLog());
1255 // There was nothing left to try after DIRECT, so we are out of
1257 EXPECT_EQ(ERR_FAILED
, rv
);
1260 TEST_F(ProxyServiceTest
, ProxyFallback_NewSettings
) {
1261 // Test proxy failover when new settings are available.
1263 MockProxyConfigService
* config_service
=
1264 new MockProxyConfigService("http://foopy/proxy.pac");
1266 MockAsyncProxyResolver resolver
;
1267 MockAsyncProxyResolverFactory
* factory
=
1268 new MockAsyncProxyResolverFactory(false);
1270 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1272 GURL
url("http://www.google.com/");
1274 // Get the proxy information.
1276 TestCompletionCallback callback1
;
1277 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
1278 NULL
, NULL
, BoundNetLog());
1279 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1281 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1282 factory
->pending_requests()[0]->script_data()->url());
1283 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1285 ASSERT_EQ(1u, resolver
.pending_requests().size());
1286 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1288 // Set the result in proxy resolver.
1289 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1290 "foopy1:8080;foopy2:9090");
1291 resolver
.pending_requests()[0]->CompleteNow(OK
);
1293 // The first item is valid.
1294 EXPECT_EQ(OK
, callback1
.WaitForResult());
1295 EXPECT_FALSE(info
.is_direct());
1296 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1298 // Fake an error on the proxy, and also a new configuration on the proxy.
1299 config_service
->SetConfig(
1300 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy-new/proxy.pac")));
1302 TestCompletionCallback callback2
;
1303 rv
= service
.ReconsiderProxyAfterError(
1304 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1305 callback2
.callback(), NULL
, NULL
, BoundNetLog());
1306 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1308 EXPECT_EQ(GURL("http://foopy-new/proxy.pac"),
1309 factory
->pending_requests()[0]->script_data()->url());
1310 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1312 ASSERT_EQ(1u, resolver
.pending_requests().size());
1313 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1315 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1316 "foopy1:8080;foopy2:9090");
1317 resolver
.pending_requests()[0]->CompleteNow(OK
);
1319 // The first proxy is still there since the configuration changed.
1320 EXPECT_EQ(OK
, callback2
.WaitForResult());
1321 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1323 // We fake another error. It should now ignore the first one.
1324 TestCompletionCallback callback3
;
1325 rv
= service
.ReconsiderProxyAfterError(
1326 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1327 callback3
.callback(), NULL
, NULL
, BoundNetLog());
1329 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1331 // We simulate a new configuration.
1332 config_service
->SetConfig(
1333 ProxyConfig::CreateFromCustomPacURL(
1334 GURL("http://foopy-new2/proxy.pac")));
1336 // We fake another error. It should go back to the first proxy.
1337 TestCompletionCallback callback4
;
1338 rv
= service
.ReconsiderProxyAfterError(
1339 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1340 callback4
.callback(), NULL
, NULL
, BoundNetLog());
1341 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1343 EXPECT_EQ(GURL("http://foopy-new2/proxy.pac"),
1344 factory
->pending_requests()[0]->script_data()->url());
1345 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1347 ASSERT_EQ(1u, resolver
.pending_requests().size());
1348 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1350 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1351 "foopy1:8080;foopy2:9090");
1352 resolver
.pending_requests()[0]->CompleteNow(OK
);
1354 EXPECT_EQ(OK
, callback4
.WaitForResult());
1355 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1357 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1358 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1359 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1362 TEST_F(ProxyServiceTest
, ProxyFallback_BadConfig
) {
1363 // Test proxy failover when the configuration is bad.
1365 MockProxyConfigService
* config_service
=
1366 new MockProxyConfigService("http://foopy/proxy.pac");
1368 MockAsyncProxyResolver resolver
;
1369 MockAsyncProxyResolverFactory
* factory
=
1370 new MockAsyncProxyResolverFactory(false);
1372 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1374 GURL
url("http://www.google.com/");
1376 // Get the proxy information.
1378 TestCompletionCallback callback1
;
1379 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
1380 NULL
, NULL
, BoundNetLog());
1381 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1383 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1384 factory
->pending_requests()[0]->script_data()->url());
1385 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1386 ASSERT_EQ(1u, resolver
.pending_requests().size());
1387 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1389 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1390 "foopy1:8080;foopy2:9090");
1391 resolver
.pending_requests()[0]->CompleteNow(OK
);
1393 // The first item is valid.
1394 EXPECT_EQ(OK
, callback1
.WaitForResult());
1395 EXPECT_FALSE(info
.is_direct());
1396 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1398 // Fake a proxy error.
1399 TestCompletionCallback callback2
;
1400 rv
= service
.ReconsiderProxyAfterError(
1401 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1402 callback2
.callback(), NULL
, NULL
, BoundNetLog());
1405 // The first proxy is ignored, and the second one is selected.
1406 EXPECT_FALSE(info
.is_direct());
1407 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1409 // Fake a PAC failure.
1411 TestCompletionCallback callback3
;
1412 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info2
, callback3
.callback(),
1413 NULL
, NULL
, BoundNetLog());
1414 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1416 ASSERT_EQ(1u, resolver
.pending_requests().size());
1417 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1419 // This simulates a javascript runtime error in the PAC script.
1420 resolver
.pending_requests()[0]->CompleteNow(ERR_FAILED
);
1422 // Although the resolver failed, the ProxyService will implicitly fall-back
1423 // to a DIRECT connection.
1424 EXPECT_EQ(OK
, callback3
.WaitForResult());
1425 EXPECT_TRUE(info2
.is_direct());
1426 EXPECT_FALSE(info2
.is_empty());
1428 // The PAC script will work properly next time and successfully return a
1429 // proxy list. Since we have not marked the configuration as bad, it should
1430 // "just work" the next time we call it.
1432 TestCompletionCallback callback4
;
1433 rv
= service
.ReconsiderProxyAfterError(
1434 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info3
,
1435 callback4
.callback(), NULL
, NULL
, BoundNetLog());
1436 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1438 ASSERT_EQ(1u, resolver
.pending_requests().size());
1439 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1441 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1442 "foopy1:8080;foopy2:9090");
1443 resolver
.pending_requests()[0]->CompleteNow(OK
);
1445 // The first proxy is not there since the it was added to the bad proxies
1446 // list by the earlier ReconsiderProxyAfterError().
1447 EXPECT_EQ(OK
, callback4
.WaitForResult());
1448 EXPECT_FALSE(info3
.is_direct());
1449 EXPECT_EQ("foopy1:8080", info3
.proxy_server().ToURI());
1451 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1452 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1453 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1456 TEST_F(ProxyServiceTest
, ProxyFallback_BadConfigMandatory
) {
1457 // Test proxy failover when the configuration is bad.
1460 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
1462 config
.set_pac_mandatory(true);
1463 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
1465 MockAsyncProxyResolver resolver
;
1466 MockAsyncProxyResolverFactory
* factory
=
1467 new MockAsyncProxyResolverFactory(false);
1469 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1471 GURL
url("http://www.google.com/");
1473 // Get the proxy information.
1475 TestCompletionCallback callback1
;
1476 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback1
.callback(),
1477 NULL
, NULL
, BoundNetLog());
1478 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1480 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1481 factory
->pending_requests()[0]->script_data()->url());
1482 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1483 ASSERT_EQ(1u, resolver
.pending_requests().size());
1484 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1486 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1487 "foopy1:8080;foopy2:9090");
1488 resolver
.pending_requests()[0]->CompleteNow(OK
);
1490 // The first item is valid.
1491 EXPECT_EQ(OK
, callback1
.WaitForResult());
1492 EXPECT_FALSE(info
.is_direct());
1493 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1495 // Fake a proxy error.
1496 TestCompletionCallback callback2
;
1497 rv
= service
.ReconsiderProxyAfterError(
1498 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info
,
1499 callback2
.callback(), NULL
, NULL
, BoundNetLog());
1502 // The first proxy is ignored, and the second one is selected.
1503 EXPECT_FALSE(info
.is_direct());
1504 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1506 // Fake a PAC failure.
1508 TestCompletionCallback callback3
;
1509 rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info2
, callback3
.callback(),
1510 NULL
, NULL
, BoundNetLog());
1511 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1513 ASSERT_EQ(1u, resolver
.pending_requests().size());
1514 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1516 // This simulates a javascript runtime error in the PAC script.
1517 resolver
.pending_requests()[0]->CompleteNow(ERR_FAILED
);
1519 // Although the resolver failed, the ProxyService will NOT fall-back
1520 // to a DIRECT connection as it is configured as mandatory.
1521 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
1522 callback3
.WaitForResult());
1523 EXPECT_FALSE(info2
.is_direct());
1524 EXPECT_TRUE(info2
.is_empty());
1526 // The PAC script will work properly next time and successfully return a
1527 // proxy list. Since we have not marked the configuration as bad, it should
1528 // "just work" the next time we call it.
1530 TestCompletionCallback callback4
;
1531 rv
= service
.ReconsiderProxyAfterError(
1532 url
, LOAD_NORMAL
, ERR_PROXY_CONNECTION_FAILED
, &info3
,
1533 callback4
.callback(), NULL
, NULL
, BoundNetLog());
1534 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1536 ASSERT_EQ(1u, resolver
.pending_requests().size());
1537 EXPECT_EQ(url
, resolver
.pending_requests()[0]->url());
1539 resolver
.pending_requests()[0]->results()->UseNamedProxy(
1540 "foopy1:8080;foopy2:9090");
1541 resolver
.pending_requests()[0]->CompleteNow(OK
);
1543 // The first proxy is not there since the it was added to the bad proxies
1544 // list by the earlier ReconsiderProxyAfterError().
1545 EXPECT_EQ(OK
, callback4
.WaitForResult());
1546 EXPECT_FALSE(info3
.is_direct());
1547 EXPECT_EQ("foopy1:8080", info3
.proxy_server().ToURI());
1550 TEST_F(ProxyServiceTest
, ProxyBypassList
) {
1551 // Test that the proxy bypass rules are consulted.
1553 TestCompletionCallback callback
[2];
1556 config
.proxy_rules().ParseFromString("foopy1:8080;foopy2:9090");
1557 config
.set_auto_detect(false);
1558 config
.proxy_rules().bypass_rules
.ParseFromString("*.org");
1560 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1563 GURL
url1("http://www.webkit.org");
1564 GURL
url2("http://www.webkit.com");
1566 // Request for a .org domain should bypass proxy.
1567 rv
= service
.ResolveProxy(url1
, LOAD_NORMAL
, &info
[0], callback
[0].callback(),
1568 NULL
, NULL
, BoundNetLog());
1570 EXPECT_TRUE(info
[0].is_direct());
1572 // Request for a .com domain hits the proxy.
1573 rv
= service
.ResolveProxy(url2
, LOAD_NORMAL
, &info
[1], callback
[1].callback(),
1574 NULL
, NULL
, BoundNetLog());
1576 EXPECT_EQ("foopy1:8080", info
[1].proxy_server().ToURI());
1579 TEST_F(ProxyServiceTest
, MarkProxiesAsBadTests
) {
1581 config
.proxy_rules().ParseFromString(
1582 "http=foopy1:8080;http=foopy2:8080;http=foopy3.8080;http=foopy4:8080");
1583 config
.set_auto_detect(false);
1585 ProxyList proxy_list
;
1586 std::vector
<ProxyServer
> additional_bad_proxies
;
1587 for (const ProxyServer
& proxy_server
:
1588 config
.proxy_rules().proxies_for_http
.GetAll()) {
1589 proxy_list
.AddProxyServer(proxy_server
);
1590 if (proxy_server
== config
.proxy_rules().proxies_for_http
.Get())
1593 additional_bad_proxies
.push_back(proxy_server
);
1596 EXPECT_EQ(3u, additional_bad_proxies
.size());
1598 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1599 ProxyInfo proxy_info
;
1600 proxy_info
.UseProxyList(proxy_list
);
1601 const ProxyRetryInfoMap
& retry_info
= service
.proxy_retry_info();
1602 service
.MarkProxiesAsBadUntil(proxy_info
, base::TimeDelta::FromSeconds(1),
1603 additional_bad_proxies
, BoundNetLog());
1604 ASSERT_EQ(4u, retry_info
.size());
1605 for (const ProxyServer
& proxy_server
:
1606 config
.proxy_rules().proxies_for_http
.GetAll()) {
1607 ProxyRetryInfoMap::const_iterator i
=
1608 retry_info
.find(proxy_server
.host_port_pair().ToString());
1609 ASSERT_TRUE(i
!= retry_info
.end());
1613 TEST_F(ProxyServiceTest
, PerProtocolProxyTests
) {
1615 config
.proxy_rules().ParseFromString("http=foopy1:8080;https=foopy2:8080");
1616 config
.set_auto_detect(false);
1618 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1619 GURL
test_url("http://www.msn.com");
1621 TestCompletionCallback callback
;
1623 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1624 NULL
, NULL
, BoundNetLog());
1626 EXPECT_FALSE(info
.is_direct());
1627 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1630 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1631 GURL
test_url("ftp://ftp.google.com");
1633 TestCompletionCallback callback
;
1635 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1636 NULL
, NULL
, BoundNetLog());
1638 EXPECT_TRUE(info
.is_direct());
1639 EXPECT_EQ("direct://", info
.proxy_server().ToURI());
1642 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1643 GURL
test_url("https://webbranch.techcu.com");
1645 TestCompletionCallback callback
;
1647 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1648 NULL
, NULL
, BoundNetLog());
1650 EXPECT_FALSE(info
.is_direct());
1651 EXPECT_EQ("foopy2:8080", info
.proxy_server().ToURI());
1654 config
.proxy_rules().ParseFromString("foopy1:8080");
1655 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1656 GURL
test_url("http://www.microsoft.com");
1658 TestCompletionCallback callback
;
1660 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1661 NULL
, NULL
, BoundNetLog());
1663 EXPECT_FALSE(info
.is_direct());
1664 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1668 TEST_F(ProxyServiceTest
, ProxyConfigSourcePropagates
) {
1669 // Test that the proxy config source is set correctly when resolving proxies
1670 // using manual proxy rules. Namely, the config source should only be set if
1671 // any of the rules were applied.
1674 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1675 config
.proxy_rules().ParseFromString("https=foopy2:8080");
1676 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1677 GURL
test_url("http://www.google.com");
1679 TestCompletionCallback callback
;
1681 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1682 NULL
, NULL
, BoundNetLog());
1684 // Should be SOURCE_TEST, even if there are no HTTP proxies configured.
1685 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1689 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1690 config
.proxy_rules().ParseFromString("https=foopy2:8080");
1691 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1692 GURL
test_url("https://www.google.com");
1694 TestCompletionCallback callback
;
1696 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1697 NULL
, NULL
, BoundNetLog());
1699 // Used the HTTPS proxy. So source should be TEST.
1700 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1704 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1705 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1706 GURL
test_url("http://www.google.com");
1708 TestCompletionCallback callback
;
1710 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1711 NULL
, NULL
, BoundNetLog());
1713 // ProxyConfig is empty. Source should still be TEST.
1714 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1718 // If only HTTP and a SOCKS proxy are specified, check if ftp/https queries
1719 // fall back to the SOCKS proxy.
1720 TEST_F(ProxyServiceTest
, DefaultProxyFallbackToSOCKS
) {
1722 config
.proxy_rules().ParseFromString("http=foopy1:8080;socks=foopy2:1080");
1723 config
.set_auto_detect(false);
1724 EXPECT_EQ(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
1725 config
.proxy_rules().type
);
1728 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1729 GURL
test_url("http://www.msn.com");
1731 TestCompletionCallback callback
;
1733 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1734 NULL
, NULL
, BoundNetLog());
1736 EXPECT_FALSE(info
.is_direct());
1737 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1740 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1741 GURL
test_url("ftp://ftp.google.com");
1743 TestCompletionCallback callback
;
1745 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1746 NULL
, NULL
, BoundNetLog());
1748 EXPECT_FALSE(info
.is_direct());
1749 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1752 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1753 GURL
test_url("https://webbranch.techcu.com");
1755 TestCompletionCallback callback
;
1757 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1758 NULL
, NULL
, BoundNetLog());
1760 EXPECT_FALSE(info
.is_direct());
1761 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1764 ProxyService
service(new MockProxyConfigService(config
), nullptr, NULL
);
1765 GURL
test_url("unknown://www.microsoft.com");
1767 TestCompletionCallback callback
;
1769 service
.ResolveProxy(test_url
, LOAD_NORMAL
, &info
, callback
.callback(),
1770 NULL
, NULL
, BoundNetLog());
1772 EXPECT_FALSE(info
.is_direct());
1773 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1777 // Test cancellation of an in-progress request.
1778 TEST_F(ProxyServiceTest
, CancelInProgressRequest
) {
1779 MockProxyConfigService
* config_service
=
1780 new MockProxyConfigService("http://foopy/proxy.pac");
1782 MockAsyncProxyResolver resolver
;
1783 MockAsyncProxyResolverFactory
* factory
=
1784 new MockAsyncProxyResolverFactory(false);
1786 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1788 // Start 3 requests.
1791 TestCompletionCallback callback1
;
1793 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
1794 callback1
.callback(), NULL
, NULL
, BoundNetLog());
1795 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1797 // Successfully initialize the PAC script.
1798 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1799 factory
->pending_requests()[0]->script_data()->url());
1800 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1802 ASSERT_EQ(1u, resolver
.pending_requests().size());
1803 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
1806 TestCompletionCallback callback2
;
1807 ProxyService::PacRequest
* request2
;
1808 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
1809 callback2
.callback(), &request2
, NULL
,
1811 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1812 ASSERT_EQ(2u, resolver
.pending_requests().size());
1813 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[1]->url());
1816 TestCompletionCallback callback3
;
1817 rv
= service
.ResolveProxy(GURL("http://request3"), LOAD_NORMAL
, &info3
,
1818 callback3
.callback(), NULL
, NULL
, BoundNetLog());
1819 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1820 ASSERT_EQ(3u, resolver
.pending_requests().size());
1821 EXPECT_EQ(GURL("http://request3"), resolver
.pending_requests()[2]->url());
1823 // Cancel the second request
1824 service
.CancelPacRequest(request2
);
1826 ASSERT_EQ(2u, resolver
.pending_requests().size());
1827 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
1828 EXPECT_EQ(GURL("http://request3"), resolver
.pending_requests()[1]->url());
1830 // Complete the two un-cancelled requests.
1831 // We complete the last one first, just to mix it up a bit.
1832 resolver
.pending_requests()[1]->results()->UseNamedProxy("request3:80");
1833 resolver
.pending_requests()[1]->CompleteNow(OK
);
1835 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
1836 resolver
.pending_requests()[0]->CompleteNow(OK
);
1838 // Complete and verify that requests ran as expected.
1839 EXPECT_EQ(OK
, callback1
.WaitForResult());
1840 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
1842 EXPECT_FALSE(callback2
.have_result()); // Cancelled.
1843 ASSERT_EQ(1u, resolver
.cancelled_requests().size());
1844 EXPECT_EQ(GURL("http://request2"), resolver
.cancelled_requests()[0]->url());
1846 EXPECT_EQ(OK
, callback3
.WaitForResult());
1847 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
1850 // Test the initial PAC download for resolver that expects bytes.
1851 TEST_F(ProxyServiceTest
, InitialPACScriptDownload
) {
1852 MockProxyConfigService
* config_service
=
1853 new MockProxyConfigService("http://foopy/proxy.pac");
1855 MockAsyncProxyResolver resolver
;
1856 MockAsyncProxyResolverFactory
* factory
=
1857 new MockAsyncProxyResolverFactory(true);
1859 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1861 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1862 service
.SetProxyScriptFetchers(fetcher
,
1863 new DoNothingDhcpProxyScriptFetcher());
1865 // Start 3 requests.
1868 TestCompletionCallback callback1
;
1869 ProxyService::PacRequest
* request1
;
1870 int rv
= service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
1871 callback1
.callback(), &request1
, NULL
,
1873 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1875 // The first request should have triggered download of PAC script.
1876 EXPECT_TRUE(fetcher
->has_pending_request());
1877 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1880 TestCompletionCallback callback2
;
1881 ProxyService::PacRequest
* request2
;
1882 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
1883 callback2
.callback(), &request2
, NULL
,
1885 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1888 TestCompletionCallback callback3
;
1889 ProxyService::PacRequest
* request3
;
1890 rv
= service
.ResolveProxy(GURL("http://request3"), LOAD_NORMAL
, &info3
,
1891 callback3
.callback(), &request3
, NULL
,
1893 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1895 // Nothing has been sent to the factory yet.
1896 EXPECT_TRUE(factory
->pending_requests().empty());
1898 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1899 service
.GetLoadState(request1
));
1900 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1901 service
.GetLoadState(request2
));
1902 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1903 service
.GetLoadState(request3
));
1905 // At this point the ProxyService should be waiting for the
1906 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1907 // PAC script download completion.
1908 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
1910 // Now that the PAC script is downloaded, it will have been sent to the proxy
1912 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
1913 factory
->pending_requests()[0]->script_data()->utf16());
1914 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
1916 ASSERT_EQ(3u, resolver
.pending_requests().size());
1917 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
1918 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[1]->url());
1919 EXPECT_EQ(GURL("http://request3"), resolver
.pending_requests()[2]->url());
1921 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request1
));
1922 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request2
));
1923 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request3
));
1925 // Complete all the requests (in some order).
1926 // Note that as we complete requests, they shift up in |pending_requests()|.
1928 resolver
.pending_requests()[2]->results()->UseNamedProxy("request3:80");
1929 resolver
.pending_requests()[2]->CompleteNow(OK
);
1931 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
1932 resolver
.pending_requests()[0]->CompleteNow(OK
);
1934 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
1935 resolver
.pending_requests()[0]->CompleteNow(OK
);
1937 // Complete and verify that requests ran as expected.
1938 EXPECT_EQ(OK
, callback1
.WaitForResult());
1939 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
1940 EXPECT_FALSE(info1
.proxy_resolve_start_time().is_null());
1941 EXPECT_FALSE(info1
.proxy_resolve_end_time().is_null());
1942 EXPECT_LE(info1
.proxy_resolve_start_time(), info1
.proxy_resolve_end_time());
1944 EXPECT_EQ(OK
, callback2
.WaitForResult());
1945 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
1946 EXPECT_FALSE(info2
.proxy_resolve_start_time().is_null());
1947 EXPECT_FALSE(info2
.proxy_resolve_end_time().is_null());
1948 EXPECT_LE(info2
.proxy_resolve_start_time(), info2
.proxy_resolve_end_time());
1950 EXPECT_EQ(OK
, callback3
.WaitForResult());
1951 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
1952 EXPECT_FALSE(info3
.proxy_resolve_start_time().is_null());
1953 EXPECT_FALSE(info3
.proxy_resolve_end_time().is_null());
1954 EXPECT_LE(info3
.proxy_resolve_start_time(), info3
.proxy_resolve_end_time());
1957 // Test changing the ProxyScriptFetcher while PAC download is in progress.
1958 TEST_F(ProxyServiceTest
, ChangeScriptFetcherWhilePACDownloadInProgress
) {
1959 MockProxyConfigService
* config_service
=
1960 new MockProxyConfigService("http://foopy/proxy.pac");
1962 MockAsyncProxyResolver resolver
;
1963 MockAsyncProxyResolverFactory
* factory
=
1964 new MockAsyncProxyResolverFactory(true);
1966 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
1968 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1969 service
.SetProxyScriptFetchers(fetcher
,
1970 new DoNothingDhcpProxyScriptFetcher());
1972 // Start 2 requests.
1975 TestCompletionCallback callback1
;
1977 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
1978 callback1
.callback(), NULL
, NULL
, BoundNetLog());
1979 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1981 // The first request should have triggered download of PAC script.
1982 EXPECT_TRUE(fetcher
->has_pending_request());
1983 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1986 TestCompletionCallback callback2
;
1987 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
1988 callback2
.callback(), NULL
, NULL
, BoundNetLog());
1989 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1991 // At this point the ProxyService should be waiting for the
1992 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1993 // PAC script download completion.
1995 // We now change out the ProxyService's script fetcher. We should restart
1996 // the initialization with the new fetcher.
1998 fetcher
= new MockProxyScriptFetcher
;
1999 service
.SetProxyScriptFetchers(fetcher
,
2000 new DoNothingDhcpProxyScriptFetcher());
2002 // Nothing has been sent to the factory yet.
2003 EXPECT_TRUE(factory
->pending_requests().empty());
2005 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2007 // Now that the PAC script is downloaded, it will have been sent to the proxy
2009 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2010 factory
->pending_requests()[0]->script_data()->utf16());
2011 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2013 ASSERT_EQ(2u, resolver
.pending_requests().size());
2014 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
2015 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[1]->url());
2018 // Test cancellation of a request, while the PAC script is being fetched.
2019 TEST_F(ProxyServiceTest
, CancelWhilePACFetching
) {
2020 MockProxyConfigService
* config_service
=
2021 new MockProxyConfigService("http://foopy/proxy.pac");
2023 MockAsyncProxyResolver resolver
;
2024 MockAsyncProxyResolverFactory
* factory
=
2025 new MockAsyncProxyResolverFactory(true);
2027 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2029 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2030 service
.SetProxyScriptFetchers(fetcher
,
2031 new DoNothingDhcpProxyScriptFetcher());
2033 // Start 3 requests.
2035 TestCompletionCallback callback1
;
2036 ProxyService::PacRequest
* request1
;
2037 BoundTestNetLog log1
;
2039 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
2040 callback1
.callback(), &request1
, NULL
, log1
.bound());
2041 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2043 // The first request should have triggered download of PAC script.
2044 EXPECT_TRUE(fetcher
->has_pending_request());
2045 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2048 TestCompletionCallback callback2
;
2049 ProxyService::PacRequest
* request2
;
2050 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
2051 callback2
.callback(), &request2
, NULL
,
2053 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2056 TestCompletionCallback callback3
;
2057 rv
= service
.ResolveProxy(GURL("http://request3"), LOAD_NORMAL
, &info3
,
2058 callback3
.callback(), NULL
, NULL
, BoundNetLog());
2059 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2061 // Nothing has been sent to the factory yet.
2062 EXPECT_TRUE(factory
->pending_requests().empty());
2064 // Cancel the first 2 requests.
2065 service
.CancelPacRequest(request1
);
2066 service
.CancelPacRequest(request2
);
2068 // At this point the ProxyService should be waiting for the
2069 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2070 // PAC script download completion.
2071 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2073 // Now that the PAC script is downloaded, it will have been sent to the
2075 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2076 factory
->pending_requests()[0]->script_data()->utf16());
2077 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2079 ASSERT_EQ(1u, resolver
.pending_requests().size());
2080 EXPECT_EQ(GURL("http://request3"), resolver
.pending_requests()[0]->url());
2082 // Complete all the requests.
2083 resolver
.pending_requests()[0]->results()->UseNamedProxy("request3:80");
2084 resolver
.pending_requests()[0]->CompleteNow(OK
);
2086 EXPECT_EQ(OK
, callback3
.WaitForResult());
2087 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
2089 EXPECT_TRUE(resolver
.cancelled_requests().empty());
2091 EXPECT_FALSE(callback1
.have_result()); // Cancelled.
2092 EXPECT_FALSE(callback2
.have_result()); // Cancelled.
2094 TestNetLogEntry::List entries1
;
2095 log1
.GetEntries(&entries1
);
2097 // Check the NetLog for request 1 (which was cancelled) got filled properly.
2098 EXPECT_EQ(4u, entries1
.size());
2099 EXPECT_TRUE(LogContainsBeginEvent(
2100 entries1
, 0, NetLog::TYPE_PROXY_SERVICE
));
2101 EXPECT_TRUE(LogContainsBeginEvent(
2102 entries1
, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
2103 // Note that TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC is never completed before
2104 // the cancellation occured.
2105 EXPECT_TRUE(LogContainsEvent(
2106 entries1
, 2, NetLog::TYPE_CANCELLED
, NetLog::PHASE_NONE
));
2107 EXPECT_TRUE(LogContainsEndEvent(
2108 entries1
, 3, NetLog::TYPE_PROXY_SERVICE
));
2111 // Test that if auto-detect fails, we fall-back to the custom pac.
2112 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomPac
) {
2114 config
.set_auto_detect(true);
2115 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2116 config
.proxy_rules().ParseFromString("http=foopy:80"); // Won't be used.
2118 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2119 MockAsyncProxyResolver resolver
;
2120 MockAsyncProxyResolverFactory
* factory
=
2121 new MockAsyncProxyResolverFactory(true);
2122 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2124 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2125 service
.SetProxyScriptFetchers(fetcher
,
2126 new DoNothingDhcpProxyScriptFetcher());
2128 // Start 2 requests.
2131 TestCompletionCallback callback1
;
2133 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
2134 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2135 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2138 TestCompletionCallback callback2
;
2139 ProxyService::PacRequest
* request2
;
2140 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
2141 callback2
.callback(), &request2
, NULL
,
2143 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2145 // Check that nothing has been sent to the proxy resolver factory yet.
2146 ASSERT_EQ(0u, factory
->pending_requests().size());
2148 // It should be trying to auto-detect first -- FAIL the autodetect during
2149 // the script download.
2150 EXPECT_TRUE(fetcher
->has_pending_request());
2151 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2152 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2154 // Next it should be trying the custom PAC url.
2155 EXPECT_TRUE(fetcher
->has_pending_request());
2156 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2157 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2159 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2160 factory
->pending_requests()[0]->script_data()->utf16());
2161 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2163 // Now finally, the pending requests should have been sent to the resolver
2164 // (which was initialized with custom PAC script).
2166 ASSERT_EQ(2u, resolver
.pending_requests().size());
2167 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
2168 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[1]->url());
2170 // Complete the pending requests.
2171 resolver
.pending_requests()[1]->results()->UseNamedProxy("request2:80");
2172 resolver
.pending_requests()[1]->CompleteNow(OK
);
2173 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2174 resolver
.pending_requests()[0]->CompleteNow(OK
);
2176 // Verify that requests ran as expected.
2177 EXPECT_EQ(OK
, callback1
.WaitForResult());
2178 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2179 EXPECT_FALSE(info1
.proxy_resolve_start_time().is_null());
2180 EXPECT_FALSE(info1
.proxy_resolve_end_time().is_null());
2181 EXPECT_LE(info1
.proxy_resolve_start_time(), info1
.proxy_resolve_end_time());
2183 EXPECT_EQ(OK
, callback2
.WaitForResult());
2184 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2185 EXPECT_FALSE(info2
.proxy_resolve_start_time().is_null());
2186 EXPECT_FALSE(info2
.proxy_resolve_end_time().is_null());
2187 EXPECT_LE(info2
.proxy_resolve_start_time(), info2
.proxy_resolve_end_time());
2190 // This is the same test as FallbackFromAutodetectToCustomPac, except
2191 // the auto-detect script fails parsing rather than downloading.
2192 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomPac2
) {
2194 config
.set_auto_detect(true);
2195 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2196 config
.proxy_rules().ParseFromString("http=foopy:80"); // Won't be used.
2198 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2199 MockAsyncProxyResolver resolver
;
2200 MockAsyncProxyResolverFactory
* factory
=
2201 new MockAsyncProxyResolverFactory(true);
2202 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2204 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2205 service
.SetProxyScriptFetchers(fetcher
,
2206 new DoNothingDhcpProxyScriptFetcher());
2208 // Start 2 requests.
2211 TestCompletionCallback callback1
;
2213 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
2214 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2215 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2218 TestCompletionCallback callback2
;
2219 ProxyService::PacRequest
* request2
;
2220 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
2221 callback2
.callback(), &request2
, NULL
,
2223 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2225 // Check that nothing has been sent to the proxy resolver factory yet.
2226 ASSERT_EQ(0u, factory
->pending_requests().size());
2228 // It should be trying to auto-detect first -- succeed the download.
2229 EXPECT_TRUE(fetcher
->has_pending_request());
2230 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2231 fetcher
->NotifyFetchCompletion(OK
, "invalid-script-contents");
2233 // The script contents passed failed basic verification step (since didn't
2234 // contain token FindProxyForURL), so it was never passed to the resolver.
2236 // Next it should be trying the custom PAC url.
2237 EXPECT_TRUE(fetcher
->has_pending_request());
2238 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2239 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2241 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2242 factory
->pending_requests()[0]->script_data()->utf16());
2243 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2245 // Now finally, the pending requests should have been sent to the resolver
2246 // (which was initialized with custom PAC script).
2248 ASSERT_EQ(2u, resolver
.pending_requests().size());
2249 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
2250 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[1]->url());
2252 // Complete the pending requests.
2253 resolver
.pending_requests()[1]->results()->UseNamedProxy("request2:80");
2254 resolver
.pending_requests()[1]->CompleteNow(OK
);
2255 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2256 resolver
.pending_requests()[0]->CompleteNow(OK
);
2258 // Verify that requests ran as expected.
2259 EXPECT_EQ(OK
, callback1
.WaitForResult());
2260 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2262 EXPECT_EQ(OK
, callback2
.WaitForResult());
2263 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2266 // Test that if all of auto-detect, a custom PAC script, and manual settings
2267 // are given, then we will try them in that order.
2268 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomToManual
) {
2270 config
.set_auto_detect(true);
2271 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2272 config
.proxy_rules().ParseFromString("http=foopy:80");
2274 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2275 MockAsyncProxyResolverFactory
* factory
=
2276 new MockAsyncProxyResolverFactory(true);
2277 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2279 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2280 service
.SetProxyScriptFetchers(fetcher
,
2281 new DoNothingDhcpProxyScriptFetcher());
2283 // Start 2 requests.
2286 TestCompletionCallback callback1
;
2288 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
2289 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2290 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2293 TestCompletionCallback callback2
;
2294 ProxyService::PacRequest
* request2
;
2295 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
2296 callback2
.callback(), &request2
, NULL
,
2298 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2300 // Check that nothing has been sent to the proxy resolver factory yet.
2301 ASSERT_EQ(0u, factory
->pending_requests().size());
2303 // It should be trying to auto-detect first -- fail the download.
2304 EXPECT_TRUE(fetcher
->has_pending_request());
2305 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2306 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2308 // Next it should be trying the custom PAC url -- fail the download.
2309 EXPECT_TRUE(fetcher
->has_pending_request());
2310 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2311 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2313 // Since we never managed to initialize a resolver, nothing should have been
2315 ASSERT_EQ(0u, factory
->pending_requests().size());
2317 // Verify that requests ran as expected -- they should have fallen back to
2318 // the manual proxy configuration for HTTP urls.
2319 EXPECT_EQ(OK
, callback1
.WaitForResult());
2320 EXPECT_EQ("foopy:80", info1
.proxy_server().ToURI());
2322 EXPECT_EQ(OK
, callback2
.WaitForResult());
2323 EXPECT_EQ("foopy:80", info2
.proxy_server().ToURI());
2326 // Test that the bypass rules are NOT applied when using autodetect.
2327 TEST_F(ProxyServiceTest
, BypassDoesntApplyToPac
) {
2329 config
.set_auto_detect(true);
2330 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2331 config
.proxy_rules().ParseFromString("http=foopy:80"); // Not used.
2332 config
.proxy_rules().bypass_rules
.ParseFromString("www.google.com");
2334 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2335 MockAsyncProxyResolver resolver
;
2336 MockAsyncProxyResolverFactory
* factory
=
2337 new MockAsyncProxyResolverFactory(true);
2338 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2340 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2341 service
.SetProxyScriptFetchers(fetcher
,
2342 new DoNothingDhcpProxyScriptFetcher());
2344 // Start 1 requests.
2347 TestCompletionCallback callback1
;
2349 service
.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL
, &info1
,
2350 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2351 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2353 // Check that nothing has been sent to the proxy resolver factory yet.
2354 ASSERT_EQ(0u, factory
->pending_requests().size());
2356 // It should be trying to auto-detect first -- succeed the download.
2357 EXPECT_TRUE(fetcher
->has_pending_request());
2358 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2359 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2361 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2362 factory
->pending_requests()[0]->script_data()->utf16());
2363 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2365 ASSERT_EQ(1u, resolver
.pending_requests().size());
2366 EXPECT_EQ(GURL("http://www.google.com"),
2367 resolver
.pending_requests()[0]->url());
2369 // Complete the pending request.
2370 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2371 resolver
.pending_requests()[0]->CompleteNow(OK
);
2373 // Verify that request ran as expected.
2374 EXPECT_EQ(OK
, callback1
.WaitForResult());
2375 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2377 // Start another request, it should pickup the bypass item.
2379 TestCompletionCallback callback2
;
2380 rv
= service
.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL
, &info2
,
2381 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2382 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2384 ASSERT_EQ(1u, resolver
.pending_requests().size());
2385 EXPECT_EQ(GURL("http://www.google.com"),
2386 resolver
.pending_requests()[0]->url());
2388 // Complete the pending request.
2389 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2390 resolver
.pending_requests()[0]->CompleteNow(OK
);
2392 EXPECT_EQ(OK
, callback2
.WaitForResult());
2393 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2396 // Delete the ProxyService while InitProxyResolver has an outstanding
2397 // request to the script fetcher. When run under valgrind, should not
2398 // have any memory errors (used to be that the ProxyScriptFetcher was
2399 // being deleted prior to the InitProxyResolver).
2400 TEST_F(ProxyServiceTest
, DeleteWhileInitProxyResolverHasOutstandingFetch
) {
2401 ProxyConfig config
=
2402 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
2404 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2405 MockAsyncProxyResolverFactory
* factory
=
2406 new MockAsyncProxyResolverFactory(true);
2407 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2409 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2410 service
.SetProxyScriptFetchers(fetcher
,
2411 new DoNothingDhcpProxyScriptFetcher());
2416 TestCompletionCallback callback1
;
2418 service
.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL
, &info1
,
2419 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2420 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2422 // Check that nothing has been sent to the proxy resolver factory yet.
2423 ASSERT_EQ(0u, factory
->pending_requests().size());
2425 // InitProxyResolver should have issued a request to the ProxyScriptFetcher
2426 // and be waiting on that to complete.
2427 EXPECT_TRUE(fetcher
->has_pending_request());
2428 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2431 // Delete the ProxyService while InitProxyResolver has an outstanding
2432 // request to the proxy resolver. When run under valgrind, should not
2433 // have any memory errors (used to be that the ProxyResolver was
2434 // being deleted prior to the InitProxyResolver).
2435 TEST_F(ProxyServiceTest
, DeleteWhileInitProxyResolverHasOutstandingSet
) {
2436 MockProxyConfigService
* config_service
=
2437 new MockProxyConfigService("http://foopy/proxy.pac");
2439 MockAsyncProxyResolverFactory
* factory
=
2440 new MockAsyncProxyResolverFactory(false);
2442 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2444 GURL
url("http://www.google.com/");
2447 TestCompletionCallback callback
;
2448 int rv
= service
.ResolveProxy(url
, LOAD_NORMAL
, &info
, callback
.callback(),
2449 NULL
, NULL
, BoundNetLog());
2450 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2452 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
2453 factory
->pending_requests()[0]->script_data()->url());
2456 TEST_F(ProxyServiceTest
, ResetProxyConfigService
) {
2457 ProxyConfig config1
;
2458 config1
.proxy_rules().ParseFromString("foopy1:8080");
2459 config1
.set_auto_detect(false);
2460 ProxyService
service(new MockProxyConfigService(config1
), nullptr, NULL
);
2463 TestCompletionCallback callback1
;
2465 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info
,
2466 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2468 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
2470 ProxyConfig config2
;
2471 config2
.proxy_rules().ParseFromString("foopy2:8080");
2472 config2
.set_auto_detect(false);
2473 service
.ResetConfigService(new MockProxyConfigService(config2
));
2474 TestCompletionCallback callback2
;
2475 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info
,
2476 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2478 EXPECT_EQ("foopy2:8080", info
.proxy_server().ToURI());
2481 // Test that when going from a configuration that required PAC to one
2482 // that does NOT, we unset the variable |should_use_proxy_resolver_|.
2483 TEST_F(ProxyServiceTest
, UpdateConfigFromPACToDirect
) {
2484 ProxyConfig config
= ProxyConfig::CreateAutoDetect();
2486 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2487 MockAsyncProxyResolver resolver
;
2488 MockAsyncProxyResolverFactory
* factory
=
2489 new MockAsyncProxyResolverFactory(false);
2490 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2495 TestCompletionCallback callback1
;
2497 service
.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL
, &info1
,
2498 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2499 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2501 // Successfully set the autodetect script.
2502 EXPECT_EQ(ProxyResolverScriptData::TYPE_AUTO_DETECT
,
2503 factory
->pending_requests()[0]->script_data()->type());
2504 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2506 // Complete the pending request.
2507 ASSERT_EQ(1u, resolver
.pending_requests().size());
2508 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2509 resolver
.pending_requests()[0]->CompleteNow(OK
);
2511 // Verify that request ran as expected.
2512 EXPECT_EQ(OK
, callback1
.WaitForResult());
2513 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2515 // Force the ProxyService to pull down a new proxy configuration.
2516 // (Even though the configuration isn't old/bad).
2518 // This new configuration no longer has auto_detect set, so
2519 // requests should complete synchronously now as direct-connect.
2520 config_service
->SetConfig(ProxyConfig::CreateDirect());
2522 // Start another request -- the effective configuration has changed.
2524 TestCompletionCallback callback2
;
2525 rv
= service
.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL
, &info2
,
2526 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2529 EXPECT_TRUE(info2
.is_direct());
2532 TEST_F(ProxyServiceTest
, NetworkChangeTriggersPacRefetch
) {
2533 MockProxyConfigService
* config_service
=
2534 new MockProxyConfigService("http://foopy/proxy.pac");
2536 MockAsyncProxyResolver resolver
;
2537 MockAsyncProxyResolverFactory
* factory
=
2538 new MockAsyncProxyResolverFactory(true);
2542 ProxyService
service(config_service
, make_scoped_ptr(factory
), &log
);
2544 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2545 service
.SetProxyScriptFetchers(fetcher
,
2546 new DoNothingDhcpProxyScriptFetcher());
2548 // Disable the "wait after IP address changes" hack, so this unit-test can
2549 // complete quickly.
2550 service
.set_stall_proxy_auto_config_delay(base::TimeDelta());
2555 TestCompletionCallback callback1
;
2557 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
2558 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2559 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2561 // The first request should have triggered initial download of PAC script.
2562 EXPECT_TRUE(fetcher
->has_pending_request());
2563 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2565 // Nothing has been sent to the factory yet.
2566 EXPECT_TRUE(factory
->pending_requests().empty());
2568 // At this point the ProxyService should be waiting for the
2569 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2570 // PAC script download completion.
2571 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2573 // Now that the PAC script is downloaded, the request will have been sent to
2574 // the proxy resolver.
2575 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2576 factory
->pending_requests()[0]->script_data()->utf16());
2577 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2579 ASSERT_EQ(1u, resolver
.pending_requests().size());
2580 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
2582 // Complete the pending request.
2583 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2584 resolver
.pending_requests()[0]->CompleteNow(OK
);
2586 // Wait for completion callback, and verify that the request ran as expected.
2587 EXPECT_EQ(OK
, callback1
.WaitForResult());
2588 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2590 // Now simluate a change in the network. The ProxyConfigService is still
2591 // going to return the same PAC URL as before, but this URL needs to be
2592 // refetched on the new network.
2593 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
2594 base::MessageLoop::current()->RunUntilIdle(); // Notification happens async.
2596 // Start a second request.
2598 TestCompletionCallback callback2
;
2599 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
2600 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2601 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2603 // This second request should have triggered the re-download of the PAC
2604 // script (since we marked the network as having changed).
2605 EXPECT_TRUE(fetcher
->has_pending_request());
2606 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2608 // Nothing has been sent to the factory yet.
2609 EXPECT_TRUE(factory
->pending_requests().empty());
2611 // Simulate the PAC script fetch as having completed (this time with
2613 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript2
);
2615 // Now that the PAC script is downloaded, the second request will have been
2616 // sent to the proxy resolver.
2617 EXPECT_EQ(ASCIIToUTF16(kValidPacScript2
),
2618 factory
->pending_requests()[0]->script_data()->utf16());
2619 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2621 ASSERT_EQ(1u, resolver
.pending_requests().size());
2622 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[0]->url());
2624 // Complete the pending second request.
2625 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2626 resolver
.pending_requests()[0]->CompleteNow(OK
);
2628 // Wait for completion callback, and verify that the request ran as expected.
2629 EXPECT_EQ(OK
, callback2
.WaitForResult());
2630 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2632 // Check that the expected events were output to the log stream. In particular
2633 // PROXY_CONFIG_CHANGED should have only been emitted once (for the initial
2634 // setup), and NOT a second time when the IP address changed.
2635 TestNetLogEntry::List entries
;
2636 log
.GetEntries(&entries
);
2638 EXPECT_TRUE(LogContainsEntryWithType(entries
, 0,
2639 NetLog::TYPE_PROXY_CONFIG_CHANGED
));
2640 ASSERT_EQ(9u, entries
.size());
2641 for (size_t i
= 1; i
< entries
.size(); ++i
)
2642 EXPECT_NE(NetLog::TYPE_PROXY_CONFIG_CHANGED
, entries
[i
].type
);
2645 // This test verifies that the PAC script specified by the settings is
2646 // periodically polled for changes. Specifically, if the initial fetch fails due
2647 // to a network error, we will eventually re-configure the service to use the
2648 // script once it becomes available.
2649 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterFailure
) {
2650 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2652 ImmediatePollPolicy poll_policy
;
2653 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2655 MockProxyConfigService
* config_service
=
2656 new MockProxyConfigService("http://foopy/proxy.pac");
2658 MockAsyncProxyResolver resolver
;
2659 MockAsyncProxyResolverFactory
* factory
=
2660 new MockAsyncProxyResolverFactory(true);
2662 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2664 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2665 service
.SetProxyScriptFetchers(fetcher
,
2666 new DoNothingDhcpProxyScriptFetcher());
2671 TestCompletionCallback callback1
;
2673 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
2674 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2675 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2677 // The first request should have triggered initial download of PAC script.
2678 EXPECT_TRUE(fetcher
->has_pending_request());
2679 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2681 // Nothing has been sent to the factory yet.
2682 EXPECT_TRUE(factory
->pending_requests().empty());
2684 // At this point the ProxyService should be waiting for the
2685 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2686 // PAC script download completion.
2688 // We simulate a failed download attempt, the proxy service should now
2689 // fall-back to DIRECT connections.
2690 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2692 ASSERT_TRUE(factory
->pending_requests().empty());
2694 // Wait for completion callback, and verify it used DIRECT.
2695 EXPECT_EQ(OK
, callback1
.WaitForResult());
2696 EXPECT_TRUE(info1
.is_direct());
2698 // At this point we have initialized the proxy service using a PAC script,
2699 // however it failed and fell-back to DIRECT.
2701 // A background task to periodically re-check the PAC script for validity will
2702 // have been started. We will now wait for the next download attempt to start.
2704 // Note that we shouldn't have to wait long here, since our test enables a
2705 // special unit-test mode.
2706 fetcher
->WaitUntilFetch();
2708 ASSERT_TRUE(factory
->pending_requests().empty());
2710 // Make sure that our background checker is trying to download the expected
2711 // PAC script (same one as before). This time we will simulate a successful
2712 // download of the script.
2713 EXPECT_TRUE(fetcher
->has_pending_request());
2714 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2715 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2717 base::MessageLoop::current()->RunUntilIdle();
2719 // Now that the PAC script is downloaded, it should be used to initialize the
2720 // ProxyResolver. Simulate a successful parse.
2721 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2722 factory
->pending_requests()[0]->script_data()->utf16());
2723 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2725 // At this point the ProxyService should have re-configured itself to use the
2726 // PAC script (thereby recovering from the initial fetch failure). We will
2727 // verify that the next Resolve request uses the resolver rather than
2730 // Start a second request.
2732 TestCompletionCallback callback2
;
2733 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
2734 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2735 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2737 // Check that it was sent to the resolver.
2738 ASSERT_EQ(1u, resolver
.pending_requests().size());
2739 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[0]->url());
2741 // Complete the pending second request.
2742 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2743 resolver
.pending_requests()[0]->CompleteNow(OK
);
2745 // Wait for completion callback, and verify that the request ran as expected.
2746 EXPECT_EQ(OK
, callback2
.WaitForResult());
2747 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2750 // This test verifies that the PAC script specified by the settings is
2751 // periodically polled for changes. Specifically, if the initial fetch succeeds,
2752 // however at a later time its *contents* change, we will eventually
2753 // re-configure the service to use the new script.
2754 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterContentChange
) {
2755 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2757 ImmediatePollPolicy poll_policy
;
2758 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2760 MockProxyConfigService
* config_service
=
2761 new MockProxyConfigService("http://foopy/proxy.pac");
2763 MockAsyncProxyResolver resolver
;
2764 MockAsyncProxyResolverFactory
* factory
=
2765 new MockAsyncProxyResolverFactory(true);
2767 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2769 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2770 service
.SetProxyScriptFetchers(fetcher
,
2771 new DoNothingDhcpProxyScriptFetcher());
2776 TestCompletionCallback callback1
;
2778 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
2779 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2780 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2782 // The first request should have triggered initial download of PAC script.
2783 EXPECT_TRUE(fetcher
->has_pending_request());
2784 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2786 // Nothing has been sent to the factory yet.
2787 EXPECT_TRUE(factory
->pending_requests().empty());
2789 // At this point the ProxyService should be waiting for the
2790 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2791 // PAC script download completion.
2792 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2794 // Now that the PAC script is downloaded, the request will have been sent to
2795 // the proxy resolver.
2796 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2797 factory
->pending_requests()[0]->script_data()->utf16());
2798 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2800 ASSERT_EQ(1u, resolver
.pending_requests().size());
2801 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
2803 // Complete the pending request.
2804 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2805 resolver
.pending_requests()[0]->CompleteNow(OK
);
2807 // Wait for completion callback, and verify that the request ran as expected.
2808 EXPECT_EQ(OK
, callback1
.WaitForResult());
2809 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2811 // At this point we have initialized the proxy service using a PAC script.
2813 // A background task to periodically re-check the PAC script for validity will
2814 // have been started. We will now wait for the next download attempt to start.
2816 // Note that we shouldn't have to wait long here, since our test enables a
2817 // special unit-test mode.
2818 fetcher
->WaitUntilFetch();
2820 ASSERT_TRUE(factory
->pending_requests().empty());
2821 ASSERT_TRUE(resolver
.pending_requests().empty());
2823 // Make sure that our background checker is trying to download the expected
2824 // PAC script (same one as before). This time we will simulate a successful
2825 // download of a DIFFERENT script.
2826 EXPECT_TRUE(fetcher
->has_pending_request());
2827 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2828 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript2
);
2830 base::MessageLoop::current()->RunUntilIdle();
2832 // Now that the PAC script is downloaded, it should be used to initialize the
2833 // ProxyResolver. Simulate a successful parse.
2834 EXPECT_EQ(ASCIIToUTF16(kValidPacScript2
),
2835 factory
->pending_requests()[0]->script_data()->utf16());
2836 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2838 // At this point the ProxyService should have re-configured itself to use the
2841 // Start a second request.
2843 TestCompletionCallback callback2
;
2844 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
2845 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2846 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2848 // Check that it was sent to the resolver.
2849 ASSERT_EQ(1u, resolver
.pending_requests().size());
2850 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[0]->url());
2852 // Complete the pending second request.
2853 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2854 resolver
.pending_requests()[0]->CompleteNow(OK
);
2856 // Wait for completion callback, and verify that the request ran as expected.
2857 EXPECT_EQ(OK
, callback2
.WaitForResult());
2858 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2861 // This test verifies that the PAC script specified by the settings is
2862 // periodically polled for changes. Specifically, if the initial fetch succeeds
2863 // and so does the next poll, however the contents of the downloaded script
2864 // have NOT changed, then we do not bother to re-initialize the proxy resolver.
2865 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterContentUnchanged
) {
2866 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2868 ImmediatePollPolicy poll_policy
;
2869 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2871 MockProxyConfigService
* config_service
=
2872 new MockProxyConfigService("http://foopy/proxy.pac");
2874 MockAsyncProxyResolver resolver
;
2875 MockAsyncProxyResolverFactory
* factory
=
2876 new MockAsyncProxyResolverFactory(true);
2878 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2880 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2881 service
.SetProxyScriptFetchers(fetcher
,
2882 new DoNothingDhcpProxyScriptFetcher());
2887 TestCompletionCallback callback1
;
2889 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
2890 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2891 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2893 // The first request should have triggered initial download of PAC script.
2894 EXPECT_TRUE(fetcher
->has_pending_request());
2895 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2897 // Nothing has been sent to the factory yet.
2898 EXPECT_TRUE(factory
->pending_requests().empty());
2900 // At this point the ProxyService should be waiting for the
2901 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2902 // PAC script download completion.
2903 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2905 // Now that the PAC script is downloaded, the request will have been sent to
2906 // the proxy resolver.
2907 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2908 factory
->pending_requests()[0]->script_data()->utf16());
2909 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
2911 ASSERT_EQ(1u, resolver
.pending_requests().size());
2912 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
2914 // Complete the pending request.
2915 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
2916 resolver
.pending_requests()[0]->CompleteNow(OK
);
2918 // Wait for completion callback, and verify that the request ran as expected.
2919 EXPECT_EQ(OK
, callback1
.WaitForResult());
2920 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2922 // At this point we have initialized the proxy service using a PAC script.
2924 // A background task to periodically re-check the PAC script for validity will
2925 // have been started. We will now wait for the next download attempt to start.
2927 // Note that we shouldn't have to wait long here, since our test enables a
2928 // special unit-test mode.
2929 fetcher
->WaitUntilFetch();
2931 ASSERT_TRUE(factory
->pending_requests().empty());
2932 ASSERT_TRUE(resolver
.pending_requests().empty());
2934 // Make sure that our background checker is trying to download the expected
2935 // PAC script (same one as before). We will simulate the same response as
2936 // last time (i.e. the script is unchanged).
2937 EXPECT_TRUE(fetcher
->has_pending_request());
2938 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2939 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2941 base::MessageLoop::current()->RunUntilIdle();
2943 ASSERT_TRUE(factory
->pending_requests().empty());
2944 ASSERT_TRUE(resolver
.pending_requests().empty());
2946 // At this point the ProxyService is still running the same PAC script as
2949 // Start a second request.
2951 TestCompletionCallback callback2
;
2952 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
2953 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2954 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2956 // Check that it was sent to the resolver.
2957 ASSERT_EQ(1u, resolver
.pending_requests().size());
2958 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[0]->url());
2960 // Complete the pending second request.
2961 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
2962 resolver
.pending_requests()[0]->CompleteNow(OK
);
2964 // Wait for completion callback, and verify that the request ran as expected.
2965 EXPECT_EQ(OK
, callback2
.WaitForResult());
2966 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2969 // This test verifies that the PAC script specified by the settings is
2970 // periodically polled for changes. Specifically, if the initial fetch succeeds,
2971 // however at a later time it starts to fail, we should re-configure the
2972 // ProxyService to stop using that PAC script.
2973 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterSuccess
) {
2974 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2976 ImmediatePollPolicy poll_policy
;
2977 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2979 MockProxyConfigService
* config_service
=
2980 new MockProxyConfigService("http://foopy/proxy.pac");
2982 MockAsyncProxyResolver resolver
;
2983 MockAsyncProxyResolverFactory
* factory
=
2984 new MockAsyncProxyResolverFactory(true);
2986 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
2988 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2989 service
.SetProxyScriptFetchers(fetcher
,
2990 new DoNothingDhcpProxyScriptFetcher());
2995 TestCompletionCallback callback1
;
2997 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
2998 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2999 EXPECT_EQ(ERR_IO_PENDING
, rv
);
3001 // The first request should have triggered initial download of PAC script.
3002 EXPECT_TRUE(fetcher
->has_pending_request());
3003 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
3005 // Nothing has been sent to the factory yet.
3006 EXPECT_TRUE(factory
->pending_requests().empty());
3008 // At this point the ProxyService should be waiting for the
3009 // ProxyScriptFetcher to invoke its completion callback, notifying it of
3010 // PAC script download completion.
3011 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
3013 // Now that the PAC script is downloaded, the request will have been sent to
3014 // the proxy resolver.
3015 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
3016 factory
->pending_requests()[0]->script_data()->utf16());
3017 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
3019 ASSERT_EQ(1u, resolver
.pending_requests().size());
3020 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
3022 // Complete the pending request.
3023 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
3024 resolver
.pending_requests()[0]->CompleteNow(OK
);
3026 // Wait for completion callback, and verify that the request ran as expected.
3027 EXPECT_EQ(OK
, callback1
.WaitForResult());
3028 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
3030 // At this point we have initialized the proxy service using a PAC script.
3032 // A background task to periodically re-check the PAC script for validity will
3033 // have been started. We will now wait for the next download attempt to start.
3035 // Note that we shouldn't have to wait long here, since our test enables a
3036 // special unit-test mode.
3037 fetcher
->WaitUntilFetch();
3039 ASSERT_TRUE(factory
->pending_requests().empty());
3040 ASSERT_TRUE(resolver
.pending_requests().empty());
3042 // Make sure that our background checker is trying to download the expected
3043 // PAC script (same one as before). This time we will simulate a failure
3044 // to download the script.
3045 EXPECT_TRUE(fetcher
->has_pending_request());
3046 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
3047 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
3049 base::MessageLoop::current()->RunUntilIdle();
3051 // At this point the ProxyService should have re-configured itself to use
3052 // DIRECT connections rather than the given proxy resolver.
3054 // Start a second request.
3056 TestCompletionCallback callback2
;
3057 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
3058 callback2
.callback(), NULL
, NULL
, BoundNetLog());
3060 EXPECT_TRUE(info2
.is_direct());
3063 // Tests that the code which decides at what times to poll the PAC
3064 // script follows the expected policy.
3065 TEST_F(ProxyServiceTest
, PACScriptPollingPolicy
) {
3066 // Retrieve the internal polling policy implementation used by ProxyService.
3067 scoped_ptr
<ProxyService::PacPollPolicy
> policy
=
3068 ProxyService::CreateDefaultPacPollPolicy();
3071 ProxyService::PacPollPolicy::Mode mode
;
3072 const base::TimeDelta initial_delay
= base::TimeDelta::FromMilliseconds(-1);
3073 base::TimeDelta delay
= initial_delay
;
3075 // --------------------------------------------------
3076 // Test the poll sequence in response to a failure.
3077 // --------------------------------------------------
3078 error
= ERR_NAME_NOT_RESOLVED
;
3081 mode
= policy
->GetNextDelay(error
, initial_delay
, &delay
);
3082 EXPECT_EQ(8, delay
.InSeconds());
3083 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_USE_TIMER
, mode
);
3086 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
3087 EXPECT_EQ(32, delay
.InSeconds());
3088 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3091 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
3092 EXPECT_EQ(120, delay
.InSeconds());
3093 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3096 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
3097 EXPECT_EQ(14400, delay
.InSeconds());
3098 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3101 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
3102 EXPECT_EQ(14400, delay
.InSeconds());
3103 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3105 // --------------------------------------------------
3106 // Test the poll sequence in response to a success.
3107 // --------------------------------------------------
3111 mode
= policy
->GetNextDelay(error
, initial_delay
, &delay
);
3112 EXPECT_EQ(43200, delay
.InSeconds());
3113 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3116 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
3117 EXPECT_EQ(43200, delay
.InSeconds());
3118 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3121 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
3122 EXPECT_EQ(43200, delay
.InSeconds());
3123 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
3126 // This tests the polling of the PAC script. Specifically, it tests that
3127 // polling occurs in response to user activity.
3128 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterActivity
) {
3129 ImmediateAfterActivityPollPolicy poll_policy
;
3130 ProxyService::set_pac_script_poll_policy(&poll_policy
);
3132 MockProxyConfigService
* config_service
=
3133 new MockProxyConfigService("http://foopy/proxy.pac");
3135 MockAsyncProxyResolver resolver
;
3136 MockAsyncProxyResolverFactory
* factory
=
3137 new MockAsyncProxyResolverFactory(true);
3139 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
3141 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
3142 service
.SetProxyScriptFetchers(fetcher
,
3143 new DoNothingDhcpProxyScriptFetcher());
3148 TestCompletionCallback callback1
;
3150 service
.ResolveProxy(GURL("http://request1"), LOAD_NORMAL
, &info1
,
3151 callback1
.callback(), NULL
, NULL
, BoundNetLog());
3152 EXPECT_EQ(ERR_IO_PENDING
, rv
);
3154 // The first request should have triggered initial download of PAC script.
3155 EXPECT_TRUE(fetcher
->has_pending_request());
3156 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
3158 // Nothing has been sent to the factory yet.
3159 EXPECT_TRUE(factory
->pending_requests().empty());
3161 // At this point the ProxyService should be waiting for the
3162 // ProxyScriptFetcher to invoke its completion callback, notifying it of
3163 // PAC script download completion.
3164 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
3166 // Now that the PAC script is downloaded, the request will have been sent to
3167 // the proxy resolver.
3168 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
3169 factory
->pending_requests()[0]->script_data()->utf16());
3170 factory
->pending_requests()[0]->CompleteNowWithForwarder(OK
, &resolver
);
3172 ASSERT_EQ(1u, resolver
.pending_requests().size());
3173 EXPECT_EQ(GURL("http://request1"), resolver
.pending_requests()[0]->url());
3175 // Complete the pending request.
3176 resolver
.pending_requests()[0]->results()->UseNamedProxy("request1:80");
3177 resolver
.pending_requests()[0]->CompleteNow(OK
);
3179 // Wait for completion callback, and verify that the request ran as expected.
3180 EXPECT_EQ(OK
, callback1
.WaitForResult());
3181 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
3183 // At this point we have initialized the proxy service using a PAC script.
3184 // Our PAC poller is set to update ONLY in response to network activity,
3185 // (i.e. another call to ResolveProxy()).
3187 ASSERT_FALSE(fetcher
->has_pending_request());
3188 ASSERT_TRUE(factory
->pending_requests().empty());
3189 ASSERT_TRUE(resolver
.pending_requests().empty());
3191 // Start a second request.
3193 TestCompletionCallback callback2
;
3194 rv
= service
.ResolveProxy(GURL("http://request2"), LOAD_NORMAL
, &info2
,
3195 callback2
.callback(), NULL
, NULL
, BoundNetLog());
3196 EXPECT_EQ(ERR_IO_PENDING
, rv
);
3198 // This request should have sent work to the resolver; complete it.
3199 ASSERT_EQ(1u, resolver
.pending_requests().size());
3200 EXPECT_EQ(GURL("http://request2"), resolver
.pending_requests()[0]->url());
3201 resolver
.pending_requests()[0]->results()->UseNamedProxy("request2:80");
3202 resolver
.pending_requests()[0]->CompleteNow(OK
);
3204 EXPECT_EQ(OK
, callback2
.WaitForResult());
3205 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
3207 // In response to getting that resolve request, the poller should have
3208 // started the next poll, and made it as far as to request the download.
3210 EXPECT_TRUE(fetcher
->has_pending_request());
3211 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
3213 // This time we will fail the download, to simulate a PAC script change.
3214 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
3216 // Drain the message loop, so ProxyService is notified of the change
3217 // and has a chance to re-configure itself.
3218 base::MessageLoop::current()->RunUntilIdle();
3220 // Start a third request -- this time we expect to get a direct connection
3221 // since the PAC script poller experienced a failure.
3223 TestCompletionCallback callback3
;
3224 rv
= service
.ResolveProxy(GURL("http://request3"), LOAD_NORMAL
, &info3
,
3225 callback3
.callback(), NULL
, NULL
, BoundNetLog());
3227 EXPECT_TRUE(info3
.is_direct());
3230 // Test that the synchronous resolution fails when a PAC script is active.
3231 TEST_F(ProxyServiceTest
, SynchronousWithPAC
) {
3232 MockProxyConfigService
* config_service
=
3233 new MockProxyConfigService("http://foopy/proxy.pac");
3235 MockAsyncProxyResolverFactory
* factory
=
3236 new MockAsyncProxyResolverFactory(false);
3238 ProxyService
service(config_service
, make_scoped_ptr(factory
), NULL
);
3240 GURL
url("http://www.google.com/");
3244 BoundTestNetLog log
;
3246 bool synchronous_success
= service
.TryResolveProxySynchronously(
3247 url
, LOAD_NORMAL
, &info
, NULL
, log
.bound());
3248 EXPECT_FALSE(synchronous_success
);
3250 // |info| should not have been modified.
3251 EXPECT_TRUE(info
.is_direct());
3254 // Test that synchronous results are returned correctly if a fixed proxy
3255 // configuration is active.
3256 TEST_F(ProxyServiceTest
, SynchronousWithFixedConfiguration
) {
3258 config
.proxy_rules().ParseFromString("foopy1:8080");
3259 config
.set_auto_detect(false);
3261 MockAsyncProxyResolverFactory
* factory
=
3262 new MockAsyncProxyResolverFactory(false);
3264 ProxyService
service(new MockProxyConfigService(config
),
3265 make_scoped_ptr(factory
), NULL
);
3267 GURL
url("http://www.google.com/");
3270 BoundTestNetLog log
;
3272 bool synchronous_success
= service
.TryResolveProxySynchronously(
3273 url
, LOAD_NORMAL
, &info
, NULL
, log
.bound());
3274 EXPECT_TRUE(synchronous_success
);
3275 EXPECT_FALSE(info
.is_direct());
3276 EXPECT_EQ("foopy1", info
.proxy_server().host_port_pair().host());
3278 // No request should have been queued.
3279 EXPECT_EQ(0u, factory
->pending_requests().size());