summaryrefslogtreecommitdiffstats
path: root/net/proxy
diff options
context:
space:
mode:
authorbattre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-06 09:31:56 +0000
committerbattre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-06 09:31:56 +0000
commit1df57a559a81831936cf531976f7ad4609840e23 (patch)
tree1c27084cbbee0e96dae88273d28121028f526c4f /net/proxy
parenta8e64523fca941d1f0bd1806e6b567fb0b62ed8a (diff)
downloadchromium_src-1df57a559a81831936cf531976f7ad4609840e23.zip
chromium_src-1df57a559a81831936cf531976f7ad4609840e23.tar.gz
chromium_src-1df57a559a81831936cf531976f7ad4609840e23.tar.bz2
Implemented unit tests for ProxyService and fixed a bug
BUG=81368 TEST=execute net_unittests --gtest_filter='ProxyServiceTest.*' Review URL: http://codereview.chromium.org/6932041 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84422 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/proxy')
-rw-r--r--net/proxy/init_proxy_resolver.cc6
-rw-r--r--net/proxy/init_proxy_resolver.h6
-rw-r--r--net/proxy/proxy_service_unittest.cc237
3 files changed, 247 insertions, 2 deletions
diff --git a/net/proxy/init_proxy_resolver.cc b/net/proxy/init_proxy_resolver.cc
index 9091168..d9d55ea 100644
--- a/net/proxy/init_proxy_resolver.cc
+++ b/net/proxy/init_proxy_resolver.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -39,6 +39,7 @@ InitProxyResolver::InitProxyResolver(ProxyResolver* resolver,
this, &InitProxyResolver::OnIOCompletion)),
user_callback_(NULL),
current_pac_url_index_(0u),
+ pac_mandatory_(false),
next_state_(STATE_NONE),
net_log_(BoundNetLog::Make(
net_log, NetLog::SOURCE_INIT_PROXY_RESOLVER)),
@@ -67,6 +68,8 @@ int InitProxyResolver::Init(const ProxyConfig& config,
effective_config_ = effective_config;
+ pac_mandatory_ = config.pac_mandatory();
+
pac_urls_ = BuildPacUrlsFallbackList(config);
DCHECK(!pac_urls_.empty());
@@ -243,6 +246,7 @@ int InitProxyResolver::DoSetPacScriptComplete(int result) {
} else {
*effective_config_ =
ProxyConfig::CreateFromCustomPacURL(current_pac_url().url);
+ effective_config_->set_pac_mandatory(pac_mandatory_);
}
}
diff --git a/net/proxy/init_proxy_resolver.h b/net/proxy/init_proxy_resolver.h
index fd656427..67cf1cb 100644
--- a/net/proxy/init_proxy_resolver.h
+++ b/net/proxy/init_proxy_resolver.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -126,6 +126,10 @@ class InitProxyResolver {
// Filled when the PAC script fetch completes.
string16 pac_script_;
+ // Flag indicating whether the caller requested a mandatory pac script
+ // (i.e. fallback to direct connections are prohibited).
+ bool pac_mandatory_;
+
UrlList pac_urls_;
State next_state_;
diff --git a/net/proxy/proxy_service_unittest.cc b/net/proxy/proxy_service_unittest.cc
index 4e6d38a..f5ae3d7 100644
--- a/net/proxy/proxy_service_unittest.cc
+++ b/net/proxy/proxy_service_unittest.cc
@@ -391,6 +391,155 @@ TEST(ProxyServiceTest, ProxyResolverFails) {
EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
}
+TEST(ProxyServiceTest, ProxyScriptFetcherFailsDownloadingMandatoryPac) {
+ // Test what happens when the ProxyScriptResolver fails to download a
+ // mandatory PAC script.
+
+ ProxyConfig config(
+ ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
+ config.set_pac_mandatory(true);
+
+ MockProxyConfigService* config_service = new MockProxyConfigService(config);
+
+ MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+ ProxyService service(config_service, resolver, NULL);
+
+ // Start first resolve request.
+ GURL url("http://www.google.com/");
+ ProxyInfo info;
+ TestCompletionCallback callback1;
+ int rv = service.ResolveProxy(url, &info, &callback1, NULL, BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+ resolver->pending_set_pac_script_request()->script_data()->url());
+ resolver->pending_set_pac_script_request()->CompleteNow(ERR_FAILED);
+
+ ASSERT_EQ(0u, resolver->pending_requests().size());
+
+ // As the proxy resolver failed the request and is configured for a mandatory
+ // PAC script, ProxyService must not implicitly fall-back to DIRECT.
+ EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
+ callback1.WaitForResult());
+ EXPECT_FALSE(info.is_direct());
+
+ // As the proxy resolver failed the request and is configured for a mandatory
+ // PAC script, ProxyService must not implicitly fall-back to DIRECT.
+ TestCompletionCallback callback2;
+ rv = service.ResolveProxy(url, &info, &callback2, NULL, BoundNetLog());
+ EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, rv);
+ EXPECT_FALSE(info.is_direct());
+}
+
+TEST(ProxyServiceTest, ProxyResolverFailsParsingJavaScriptMandatoryPac) {
+ // Test what happens when the ProxyResolver fails that is configured to use a
+ // mandatory PAC script. The download of the PAC script has already
+ // succeeded but the PAC script contains no valid javascript.
+
+ ProxyConfig config(
+ ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
+ config.set_pac_mandatory(true);
+
+ MockProxyConfigService* config_service = new MockProxyConfigService(config);
+
+ MockAsyncProxyResolverExpectsBytes* resolver =
+ new MockAsyncProxyResolverExpectsBytes;
+
+ ProxyService service(config_service, resolver, NULL);
+
+ MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+ service.SetProxyScriptFetcher(fetcher);
+
+ // Start resolve request.
+ GURL url("http://www.google.com/");
+ ProxyInfo info;
+ TestCompletionCallback callback;
+ int rv = service.ResolveProxy(url, &info, &callback, NULL, BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ // Check that nothing has been sent to the proxy resolver yet.
+ ASSERT_EQ(0u, resolver->pending_requests().size());
+
+ // Downloading the PAC script succeeds.
+ EXPECT_TRUE(fetcher->has_pending_request());
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+ fetcher->NotifyFetchCompletion(OK, "invalid-script-contents");
+
+ // Simulate a parse error.
+ EXPECT_EQ(ASCIIToUTF16("invalid-script-contents"),
+ resolver->pending_set_pac_script_request()->script_data()->utf16());
+ resolver->pending_set_pac_script_request()->CompleteNow(
+ ERR_PAC_SCRIPT_FAILED);
+
+ EXPECT_FALSE(fetcher->has_pending_request());
+ ASSERT_EQ(0u, resolver->pending_requests().size());
+
+ // As the proxy resolver failed the request and is configured for a mandatory
+ // PAC script, ProxyService must not implicitly fall-back to DIRECT.
+ EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
+ callback.WaitForResult());
+ EXPECT_FALSE(info.is_direct());
+}
+
+TEST(ProxyServiceTest, ProxyResolverFailsInJavaScriptMandatoryPac) {
+ // Test what happens when the ProxyResolver fails that is configured to use a
+ // mandatory PAC script. The download and setting of the PAC script have
+ // already succeeded, so this corresponds with a javascript runtime error
+ // while calling FindProxyForURL().
+
+ ProxyConfig config(
+ ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
+ config.set_pac_mandatory(true);
+
+ MockProxyConfigService* config_service = new MockProxyConfigService(config);
+
+ MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+ ProxyService service(config_service, resolver, NULL);
+
+ // Start first resolve request.
+ GURL url("http://www.google.com/");
+ ProxyInfo info;
+ TestCompletionCallback callback1;
+ int rv = service.ResolveProxy(url, &info, &callback1, NULL, BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+ resolver->pending_set_pac_script_request()->script_data()->url());
+ resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+ ASSERT_EQ(1u, resolver->pending_requests().size());
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+ // Fail the first resolve request in MockAsyncProxyResolver.
+ resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
+
+ // As the proxy resolver failed the request and is configured for a mandatory
+ // PAC script, ProxyService must not implicitly fall-back to DIRECT.
+ EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
+ callback1.WaitForResult());
+ EXPECT_FALSE(info.is_direct());
+
+ // The second resolve request will try to run through the proxy resolver,
+ // regardless of whether the first request failed in it.
+ TestCompletionCallback callback2;
+ rv = service.ResolveProxy(url, &info, &callback2, NULL, BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ ASSERT_EQ(1u, resolver->pending_requests().size());
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+ // This time we will have the resolver succeed (perhaps the PAC script has
+ // a dependency on the current time).
+ resolver->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
+ resolver->pending_requests()[0]->CompleteNow(OK);
+
+ EXPECT_EQ(OK, callback2.WaitForResult());
+ EXPECT_FALSE(info.is_direct());
+ EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
+}
+
TEST(ProxyServiceTest, ProxyFallback) {
// Test what happens when we specify multiple proxy servers and some of them
// are bad.
@@ -719,6 +868,94 @@ TEST(ProxyServiceTest, ProxyFallback_BadConfig) {
EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI());
}
+TEST(ProxyServiceTest, ProxyFallback_BadConfigMandatory) {
+ // Test proxy failover when the configuration is bad.
+
+ ProxyConfig config(
+ ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
+
+ config.set_pac_mandatory(true);
+ MockProxyConfigService* config_service = new MockProxyConfigService(config);
+
+ MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+ ProxyService service(config_service, resolver, NULL);
+
+ GURL url("http://www.google.com/");
+
+ // Get the proxy information.
+ ProxyInfo info;
+ TestCompletionCallback callback1;
+ int rv = service.ResolveProxy(url, &info, &callback1, NULL, BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+ resolver->pending_set_pac_script_request()->script_data()->url());
+ resolver->pending_set_pac_script_request()->CompleteNow(OK);
+ ASSERT_EQ(1u, resolver->pending_requests().size());
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+ resolver->pending_requests()[0]->results()->UseNamedProxy(
+ "foopy1:8080;foopy2:9090");
+ resolver->pending_requests()[0]->CompleteNow(OK);
+
+ // The first item is valid.
+ EXPECT_EQ(OK, callback1.WaitForResult());
+ EXPECT_FALSE(info.is_direct());
+ EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
+
+ // Fake a proxy error.
+ TestCompletionCallback callback2;
+ rv = service.ReconsiderProxyAfterError(url, &info, &callback2, NULL,
+ BoundNetLog());
+ EXPECT_EQ(OK, rv);
+
+ // The first proxy is ignored, and the second one is selected.
+ EXPECT_FALSE(info.is_direct());
+ EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
+
+ // Fake a PAC failure.
+ ProxyInfo info2;
+ TestCompletionCallback callback3;
+ rv = service.ResolveProxy(url, &info2, &callback3, NULL, BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ ASSERT_EQ(1u, resolver->pending_requests().size());
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+ // This simulates a javascript runtime error in the PAC script.
+ resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
+
+ // Although the resolver failed, the ProxyService will NOT fall-back
+ // to a DIRECT connection as it is configured as mandatory.
+ EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
+ callback3.WaitForResult());
+ EXPECT_FALSE(info2.is_direct());
+ EXPECT_TRUE(info2.is_empty());
+
+ // The PAC script will work properly next time and successfully return a
+ // proxy list. Since we have not marked the configuration as bad, it should
+ // "just work" the next time we call it.
+ ProxyInfo info3;
+ TestCompletionCallback callback4;
+ rv = service.ReconsiderProxyAfterError(url, &info3, &callback4, NULL,
+ BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ ASSERT_EQ(1u, resolver->pending_requests().size());
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+ resolver->pending_requests()[0]->results()->UseNamedProxy(
+ "foopy1:8080;foopy2:9090");
+ resolver->pending_requests()[0]->CompleteNow(OK);
+
+ // The first proxy is not there since the it was added to the bad proxies
+ // list by the earlier ReconsiderProxyAfterError().
+ EXPECT_EQ(OK, callback4.WaitForResult());
+ EXPECT_FALSE(info3.is_direct());
+ EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI());
+}
+
TEST(ProxyServiceTest, ProxyBypassList) {
// Test that the proxy bypass rules are consulted.