1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/proxy/proxy_service.h"
9 #include "base/format_macros.h"
10 #include "base/logging.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "net/base/load_flags.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/net_log.h"
16 #include "net/base/net_log_unittest.h"
17 #include "net/base/network_delegate.h"
18 #include "net/base/test_completion_callback.h"
19 #include "net/proxy/dhcp_proxy_script_fetcher.h"
20 #include "net/proxy/mock_proxy_resolver.h"
21 #include "net/proxy/mock_proxy_script_fetcher.h"
22 #include "net/proxy/proxy_config_service.h"
23 #include "net/proxy/proxy_resolver.h"
24 #include "net/proxy/proxy_script_fetcher.h"
25 #include "testing/gtest/include/gtest/gtest.h"
28 using base::ASCIIToUTF16
;
30 // TODO(eroman): Write a test which exercises
31 // ProxyService::SuspendAllPendingRequests().
35 // This polling policy will decide to poll every 1 ms.
36 class ImmediatePollPolicy
: public ProxyService::PacPollPolicy
{
38 ImmediatePollPolicy() {}
40 virtual Mode
GetNextDelay(int error
, base::TimeDelta current_delay
,
41 base::TimeDelta
* next_delay
) const OVERRIDE
{
42 *next_delay
= base::TimeDelta::FromMilliseconds(1);
43 return MODE_USE_TIMER
;
47 DISALLOW_COPY_AND_ASSIGN(ImmediatePollPolicy
);
50 // This polling policy chooses a fantastically large delay. In other words, it
51 // will never trigger a poll
52 class NeverPollPolicy
: public ProxyService::PacPollPolicy
{
56 virtual Mode
GetNextDelay(int error
, base::TimeDelta current_delay
,
57 base::TimeDelta
* next_delay
) const OVERRIDE
{
58 *next_delay
= base::TimeDelta::FromDays(60);
59 return MODE_USE_TIMER
;
63 DISALLOW_COPY_AND_ASSIGN(NeverPollPolicy
);
66 // This polling policy starts a poll immediately after network activity.
67 class ImmediateAfterActivityPollPolicy
: public ProxyService::PacPollPolicy
{
69 ImmediateAfterActivityPollPolicy() {}
71 virtual Mode
GetNextDelay(int error
, base::TimeDelta current_delay
,
72 base::TimeDelta
* next_delay
) const OVERRIDE
{
73 *next_delay
= base::TimeDelta();
74 return MODE_START_AFTER_ACTIVITY
;
78 DISALLOW_COPY_AND_ASSIGN(ImmediateAfterActivityPollPolicy
);
81 // This test fixture is used to partially disable the background polling done by
82 // the ProxyService (which it uses to detect whenever its PAC script contents or
83 // WPAD results have changed).
85 // We disable the feature by setting the poll interval to something really
86 // large, so it will never actually be reached even on the slowest bots that run
89 // We disable the polling in order to avoid any timing dependencies in the
90 // tests. If the bot were to run the tests very slowly and we hadn't disabled
91 // polling, then it might start a background re-try in the middle of our test
92 // and confuse our expectations leading to flaky failures.
94 // The tests which verify the polling code re-enable the polling behavior but
95 // are careful to avoid timing problems.
96 class ProxyServiceTest
: public testing::Test
{
98 virtual void SetUp() OVERRIDE
{
99 testing::Test::SetUp();
101 ProxyService::set_pac_script_poll_policy(&never_poll_policy_
);
104 virtual void TearDown() OVERRIDE
{
105 // Restore the original policy.
106 ProxyService::set_pac_script_poll_policy(previous_policy_
);
107 testing::Test::TearDown();
111 NeverPollPolicy never_poll_policy_
;
112 const ProxyService::PacPollPolicy
* previous_policy_
;
115 const char kValidPacScript1
[] = "pac-script-v1-FindProxyForURL";
116 const char kValidPacScript2
[] = "pac-script-v2-FindProxyForURL";
118 class MockProxyConfigService
: public ProxyConfigService
{
120 explicit MockProxyConfigService(const ProxyConfig
& config
)
121 : availability_(CONFIG_VALID
),
125 explicit MockProxyConfigService(const std::string
& pac_url
)
126 : availability_(CONFIG_VALID
),
127 config_(ProxyConfig::CreateFromCustomPacURL(GURL(pac_url
))) {
130 virtual void AddObserver(Observer
* observer
) OVERRIDE
{
131 observers_
.AddObserver(observer
);
134 virtual void RemoveObserver(Observer
* observer
) OVERRIDE
{
135 observers_
.RemoveObserver(observer
);
138 virtual ConfigAvailability
GetLatestProxyConfig(ProxyConfig
* results
)
140 if (availability_
== CONFIG_VALID
)
142 return availability_
;
145 void SetConfig(const ProxyConfig
& config
) {
146 availability_
= CONFIG_VALID
;
148 FOR_EACH_OBSERVER(Observer
, observers_
,
149 OnProxyConfigChanged(config_
, availability_
));
153 ConfigAvailability availability_
;
155 ObserverList
<Observer
, true> observers_
;
158 // A test network delegate that exercises the OnResolveProxy callback.
159 class TestResolveProxyNetworkDelegate
: public NetworkDelegate
{
161 TestResolveProxyNetworkDelegate()
162 : on_resolve_proxy_called_(false),
164 remove_proxy_(false) {
167 virtual void OnResolveProxy(
168 const GURL
& url
, int load_flags
, ProxyInfo
* result
) OVERRIDE
{
169 on_resolve_proxy_called_
= true;
170 DCHECK(!add_proxy_
|| !remove_proxy_
);
172 result
->UseNamedProxy("delegate_proxy.com");
173 } else if (remove_proxy_
) {
178 bool on_resolve_proxy_called() const {
179 return on_resolve_proxy_called_
;
182 void set_add_proxy(bool add_proxy
) {
183 add_proxy_
= add_proxy
;
186 void set_remove_proxy(bool remove_proxy
) {
187 remove_proxy_
= remove_proxy
;
191 bool on_resolve_proxy_called_
;
198 TEST_F(ProxyServiceTest
, Direct
) {
199 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
200 ProxyService
service(new MockProxyConfigService(
201 ProxyConfig::CreateDirect()), resolver
, NULL
);
203 GURL
url("http://www.google.com/");
206 TestCompletionCallback callback
;
207 CapturingBoundNetLog log
;
208 int rv
= service
.ResolveProxy(
209 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
212 EXPECT_TRUE(resolver
->pending_requests().empty());
214 EXPECT_TRUE(info
.is_direct());
215 EXPECT_TRUE(info
.proxy_resolve_start_time().is_null());
216 EXPECT_TRUE(info
.proxy_resolve_end_time().is_null());
218 // Check the NetLog was filled correctly.
219 CapturingNetLog::CapturedEntryList entries
;
220 log
.GetEntries(&entries
);
222 EXPECT_EQ(3u, entries
.size());
223 EXPECT_TRUE(LogContainsBeginEvent(
224 entries
, 0, NetLog::TYPE_PROXY_SERVICE
));
225 EXPECT_TRUE(LogContainsEvent(
226 entries
, 1, NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST
,
227 NetLog::PHASE_NONE
));
228 EXPECT_TRUE(LogContainsEndEvent(
229 entries
, 2, NetLog::TYPE_PROXY_SERVICE
));
232 TEST_F(ProxyServiceTest
, OnResolveProxyCallbackAddProxy
) {
234 config
.proxy_rules().ParseFromString("foopy1:8080");
235 config
.set_auto_detect(false);
236 config
.proxy_rules().bypass_rules
.ParseFromString("*.org");
238 ProxyService
service(
239 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
241 GURL
url("http://www.google.com/");
242 GURL
bypass_url("http://internet.org");
245 TestCompletionCallback callback
;
246 CapturingBoundNetLog log
;
248 // First, warm up the ProxyService.
249 int rv
= service
.ResolveProxy(
250 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
254 // Verify that network delegate is invoked.
255 TestResolveProxyNetworkDelegate delegate
;
256 rv
= service
.ResolveProxy(
257 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
259 EXPECT_TRUE(delegate
.on_resolve_proxy_called());
261 // Verify that the NetworkDelegate's behavior is stateless across
262 // invocations of ResolveProxy. Start by having the callback add a proxy
263 // and checking that subsequent requests are not affected.
264 delegate
.set_add_proxy(true);
266 // Callback should interpose:
267 rv
= service
.ResolveProxy(
268 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
270 EXPECT_FALSE(info
.is_direct());
271 EXPECT_EQ(info
.proxy_server().host_port_pair().host(), "delegate_proxy.com");
272 delegate
.set_add_proxy(false);
274 // Check non-bypassed URL:
275 rv
= service
.ResolveProxy(
276 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
278 EXPECT_FALSE(info
.is_direct());
279 EXPECT_EQ(info
.proxy_server().host_port_pair().host(), "foopy1");
281 // Check bypassed URL:
282 rv
= service
.ResolveProxy(
283 bypass_url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
,
284 &delegate
, log
.bound());
285 EXPECT_TRUE(info
.is_direct());
288 TEST_F(ProxyServiceTest
, OnResolveProxyCallbackRemoveProxy
) {
289 // Same as OnResolveProxyCallbackAddProxy, but verify that the
290 // NetworkDelegate's behavior is stateless across invocations after it
291 // *removes* a proxy.
293 config
.proxy_rules().ParseFromString("foopy1:8080");
294 config
.set_auto_detect(false);
295 config
.proxy_rules().bypass_rules
.ParseFromString("*.org");
297 ProxyService
service(
298 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
300 GURL
url("http://www.google.com/");
301 GURL
bypass_url("http://internet.org");
304 TestCompletionCallback callback
;
305 CapturingBoundNetLog log
;
307 // First, warm up the ProxyService.
308 int rv
= service
.ResolveProxy(
309 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
313 TestResolveProxyNetworkDelegate delegate
;
314 delegate
.set_remove_proxy(true);
316 // Callback should interpose:
317 rv
= service
.ResolveProxy(
318 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
320 EXPECT_TRUE(info
.is_direct());
321 delegate
.set_remove_proxy(false);
323 // Check non-bypassed URL:
324 rv
= service
.ResolveProxy(
325 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, &delegate
,
327 EXPECT_FALSE(info
.is_direct());
328 EXPECT_EQ(info
.proxy_server().host_port_pair().host(), "foopy1");
330 // Check bypassed URL:
331 rv
= service
.ResolveProxy(
332 bypass_url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
,
333 &delegate
, log
.bound());
334 EXPECT_TRUE(info
.is_direct());
337 TEST_F(ProxyServiceTest
, PAC
) {
338 MockProxyConfigService
* config_service
=
339 new MockProxyConfigService("http://foopy/proxy.pac");
341 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
343 ProxyService
service(config_service
, resolver
, NULL
);
345 GURL
url("http://www.google.com/");
348 TestCompletionCallback callback
;
349 ProxyService::PacRequest
* request
;
350 CapturingBoundNetLog log
;
352 int rv
= service
.ResolveProxy(
353 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), &request
, NULL
,
355 EXPECT_EQ(ERR_IO_PENDING
, rv
);
357 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request
));
359 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
360 resolver
->pending_set_pac_script_request()->script_data()->url());
361 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
363 ASSERT_EQ(1u, resolver
->pending_requests().size());
364 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
366 // Set the result in proxy resolver.
367 resolver
->pending_requests()[0]->results()->UseNamedProxy("foopy");
368 resolver
->pending_requests()[0]->CompleteNow(OK
);
370 EXPECT_EQ(OK
, callback
.WaitForResult());
371 EXPECT_FALSE(info
.is_direct());
372 EXPECT_EQ("foopy:80", info
.proxy_server().ToURI());
373 EXPECT_TRUE(info
.did_use_pac_script());
375 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
376 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
377 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
379 // Check the NetLog was filled correctly.
380 CapturingNetLog::CapturedEntryList entries
;
381 log
.GetEntries(&entries
);
383 EXPECT_EQ(5u, entries
.size());
384 EXPECT_TRUE(LogContainsBeginEvent(
385 entries
, 0, NetLog::TYPE_PROXY_SERVICE
));
386 EXPECT_TRUE(LogContainsBeginEvent(
387 entries
, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
388 EXPECT_TRUE(LogContainsEndEvent(
389 entries
, 2, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
390 EXPECT_TRUE(LogContainsEndEvent(
391 entries
, 4, NetLog::TYPE_PROXY_SERVICE
));
394 // Test that the proxy resolver does not see the URL's username/password
395 // or its reference section.
396 TEST_F(ProxyServiceTest
, PAC_NoIdentityOrHash
) {
397 MockProxyConfigService
* config_service
=
398 new MockProxyConfigService("http://foopy/proxy.pac");
400 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
402 ProxyService
service(config_service
, resolver
, NULL
);
404 GURL
url("http://username:password@www.google.com/?ref#hash#hash");
407 TestCompletionCallback callback
;
408 int rv
= service
.ResolveProxy(
409 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
411 EXPECT_EQ(ERR_IO_PENDING
, rv
);
413 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
414 resolver
->pending_set_pac_script_request()->script_data()->url());
415 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
417 ASSERT_EQ(1u, resolver
->pending_requests().size());
418 // The URL should have been simplified, stripping the username/password/hash.
419 EXPECT_EQ(GURL("http://www.google.com/?ref"),
420 resolver
->pending_requests()[0]->url());
422 // We end here without ever completing the request -- destruction of
423 // ProxyService will cancel the outstanding request.
426 TEST_F(ProxyServiceTest
, PAC_FailoverWithoutDirect
) {
427 MockProxyConfigService
* config_service
=
428 new MockProxyConfigService("http://foopy/proxy.pac");
429 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
431 ProxyService
service(config_service
, resolver
, NULL
);
433 GURL
url("http://www.google.com/");
436 TestCompletionCallback callback1
;
437 int rv
= service
.ResolveProxy(
438 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
440 EXPECT_EQ(ERR_IO_PENDING
, rv
);
442 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
443 resolver
->pending_set_pac_script_request()->script_data()->url());
444 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
446 ASSERT_EQ(1u, resolver
->pending_requests().size());
447 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
449 // Set the result in proxy resolver.
450 resolver
->pending_requests()[0]->results()->UseNamedProxy("foopy:8080");
451 resolver
->pending_requests()[0]->CompleteNow(OK
);
453 EXPECT_EQ(OK
, callback1
.WaitForResult());
454 EXPECT_FALSE(info
.is_direct());
455 EXPECT_EQ("foopy:8080", info
.proxy_server().ToURI());
456 EXPECT_TRUE(info
.did_use_pac_script());
458 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
459 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
460 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
462 // Now, imagine that connecting to foopy:8080 fails: there is nothing
463 // left to fallback to, since our proxy list was NOT terminated by
465 TestCompletionCallback callback2
;
466 rv
= service
.ReconsiderProxyAfterError(
467 url
, net::LOAD_NORMAL
, net::ERR_PROXY_CONNECTION_FAILED
,
468 &info
, callback2
.callback(), NULL
, NULL
, BoundNetLog());
469 // ReconsiderProxyAfterError returns error indicating nothing left.
470 EXPECT_EQ(ERR_FAILED
, rv
);
471 EXPECT_TRUE(info
.is_empty());
474 // Test that if the execution of the PAC script fails (i.e. javascript runtime
475 // error), and the PAC settings are non-mandatory, that we fall-back to direct.
476 TEST_F(ProxyServiceTest
, PAC_RuntimeError
) {
477 MockProxyConfigService
* config_service
=
478 new MockProxyConfigService("http://foopy/proxy.pac");
479 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
481 ProxyService
service(config_service
, resolver
, NULL
);
483 GURL
url("http://this-causes-js-error/");
486 TestCompletionCallback callback1
;
487 int rv
= service
.ResolveProxy(
488 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
490 EXPECT_EQ(ERR_IO_PENDING
, rv
);
492 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
493 resolver
->pending_set_pac_script_request()->script_data()->url());
494 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
496 ASSERT_EQ(1u, resolver
->pending_requests().size());
497 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
499 // Simulate a failure in the PAC executor.
500 resolver
->pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_FAILED
);
502 EXPECT_EQ(OK
, callback1
.WaitForResult());
504 // Since the PAC script was non-mandatory, we should have fallen-back to
506 EXPECT_TRUE(info
.is_direct());
507 EXPECT_TRUE(info
.did_use_pac_script());
508 EXPECT_EQ(1, info
.config_id());
510 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
511 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
512 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
515 // The proxy list could potentially contain the DIRECT fallback choice
516 // in a location other than the very end of the list, and could even
517 // specify it multiple times.
519 // This is not a typical usage, but we will obey it.
520 // (If we wanted to disallow this type of input, the right place to
521 // enforce it would be in parsing the PAC result string).
523 // This test will use the PAC result string:
525 // "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20"
527 // For which we expect it to try DIRECT, then foobar:10, then DIRECT again,
528 // then foobar:20, and then give up and error.
530 // The important check of this test is to make sure that DIRECT is not somehow
531 // cached as being a bad proxy.
532 TEST_F(ProxyServiceTest
, PAC_FailoverAfterDirect
) {
533 MockProxyConfigService
* config_service
=
534 new MockProxyConfigService("http://foopy/proxy.pac");
535 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
537 ProxyService
service(config_service
, resolver
, NULL
);
539 GURL
url("http://www.google.com/");
542 TestCompletionCallback callback1
;
543 int rv
= service
.ResolveProxy(
544 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
546 EXPECT_EQ(ERR_IO_PENDING
, rv
);
548 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
549 resolver
->pending_set_pac_script_request()->script_data()->url());
550 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
552 ASSERT_EQ(1u, resolver
->pending_requests().size());
553 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
555 // Set the result in proxy resolver.
556 resolver
->pending_requests()[0]->results()->UsePacString(
557 "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20");
558 resolver
->pending_requests()[0]->CompleteNow(OK
);
560 EXPECT_EQ(OK
, callback1
.WaitForResult());
561 EXPECT_TRUE(info
.is_direct());
564 TestCompletionCallback callback2
;
565 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
566 net::ERR_PROXY_CONNECTION_FAILED
,
567 &info
, callback2
.callback(), NULL
,
568 NULL
, BoundNetLog());
570 EXPECT_FALSE(info
.is_direct());
571 EXPECT_EQ("foobar:10", info
.proxy_server().ToURI());
574 TestCompletionCallback callback3
;
575 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
576 net::ERR_PROXY_CONNECTION_FAILED
,
577 &info
, callback3
.callback(), NULL
,
578 NULL
, BoundNetLog());
580 EXPECT_TRUE(info
.is_direct());
583 TestCompletionCallback callback4
;
584 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
585 net::ERR_PROXY_CONNECTION_FAILED
,
586 &info
, callback4
.callback(), NULL
,
587 NULL
, BoundNetLog());
589 EXPECT_FALSE(info
.is_direct());
590 EXPECT_EQ("foobar:20", info
.proxy_server().ToURI());
592 // Fallback 4 -- Nothing to fall back to!
593 TestCompletionCallback callback5
;
594 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
595 net::ERR_PROXY_CONNECTION_FAILED
,
596 &info
, callback5
.callback(), NULL
,
597 NULL
, BoundNetLog());
598 EXPECT_EQ(ERR_FAILED
, rv
);
599 EXPECT_TRUE(info
.is_empty());
602 TEST_F(ProxyServiceTest
, PAC_ConfigSourcePropagates
) {
603 // Test whether the ProxyConfigSource set by the ProxyConfigService is applied
604 // to ProxyInfo after the proxy is resolved via a PAC script.
606 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
607 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
609 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
610 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
611 ProxyService
service(config_service
, resolver
, NULL
);
613 // Resolve something.
614 GURL
url("http://www.google.com/");
616 TestCompletionCallback callback
;
617 int rv
= service
.ResolveProxy(
618 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
620 ASSERT_EQ(ERR_IO_PENDING
, rv
);
621 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
622 ASSERT_EQ(1u, resolver
->pending_requests().size());
624 // Set the result in proxy resolver.
625 resolver
->pending_requests()[0]->results()->UseNamedProxy("foopy");
626 resolver
->pending_requests()[0]->CompleteNow(OK
);
628 EXPECT_EQ(OK
, callback
.WaitForResult());
629 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
630 EXPECT_TRUE(info
.did_use_pac_script());
632 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
633 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
634 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
637 TEST_F(ProxyServiceTest
, ProxyResolverFails
) {
638 // Test what happens when the ProxyResolver fails. The download and setting
639 // of the PAC script have already succeeded, so this corresponds with a
640 // javascript runtime error while calling FindProxyForURL().
642 MockProxyConfigService
* config_service
=
643 new MockProxyConfigService("http://foopy/proxy.pac");
645 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
647 ProxyService
service(config_service
, resolver
, NULL
);
649 // Start first resolve request.
650 GURL
url("http://www.google.com/");
652 TestCompletionCallback callback1
;
653 int rv
= service
.ResolveProxy(
654 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
656 EXPECT_EQ(ERR_IO_PENDING
, rv
);
658 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
659 resolver
->pending_set_pac_script_request()->script_data()->url());
660 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
662 ASSERT_EQ(1u, resolver
->pending_requests().size());
663 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
665 // Fail the first resolve request in MockAsyncProxyResolver.
666 resolver
->pending_requests()[0]->CompleteNow(ERR_FAILED
);
668 // Although the proxy resolver failed the request, ProxyService implicitly
669 // falls-back to DIRECT.
670 EXPECT_EQ(OK
, callback1
.WaitForResult());
671 EXPECT_TRUE(info
.is_direct());
673 // Failed PAC executions still have proxy resolution times.
674 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
675 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
676 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
678 // The second resolve request will try to run through the proxy resolver,
679 // regardless of whether the first request failed in it.
680 TestCompletionCallback callback2
;
681 rv
= service
.ResolveProxy(
682 url
, net::LOAD_NORMAL
, &info
, callback2
.callback(), NULL
, NULL
,
684 EXPECT_EQ(ERR_IO_PENDING
, rv
);
686 ASSERT_EQ(1u, resolver
->pending_requests().size());
687 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
689 // This time we will have the resolver succeed (perhaps the PAC script has
690 // a dependency on the current time).
691 resolver
->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
692 resolver
->pending_requests()[0]->CompleteNow(OK
);
694 EXPECT_EQ(OK
, callback2
.WaitForResult());
695 EXPECT_FALSE(info
.is_direct());
696 EXPECT_EQ("foopy_valid:8080", info
.proxy_server().ToURI());
699 TEST_F(ProxyServiceTest
, ProxyScriptFetcherFailsDownloadingMandatoryPac
) {
700 // Test what happens when the ProxyScriptResolver fails to download a
701 // mandatory PAC script.
704 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
705 config
.set_pac_mandatory(true);
707 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
709 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
711 ProxyService
service(config_service
, resolver
, NULL
);
713 // Start first resolve request.
714 GURL
url("http://www.google.com/");
716 TestCompletionCallback callback1
;
717 int rv
= service
.ResolveProxy(
718 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
720 EXPECT_EQ(ERR_IO_PENDING
, rv
);
722 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
723 resolver
->pending_set_pac_script_request()->script_data()->url());
724 resolver
->pending_set_pac_script_request()->CompleteNow(ERR_FAILED
);
726 ASSERT_EQ(0u, resolver
->pending_requests().size());
728 // As the proxy resolver failed the request and is configured for a mandatory
729 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
730 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
731 callback1
.WaitForResult());
732 EXPECT_FALSE(info
.is_direct());
734 // As the proxy resolver failed the request and is configured for a mandatory
735 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
736 TestCompletionCallback callback2
;
737 rv
= service
.ResolveProxy(
738 url
, net::LOAD_NORMAL
, &info
, callback2
.callback(), NULL
, NULL
,
740 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
, rv
);
741 EXPECT_FALSE(info
.is_direct());
744 TEST_F(ProxyServiceTest
, ProxyResolverFailsParsingJavaScriptMandatoryPac
) {
745 // Test what happens when the ProxyResolver fails that is configured to use a
746 // mandatory PAC script. The download of the PAC script has already
747 // succeeded but the PAC script contains no valid javascript.
750 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
751 config
.set_pac_mandatory(true);
753 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
755 MockAsyncProxyResolverExpectsBytes
* resolver
=
756 new MockAsyncProxyResolverExpectsBytes
;
758 ProxyService
service(config_service
, resolver
, NULL
);
760 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
761 DhcpProxyScriptFetcher
* dhcp_fetcher
= new DoNothingDhcpProxyScriptFetcher();
762 service
.SetProxyScriptFetchers(fetcher
, dhcp_fetcher
);
764 // Start resolve request.
765 GURL
url("http://www.google.com/");
767 TestCompletionCallback callback
;
768 int rv
= service
.ResolveProxy(
769 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
771 EXPECT_EQ(ERR_IO_PENDING
, rv
);
773 // Check that nothing has been sent to the proxy resolver yet.
774 ASSERT_EQ(0u, resolver
->pending_requests().size());
776 // Downloading the PAC script succeeds.
777 EXPECT_TRUE(fetcher
->has_pending_request());
778 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
779 fetcher
->NotifyFetchCompletion(OK
, "invalid-script-contents");
781 EXPECT_FALSE(fetcher
->has_pending_request());
782 ASSERT_EQ(0u, resolver
->pending_requests().size());
784 // Since ProxyScriptDecider failed to identify a valid PAC and PAC was
785 // mandatory for this configuration, the ProxyService must not implicitly
786 // fall-back to DIRECT.
787 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
788 callback
.WaitForResult());
789 EXPECT_FALSE(info
.is_direct());
792 TEST_F(ProxyServiceTest
, ProxyResolverFailsInJavaScriptMandatoryPac
) {
793 // Test what happens when the ProxyResolver fails that is configured to use a
794 // mandatory PAC script. The download and setting of the PAC script have
795 // already succeeded, so this corresponds with a javascript runtime error
796 // while calling FindProxyForURL().
799 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
800 config
.set_pac_mandatory(true);
802 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
804 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
806 ProxyService
service(config_service
, resolver
, NULL
);
808 // Start first resolve request.
809 GURL
url("http://www.google.com/");
811 TestCompletionCallback callback1
;
812 int rv
= service
.ResolveProxy(
813 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
815 EXPECT_EQ(ERR_IO_PENDING
, rv
);
817 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
818 resolver
->pending_set_pac_script_request()->script_data()->url());
819 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
821 ASSERT_EQ(1u, resolver
->pending_requests().size());
822 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
824 // Fail the first resolve request in MockAsyncProxyResolver.
825 resolver
->pending_requests()[0]->CompleteNow(ERR_FAILED
);
827 // As the proxy resolver failed the request and is configured for a mandatory
828 // PAC script, ProxyService must not implicitly fall-back to DIRECT.
829 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
830 callback1
.WaitForResult());
831 EXPECT_FALSE(info
.is_direct());
833 // The second resolve request will try to run through the proxy resolver,
834 // regardless of whether the first request failed in it.
835 TestCompletionCallback callback2
;
836 rv
= service
.ResolveProxy(
837 url
, net::LOAD_NORMAL
, &info
, callback2
.callback(), NULL
, NULL
,
839 EXPECT_EQ(ERR_IO_PENDING
, rv
);
841 ASSERT_EQ(1u, resolver
->pending_requests().size());
842 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
844 // This time we will have the resolver succeed (perhaps the PAC script has
845 // a dependency on the current time).
846 resolver
->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
847 resolver
->pending_requests()[0]->CompleteNow(OK
);
849 EXPECT_EQ(OK
, callback2
.WaitForResult());
850 EXPECT_FALSE(info
.is_direct());
851 EXPECT_EQ("foopy_valid:8080", info
.proxy_server().ToURI());
854 TEST_F(ProxyServiceTest
, ProxyFallback
) {
855 // Test what happens when we specify multiple proxy servers and some of them
858 MockProxyConfigService
* config_service
=
859 new MockProxyConfigService("http://foopy/proxy.pac");
861 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
863 ProxyService
service(config_service
, resolver
, NULL
);
865 GURL
url("http://www.google.com/");
867 // Get the proxy information.
869 TestCompletionCallback callback1
;
870 int rv
= service
.ResolveProxy(
871 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
873 EXPECT_EQ(ERR_IO_PENDING
, rv
);
875 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
876 resolver
->pending_set_pac_script_request()->script_data()->url());
877 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
879 ASSERT_EQ(1u, resolver
->pending_requests().size());
880 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
882 // Set the result in proxy resolver.
883 resolver
->pending_requests()[0]->results()->UseNamedProxy(
884 "foopy1:8080;foopy2:9090");
885 resolver
->pending_requests()[0]->CompleteNow(OK
);
887 // The first item is valid.
888 EXPECT_EQ(OK
, callback1
.WaitForResult());
889 EXPECT_FALSE(info
.is_direct());
890 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
892 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
893 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
894 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
895 base::TimeTicks proxy_resolve_start_time
= info
.proxy_resolve_start_time();
896 base::TimeTicks proxy_resolve_end_time
= info
.proxy_resolve_end_time();
898 // Fake an error on the proxy.
899 TestCompletionCallback callback2
;
900 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
901 net::ERR_PROXY_CONNECTION_FAILED
,
902 &info
, callback2
.callback(), NULL
,
903 NULL
, BoundNetLog());
906 // Proxy times should not have been modified by fallback.
907 EXPECT_EQ(proxy_resolve_start_time
, info
.proxy_resolve_start_time());
908 EXPECT_EQ(proxy_resolve_end_time
, info
.proxy_resolve_end_time());
910 // The second proxy should be specified.
911 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
912 // Report back that the second proxy worked. This will globally mark the
913 // first proxy as bad.
914 service
.ReportSuccess(info
);
916 TestCompletionCallback callback3
;
917 rv
= service
.ResolveProxy(
918 url
, net::LOAD_NORMAL
, &info
, callback3
.callback(), NULL
, NULL
,
920 EXPECT_EQ(ERR_IO_PENDING
, rv
);
922 ASSERT_EQ(1u, resolver
->pending_requests().size());
923 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
925 // Set the result in proxy resolver -- the second result is already known
926 // to be bad, so we will not try to use it initially.
927 resolver
->pending_requests()[0]->results()->UseNamedProxy(
928 "foopy3:7070;foopy1:8080;foopy2:9090");
929 resolver
->pending_requests()[0]->CompleteNow(OK
);
931 EXPECT_EQ(OK
, callback3
.WaitForResult());
932 EXPECT_FALSE(info
.is_direct());
933 EXPECT_EQ("foopy3:7070", info
.proxy_server().ToURI());
935 // Proxy times should have been updated, so get them again.
936 EXPECT_LE(proxy_resolve_end_time
, info
.proxy_resolve_start_time());
937 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
938 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
939 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
940 proxy_resolve_start_time
= info
.proxy_resolve_start_time();
941 proxy_resolve_end_time
= info
.proxy_resolve_end_time();
943 // We fake another error. It should now try the third one.
944 TestCompletionCallback callback4
;
945 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
946 net::ERR_PROXY_CONNECTION_FAILED
,
947 &info
, callback4
.callback(), NULL
,
948 NULL
, BoundNetLog());
950 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
952 // We fake another error. At this point we have tried all of the
953 // proxy servers we thought were valid; next we try the proxy server
954 // that was in our bad proxies map (foopy1:8080).
955 TestCompletionCallback callback5
;
956 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
957 net::ERR_PROXY_CONNECTION_FAILED
,
958 &info
, callback5
.callback(), NULL
,
959 NULL
, BoundNetLog());
961 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
963 // Fake another error, the last proxy is gone, the list should now be empty,
964 // so there is nothing left to try.
965 TestCompletionCallback callback6
;
966 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
967 net::ERR_PROXY_CONNECTION_FAILED
,
968 &info
, callback6
.callback(), NULL
,
969 NULL
, BoundNetLog());
970 EXPECT_EQ(ERR_FAILED
, rv
);
971 EXPECT_FALSE(info
.is_direct());
972 EXPECT_TRUE(info
.is_empty());
974 // Proxy times should not have been modified by fallback.
975 EXPECT_EQ(proxy_resolve_start_time
, info
.proxy_resolve_start_time());
976 EXPECT_EQ(proxy_resolve_end_time
, info
.proxy_resolve_end_time());
978 // Look up proxies again
979 TestCompletionCallback callback7
;
980 rv
= service
.ResolveProxy(url
, net::LOAD_NORMAL
, &info
, callback7
.callback(),
981 NULL
, NULL
, BoundNetLog());
982 EXPECT_EQ(ERR_IO_PENDING
, rv
);
984 ASSERT_EQ(1u, resolver
->pending_requests().size());
985 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
987 // This time, the first 3 results have been found to be bad, but only the
988 // first proxy has been confirmed ...
989 resolver
->pending_requests()[0]->results()->UseNamedProxy(
990 "foopy1:8080;foopy3:7070;foopy2:9090;foopy4:9091");
991 resolver
->pending_requests()[0]->CompleteNow(OK
);
993 // ... therefore, we should see the second proxy first.
994 EXPECT_EQ(OK
, callback7
.WaitForResult());
995 EXPECT_FALSE(info
.is_direct());
996 EXPECT_EQ("foopy3:7070", info
.proxy_server().ToURI());
998 EXPECT_LE(proxy_resolve_end_time
, info
.proxy_resolve_start_time());
999 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1000 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1001 // TODO(nsylvain): Test that the proxy can be retried after the delay.
1004 // This test is similar to ProxyFallback, but this time we have an explicit
1005 // fallback choice to DIRECT.
1006 TEST_F(ProxyServiceTest
, ProxyFallbackToDirect
) {
1007 MockProxyConfigService
* config_service
=
1008 new MockProxyConfigService("http://foopy/proxy.pac");
1010 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
1012 ProxyService
service(config_service
, resolver
, NULL
);
1014 GURL
url("http://www.google.com/");
1016 // Get the proxy information.
1018 TestCompletionCallback callback1
;
1019 int rv
= service
.ResolveProxy(
1020 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
1022 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1024 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1025 resolver
->pending_set_pac_script_request()->script_data()->url());
1026 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1028 ASSERT_EQ(1u, resolver
->pending_requests().size());
1029 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1031 // Set the result in proxy resolver.
1032 resolver
->pending_requests()[0]->results()->UsePacString(
1033 "PROXY foopy1:8080; PROXY foopy2:9090; DIRECT");
1034 resolver
->pending_requests()[0]->CompleteNow(OK
);
1036 // Get the first result.
1037 EXPECT_EQ(OK
, callback1
.WaitForResult());
1038 EXPECT_FALSE(info
.is_direct());
1039 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1041 // Fake an error on the proxy.
1042 TestCompletionCallback callback2
;
1043 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1044 net::ERR_PROXY_CONNECTION_FAILED
,
1045 &info
, callback2
.callback(), NULL
,
1046 NULL
, BoundNetLog());
1049 // Now we get back the second proxy.
1050 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1052 // Fake an error on this proxy as well.
1053 TestCompletionCallback callback3
;
1054 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1055 net::ERR_PROXY_CONNECTION_FAILED
,
1056 &info
, callback3
.callback(), NULL
,
1057 NULL
, BoundNetLog());
1060 // Finally, we get back DIRECT.
1061 EXPECT_TRUE(info
.is_direct());
1063 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1064 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1065 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1067 // Now we tell the proxy service that even DIRECT failed.
1068 TestCompletionCallback callback4
;
1069 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1070 net::ERR_PROXY_CONNECTION_FAILED
,
1071 &info
, callback4
.callback(), NULL
,
1072 NULL
, BoundNetLog());
1073 // There was nothing left to try after DIRECT, so we are out of
1075 EXPECT_EQ(ERR_FAILED
, rv
);
1078 TEST_F(ProxyServiceTest
, ProxyFallback_NewSettings
) {
1079 // Test proxy failover when new settings are available.
1081 MockProxyConfigService
* config_service
=
1082 new MockProxyConfigService("http://foopy/proxy.pac");
1084 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
1086 ProxyService
service(config_service
, resolver
, NULL
);
1088 GURL
url("http://www.google.com/");
1090 // Get the proxy information.
1092 TestCompletionCallback callback1
;
1093 int rv
= service
.ResolveProxy(
1094 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
1096 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1098 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1099 resolver
->pending_set_pac_script_request()->script_data()->url());
1100 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1102 ASSERT_EQ(1u, resolver
->pending_requests().size());
1103 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1105 // Set the result in proxy resolver.
1106 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1107 "foopy1:8080;foopy2:9090");
1108 resolver
->pending_requests()[0]->CompleteNow(OK
);
1110 // The first item is valid.
1111 EXPECT_EQ(OK
, callback1
.WaitForResult());
1112 EXPECT_FALSE(info
.is_direct());
1113 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1115 // Fake an error on the proxy, and also a new configuration on the proxy.
1116 config_service
->SetConfig(
1117 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy-new/proxy.pac")));
1119 TestCompletionCallback callback2
;
1120 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1121 net::ERR_PROXY_CONNECTION_FAILED
,
1122 &info
, callback2
.callback(), NULL
,
1123 NULL
, BoundNetLog());
1124 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1126 EXPECT_EQ(GURL("http://foopy-new/proxy.pac"),
1127 resolver
->pending_set_pac_script_request()->script_data()->url());
1128 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1130 ASSERT_EQ(1u, resolver
->pending_requests().size());
1131 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1133 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1134 "foopy1:8080;foopy2:9090");
1135 resolver
->pending_requests()[0]->CompleteNow(OK
);
1137 // The first proxy is still there since the configuration changed.
1138 EXPECT_EQ(OK
, callback2
.WaitForResult());
1139 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1141 // We fake another error. It should now ignore the first one.
1142 TestCompletionCallback callback3
;
1143 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1144 net::ERR_PROXY_CONNECTION_FAILED
,
1145 &info
, callback3
.callback(), NULL
,
1146 NULL
, BoundNetLog());
1148 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1150 // We simulate a new configuration.
1151 config_service
->SetConfig(
1152 ProxyConfig::CreateFromCustomPacURL(
1153 GURL("http://foopy-new2/proxy.pac")));
1155 // We fake another error. It should go back to the first proxy.
1156 TestCompletionCallback callback4
;
1157 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1158 net::ERR_PROXY_CONNECTION_FAILED
,
1159 &info
, callback4
.callback(), NULL
,
1160 NULL
, BoundNetLog());
1161 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1163 EXPECT_EQ(GURL("http://foopy-new2/proxy.pac"),
1164 resolver
->pending_set_pac_script_request()->script_data()->url());
1165 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1167 ASSERT_EQ(1u, resolver
->pending_requests().size());
1168 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1170 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1171 "foopy1:8080;foopy2:9090");
1172 resolver
->pending_requests()[0]->CompleteNow(OK
);
1174 EXPECT_EQ(OK
, callback4
.WaitForResult());
1175 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1177 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1178 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1179 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1182 TEST_F(ProxyServiceTest
, ProxyFallback_BadConfig
) {
1183 // Test proxy failover when the configuration is bad.
1185 MockProxyConfigService
* config_service
=
1186 new MockProxyConfigService("http://foopy/proxy.pac");
1188 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
1190 ProxyService
service(config_service
, resolver
, NULL
);
1192 GURL
url("http://www.google.com/");
1194 // Get the proxy information.
1196 TestCompletionCallback callback1
;
1197 int rv
= service
.ResolveProxy(
1198 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
1200 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1202 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1203 resolver
->pending_set_pac_script_request()->script_data()->url());
1204 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1205 ASSERT_EQ(1u, resolver
->pending_requests().size());
1206 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1208 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1209 "foopy1:8080;foopy2:9090");
1210 resolver
->pending_requests()[0]->CompleteNow(OK
);
1212 // The first item is valid.
1213 EXPECT_EQ(OK
, callback1
.WaitForResult());
1214 EXPECT_FALSE(info
.is_direct());
1215 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1217 // Fake a proxy error.
1218 TestCompletionCallback callback2
;
1219 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1220 net::ERR_PROXY_CONNECTION_FAILED
,
1221 &info
, callback2
.callback(), NULL
,
1222 NULL
, BoundNetLog());
1225 // The first proxy is ignored, and the second one is selected.
1226 EXPECT_FALSE(info
.is_direct());
1227 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1229 // Fake a PAC failure.
1231 TestCompletionCallback callback3
;
1232 rv
= service
.ResolveProxy(
1233 url
, net::LOAD_NORMAL
, &info2
, callback3
.callback(), NULL
, NULL
,
1235 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1237 ASSERT_EQ(1u, resolver
->pending_requests().size());
1238 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1240 // This simulates a javascript runtime error in the PAC script.
1241 resolver
->pending_requests()[0]->CompleteNow(ERR_FAILED
);
1243 // Although the resolver failed, the ProxyService will implicitly fall-back
1244 // to a DIRECT connection.
1245 EXPECT_EQ(OK
, callback3
.WaitForResult());
1246 EXPECT_TRUE(info2
.is_direct());
1247 EXPECT_FALSE(info2
.is_empty());
1249 // The PAC script will work properly next time and successfully return a
1250 // proxy list. Since we have not marked the configuration as bad, it should
1251 // "just work" the next time we call it.
1253 TestCompletionCallback callback4
;
1254 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1255 net::ERR_PROXY_CONNECTION_FAILED
,
1256 &info3
, callback4
.callback(),
1257 NULL
, NULL
, BoundNetLog());
1258 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1260 ASSERT_EQ(1u, resolver
->pending_requests().size());
1261 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1263 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1264 "foopy1:8080;foopy2:9090");
1265 resolver
->pending_requests()[0]->CompleteNow(OK
);
1267 // The first proxy is not there since the it was added to the bad proxies
1268 // list by the earlier ReconsiderProxyAfterError().
1269 EXPECT_EQ(OK
, callback4
.WaitForResult());
1270 EXPECT_FALSE(info3
.is_direct());
1271 EXPECT_EQ("foopy1:8080", info3
.proxy_server().ToURI());
1273 EXPECT_FALSE(info
.proxy_resolve_start_time().is_null());
1274 EXPECT_FALSE(info
.proxy_resolve_end_time().is_null());
1275 EXPECT_LE(info
.proxy_resolve_start_time(), info
.proxy_resolve_end_time());
1278 TEST_F(ProxyServiceTest
, ProxyFallback_BadConfigMandatory
) {
1279 // Test proxy failover when the configuration is bad.
1282 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
1284 config
.set_pac_mandatory(true);
1285 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
1287 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
1289 ProxyService
service(config_service
, resolver
, NULL
);
1291 GURL
url("http://www.google.com/");
1293 // Get the proxy information.
1295 TestCompletionCallback callback1
;
1296 int rv
= service
.ResolveProxy(
1297 url
, net::LOAD_NORMAL
, &info
, callback1
.callback(), NULL
, NULL
,
1299 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1301 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1302 resolver
->pending_set_pac_script_request()->script_data()->url());
1303 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1304 ASSERT_EQ(1u, resolver
->pending_requests().size());
1305 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1307 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1308 "foopy1:8080;foopy2:9090");
1309 resolver
->pending_requests()[0]->CompleteNow(OK
);
1311 // The first item is valid.
1312 EXPECT_EQ(OK
, callback1
.WaitForResult());
1313 EXPECT_FALSE(info
.is_direct());
1314 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1316 // Fake a proxy error.
1317 TestCompletionCallback callback2
;
1318 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1319 net::ERR_PROXY_CONNECTION_FAILED
,
1320 &info
, callback2
.callback(), NULL
,
1321 NULL
, BoundNetLog());
1324 // The first proxy is ignored, and the second one is selected.
1325 EXPECT_FALSE(info
.is_direct());
1326 EXPECT_EQ("foopy2:9090", info
.proxy_server().ToURI());
1328 // Fake a PAC failure.
1330 TestCompletionCallback callback3
;
1331 rv
= service
.ResolveProxy(
1332 url
, net::LOAD_NORMAL
, &info2
, callback3
.callback(), NULL
, NULL
,
1334 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1336 ASSERT_EQ(1u, resolver
->pending_requests().size());
1337 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1339 // This simulates a javascript runtime error in the PAC script.
1340 resolver
->pending_requests()[0]->CompleteNow(ERR_FAILED
);
1342 // Although the resolver failed, the ProxyService will NOT fall-back
1343 // to a DIRECT connection as it is configured as mandatory.
1344 EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED
,
1345 callback3
.WaitForResult());
1346 EXPECT_FALSE(info2
.is_direct());
1347 EXPECT_TRUE(info2
.is_empty());
1349 // The PAC script will work properly next time and successfully return a
1350 // proxy list. Since we have not marked the configuration as bad, it should
1351 // "just work" the next time we call it.
1353 TestCompletionCallback callback4
;
1354 rv
= service
.ReconsiderProxyAfterError(url
, net::LOAD_NORMAL
,
1355 net::ERR_PROXY_CONNECTION_FAILED
,
1356 &info3
, callback4
.callback(),
1357 NULL
, NULL
, BoundNetLog());
1358 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1360 ASSERT_EQ(1u, resolver
->pending_requests().size());
1361 EXPECT_EQ(url
, resolver
->pending_requests()[0]->url());
1363 resolver
->pending_requests()[0]->results()->UseNamedProxy(
1364 "foopy1:8080;foopy2:9090");
1365 resolver
->pending_requests()[0]->CompleteNow(OK
);
1367 // The first proxy is not there since the it was added to the bad proxies
1368 // list by the earlier ReconsiderProxyAfterError().
1369 EXPECT_EQ(OK
, callback4
.WaitForResult());
1370 EXPECT_FALSE(info3
.is_direct());
1371 EXPECT_EQ("foopy1:8080", info3
.proxy_server().ToURI());
1374 TEST_F(ProxyServiceTest
, ProxyBypassList
) {
1375 // Test that the proxy bypass rules are consulted.
1377 TestCompletionCallback callback
[2];
1380 config
.proxy_rules().ParseFromString("foopy1:8080;foopy2:9090");
1381 config
.set_auto_detect(false);
1382 config
.proxy_rules().bypass_rules
.ParseFromString("*.org");
1384 ProxyService
service(
1385 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1388 GURL
url1("http://www.webkit.org");
1389 GURL
url2("http://www.webkit.com");
1391 // Request for a .org domain should bypass proxy.
1392 rv
= service
.ResolveProxy(
1393 url1
, net::LOAD_NORMAL
, &info
[0], callback
[0].callback(), NULL
, NULL
,
1396 EXPECT_TRUE(info
[0].is_direct());
1398 // Request for a .com domain hits the proxy.
1399 rv
= service
.ResolveProxy(
1400 url2
, net::LOAD_NORMAL
, &info
[1], callback
[1].callback(), NULL
, NULL
,
1403 EXPECT_EQ("foopy1:8080", info
[1].proxy_server().ToURI());
1407 TEST_F(ProxyServiceTest
, PerProtocolProxyTests
) {
1409 config
.proxy_rules().ParseFromString("http=foopy1:8080;https=foopy2:8080");
1410 config
.set_auto_detect(false);
1412 ProxyService
service(
1413 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1414 GURL
test_url("http://www.msn.com");
1416 TestCompletionCallback callback
;
1417 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1418 callback
.callback(), NULL
, NULL
,
1421 EXPECT_FALSE(info
.is_direct());
1422 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1425 ProxyService
service(
1426 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1427 GURL
test_url("ftp://ftp.google.com");
1429 TestCompletionCallback callback
;
1430 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1431 callback
.callback(), NULL
,
1432 NULL
, BoundNetLog());
1434 EXPECT_TRUE(info
.is_direct());
1435 EXPECT_EQ("direct://", info
.proxy_server().ToURI());
1438 ProxyService
service(
1439 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1440 GURL
test_url("https://webbranch.techcu.com");
1442 TestCompletionCallback callback
;
1443 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1444 callback
.callback(), NULL
,
1445 NULL
, BoundNetLog());
1447 EXPECT_FALSE(info
.is_direct());
1448 EXPECT_EQ("foopy2:8080", info
.proxy_server().ToURI());
1451 config
.proxy_rules().ParseFromString("foopy1:8080");
1452 ProxyService
service(
1453 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1454 GURL
test_url("http://www.microsoft.com");
1456 TestCompletionCallback callback
;
1457 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1458 callback
.callback(), NULL
,
1459 NULL
, BoundNetLog());
1461 EXPECT_FALSE(info
.is_direct());
1462 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1466 TEST_F(ProxyServiceTest
, ProxyConfigSourcePropagates
) {
1467 // Test that the proxy config source is set correctly when resolving proxies
1468 // using manual proxy rules. Namely, the config source should only be set if
1469 // any of the rules were applied.
1472 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1473 config
.proxy_rules().ParseFromString("https=foopy2:8080");
1474 ProxyService
service(
1475 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1476 GURL
test_url("http://www.google.com");
1478 TestCompletionCallback callback
;
1479 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1480 callback
.callback(), NULL
,
1481 NULL
, BoundNetLog());
1483 // Should be SOURCE_TEST, even if there are no HTTP proxies configured.
1484 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1488 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1489 config
.proxy_rules().ParseFromString("https=foopy2:8080");
1490 ProxyService
service(
1491 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1492 GURL
test_url("https://www.google.com");
1494 TestCompletionCallback callback
;
1495 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1496 callback
.callback(), NULL
,
1497 NULL
, BoundNetLog());
1499 // Used the HTTPS proxy. So source should be TEST.
1500 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1504 config
.set_source(PROXY_CONFIG_SOURCE_TEST
);
1505 ProxyService
service(
1506 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1507 GURL
test_url("http://www.google.com");
1509 TestCompletionCallback callback
;
1510 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1511 callback
.callback(), NULL
,
1512 NULL
, BoundNetLog());
1514 // ProxyConfig is empty. Source should still be TEST.
1515 EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST
, info
.config_source());
1519 // If only HTTP and a SOCKS proxy are specified, check if ftp/https queries
1520 // fall back to the SOCKS proxy.
1521 TEST_F(ProxyServiceTest
, DefaultProxyFallbackToSOCKS
) {
1523 config
.proxy_rules().ParseFromString("http=foopy1:8080;socks=foopy2:1080");
1524 config
.set_auto_detect(false);
1525 EXPECT_EQ(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
1526 config
.proxy_rules().type
);
1529 ProxyService
service(
1530 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1531 GURL
test_url("http://www.msn.com");
1533 TestCompletionCallback callback
;
1534 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1535 callback
.callback(), NULL
,
1536 NULL
, BoundNetLog());
1538 EXPECT_FALSE(info
.is_direct());
1539 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
1542 ProxyService
service(
1543 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1544 GURL
test_url("ftp://ftp.google.com");
1546 TestCompletionCallback callback
;
1547 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1548 callback
.callback(), NULL
,
1549 NULL
, BoundNetLog());
1551 EXPECT_FALSE(info
.is_direct());
1552 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1555 ProxyService
service(
1556 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1557 GURL
test_url("https://webbranch.techcu.com");
1559 TestCompletionCallback callback
;
1560 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1561 callback
.callback(), NULL
,
1562 NULL
, BoundNetLog());
1564 EXPECT_FALSE(info
.is_direct());
1565 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1568 ProxyService
service(
1569 new MockProxyConfigService(config
), new MockAsyncProxyResolver
, NULL
);
1570 GURL
test_url("unknown://www.microsoft.com");
1572 TestCompletionCallback callback
;
1573 int rv
= service
.ResolveProxy(test_url
, net::LOAD_NORMAL
, &info
,
1574 callback
.callback(), NULL
,
1575 NULL
, BoundNetLog());
1577 EXPECT_FALSE(info
.is_direct());
1578 EXPECT_EQ("socks4://foopy2:1080", info
.proxy_server().ToURI());
1582 // Test cancellation of an in-progress request.
1583 TEST_F(ProxyServiceTest
, CancelInProgressRequest
) {
1584 MockProxyConfigService
* config_service
=
1585 new MockProxyConfigService("http://foopy/proxy.pac");
1587 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
1589 ProxyService
service(config_service
, resolver
, NULL
);
1591 // Start 3 requests.
1594 TestCompletionCallback callback1
;
1595 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1596 &info1
, callback1
.callback(), NULL
, NULL
,
1598 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1600 // Nothing has been sent to the proxy resolver yet, since the proxy
1601 // resolver has not been configured yet.
1602 ASSERT_EQ(0u, resolver
->pending_requests().size());
1604 // Successfully initialize the PAC script.
1605 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1606 resolver
->pending_set_pac_script_request()->script_data()->url());
1607 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1609 ASSERT_EQ(1u, resolver
->pending_requests().size());
1610 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
1613 TestCompletionCallback callback2
;
1614 ProxyService::PacRequest
* request2
;
1615 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1616 callback2
.callback(), &request2
, NULL
,
1618 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1619 ASSERT_EQ(2u, resolver
->pending_requests().size());
1620 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[1]->url());
1623 TestCompletionCallback callback3
;
1624 rv
= service
.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL
, &info3
,
1625 callback3
.callback(), NULL
, NULL
, BoundNetLog());
1626 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1627 ASSERT_EQ(3u, resolver
->pending_requests().size());
1628 EXPECT_EQ(GURL("http://request3"), resolver
->pending_requests()[2]->url());
1630 // Cancel the second request
1631 service
.CancelPacRequest(request2
);
1633 ASSERT_EQ(2u, resolver
->pending_requests().size());
1634 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
1635 EXPECT_EQ(GURL("http://request3"), resolver
->pending_requests()[1]->url());
1637 // Complete the two un-cancelled requests.
1638 // We complete the last one first, just to mix it up a bit.
1639 resolver
->pending_requests()[1]->results()->UseNamedProxy("request3:80");
1640 resolver
->pending_requests()[1]->CompleteNow(OK
);
1642 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1643 resolver
->pending_requests()[0]->CompleteNow(OK
);
1645 // Complete and verify that requests ran as expected.
1646 EXPECT_EQ(OK
, callback1
.WaitForResult());
1647 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
1649 EXPECT_FALSE(callback2
.have_result()); // Cancelled.
1650 ASSERT_EQ(1u, resolver
->cancelled_requests().size());
1651 EXPECT_EQ(GURL("http://request2"), resolver
->cancelled_requests()[0]->url());
1653 EXPECT_EQ(OK
, callback3
.WaitForResult());
1654 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
1657 // Test the initial PAC download for resolver that expects bytes.
1658 TEST_F(ProxyServiceTest
, InitialPACScriptDownload
) {
1659 MockProxyConfigService
* config_service
=
1660 new MockProxyConfigService("http://foopy/proxy.pac");
1662 MockAsyncProxyResolverExpectsBytes
* resolver
=
1663 new MockAsyncProxyResolverExpectsBytes
;
1665 ProxyService
service(config_service
, resolver
, NULL
);
1667 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1668 service
.SetProxyScriptFetchers(fetcher
,
1669 new DoNothingDhcpProxyScriptFetcher());
1671 // Start 3 requests.
1674 TestCompletionCallback callback1
;
1675 ProxyService::PacRequest
* request1
;
1676 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1677 &info1
, callback1
.callback(), &request1
, NULL
,
1679 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1681 // The first request should have triggered download of PAC script.
1682 EXPECT_TRUE(fetcher
->has_pending_request());
1683 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1686 TestCompletionCallback callback2
;
1687 ProxyService::PacRequest
* request2
;
1688 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1689 callback2
.callback(), &request2
, NULL
,
1691 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1694 TestCompletionCallback callback3
;
1695 ProxyService::PacRequest
* request3
;
1696 rv
= service
.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL
, &info3
,
1697 callback3
.callback(), &request3
, NULL
,
1699 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1701 // Nothing has been sent to the resolver yet.
1702 EXPECT_TRUE(resolver
->pending_requests().empty());
1704 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1705 service
.GetLoadState(request1
));
1706 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1707 service
.GetLoadState(request2
));
1708 EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT
,
1709 service
.GetLoadState(request3
));
1711 // At this point the ProxyService should be waiting for the
1712 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1713 // PAC script download completion.
1714 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
1716 // Now that the PAC script is downloaded, it will have been sent to the proxy
1718 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
1719 resolver
->pending_set_pac_script_request()->script_data()->utf16());
1720 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1722 ASSERT_EQ(3u, resolver
->pending_requests().size());
1723 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
1724 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[1]->url());
1725 EXPECT_EQ(GURL("http://request3"), resolver
->pending_requests()[2]->url());
1727 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request1
));
1728 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request2
));
1729 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, service
.GetLoadState(request3
));
1731 // Complete all the requests (in some order).
1732 // Note that as we complete requests, they shift up in |pending_requests()|.
1734 resolver
->pending_requests()[2]->results()->UseNamedProxy("request3:80");
1735 resolver
->pending_requests()[2]->CompleteNow(OK
);
1737 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1738 resolver
->pending_requests()[0]->CompleteNow(OK
);
1740 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
1741 resolver
->pending_requests()[0]->CompleteNow(OK
);
1743 // Complete and verify that requests ran as expected.
1744 EXPECT_EQ(OK
, callback1
.WaitForResult());
1745 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
1746 EXPECT_FALSE(info1
.proxy_resolve_start_time().is_null());
1747 EXPECT_FALSE(info1
.proxy_resolve_end_time().is_null());
1748 EXPECT_LE(info1
.proxy_resolve_start_time(), info1
.proxy_resolve_end_time());
1750 EXPECT_EQ(OK
, callback2
.WaitForResult());
1751 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
1752 EXPECT_FALSE(info2
.proxy_resolve_start_time().is_null());
1753 EXPECT_FALSE(info2
.proxy_resolve_end_time().is_null());
1754 EXPECT_LE(info2
.proxy_resolve_start_time(), info2
.proxy_resolve_end_time());
1756 EXPECT_EQ(OK
, callback3
.WaitForResult());
1757 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
1758 EXPECT_FALSE(info3
.proxy_resolve_start_time().is_null());
1759 EXPECT_FALSE(info3
.proxy_resolve_end_time().is_null());
1760 EXPECT_LE(info3
.proxy_resolve_start_time(), info3
.proxy_resolve_end_time());
1763 // Test changing the ProxyScriptFetcher while PAC download is in progress.
1764 TEST_F(ProxyServiceTest
, ChangeScriptFetcherWhilePACDownloadInProgress
) {
1765 MockProxyConfigService
* config_service
=
1766 new MockProxyConfigService("http://foopy/proxy.pac");
1768 MockAsyncProxyResolverExpectsBytes
* resolver
=
1769 new MockAsyncProxyResolverExpectsBytes
;
1771 ProxyService
service(config_service
, resolver
, NULL
);
1773 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1774 service
.SetProxyScriptFetchers(fetcher
,
1775 new DoNothingDhcpProxyScriptFetcher());
1777 // Start 2 requests.
1780 TestCompletionCallback callback1
;
1781 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1782 &info1
, callback1
.callback(), NULL
, NULL
,
1784 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1786 // The first request should have triggered download of PAC script.
1787 EXPECT_TRUE(fetcher
->has_pending_request());
1788 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1791 TestCompletionCallback callback2
;
1792 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1793 callback2
.callback(), NULL
, NULL
, BoundNetLog());
1794 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1796 // At this point the ProxyService should be waiting for the
1797 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1798 // PAC script download completion.
1800 // We now change out the ProxyService's script fetcher. We should restart
1801 // the initialization with the new fetcher.
1803 fetcher
= new MockProxyScriptFetcher
;
1804 service
.SetProxyScriptFetchers(fetcher
,
1805 new DoNothingDhcpProxyScriptFetcher());
1807 // Nothing has been sent to the resolver yet.
1808 EXPECT_TRUE(resolver
->pending_requests().empty());
1810 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
1812 // Now that the PAC script is downloaded, it will have been sent to the proxy
1814 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
1815 resolver
->pending_set_pac_script_request()->script_data()->utf16());
1816 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1818 ASSERT_EQ(2u, resolver
->pending_requests().size());
1819 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
1820 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[1]->url());
1823 // Test cancellation of a request, while the PAC script is being fetched.
1824 TEST_F(ProxyServiceTest
, CancelWhilePACFetching
) {
1825 MockProxyConfigService
* config_service
=
1826 new MockProxyConfigService("http://foopy/proxy.pac");
1828 MockAsyncProxyResolverExpectsBytes
* resolver
=
1829 new MockAsyncProxyResolverExpectsBytes
;
1831 ProxyService
service(config_service
, resolver
, NULL
);
1833 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1834 service
.SetProxyScriptFetchers(fetcher
,
1835 new DoNothingDhcpProxyScriptFetcher());
1837 // Start 3 requests.
1839 TestCompletionCallback callback1
;
1840 ProxyService::PacRequest
* request1
;
1841 CapturingBoundNetLog log1
;
1842 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1843 &info1
, callback1
.callback(), &request1
, NULL
,
1845 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1847 // The first request should have triggered download of PAC script.
1848 EXPECT_TRUE(fetcher
->has_pending_request());
1849 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1852 TestCompletionCallback callback2
;
1853 ProxyService::PacRequest
* request2
;
1854 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1855 callback2
.callback(), &request2
, NULL
,
1857 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1860 TestCompletionCallback callback3
;
1861 rv
= service
.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL
, &info3
,
1862 callback3
.callback(), NULL
, NULL
, BoundNetLog());
1863 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1865 // Nothing has been sent to the resolver yet.
1866 EXPECT_TRUE(resolver
->pending_requests().empty());
1868 // Cancel the first 2 requests.
1869 service
.CancelPacRequest(request1
);
1870 service
.CancelPacRequest(request2
);
1872 // At this point the ProxyService should be waiting for the
1873 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1874 // PAC script download completion.
1875 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
1877 // Now that the PAC script is downloaded, it will have been sent to the
1879 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
1880 resolver
->pending_set_pac_script_request()->script_data()->utf16());
1881 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1883 ASSERT_EQ(1u, resolver
->pending_requests().size());
1884 EXPECT_EQ(GURL("http://request3"), resolver
->pending_requests()[0]->url());
1886 // Complete all the requests.
1887 resolver
->pending_requests()[0]->results()->UseNamedProxy("request3:80");
1888 resolver
->pending_requests()[0]->CompleteNow(OK
);
1890 EXPECT_EQ(OK
, callback3
.WaitForResult());
1891 EXPECT_EQ("request3:80", info3
.proxy_server().ToURI());
1893 EXPECT_TRUE(resolver
->cancelled_requests().empty());
1895 EXPECT_FALSE(callback1
.have_result()); // Cancelled.
1896 EXPECT_FALSE(callback2
.have_result()); // Cancelled.
1898 CapturingNetLog::CapturedEntryList entries1
;
1899 log1
.GetEntries(&entries1
);
1901 // Check the NetLog for request 1 (which was cancelled) got filled properly.
1902 EXPECT_EQ(4u, entries1
.size());
1903 EXPECT_TRUE(LogContainsBeginEvent(
1904 entries1
, 0, NetLog::TYPE_PROXY_SERVICE
));
1905 EXPECT_TRUE(LogContainsBeginEvent(
1906 entries1
, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC
));
1907 // Note that TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC is never completed before
1908 // the cancellation occured.
1909 EXPECT_TRUE(LogContainsEvent(
1910 entries1
, 2, NetLog::TYPE_CANCELLED
, NetLog::PHASE_NONE
));
1911 EXPECT_TRUE(LogContainsEndEvent(
1912 entries1
, 3, NetLog::TYPE_PROXY_SERVICE
));
1915 // Test that if auto-detect fails, we fall-back to the custom pac.
1916 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomPac
) {
1918 config
.set_auto_detect(true);
1919 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
1920 config
.proxy_rules().ParseFromString("http=foopy:80"); // Won't be used.
1922 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
1923 MockAsyncProxyResolverExpectsBytes
* resolver
=
1924 new MockAsyncProxyResolverExpectsBytes
;
1925 ProxyService
service(config_service
, resolver
, NULL
);
1927 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
1928 service
.SetProxyScriptFetchers(fetcher
,
1929 new DoNothingDhcpProxyScriptFetcher());
1931 // Start 2 requests.
1934 TestCompletionCallback callback1
;
1935 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
1936 &info1
, callback1
.callback(), NULL
, NULL
,
1938 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1941 TestCompletionCallback callback2
;
1942 ProxyService::PacRequest
* request2
;
1943 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
1944 callback2
.callback(), &request2
, NULL
,
1946 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1948 // Check that nothing has been sent to the proxy resolver yet.
1949 ASSERT_EQ(0u, resolver
->pending_requests().size());
1951 // It should be trying to auto-detect first -- FAIL the autodetect during
1952 // the script download.
1953 EXPECT_TRUE(fetcher
->has_pending_request());
1954 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
1955 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
1957 // Next it should be trying the custom PAC url.
1958 EXPECT_TRUE(fetcher
->has_pending_request());
1959 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
1960 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
1962 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
1963 resolver
->pending_set_pac_script_request()->script_data()->utf16());
1964 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
1966 // Now finally, the pending requests should have been sent to the resolver
1967 // (which was initialized with custom PAC script).
1969 ASSERT_EQ(2u, resolver
->pending_requests().size());
1970 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
1971 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[1]->url());
1973 // Complete the pending requests.
1974 resolver
->pending_requests()[1]->results()->UseNamedProxy("request2:80");
1975 resolver
->pending_requests()[1]->CompleteNow(OK
);
1976 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1977 resolver
->pending_requests()[0]->CompleteNow(OK
);
1979 // Verify that requests ran as expected.
1980 EXPECT_EQ(OK
, callback1
.WaitForResult());
1981 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
1982 EXPECT_FALSE(info1
.proxy_resolve_start_time().is_null());
1983 EXPECT_FALSE(info1
.proxy_resolve_end_time().is_null());
1984 EXPECT_LE(info1
.proxy_resolve_start_time(), info1
.proxy_resolve_end_time());
1986 EXPECT_EQ(OK
, callback2
.WaitForResult());
1987 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
1988 EXPECT_FALSE(info2
.proxy_resolve_start_time().is_null());
1989 EXPECT_FALSE(info2
.proxy_resolve_end_time().is_null());
1990 EXPECT_LE(info2
.proxy_resolve_start_time(), info2
.proxy_resolve_end_time());
1993 // This is the same test as FallbackFromAutodetectToCustomPac, except
1994 // the auto-detect script fails parsing rather than downloading.
1995 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomPac2
) {
1997 config
.set_auto_detect(true);
1998 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
1999 config
.proxy_rules().ParseFromString("http=foopy:80"); // Won't be used.
2001 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2002 MockAsyncProxyResolverExpectsBytes
* resolver
=
2003 new MockAsyncProxyResolverExpectsBytes
;
2004 ProxyService
service(config_service
, resolver
, NULL
);
2006 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2007 service
.SetProxyScriptFetchers(fetcher
,
2008 new DoNothingDhcpProxyScriptFetcher());
2010 // Start 2 requests.
2013 TestCompletionCallback callback1
;
2014 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2015 &info1
, callback1
.callback(), NULL
, NULL
,
2017 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2020 TestCompletionCallback callback2
;
2021 ProxyService::PacRequest
* request2
;
2022 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
2023 callback2
.callback(), &request2
, NULL
,
2025 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2027 // Check that nothing has been sent to the proxy resolver yet.
2028 ASSERT_EQ(0u, resolver
->pending_requests().size());
2030 // It should be trying to auto-detect first -- succeed the download.
2031 EXPECT_TRUE(fetcher
->has_pending_request());
2032 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2033 fetcher
->NotifyFetchCompletion(OK
, "invalid-script-contents");
2035 // The script contents passed failed basic verification step (since didn't
2036 // contain token FindProxyForURL), so it was never passed to the resolver.
2038 // Next it should be trying the custom PAC url.
2039 EXPECT_TRUE(fetcher
->has_pending_request());
2040 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2041 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2043 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2044 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2045 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2047 // Now finally, the pending requests should have been sent to the resolver
2048 // (which was initialized with custom PAC script).
2050 ASSERT_EQ(2u, resolver
->pending_requests().size());
2051 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2052 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[1]->url());
2054 // Complete the pending requests.
2055 resolver
->pending_requests()[1]->results()->UseNamedProxy("request2:80");
2056 resolver
->pending_requests()[1]->CompleteNow(OK
);
2057 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2058 resolver
->pending_requests()[0]->CompleteNow(OK
);
2060 // Verify that requests ran as expected.
2061 EXPECT_EQ(OK
, callback1
.WaitForResult());
2062 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2064 EXPECT_EQ(OK
, callback2
.WaitForResult());
2065 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2068 // Test that if all of auto-detect, a custom PAC script, and manual settings
2069 // are given, then we will try them in that order.
2070 TEST_F(ProxyServiceTest
, FallbackFromAutodetectToCustomToManual
) {
2072 config
.set_auto_detect(true);
2073 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2074 config
.proxy_rules().ParseFromString("http=foopy:80");
2076 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2077 MockAsyncProxyResolverExpectsBytes
* resolver
=
2078 new MockAsyncProxyResolverExpectsBytes
;
2079 ProxyService
service(config_service
, resolver
, NULL
);
2081 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2082 service
.SetProxyScriptFetchers(fetcher
,
2083 new DoNothingDhcpProxyScriptFetcher());
2085 // Start 2 requests.
2088 TestCompletionCallback callback1
;
2089 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2090 &info1
, callback1
.callback(), NULL
, NULL
,
2092 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2095 TestCompletionCallback callback2
;
2096 ProxyService::PacRequest
* request2
;
2097 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
2098 callback2
.callback(), &request2
, NULL
,
2100 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2102 // Check that nothing has been sent to the proxy resolver yet.
2103 ASSERT_EQ(0u, resolver
->pending_requests().size());
2105 // It should be trying to auto-detect first -- fail the download.
2106 EXPECT_TRUE(fetcher
->has_pending_request());
2107 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2108 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2110 // Next it should be trying the custom PAC url -- fail the download.
2111 EXPECT_TRUE(fetcher
->has_pending_request());
2112 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2113 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2115 // Since we never managed to initialize a ProxyResolver, nothing should have
2117 ASSERT_EQ(0u, resolver
->pending_requests().size());
2119 // Verify that requests ran as expected -- they should have fallen back to
2120 // the manual proxy configuration for HTTP urls.
2121 EXPECT_EQ(OK
, callback1
.WaitForResult());
2122 EXPECT_EQ("foopy:80", info1
.proxy_server().ToURI());
2124 EXPECT_EQ(OK
, callback2
.WaitForResult());
2125 EXPECT_EQ("foopy:80", info2
.proxy_server().ToURI());
2128 // Test that the bypass rules are NOT applied when using autodetect.
2129 TEST_F(ProxyServiceTest
, BypassDoesntApplyToPac
) {
2131 config
.set_auto_detect(true);
2132 config
.set_pac_url(GURL("http://foopy/proxy.pac"));
2133 config
.proxy_rules().ParseFromString("http=foopy:80"); // Not used.
2134 config
.proxy_rules().bypass_rules
.ParseFromString("www.google.com");
2136 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2137 MockAsyncProxyResolverExpectsBytes
* resolver
=
2138 new MockAsyncProxyResolverExpectsBytes
;
2139 ProxyService
service(config_service
, resolver
, NULL
);
2141 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2142 service
.SetProxyScriptFetchers(fetcher
,
2143 new DoNothingDhcpProxyScriptFetcher());
2145 // Start 1 requests.
2148 TestCompletionCallback callback1
;
2149 int rv
= service
.ResolveProxy(
2150 GURL("http://www.google.com"), net::LOAD_NORMAL
, &info1
,
2151 callback1
.callback(), NULL
, NULL
, BoundNetLog());
2152 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2154 // Check that nothing has been sent to the proxy resolver yet.
2155 ASSERT_EQ(0u, resolver
->pending_requests().size());
2157 // It should be trying to auto-detect first -- succeed the download.
2158 EXPECT_TRUE(fetcher
->has_pending_request());
2159 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher
->pending_request_url());
2160 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2162 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2163 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2164 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2166 ASSERT_EQ(1u, resolver
->pending_requests().size());
2167 EXPECT_EQ(GURL("http://www.google.com"),
2168 resolver
->pending_requests()[0]->url());
2170 // Complete the pending request.
2171 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2172 resolver
->pending_requests()[0]->CompleteNow(OK
);
2174 // Verify that request ran as expected.
2175 EXPECT_EQ(OK
, callback1
.WaitForResult());
2176 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2178 // Start another request, it should pickup the bypass item.
2180 TestCompletionCallback callback2
;
2181 rv
= service
.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL
,
2182 &info2
, callback2
.callback(), NULL
, NULL
,
2184 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2186 ASSERT_EQ(1u, resolver
->pending_requests().size());
2187 EXPECT_EQ(GURL("http://www.google.com"),
2188 resolver
->pending_requests()[0]->url());
2190 // Complete the pending request.
2191 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
2192 resolver
->pending_requests()[0]->CompleteNow(OK
);
2194 EXPECT_EQ(OK
, callback2
.WaitForResult());
2195 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2198 // Delete the ProxyService while InitProxyResolver has an outstanding
2199 // request to the script fetcher. When run under valgrind, should not
2200 // have any memory errors (used to be that the ProxyScriptFetcher was
2201 // being deleted prior to the InitProxyResolver).
2202 TEST_F(ProxyServiceTest
, DeleteWhileInitProxyResolverHasOutstandingFetch
) {
2203 ProxyConfig config
=
2204 ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
2206 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2207 MockAsyncProxyResolverExpectsBytes
* resolver
=
2208 new MockAsyncProxyResolverExpectsBytes
;
2209 ProxyService
service(config_service
, resolver
, NULL
);
2211 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2212 service
.SetProxyScriptFetchers(fetcher
,
2213 new DoNothingDhcpProxyScriptFetcher());
2218 TestCompletionCallback callback1
;
2219 int rv
= service
.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL
,
2220 &info1
, callback1
.callback(), NULL
, NULL
,
2222 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2224 // Check that nothing has been sent to the proxy resolver yet.
2225 ASSERT_EQ(0u, resolver
->pending_requests().size());
2227 // InitProxyResolver should have issued a request to the ProxyScriptFetcher
2228 // and be waiting on that to complete.
2229 EXPECT_TRUE(fetcher
->has_pending_request());
2230 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2233 // Delete the ProxyService while InitProxyResolver has an outstanding
2234 // request to the proxy resolver. When run under valgrind, should not
2235 // have any memory errors (used to be that the ProxyResolver was
2236 // being deleted prior to the InitProxyResolver).
2237 TEST_F(ProxyServiceTest
, DeleteWhileInitProxyResolverHasOutstandingSet
) {
2238 MockProxyConfigService
* config_service
=
2239 new MockProxyConfigService("http://foopy/proxy.pac");
2241 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
2243 ProxyService
service(config_service
, resolver
, NULL
);
2245 GURL
url("http://www.google.com/");
2248 TestCompletionCallback callback
;
2249 int rv
= service
.ResolveProxy(
2250 url
, net::LOAD_NORMAL
, &info
, callback
.callback(), NULL
, NULL
,
2252 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2254 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
2255 resolver
->pending_set_pac_script_request()->script_data()->url());
2258 TEST_F(ProxyServiceTest
, ResetProxyConfigService
) {
2259 ProxyConfig config1
;
2260 config1
.proxy_rules().ParseFromString("foopy1:8080");
2261 config1
.set_auto_detect(false);
2262 ProxyService
service(
2263 new MockProxyConfigService(config1
),
2264 new MockAsyncProxyResolverExpectsBytes
, NULL
);
2267 TestCompletionCallback callback1
;
2268 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2269 &info
, callback1
.callback(), NULL
, NULL
,
2272 EXPECT_EQ("foopy1:8080", info
.proxy_server().ToURI());
2274 ProxyConfig config2
;
2275 config2
.proxy_rules().ParseFromString("foopy2:8080");
2276 config2
.set_auto_detect(false);
2277 service
.ResetConfigService(new MockProxyConfigService(config2
));
2278 TestCompletionCallback callback2
;
2279 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info
,
2280 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2282 EXPECT_EQ("foopy2:8080", info
.proxy_server().ToURI());
2285 // Test that when going from a configuration that required PAC to one
2286 // that does NOT, we unset the variable |should_use_proxy_resolver_|.
2287 TEST_F(ProxyServiceTest
, UpdateConfigFromPACToDirect
) {
2288 ProxyConfig config
= ProxyConfig::CreateAutoDetect();
2290 MockProxyConfigService
* config_service
= new MockProxyConfigService(config
);
2291 MockAsyncProxyResolver
* resolver
= new MockAsyncProxyResolver
;
2292 ProxyService
service(config_service
, resolver
, NULL
);
2297 TestCompletionCallback callback1
;
2298 int rv
= service
.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL
,
2299 &info1
, callback1
.callback(), NULL
, NULL
,
2301 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2303 // Check that nothing has been sent to the proxy resolver yet.
2304 ASSERT_EQ(0u, resolver
->pending_requests().size());
2306 // Successfully set the autodetect script.
2307 EXPECT_EQ(ProxyResolverScriptData::TYPE_AUTO_DETECT
,
2308 resolver
->pending_set_pac_script_request()->script_data()->type());
2309 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2311 // Complete the pending request.
2312 ASSERT_EQ(1u, resolver
->pending_requests().size());
2313 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2314 resolver
->pending_requests()[0]->CompleteNow(OK
);
2316 // Verify that request ran as expected.
2317 EXPECT_EQ(OK
, callback1
.WaitForResult());
2318 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2320 // Force the ProxyService to pull down a new proxy configuration.
2321 // (Even though the configuration isn't old/bad).
2323 // This new configuration no longer has auto_detect set, so
2324 // requests should complete synchronously now as direct-connect.
2325 config_service
->SetConfig(ProxyConfig::CreateDirect());
2327 // Start another request -- the effective configuration has changed.
2329 TestCompletionCallback callback2
;
2330 rv
= service
.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL
,
2331 &info2
, callback2
.callback(), NULL
, NULL
,
2335 EXPECT_TRUE(info2
.is_direct());
2338 TEST_F(ProxyServiceTest
, NetworkChangeTriggersPacRefetch
) {
2339 MockProxyConfigService
* config_service
=
2340 new MockProxyConfigService("http://foopy/proxy.pac");
2342 MockAsyncProxyResolverExpectsBytes
* resolver
=
2343 new MockAsyncProxyResolverExpectsBytes
;
2345 CapturingNetLog log
;
2347 ProxyService
service(config_service
, resolver
, &log
);
2349 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2350 service
.SetProxyScriptFetchers(fetcher
,
2351 new DoNothingDhcpProxyScriptFetcher());
2353 // Disable the "wait after IP address changes" hack, so this unit-test can
2354 // complete quickly.
2355 service
.set_stall_proxy_auto_config_delay(base::TimeDelta());
2360 TestCompletionCallback callback1
;
2361 int rv
= service
.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL
,
2362 &info1
, callback1
.callback(), NULL
, NULL
,
2364 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2366 // The first request should have triggered initial download of PAC script.
2367 EXPECT_TRUE(fetcher
->has_pending_request());
2368 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2370 // Nothing has been sent to the resolver yet.
2371 EXPECT_TRUE(resolver
->pending_requests().empty());
2373 // At this point the ProxyService should be waiting for the
2374 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2375 // PAC script download completion.
2376 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2378 // Now that the PAC script is downloaded, the request will have been sent to
2379 // the proxy resolver.
2380 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2381 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2382 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2384 ASSERT_EQ(1u, resolver
->pending_requests().size());
2385 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2387 // Complete the pending request.
2388 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2389 resolver
->pending_requests()[0]->CompleteNow(OK
);
2391 // Wait for completion callback, and verify that the request ran as expected.
2392 EXPECT_EQ(OK
, callback1
.WaitForResult());
2393 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2395 // Now simluate a change in the network. The ProxyConfigService is still
2396 // going to return the same PAC URL as before, but this URL needs to be
2397 // refetched on the new network.
2398 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
2399 base::MessageLoop::current()->RunUntilIdle(); // Notification happens async.
2401 // Start a second request.
2403 TestCompletionCallback callback2
;
2404 rv
= service
.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL
, &info2
,
2405 callback2
.callback(), NULL
, NULL
, BoundNetLog());
2406 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2408 // This second request should have triggered the re-download of the PAC
2409 // script (since we marked the network as having changed).
2410 EXPECT_TRUE(fetcher
->has_pending_request());
2411 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2413 // Nothing has been sent to the resolver yet.
2414 EXPECT_TRUE(resolver
->pending_requests().empty());
2416 // Simulate the PAC script fetch as having completed (this time with
2418 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript2
);
2420 // Now that the PAC script is downloaded, the second request will have been
2421 // sent to the proxy resolver.
2422 EXPECT_EQ(ASCIIToUTF16(kValidPacScript2
),
2423 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2424 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2426 ASSERT_EQ(1u, resolver
->pending_requests().size());
2427 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[0]->url());
2429 // Complete the pending second request.
2430 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
2431 resolver
->pending_requests()[0]->CompleteNow(OK
);
2433 // Wait for completion callback, and verify that the request ran as expected.
2434 EXPECT_EQ(OK
, callback2
.WaitForResult());
2435 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2437 // Check that the expected events were output to the log stream. In particular
2438 // PROXY_CONFIG_CHANGED should have only been emitted once (for the initial
2439 // setup), and NOT a second time when the IP address changed.
2440 CapturingNetLog::CapturedEntryList entries
;
2441 log
.GetEntries(&entries
);
2443 EXPECT_TRUE(LogContainsEntryWithType(entries
, 0,
2444 NetLog::TYPE_PROXY_CONFIG_CHANGED
));
2445 ASSERT_EQ(9u, entries
.size());
2446 for (size_t i
= 1; i
< entries
.size(); ++i
)
2447 EXPECT_NE(NetLog::TYPE_PROXY_CONFIG_CHANGED
, entries
[i
].type
);
2450 // This test verifies that the PAC script specified by the settings is
2451 // periodically polled for changes. Specifically, if the initial fetch fails due
2452 // to a network error, we will eventually re-configure the service to use the
2453 // script once it becomes available.
2454 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterFailure
) {
2455 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2457 ImmediatePollPolicy poll_policy
;
2458 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2460 MockProxyConfigService
* config_service
=
2461 new MockProxyConfigService("http://foopy/proxy.pac");
2463 MockAsyncProxyResolverExpectsBytes
* resolver
=
2464 new MockAsyncProxyResolverExpectsBytes
;
2466 ProxyService
service(config_service
, resolver
, NULL
);
2468 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2469 service
.SetProxyScriptFetchers(fetcher
,
2470 new DoNothingDhcpProxyScriptFetcher());
2475 TestCompletionCallback callback1
;
2476 int rv
= service
.ResolveProxy(
2477 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2478 NULL
, NULL
, BoundNetLog());
2479 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2481 // The first request should have triggered initial download of PAC script.
2482 EXPECT_TRUE(fetcher
->has_pending_request());
2483 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2485 // Nothing has been sent to the resolver yet.
2486 EXPECT_TRUE(resolver
->pending_requests().empty());
2488 // At this point the ProxyService should be waiting for the
2489 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2490 // PAC script download completion.
2492 // We simulate a failed download attempt, the proxy service should now
2493 // fall-back to DIRECT connections.
2494 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2496 ASSERT_TRUE(resolver
->pending_requests().empty());
2498 // Wait for completion callback, and verify it used DIRECT.
2499 EXPECT_EQ(OK
, callback1
.WaitForResult());
2500 EXPECT_TRUE(info1
.is_direct());
2502 // At this point we have initialized the proxy service using a PAC script,
2503 // however it failed and fell-back to DIRECT.
2505 // A background task to periodically re-check the PAC script for validity will
2506 // have been started. We will now wait for the next download attempt to start.
2508 // Note that we shouldn't have to wait long here, since our test enables a
2509 // special unit-test mode.
2510 fetcher
->WaitUntilFetch();
2512 ASSERT_TRUE(resolver
->pending_requests().empty());
2514 // Make sure that our background checker is trying to download the expected
2515 // PAC script (same one as before). This time we will simulate a successful
2516 // download of the script.
2517 EXPECT_TRUE(fetcher
->has_pending_request());
2518 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2519 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2521 base::MessageLoop::current()->RunUntilIdle();
2523 // Now that the PAC script is downloaded, it should be used to initialize the
2524 // ProxyResolver. Simulate a successful parse.
2525 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2526 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2527 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2529 // At this point the ProxyService should have re-configured itself to use the
2530 // PAC script (thereby recovering from the initial fetch failure). We will
2531 // verify that the next Resolve request uses the resolver rather than
2534 // Start a second request.
2536 TestCompletionCallback callback2
;
2537 rv
= service
.ResolveProxy(
2538 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2539 NULL
, NULL
, BoundNetLog());
2540 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2542 // Check that it was sent to the resolver.
2543 ASSERT_EQ(1u, resolver
->pending_requests().size());
2544 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[0]->url());
2546 // Complete the pending second request.
2547 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
2548 resolver
->pending_requests()[0]->CompleteNow(OK
);
2550 // Wait for completion callback, and verify that the request ran as expected.
2551 EXPECT_EQ(OK
, callback2
.WaitForResult());
2552 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2555 // This test verifies that the PAC script specified by the settings is
2556 // periodically polled for changes. Specifically, if the initial fetch succeeds,
2557 // however at a later time its *contents* change, we will eventually
2558 // re-configure the service to use the new script.
2559 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterContentChange
) {
2560 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2562 ImmediatePollPolicy poll_policy
;
2563 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2565 MockProxyConfigService
* config_service
=
2566 new MockProxyConfigService("http://foopy/proxy.pac");
2568 MockAsyncProxyResolverExpectsBytes
* resolver
=
2569 new MockAsyncProxyResolverExpectsBytes
;
2571 ProxyService
service(config_service
, resolver
, NULL
);
2573 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2574 service
.SetProxyScriptFetchers(fetcher
,
2575 new DoNothingDhcpProxyScriptFetcher());
2580 TestCompletionCallback callback1
;
2581 int rv
= service
.ResolveProxy(
2582 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2583 NULL
, NULL
, BoundNetLog());
2584 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2586 // The first request should have triggered initial download of PAC script.
2587 EXPECT_TRUE(fetcher
->has_pending_request());
2588 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2590 // Nothing has been sent to the resolver yet.
2591 EXPECT_TRUE(resolver
->pending_requests().empty());
2593 // At this point the ProxyService should be waiting for the
2594 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2595 // PAC script download completion.
2596 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2598 // Now that the PAC script is downloaded, the request will have been sent to
2599 // the proxy resolver.
2600 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2601 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2602 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2604 ASSERT_EQ(1u, resolver
->pending_requests().size());
2605 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2607 // Complete the pending request.
2608 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2609 resolver
->pending_requests()[0]->CompleteNow(OK
);
2611 // Wait for completion callback, and verify that the request ran as expected.
2612 EXPECT_EQ(OK
, callback1
.WaitForResult());
2613 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2615 // At this point we have initialized the proxy service using a PAC script.
2617 // A background task to periodically re-check the PAC script for validity will
2618 // have been started. We will now wait for the next download attempt to start.
2620 // Note that we shouldn't have to wait long here, since our test enables a
2621 // special unit-test mode.
2622 fetcher
->WaitUntilFetch();
2624 ASSERT_TRUE(resolver
->pending_requests().empty());
2626 // Make sure that our background checker is trying to download the expected
2627 // PAC script (same one as before). This time we will simulate a successful
2628 // download of a DIFFERENT script.
2629 EXPECT_TRUE(fetcher
->has_pending_request());
2630 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2631 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript2
);
2633 base::MessageLoop::current()->RunUntilIdle();
2635 // Now that the PAC script is downloaded, it should be used to initialize the
2636 // ProxyResolver. Simulate a successful parse.
2637 EXPECT_EQ(ASCIIToUTF16(kValidPacScript2
),
2638 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2639 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2641 // At this point the ProxyService should have re-configured itself to use the
2644 // Start a second request.
2646 TestCompletionCallback callback2
;
2647 rv
= service
.ResolveProxy(
2648 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2649 NULL
, NULL
, BoundNetLog());
2650 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2652 // Check that it was sent to the resolver.
2653 ASSERT_EQ(1u, resolver
->pending_requests().size());
2654 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[0]->url());
2656 // Complete the pending second request.
2657 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
2658 resolver
->pending_requests()[0]->CompleteNow(OK
);
2660 // Wait for completion callback, and verify that the request ran as expected.
2661 EXPECT_EQ(OK
, callback2
.WaitForResult());
2662 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2665 // This test verifies that the PAC script specified by the settings is
2666 // periodically polled for changes. Specifically, if the initial fetch succeeds
2667 // and so does the next poll, however the contents of the downloaded script
2668 // have NOT changed, then we do not bother to re-initialize the proxy resolver.
2669 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterContentUnchanged
) {
2670 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2672 ImmediatePollPolicy poll_policy
;
2673 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2675 MockProxyConfigService
* config_service
=
2676 new MockProxyConfigService("http://foopy/proxy.pac");
2678 MockAsyncProxyResolverExpectsBytes
* resolver
=
2679 new MockAsyncProxyResolverExpectsBytes
;
2681 ProxyService
service(config_service
, resolver
, NULL
);
2683 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2684 service
.SetProxyScriptFetchers(fetcher
,
2685 new DoNothingDhcpProxyScriptFetcher());
2690 TestCompletionCallback callback1
;
2691 int rv
= service
.ResolveProxy(
2692 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2693 NULL
, NULL
, BoundNetLog());
2694 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2696 // The first request should have triggered initial download of PAC script.
2697 EXPECT_TRUE(fetcher
->has_pending_request());
2698 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2700 // Nothing has been sent to the resolver yet.
2701 EXPECT_TRUE(resolver
->pending_requests().empty());
2703 // At this point the ProxyService should be waiting for the
2704 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2705 // PAC script download completion.
2706 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2708 // Now that the PAC script is downloaded, the request will have been sent to
2709 // the proxy resolver.
2710 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2711 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2712 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2714 ASSERT_EQ(1u, resolver
->pending_requests().size());
2715 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2717 // Complete the pending request.
2718 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2719 resolver
->pending_requests()[0]->CompleteNow(OK
);
2721 // Wait for completion callback, and verify that the request ran as expected.
2722 EXPECT_EQ(OK
, callback1
.WaitForResult());
2723 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2725 // At this point we have initialized the proxy service using a PAC script.
2727 // A background task to periodically re-check the PAC script for validity will
2728 // have been started. We will now wait for the next download attempt to start.
2730 // Note that we shouldn't have to wait long here, since our test enables a
2731 // special unit-test mode.
2732 fetcher
->WaitUntilFetch();
2734 ASSERT_TRUE(resolver
->pending_requests().empty());
2736 // Make sure that our background checker is trying to download the expected
2737 // PAC script (same one as before). We will simulate the same response as
2738 // last time (i.e. the script is unchanged).
2739 EXPECT_TRUE(fetcher
->has_pending_request());
2740 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2741 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2743 base::MessageLoop::current()->RunUntilIdle();
2745 ASSERT_FALSE(resolver
->has_pending_set_pac_script_request());
2747 // At this point the ProxyService is still running the same PAC script as
2750 // Start a second request.
2752 TestCompletionCallback callback2
;
2753 rv
= service
.ResolveProxy(
2754 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2755 NULL
, NULL
, BoundNetLog());
2756 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2758 // Check that it was sent to the resolver.
2759 ASSERT_EQ(1u, resolver
->pending_requests().size());
2760 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[0]->url());
2762 // Complete the pending second request.
2763 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
2764 resolver
->pending_requests()[0]->CompleteNow(OK
);
2766 // Wait for completion callback, and verify that the request ran as expected.
2767 EXPECT_EQ(OK
, callback2
.WaitForResult());
2768 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
2771 // This test verifies that the PAC script specified by the settings is
2772 // periodically polled for changes. Specifically, if the initial fetch succeeds,
2773 // however at a later time it starts to fail, we should re-configure the
2774 // ProxyService to stop using that PAC script.
2775 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterSuccess
) {
2776 // Change the retry policy to wait a mere 1 ms before retrying, so the test
2778 ImmediatePollPolicy poll_policy
;
2779 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2781 MockProxyConfigService
* config_service
=
2782 new MockProxyConfigService("http://foopy/proxy.pac");
2784 MockAsyncProxyResolverExpectsBytes
* resolver
=
2785 new MockAsyncProxyResolverExpectsBytes
;
2787 ProxyService
service(config_service
, resolver
, NULL
);
2789 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2790 service
.SetProxyScriptFetchers(fetcher
,
2791 new DoNothingDhcpProxyScriptFetcher());
2796 TestCompletionCallback callback1
;
2797 int rv
= service
.ResolveProxy(
2798 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2799 NULL
, NULL
, BoundNetLog());
2800 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2802 // The first request should have triggered initial download of PAC script.
2803 EXPECT_TRUE(fetcher
->has_pending_request());
2804 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2806 // Nothing has been sent to the resolver yet.
2807 EXPECT_TRUE(resolver
->pending_requests().empty());
2809 // At this point the ProxyService should be waiting for the
2810 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2811 // PAC script download completion.
2812 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2814 // Now that the PAC script is downloaded, the request will have been sent to
2815 // the proxy resolver.
2816 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2817 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2818 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2820 ASSERT_EQ(1u, resolver
->pending_requests().size());
2821 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2823 // Complete the pending request.
2824 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2825 resolver
->pending_requests()[0]->CompleteNow(OK
);
2827 // Wait for completion callback, and verify that the request ran as expected.
2828 EXPECT_EQ(OK
, callback1
.WaitForResult());
2829 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2831 // At this point we have initialized the proxy service using a PAC script.
2833 // A background task to periodically re-check the PAC script for validity will
2834 // have been started. We will now wait for the next download attempt to start.
2836 // Note that we shouldn't have to wait long here, since our test enables a
2837 // special unit-test mode.
2838 fetcher
->WaitUntilFetch();
2840 ASSERT_TRUE(resolver
->pending_requests().empty());
2842 // Make sure that our background checker is trying to download the expected
2843 // PAC script (same one as before). This time we will simulate a failure
2844 // to download the script.
2845 EXPECT_TRUE(fetcher
->has_pending_request());
2846 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2847 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
2849 base::MessageLoop::current()->RunUntilIdle();
2851 // At this point the ProxyService should have re-configured itself to use
2852 // DIRECT connections rather than the given proxy resolver.
2854 // Start a second request.
2856 TestCompletionCallback callback2
;
2857 rv
= service
.ResolveProxy(
2858 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2859 NULL
, NULL
, BoundNetLog());
2861 EXPECT_TRUE(info2
.is_direct());
2864 // Tests that the code which decides at what times to poll the PAC
2865 // script follows the expected policy.
2866 TEST_F(ProxyServiceTest
, PACScriptPollingPolicy
) {
2867 // Retrieve the internal polling policy implementation used by ProxyService.
2868 scoped_ptr
<ProxyService::PacPollPolicy
> policy
=
2869 ProxyService::CreateDefaultPacPollPolicy();
2872 ProxyService::PacPollPolicy::Mode mode
;
2873 const base::TimeDelta initial_delay
= base::TimeDelta::FromMilliseconds(-1);
2874 base::TimeDelta delay
= initial_delay
;
2876 // --------------------------------------------------
2877 // Test the poll sequence in response to a failure.
2878 // --------------------------------------------------
2879 error
= ERR_NAME_NOT_RESOLVED
;
2882 mode
= policy
->GetNextDelay(error
, initial_delay
, &delay
);
2883 EXPECT_EQ(8, delay
.InSeconds());
2884 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_USE_TIMER
, mode
);
2887 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2888 EXPECT_EQ(32, delay
.InSeconds());
2889 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2892 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2893 EXPECT_EQ(120, delay
.InSeconds());
2894 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2897 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2898 EXPECT_EQ(14400, delay
.InSeconds());
2899 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2902 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2903 EXPECT_EQ(14400, delay
.InSeconds());
2904 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2906 // --------------------------------------------------
2907 // Test the poll sequence in response to a success.
2908 // --------------------------------------------------
2912 mode
= policy
->GetNextDelay(error
, initial_delay
, &delay
);
2913 EXPECT_EQ(43200, delay
.InSeconds());
2914 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2917 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2918 EXPECT_EQ(43200, delay
.InSeconds());
2919 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2922 mode
= policy
->GetNextDelay(error
, delay
, &delay
);
2923 EXPECT_EQ(43200, delay
.InSeconds());
2924 EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY
, mode
);
2927 // This tests the polling of the PAC script. Specifically, it tests that
2928 // polling occurs in response to user activity.
2929 TEST_F(ProxyServiceTest
, PACScriptRefetchAfterActivity
) {
2930 ImmediateAfterActivityPollPolicy poll_policy
;
2931 ProxyService::set_pac_script_poll_policy(&poll_policy
);
2933 MockProxyConfigService
* config_service
=
2934 new MockProxyConfigService("http://foopy/proxy.pac");
2936 MockAsyncProxyResolverExpectsBytes
* resolver
=
2937 new MockAsyncProxyResolverExpectsBytes
;
2939 ProxyService
service(config_service
, resolver
, NULL
);
2941 MockProxyScriptFetcher
* fetcher
= new MockProxyScriptFetcher
;
2942 service
.SetProxyScriptFetchers(fetcher
,
2943 new DoNothingDhcpProxyScriptFetcher());
2948 TestCompletionCallback callback1
;
2949 int rv
= service
.ResolveProxy(
2950 GURL("http://request1"), net::LOAD_NORMAL
, &info1
, callback1
.callback(),
2951 NULL
, NULL
, BoundNetLog());
2952 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2954 // The first request should have triggered initial download of PAC script.
2955 EXPECT_TRUE(fetcher
->has_pending_request());
2956 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
2958 // Nothing has been sent to the resolver yet.
2959 EXPECT_TRUE(resolver
->pending_requests().empty());
2961 // At this point the ProxyService should be waiting for the
2962 // ProxyScriptFetcher to invoke its completion callback, notifying it of
2963 // PAC script download completion.
2964 fetcher
->NotifyFetchCompletion(OK
, kValidPacScript1
);
2966 // Now that the PAC script is downloaded, the request will have been sent to
2967 // the proxy resolver.
2968 EXPECT_EQ(ASCIIToUTF16(kValidPacScript1
),
2969 resolver
->pending_set_pac_script_request()->script_data()->utf16());
2970 resolver
->pending_set_pac_script_request()->CompleteNow(OK
);
2972 ASSERT_EQ(1u, resolver
->pending_requests().size());
2973 EXPECT_EQ(GURL("http://request1"), resolver
->pending_requests()[0]->url());
2975 // Complete the pending request.
2976 resolver
->pending_requests()[0]->results()->UseNamedProxy("request1:80");
2977 resolver
->pending_requests()[0]->CompleteNow(OK
);
2979 // Wait for completion callback, and verify that the request ran as expected.
2980 EXPECT_EQ(OK
, callback1
.WaitForResult());
2981 EXPECT_EQ("request1:80", info1
.proxy_server().ToURI());
2983 // At this point we have initialized the proxy service using a PAC script.
2984 // Our PAC poller is set to update ONLY in response to network activity,
2985 // (i.e. another call to ResolveProxy()).
2987 ASSERT_FALSE(fetcher
->has_pending_request());
2988 ASSERT_TRUE(resolver
->pending_requests().empty());
2990 // Start a second request.
2992 TestCompletionCallback callback2
;
2993 rv
= service
.ResolveProxy(
2994 GURL("http://request2"), net::LOAD_NORMAL
, &info2
, callback2
.callback(),
2995 NULL
, NULL
, BoundNetLog());
2996 EXPECT_EQ(ERR_IO_PENDING
, rv
);
2998 // This request should have sent work to the resolver; complete it.
2999 ASSERT_EQ(1u, resolver
->pending_requests().size());
3000 EXPECT_EQ(GURL("http://request2"), resolver
->pending_requests()[0]->url());
3001 resolver
->pending_requests()[0]->results()->UseNamedProxy("request2:80");
3002 resolver
->pending_requests()[0]->CompleteNow(OK
);
3004 EXPECT_EQ(OK
, callback2
.WaitForResult());
3005 EXPECT_EQ("request2:80", info2
.proxy_server().ToURI());
3007 // In response to getting that resolve request, the poller should have
3008 // started the next poll, and made it as far as to request the download.
3010 EXPECT_TRUE(fetcher
->has_pending_request());
3011 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher
->pending_request_url());
3013 // This time we will fail the download, to simulate a PAC script change.
3014 fetcher
->NotifyFetchCompletion(ERR_FAILED
, std::string());
3016 // Drain the message loop, so ProxyService is notified of the change
3017 // and has a chance to re-configure itself.
3018 base::MessageLoop::current()->RunUntilIdle();
3020 // Start a third request -- this time we expect to get a direct connection
3021 // since the PAC script poller experienced a failure.
3023 TestCompletionCallback callback3
;
3024 rv
= service
.ResolveProxy(
3025 GURL("http://request3"), net::LOAD_NORMAL
, &info3
, callback3
.callback(),
3026 NULL
, NULL
, BoundNetLog());
3028 EXPECT_TRUE(info3
.is_direct());