diff options
author | hamaji@chromium.org <hamaji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-06 12:52:19 +0000 |
---|---|---|
committer | hamaji@chromium.org <hamaji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-06 12:52:19 +0000 |
commit | c6efbc6788d6b4f030e304dc0657ba403078493e (patch) | |
tree | 62b95b91b76ae8993a0f8466ba1d19b1159f154c /net | |
parent | ffc53c99a52e01525980d50f180a0eb8c96eb688 (diff) | |
download | chromium_src-c6efbc6788d6b4f030e304dc0657ba403078493e.zip chromium_src-c6efbc6788d6b4f030e304dc0657ba403078493e.tar.gz chromium_src-c6efbc6788d6b4f030e304dc0657ba403078493e.tar.bz2 |
Reverting r22603, which reverts r22591. It seems that the revert doesn't help...
TEST=none
BUG=none
TBR=eroman
Review URL: http://codereview.chromium.org/164057
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@22605 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/net.gyp | 1 | ||||
-rw-r--r-- | net/proxy/mock_proxy_resolver.h | 1375 | ||||
-rw-r--r-- | net/proxy/proxy_service_unittest.cc | 151 |
3 files changed, 10 insertions, 1517 deletions
diff --git a/net/net.gyp b/net/net.gyp index 3bba793..cc993c7 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -498,6 +498,7 @@ 'http/http_util_unittest.cc', 'http/http_vary_data_unittest.cc', 'proxy/init_proxy_resolver_unittest.cc', + 'proxy/mock_proxy_resolver.h', 'proxy/proxy_config_service_linux_unittest.cc', 'proxy/proxy_config_service_win_unittest.cc', 'proxy/proxy_config_unittest.cc', diff --git a/net/proxy/mock_proxy_resolver.h b/net/proxy/mock_proxy_resolver.h index 0dac40b..0b1e8a5 100644 --- a/net/proxy/mock_proxy_resolver.h +++ b/net/proxy/mock_proxy_resolver.h @@ -1,40 +1,18 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 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. +#ifndef NET_PROXY_MOCK_PROXY_RESOLVER_H_ +#define NET_PROXY_MOCK_PROXY_RESOLVER_H_ + #include <vector> #include "base/logging.h" -#include "base/string_util.h" #include "googleurl/src/gurl.h" #include "net/base/net_errors.h" -#include "net/base/test_completion_callback.h" -#include "net/proxy/proxy_config_service.h" #include "net/proxy/proxy_resolver.h" -#include "net/proxy/proxy_script_fetcher.h" -#include "net/proxy/proxy_service.h" -#include "testing/gtest/include/gtest/gtest.h" -// TODO(eroman): Write a test which exercises -// ProxyService::SuspendAllPendingRequests(). namespace net { -namespace { - -class MockProxyConfigService: public ProxyConfigService { - public: - MockProxyConfigService() {} // Direct connect. - explicit MockProxyConfigService(const ProxyConfig& pc) : config(pc) {} - explicit MockProxyConfigService(const std::string& pac_url) { - config.pac_url = GURL(pac_url); - } - - virtual int GetProxyConfig(ProxyConfig* results) { - *results = config; - return OK; - } - - ProxyConfig config; -}; // Asynchronous mock proxy resolver. All requests complete asynchronously, // user must call Request::CompleteNow() on a pending request to signal it. @@ -133,7 +111,7 @@ class MockAsyncProxyResolverBase : public ProxyResolver { virtual int SetPacScript(const GURL& pac_url, const std::string& pac_bytes, CompletionCallback* callback) { - EXPECT_EQ(NULL, pending_set_pac_script_request_.get()); + DCHECK(!pending_set_pac_script_request_.get()); pending_set_pac_script_request_.reset( new SetPacScriptRequest(this, pac_url, pac_bytes, callback)); // Finished when user calls SetPacScriptRequest::CompleteNow(). @@ -160,7 +138,7 @@ class MockAsyncProxyResolverBase : public ProxyResolver { } void RemovePendingSetPacScriptRequest(SetPacScriptRequest* request) { - EXPECT_EQ(request, pending_set_pac_script_request()); + DCHECK_EQ(request, pending_set_pac_script_request()); pending_set_pac_script_request_.reset(); } @@ -186,1343 +164,6 @@ class MockAsyncProxyResolverExpectsBytes : public MockAsyncProxyResolverBase { : MockAsyncProxyResolverBase(true /*expects_pac_bytes*/) {} }; -} // namespace - -// A mock ProxyScriptFetcher. No result will be returned to the fetch client -// until we call NotifyFetchCompletion() to set the results. -class MockProxyScriptFetcher : public ProxyScriptFetcher { - public: - MockProxyScriptFetcher() - : pending_request_callback_(NULL), pending_request_bytes_(NULL) { - } - - // ProxyScriptFetcher implementation. - virtual int Fetch(const GURL& url, - std::string* bytes, - CompletionCallback* callback) { - DCHECK(!has_pending_request()); - - // Save the caller's information, and have them wait. - pending_request_url_ = url; - pending_request_callback_ = callback; - pending_request_bytes_ = bytes; - return ERR_IO_PENDING; - } - - void NotifyFetchCompletion(int result, const std::string& bytes) { - DCHECK(has_pending_request()); - *pending_request_bytes_ = bytes; - CompletionCallback* callback = pending_request_callback_; - pending_request_callback_ = NULL; - callback->Run(result); - } - - virtual void Cancel() {} - - const GURL& pending_request_url() const { - return pending_request_url_; - } - - bool has_pending_request() const { - return pending_request_callback_ != NULL; - } - - private: - GURL pending_request_url_; - CompletionCallback* pending_request_callback_; - std::string* pending_request_bytes_; -}; - -TEST(ProxyServiceTest, Direct) { - MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; - ProxyService service(new MockProxyConfigService, resolver); - - GURL url("http://www.google.com/"); - - ProxyInfo info; - TestCompletionCallback callback; - int rv = service.ResolveProxy(url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_TRUE(resolver->pending_requests().empty()); - - EXPECT_TRUE(info.is_direct()); -} - -TEST(ProxyServiceTest, PAC) { - MockProxyConfigService* config_service = - new MockProxyConfigService("http://foopy/proxy.pac"); - - MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; - - ProxyService service(config_service, resolver); - - GURL url("http://www.google.com/"); - - ProxyInfo info; - TestCompletionCallback callback; - int rv = service.ResolveProxy(url, &info, &callback, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - EXPECT_EQ(GURL("http://foopy/proxy.pac"), - resolver->pending_set_pac_script_request()->pac_url()); - resolver->pending_set_pac_script_request()->CompleteNow(OK); - - ASSERT_EQ(1u, resolver->pending_requests().size()); - EXPECT_EQ(url, resolver->pending_requests()[0]->url()); - - // Set the result in proxy resolver. - resolver->pending_requests()[0]->results()->UseNamedProxy("foopy"); - resolver->pending_requests()[0]->CompleteNow(OK); - - EXPECT_EQ(OK, callback.WaitForResult()); - EXPECT_FALSE(info.is_direct()); - EXPECT_EQ("foopy:80", info.proxy_server().ToURI()); -} - -// Test that the proxy resolver does not see the URL's username/password -// or its reference section. -TEST(ProxyServiceTest, PAC_NoIdentityOrHash) { - MockProxyConfigService* config_service = - new MockProxyConfigService("http://foopy/proxy.pac"); - - MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; - - ProxyService service(config_service, resolver); - - GURL url("http://username:password@www.google.com/?ref#hash#hash"); - - ProxyInfo info; - TestCompletionCallback callback; - int rv = service.ResolveProxy(url, &info, &callback, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - EXPECT_EQ(GURL("http://foopy/proxy.pac"), - resolver->pending_set_pac_script_request()->pac_url()); - resolver->pending_set_pac_script_request()->CompleteNow(OK); - - ASSERT_EQ(1u, resolver->pending_requests().size()); - // The URL should have been simplified, stripping the username/password/hash. - EXPECT_EQ(GURL("http://www.google.com/?ref"), - resolver->pending_requests()[0]->url()); - - // We end here without ever completing the request -- destruction of - // ProxyService will cancel the outstanding request. -} - -TEST(ProxyServiceTest, PAC_FailoverToDirect) { - MockProxyConfigService* config_service = - new MockProxyConfigService("http://foopy/proxy.pac"); - MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; - - ProxyService service(config_service, resolver); - - GURL url("http://www.google.com/"); - - ProxyInfo info; - TestCompletionCallback callback1; - int rv = service.ResolveProxy(url, &info, &callback1, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - EXPECT_EQ(GURL("http://foopy/proxy.pac"), - resolver->pending_set_pac_script_request()->pac_url()); - resolver->pending_set_pac_script_request()->CompleteNow(OK); - - ASSERT_EQ(1u, resolver->pending_requests().size()); - EXPECT_EQ(url, resolver->pending_requests()[0]->url()); - - // Set the result in proxy resolver. - resolver->pending_requests()[0]->results()->UseNamedProxy("foopy:8080"); - resolver->pending_requests()[0]->CompleteNow(OK); - - EXPECT_EQ(OK, callback1.WaitForResult()); - EXPECT_FALSE(info.is_direct()); - EXPECT_EQ("foopy:8080", info.proxy_server().ToURI()); - - // Now, imagine that connecting to foopy:8080 fails. - TestCompletionCallback callback2; - rv = service.ReconsiderProxyAfterError(url, &info, &callback2, NULL); - EXPECT_EQ(OK, rv); - EXPECT_TRUE(info.is_direct()); -} - -TEST(ProxyServiceTest, ProxyResolverFails) { - // Test what happens when the ProxyResolver fails (this could represent - // a failure to download the PAC script in the case of ProxyResolvers which - // do the fetch internally.) - // TODO(eroman): change this comment. - - MockProxyConfigService* config_service = - new MockProxyConfigService("http://foopy/proxy.pac"); - - MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; - - ProxyService service(config_service, resolver); - - // Start first resolve request. - GURL url("http://www.google.com/"); - ProxyInfo info; - TestCompletionCallback callback1; - int rv = service.ResolveProxy(url, &info, &callback1, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - EXPECT_EQ(GURL("http://foopy/proxy.pac"), - resolver->pending_set_pac_script_request()->pac_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); - - EXPECT_EQ(ERR_FAILED, callback1.WaitForResult()); - - // The second resolve request will automatically select direct connect, - // because it has cached the configuration as being bad. - TestCompletionCallback callback2; - rv = service.ResolveProxy(url, &info, &callback2, NULL); - EXPECT_EQ(OK, rv); - EXPECT_TRUE(info.is_direct()); - EXPECT_TRUE(resolver->pending_requests().empty()); - - // But, if that fails, then we should give the proxy config another shot - // since we have never tried it with this URL before. - TestCompletionCallback callback3; - rv = service.ReconsiderProxyAfterError(url, &info, &callback3, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - ASSERT_EQ(1u, resolver->pending_requests().size()); - EXPECT_EQ(url, resolver->pending_requests()[0]->url()); - - // Set the result in proxy resolver. - resolver->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080"); - resolver->pending_requests()[0]->CompleteNow(OK); - - EXPECT_EQ(OK, callback3.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. - - MockProxyConfigService* config_service = - new MockProxyConfigService("http://foopy/proxy.pac"); - - MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; - - ProxyService service(config_service, resolver); - - GURL url("http://www.google.com/"); - - // Get the proxy information. - ProxyInfo info; - TestCompletionCallback callback1; - int rv = service.ResolveProxy(url, &info, &callback1, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - EXPECT_EQ(GURL("http://foopy/proxy.pac"), - resolver->pending_set_pac_script_request()->pac_url()); - resolver->pending_set_pac_script_request()->CompleteNow(OK); - - ASSERT_EQ(1u, resolver->pending_requests().size()); - EXPECT_EQ(url, resolver->pending_requests()[0]->url()); - - // Set the result in proxy resolver. - 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 an error on the proxy. - TestCompletionCallback callback2; - rv = service.ReconsiderProxyAfterError(url, &info, &callback2, NULL); - EXPECT_EQ(OK, rv); - - // The second proxy should be specified. - EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI()); - - TestCompletionCallback callback3; - rv = service.ResolveProxy(url, &info, &callback3, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - ASSERT_EQ(1u, resolver->pending_requests().size()); - EXPECT_EQ(url, resolver->pending_requests()[0]->url()); - - // Set the result in proxy resolver -- the second result is already known - // to be bad. - resolver->pending_requests()[0]->results()->UseNamedProxy( - "foopy3:7070;foopy1:8080;foopy2:9090"); - resolver->pending_requests()[0]->CompleteNow(OK); - - EXPECT_EQ(OK, callback3.WaitForResult()); - EXPECT_FALSE(info.is_direct()); - EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI()); - - // We fake another error. It should now try the third one. - TestCompletionCallback callback4; - rv = service.ReconsiderProxyAfterError(url, &info, &callback4, NULL); - EXPECT_EQ(OK, rv); - EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI()); - - // Fake another error, the last proxy is gone, the list should now be empty. - TestCompletionCallback callback5; - rv = service.ReconsiderProxyAfterError(url, &info, &callback5, NULL); - EXPECT_EQ(OK, rv); // We try direct. - EXPECT_TRUE(info.is_direct()); - - // If it fails again, we don't have anything else to try. - TestCompletionCallback callback6; - rv = service.ReconsiderProxyAfterError(url, &info, &callback6, NULL); - EXPECT_EQ(ERR_FAILED, rv); - - // TODO(nsylvain): Test that the proxy can be retried after the delay. -} - -TEST(ProxyServiceTest, ProxyFallback_NewSettings) { - // Test proxy failover when new settings are available. - - MockProxyConfigService* config_service = - new MockProxyConfigService("http://foopy/proxy.pac"); - - MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; - - ProxyService service(config_service, resolver); - - GURL url("http://www.google.com/"); - - // Get the proxy information. - ProxyInfo info; - TestCompletionCallback callback1; - int rv = service.ResolveProxy(url, &info, &callback1, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - EXPECT_EQ(GURL("http://foopy/proxy.pac"), - resolver->pending_set_pac_script_request()->pac_url()); - resolver->pending_set_pac_script_request()->CompleteNow(OK); - - ASSERT_EQ(1u, resolver->pending_requests().size()); - EXPECT_EQ(url, resolver->pending_requests()[0]->url()); - - // Set the result in proxy resolver. - 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 an error on the proxy, and also a new configuration on the proxy. - config_service->config = ProxyConfig(); - config_service->config.pac_url = GURL("http://foopy-new/proxy.pac"); - - TestCompletionCallback callback2; - rv = service.ReconsiderProxyAfterError(url, &info, &callback2, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - EXPECT_EQ(GURL("http://foopy-new/proxy.pac"), - resolver->pending_set_pac_script_request()->pac_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 proxy is still there since the configuration changed. - EXPECT_EQ(OK, callback2.WaitForResult()); - EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); - - // We fake another error. It should now ignore the first one. - TestCompletionCallback callback3; - rv = service.ReconsiderProxyAfterError(url, &info, &callback3, NULL); - EXPECT_EQ(OK, rv); - EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI()); - - // We simulate a new configuration. - config_service->config = ProxyConfig(); - config_service->config.pac_url = GURL("http://foopy-new2/proxy.pac"); - - // We fake another error. It should go back to the first proxy. - TestCompletionCallback callback4; - rv = service.ReconsiderProxyAfterError(url, &info, &callback4, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - EXPECT_EQ(GURL("http://foopy-new2/proxy.pac"), - resolver->pending_set_pac_script_request()->pac_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); - - EXPECT_EQ(OK, callback4.WaitForResult()); - EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); -} - -TEST(ProxyServiceTest, ProxyFallback_BadConfig) { - // Test proxy failover when the configuration is bad. - - MockProxyConfigService* config_service = - new MockProxyConfigService("http://foopy/proxy.pac"); - - MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; - - ProxyService service(config_service, resolver); - - GURL url("http://www.google.com/"); - - // Get the proxy information. - ProxyInfo info; - TestCompletionCallback callback1; - int rv = service.ResolveProxy(url, &info, &callback1, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - EXPECT_EQ(GURL("http://foopy/proxy.pac"), - resolver->pending_set_pac_script_request()->pac_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); - 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); - 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]->CompleteNow(ERR_FAILED); - - // No proxy servers are returned. It's a direct connection. - EXPECT_EQ(ERR_FAILED, callback3.WaitForResult()); - EXPECT_TRUE(info2.is_direct()); - - // The PAC will now be fixed and will return a proxy server. - // It should also clear the list of bad proxies. - - // Try to resolve, it will still return "direct" because we have no reason - // to check the config since everything works. - ProxyInfo info3; - TestCompletionCallback callback4; - rv = service.ResolveProxy(url, &info3, &callback4, NULL); - EXPECT_EQ(OK, rv); - EXPECT_TRUE(info3.is_direct()); - - // But if the direct connection fails, we check if the ProxyInfo tried to - // resolve the proxy before, and if not (like in this case), we give the - // PAC another try. - TestCompletionCallback callback5; - rv = service.ReconsiderProxyAfterError(url, &info3, &callback5, NULL); - 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 still there since the list of bad proxies got cleared. - EXPECT_EQ(OK, callback5.WaitForResult()); - EXPECT_FALSE(info3.is_direct()); - EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI()); -} - -TEST(ProxyServiceTest, ProxyBypassList) { - // Test what happens when a proxy bypass list is specified. - - ProxyInfo info; - ProxyConfig config; - config.proxy_rules.ParseFromString("foopy1:8080;foopy2:9090"); - config.auto_detect = false; - config.proxy_bypass_local_names = true; - - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver()); - GURL url("http://www.google.com/"); - // Get the proxy information. - TestCompletionCallback callback; - int rv = service.ResolveProxy(url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_FALSE(info.is_direct()); - } - - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver()); - GURL test_url("http://local"); - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_TRUE(info.is_direct()); - } - - config.proxy_bypass.clear(); - config.proxy_bypass.push_back("*.org"); - config.proxy_bypass_local_names = true; - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - GURL test_url("http://www.webkit.org"); - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_TRUE(info.is_direct()); - } - - config.proxy_bypass.clear(); - config.proxy_bypass.push_back("*.org"); - config.proxy_bypass.push_back("7*"); - config.proxy_bypass_local_names = true; - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - GURL test_url("http://74.125.19.147"); - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_TRUE(info.is_direct()); - } - - config.proxy_bypass.clear(); - config.proxy_bypass.push_back("*.org"); - config.proxy_bypass_local_names = true; - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - GURL test_url("http://www.msn.com"); - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_FALSE(info.is_direct()); - } - - config.proxy_bypass.clear(); - config.proxy_bypass.push_back("*.MSN.COM"); - config.proxy_bypass_local_names = true; - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - GURL test_url("http://www.msnbc.msn.com"); - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_TRUE(info.is_direct()); - } - - config.proxy_bypass.clear(); - config.proxy_bypass.push_back("*.msn.com"); - config.proxy_bypass_local_names = true; - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - GURL test_url("HTTP://WWW.MSNBC.MSN.COM"); - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_TRUE(info.is_direct()); - } -} - -TEST(ProxyServiceTest, ProxyBypassListWithPorts) { - // Test port specification in bypass list entries. - ProxyInfo info; - ProxyConfig config; - config.proxy_rules.ParseFromString("foopy1:8080;foopy2:9090"); - config.auto_detect = false; - config.proxy_bypass_local_names = false; - - config.proxy_bypass.clear(); - config.proxy_bypass.push_back("*.example.com:99"); - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - { - GURL test_url("http://www.example.com:99"); - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_TRUE(info.is_direct()); - } - { - GURL test_url("http://www.example.com:100"); - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_FALSE(info.is_direct()); - } - { - GURL test_url("http://www.example.com"); - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_FALSE(info.is_direct()); - } - } - - config.proxy_bypass.clear(); - config.proxy_bypass.push_back("*.example.com:80"); - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - GURL test_url("http://www.example.com"); - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_TRUE(info.is_direct()); - } - - config.proxy_bypass.clear(); - config.proxy_bypass.push_back("*.example.com"); - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - GURL test_url("http://www.example.com:99"); - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_TRUE(info.is_direct()); - } - - // IPv6 with port. - config.proxy_bypass.clear(); - config.proxy_bypass.push_back("[3ffe:2a00:100:7031::1]:99"); - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - { - GURL test_url("http://[3ffe:2a00:100:7031::1]:99/"); - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_TRUE(info.is_direct()); - } - { - GURL test_url("http://[3ffe:2a00:100:7031::1]/"); - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_FALSE(info.is_direct()); - } - } - - // IPv6 without port. The bypass entry ought to work without the - // brackets, but the bypass matching logic in ProxyService is - // currently limited. - config.proxy_bypass.clear(); - config.proxy_bypass.push_back("[3ffe:2a00:100:7031::1]"); - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - { - GURL test_url("http://[3ffe:2a00:100:7031::1]:99/"); - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_TRUE(info.is_direct()); - } - { - GURL test_url("http://[3ffe:2a00:100:7031::1]/"); - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_TRUE(info.is_direct()); - } - } -} - -TEST(ProxyServiceTest, PerProtocolProxyTests) { - ProxyConfig config; - config.proxy_rules.ParseFromString("http=foopy1:8080;https=foopy2:8080"); - config.auto_detect = false; - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - GURL test_url("http://www.msn.com"); - ProxyInfo info; - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_FALSE(info.is_direct()); - EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); - } - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - GURL test_url("ftp://ftp.google.com"); - ProxyInfo info; - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_TRUE(info.is_direct()); - EXPECT_EQ("direct://", info.proxy_server().ToURI()); - } - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - GURL test_url("https://webbranch.techcu.com"); - ProxyInfo info; - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_FALSE(info.is_direct()); - EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI()); - } - { - config.proxy_rules.ParseFromString("foopy1:8080"); - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - GURL test_url("http://www.microsoft.com"); - ProxyInfo info; - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_FALSE(info.is_direct()); - EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); - } -} - -// If only HTTP and a SOCKS proxy are specified, check if ftp/https queries -// fall back to the SOCKS proxy. -TEST(ProxyServiceTest, DefaultProxyFallbackToSOCKS) { - ProxyConfig config; - config.proxy_rules.ParseFromString("http=foopy1:8080;socks=foopy2:1080"); - config.auto_detect = false; - EXPECT_EQ(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, - config.proxy_rules.type); - - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - GURL test_url("http://www.msn.com"); - ProxyInfo info; - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_FALSE(info.is_direct()); - EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); - } - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - GURL test_url("ftp://ftp.google.com"); - ProxyInfo info; - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_FALSE(info.is_direct()); - EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI()); - } - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - GURL test_url("https://webbranch.techcu.com"); - ProxyInfo info; - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_FALSE(info.is_direct()); - EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI()); - } - { - ProxyService service(new MockProxyConfigService(config), - new MockAsyncProxyResolver); - GURL test_url("unknown://www.microsoft.com"); - ProxyInfo info; - TestCompletionCallback callback; - int rv = service.ResolveProxy(test_url, &info, &callback, NULL); - EXPECT_EQ(OK, rv); - EXPECT_FALSE(info.is_direct()); - EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI()); - } -} - -// Test cancellation of an in-progress request. -TEST(ProxyServiceTest, CancelInProgressRequest) { - MockProxyConfigService* config_service = - new MockProxyConfigService("http://foopy/proxy.pac"); - - MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; - - ProxyService service(config_service, resolver); - - // Start 3 requests. - - ProxyInfo info1; - TestCompletionCallback callback1; - int rv = service.ResolveProxy( - GURL("http://request1"), &info1, &callback1, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - // Nothing has been sent to the proxy resolver yet, since the proxy - // resolver has not been configured yet. - ASSERT_EQ(0u, resolver->pending_requests().size()); - - // Successfully initialize the PAC script. - EXPECT_EQ(GURL("http://foopy/proxy.pac"), - resolver->pending_set_pac_script_request()->pac_url()); - resolver->pending_set_pac_script_request()->CompleteNow(OK); - - ASSERT_EQ(1u, resolver->pending_requests().size()); - EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url()); - - ProxyInfo info2; - TestCompletionCallback callback2; - ProxyService::PacRequest* request2; - rv = service.ResolveProxy( - GURL("http://request2"), &info2, &callback2, &request2); - EXPECT_EQ(ERR_IO_PENDING, rv); - ASSERT_EQ(2u, resolver->pending_requests().size()); - EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url()); - - ProxyInfo info3; - TestCompletionCallback callback3; - rv = service.ResolveProxy( - GURL("http://request3"), &info3, &callback3, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - ASSERT_EQ(3u, resolver->pending_requests().size()); - EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url()); - - // Cancel the second request - service.CancelPacRequest(request2); - - ASSERT_EQ(2u, resolver->pending_requests().size()); - EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url()); - EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[1]->url()); - - // Complete the two un-cancelled requests. - // We complete the last one first, just to mix it up a bit. - resolver->pending_requests()[1]->results()->UseNamedProxy("request3:80"); - resolver->pending_requests()[1]->CompleteNow(OK); - - resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80"); - resolver->pending_requests()[0]->CompleteNow(OK); - - // Complete and verify that requests ran as expected. - EXPECT_EQ(OK, callback1.WaitForResult()); - EXPECT_EQ("request1:80", info1.proxy_server().ToURI()); - - EXPECT_FALSE(callback2.have_result()); // Cancelled. - ASSERT_EQ(1u, resolver->cancelled_requests().size()); - EXPECT_EQ(GURL("http://request2"), resolver->cancelled_requests()[0]->url()); - - EXPECT_EQ(OK, callback3.WaitForResult()); - EXPECT_EQ("request3:80", info3.proxy_server().ToURI()); -} - -// Test the initial PAC download for ProxyResolverWithoutFetch. -TEST(ProxyServiceTest, InitialPACScriptDownload) { - MockProxyConfigService* config_service = - new MockProxyConfigService("http://foopy/proxy.pac"); - - MockAsyncProxyResolverExpectsBytes* resolver = - new MockAsyncProxyResolverExpectsBytes; - - ProxyService service(config_service, resolver); - - MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; - service.SetProxyScriptFetcher(fetcher); - - // Start 3 requests. - - ProxyInfo info1; - TestCompletionCallback callback1; - int rv = service.ResolveProxy( - GURL("http://request1"), &info1, &callback1, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - // The first request should have triggered download of PAC script. - EXPECT_TRUE(fetcher->has_pending_request()); - EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url()); - - ProxyInfo info2; - TestCompletionCallback callback2; - rv = service.ResolveProxy( - GURL("http://request2"), &info2, &callback2, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - ProxyInfo info3; - TestCompletionCallback callback3; - rv = service.ResolveProxy( - GURL("http://request3"), &info3, &callback3, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - // Nothing has been sent to the resolver yet. - EXPECT_TRUE(resolver->pending_requests().empty()); - - // At this point the ProxyService should be waiting for the - // ProxyScriptFetcher to invoke its completion callback, notifying it of - // PAC script download completion. - fetcher->NotifyFetchCompletion(OK, "pac-v1"); - - // Now that the PAC script is downloaded, it will have been sent to the proxy - // resolver. - EXPECT_EQ("pac-v1", resolver->pending_set_pac_script_request()->pac_bytes()); - resolver->pending_set_pac_script_request()->CompleteNow(OK); - - ASSERT_EQ(3u, resolver->pending_requests().size()); - EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url()); - EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url()); - EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url()); - - // Complete all the requests (in some order). - // Note that as we complete requests, they shift up in |pending_requests()|. - - resolver->pending_requests()[2]->results()->UseNamedProxy("request3:80"); - resolver->pending_requests()[2]->CompleteNow(OK); - - resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80"); - resolver->pending_requests()[0]->CompleteNow(OK); - - resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80"); - resolver->pending_requests()[0]->CompleteNow(OK); - - // Complete and verify that requests ran as expected. - EXPECT_EQ(OK, callback1.WaitForResult()); - EXPECT_EQ("request1:80", info1.proxy_server().ToURI()); - - EXPECT_EQ(OK, callback2.WaitForResult()); - EXPECT_EQ("request2:80", info2.proxy_server().ToURI()); - - EXPECT_EQ(OK, callback3.WaitForResult()); - EXPECT_EQ("request3:80", info3.proxy_server().ToURI()); -} - -// Test cancellation of a request, while the PAC script is being fetched. -TEST(ProxyServiceTest, CancelWhilePACFetching) { - MockProxyConfigService* config_service = - new MockProxyConfigService("http://foopy/proxy.pac"); - - MockAsyncProxyResolverExpectsBytes* resolver = - new MockAsyncProxyResolverExpectsBytes; - - ProxyService service(config_service, resolver); - - MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; - service.SetProxyScriptFetcher(fetcher); - - // Start 3 requests. - ProxyInfo info1; - TestCompletionCallback callback1; - ProxyService::PacRequest* request1; - int rv = service.ResolveProxy( - GURL("http://request1"), &info1, &callback1, &request1); - EXPECT_EQ(ERR_IO_PENDING, rv); - - // The first request should have triggered download of PAC script. - EXPECT_TRUE(fetcher->has_pending_request()); - EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url()); - - ProxyInfo info2; - TestCompletionCallback callback2; - ProxyService::PacRequest* request2; - rv = service.ResolveProxy( - GURL("http://request2"), &info2, &callback2, &request2); - EXPECT_EQ(ERR_IO_PENDING, rv); - - ProxyInfo info3; - TestCompletionCallback callback3; - rv = service.ResolveProxy( - GURL("http://request3"), &info3, &callback3, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - // Nothing has been sent to the resolver yet. - EXPECT_TRUE(resolver->pending_requests().empty()); - - // Cancel the first 2 requests. - service.CancelPacRequest(request1); - service.CancelPacRequest(request2); - - // At this point the ProxyService should be waiting for the - // ProxyScriptFetcher to invoke its completion callback, notifying it of - // PAC script download completion. - fetcher->NotifyFetchCompletion(OK, "pac-v1"); - - // Now that the PAC script is downloaded, it will have been sent to the - // proxy resolver. - EXPECT_EQ("pac-v1", resolver->pending_set_pac_script_request()->pac_bytes()); - resolver->pending_set_pac_script_request()->CompleteNow(OK); - - ASSERT_EQ(1u, resolver->pending_requests().size()); - EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[0]->url()); - - // Complete all the requests. - resolver->pending_requests()[0]->results()->UseNamedProxy("request3:80"); - resolver->pending_requests()[0]->CompleteNow(OK); - - EXPECT_EQ(OK, callback3.WaitForResult()); - EXPECT_EQ("request3:80", info3.proxy_server().ToURI()); - - EXPECT_TRUE(resolver->cancelled_requests().empty()); - - EXPECT_FALSE(callback1.have_result()); // Cancelled. - EXPECT_FALSE(callback2.have_result()); // Cancelled. -} - -// Test that if auto-detect fails, we fall-back to the custom pac. -TEST(ProxyServiceTest, FallbackFromAutodetectToCustomPac) { - ProxyConfig config; - config.auto_detect = true; - config.pac_url = GURL("http://foopy/proxy.pac"); - config.proxy_rules.ParseFromString("http=foopy:80"); // Won't be used. - - MockProxyConfigService* config_service = new MockProxyConfigService(config); - MockAsyncProxyResolverExpectsBytes* resolver = - new MockAsyncProxyResolverExpectsBytes; - ProxyService service(config_service, resolver); - - MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; - service.SetProxyScriptFetcher(fetcher); - - // Start 2 requests. - - ProxyInfo info1; - TestCompletionCallback callback1; - int rv = service.ResolveProxy( - GURL("http://request1"), &info1, &callback1, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - ProxyInfo info2; - TestCompletionCallback callback2; - ProxyService::PacRequest* request2; - rv = service.ResolveProxy( - GURL("http://request2"), &info2, &callback2, &request2); - EXPECT_EQ(ERR_IO_PENDING, rv); - - // Check that nothing has been sent to the proxy resolver yet. - ASSERT_EQ(0u, resolver->pending_requests().size()); - - // It should be trying to auto-detect first -- FAIL the autodetect during - // the script download. - EXPECT_TRUE(fetcher->has_pending_request()); - EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url()); - fetcher->NotifyFetchCompletion(ERR_FAILED, ""); - - // Next it should be trying the custom PAC url. - EXPECT_TRUE(fetcher->has_pending_request()); - EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url()); - fetcher->NotifyFetchCompletion(OK, "custom-pac-script"); - - EXPECT_EQ("custom-pac-script", - resolver->pending_set_pac_script_request()->pac_bytes()); - resolver->pending_set_pac_script_request()->CompleteNow(OK); - - // Now finally, the pending requests should have been sent to the resolver - // (which was initialized with custom PAC script). - - ASSERT_EQ(2u, resolver->pending_requests().size()); - EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url()); - EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url()); - - // Complete the pending requests. - resolver->pending_requests()[1]->results()->UseNamedProxy("request2:80"); - resolver->pending_requests()[1]->CompleteNow(OK); - resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80"); - resolver->pending_requests()[0]->CompleteNow(OK); - - // Verify that requests ran as expected. - EXPECT_EQ(OK, callback1.WaitForResult()); - EXPECT_EQ("request1:80", info1.proxy_server().ToURI()); - - EXPECT_EQ(OK, callback2.WaitForResult()); - EXPECT_EQ("request2:80", info2.proxy_server().ToURI()); -} - -// This is the same test as FallbackFromAutodetectToCustomPac, except -// the auto-detect script fails parsing rather than downloading. -TEST(ProxyServiceTest, FallbackFromAutodetectToCustomPac2) { - ProxyConfig config; - config.auto_detect = true; - config.pac_url = GURL("http://foopy/proxy.pac"); - config.proxy_rules.ParseFromString("http=foopy:80"); // Won't be used. - - MockProxyConfigService* config_service = new MockProxyConfigService(config); - MockAsyncProxyResolverExpectsBytes* resolver = - new MockAsyncProxyResolverExpectsBytes; - ProxyService service(config_service, resolver); - - MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; - service.SetProxyScriptFetcher(fetcher); - - // Start 2 requests. - - ProxyInfo info1; - TestCompletionCallback callback1; - int rv = service.ResolveProxy( - GURL("http://request1"), &info1, &callback1, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - ProxyInfo info2; - TestCompletionCallback callback2; - ProxyService::PacRequest* request2; - rv = service.ResolveProxy( - GURL("http://request2"), &info2, &callback2, &request2); - EXPECT_EQ(ERR_IO_PENDING, rv); - - // Check that nothing has been sent to the proxy resolver yet. - ASSERT_EQ(0u, resolver->pending_requests().size()); - - // It should be trying to auto-detect first -- succeed the download. - EXPECT_TRUE(fetcher->has_pending_request()); - EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url()); - fetcher->NotifyFetchCompletion(OK, "invalid-script-contents"); - - // Simulate a parse error. - EXPECT_EQ("invalid-script-contents", - resolver->pending_set_pac_script_request()->pac_bytes()); - resolver->pending_set_pac_script_request()->CompleteNow( - ERR_PAC_SCRIPT_FAILED); - - // Next it should be trying the custom PAC url. - EXPECT_TRUE(fetcher->has_pending_request()); - EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url()); - fetcher->NotifyFetchCompletion(OK, "custom-pac-script"); - - EXPECT_EQ("custom-pac-script", - resolver->pending_set_pac_script_request()->pac_bytes()); - resolver->pending_set_pac_script_request()->CompleteNow(OK); - - // Now finally, the pending requests should have been sent to the resolver - // (which was initialized with custom PAC script). - - ASSERT_EQ(2u, resolver->pending_requests().size()); - EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url()); - EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url()); - - // Complete the pending requests. - resolver->pending_requests()[1]->results()->UseNamedProxy("request2:80"); - resolver->pending_requests()[1]->CompleteNow(OK); - resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80"); - resolver->pending_requests()[0]->CompleteNow(OK); - - // Verify that requests ran as expected. - EXPECT_EQ(OK, callback1.WaitForResult()); - EXPECT_EQ("request1:80", info1.proxy_server().ToURI()); - - EXPECT_EQ(OK, callback2.WaitForResult()); - EXPECT_EQ("request2:80", info2.proxy_server().ToURI()); -} - -// Test that if all of auto-detect, a custom PAC script, and manual settings -// are given, then we will try them in that order. -TEST(ProxyServiceTest, FallbackFromAutodetectToCustomToManual) { - ProxyConfig config; - config.auto_detect = true; - config.pac_url = GURL("http://foopy/proxy.pac"); - config.proxy_rules.ParseFromString("http=foopy:80"); - - MockProxyConfigService* config_service = new MockProxyConfigService(config); - MockAsyncProxyResolverExpectsBytes* resolver = - new MockAsyncProxyResolverExpectsBytes; - ProxyService service(config_service, resolver); - - MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; - service.SetProxyScriptFetcher(fetcher); - - // Start 2 requests. - - ProxyInfo info1; - TestCompletionCallback callback1; - int rv = service.ResolveProxy( - GURL("http://request1"), &info1, &callback1, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - ProxyInfo info2; - TestCompletionCallback callback2; - ProxyService::PacRequest* request2; - rv = service.ResolveProxy( - GURL("http://request2"), &info2, &callback2, &request2); - EXPECT_EQ(ERR_IO_PENDING, rv); - - // Check that nothing has been sent to the proxy resolver yet. - ASSERT_EQ(0u, resolver->pending_requests().size()); - - // It should be trying to auto-detect first -- fail the download. - EXPECT_TRUE(fetcher->has_pending_request()); - EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url()); - fetcher->NotifyFetchCompletion(ERR_FAILED, ""); - - // Next it should be trying the custom PAC url -- fail the download. - EXPECT_TRUE(fetcher->has_pending_request()); - EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url()); - fetcher->NotifyFetchCompletion(ERR_FAILED, ""); - - // Since we never managed to initialize a ProxyResolver, nothing should have - // been sent to it. - ASSERT_EQ(0u, resolver->pending_requests().size()); - - // Verify that requests ran as expected -- they should have fallen back to - // the manual proxy configuration for HTTP urls. - EXPECT_EQ(OK, callback1.WaitForResult()); - EXPECT_EQ("foopy:80", info1.proxy_server().ToURI()); - - EXPECT_EQ(OK, callback2.WaitForResult()); - EXPECT_EQ("foopy:80", info2.proxy_server().ToURI()); -} - -// Test that the bypass rules are NOT applied when using autodetect. -TEST(ProxyServiceTest, BypassDoesntApplyToPac) { - ProxyConfig config; - config.auto_detect = true; - config.pac_url = GURL("http://foopy/proxy.pac"); - config.proxy_rules.ParseFromString("http=foopy:80"); // Not used. - config.proxy_bypass.push_back("www.google.com"); - - MockProxyConfigService* config_service = new MockProxyConfigService(config); - MockAsyncProxyResolverExpectsBytes* resolver = - new MockAsyncProxyResolverExpectsBytes; - ProxyService service(config_service, resolver); - - MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; - service.SetProxyScriptFetcher(fetcher); - - // Start 1 requests. - - ProxyInfo info1; - TestCompletionCallback callback1; - int rv = service.ResolveProxy( - GURL("http://www.google.com"), &info1, &callback1, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - // Check that nothing has been sent to the proxy resolver yet. - ASSERT_EQ(0u, resolver->pending_requests().size()); - - // It should be trying to auto-detect first -- succeed the download. - EXPECT_TRUE(fetcher->has_pending_request()); - EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url()); - fetcher->NotifyFetchCompletion(OK, "auto-detect"); - - EXPECT_EQ("auto-detect", - resolver->pending_set_pac_script_request()->pac_bytes()); - resolver->pending_set_pac_script_request()->CompleteNow(OK); - - ASSERT_EQ(1u, resolver->pending_requests().size()); - EXPECT_EQ(GURL("http://www.google.com"), - resolver->pending_requests()[0]->url()); - - // Complete the pending request. - resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80"); - resolver->pending_requests()[0]->CompleteNow(OK); - - // Verify that request ran as expected. - EXPECT_EQ(OK, callback1.WaitForResult()); - EXPECT_EQ("request1:80", info1.proxy_server().ToURI()); - - // Start another request, it should pickup the bypass item. - ProxyInfo info2; - TestCompletionCallback callback2; - rv = service.ResolveProxy( - GURL("http://www.google.com"), &info2, &callback2, NULL); - EXPECT_EQ(ERR_IO_PENDING, rv); - - ASSERT_EQ(1u, resolver->pending_requests().size()); - EXPECT_EQ(GURL("http://www.google.com"), - resolver->pending_requests()[0]->url()); - - // Complete the pending request. - resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80"); - resolver->pending_requests()[0]->CompleteNow(OK); - - EXPECT_EQ(OK, callback2.WaitForResult()); - EXPECT_EQ("request2:80", info2.proxy_server().ToURI()); -} - -TEST(ProxyServiceTest, ResetProxyConfigService) { - ProxyConfig config1; - config1.proxy_rules.ParseFromString("foopy1:8080"); - config1.auto_detect = false; - ProxyService service(new MockProxyConfigService(config1), - new MockAsyncProxyResolverExpectsBytes); - - ProxyInfo info; - TestCompletionCallback callback1; - int rv = service.ResolveProxy( - GURL("http://request1"), &info, &callback1, NULL); - EXPECT_EQ(OK, rv); - EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); - - ProxyConfig config2; - config2.proxy_rules.ParseFromString("foopy2:8080"); - config2.auto_detect = false; - service.ResetConfigService(new MockProxyConfigService(config2)); - TestCompletionCallback callback2; - rv = service.ResolveProxy(GURL("http://request2"), &info, &callback2, NULL); - EXPECT_EQ(OK, rv); - EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI()); -} - -TEST(ProxyServiceTest, IsLocalName) { - const struct { - const char* url; - bool expected_is_local; - } tests[] = { - // Single-component hostnames are considered local. - {"http://localhost/x", true}, - {"http://www", true}, - - // IPv4 loopback interface. - {"http://127.0.0.1/x", true}, - {"http://127.0.0.1:80/x", true}, - - // IPv6 loopback interface. - {"http://[::1]:80/x", true}, - {"http://[0:0::1]:6233/x", true}, - {"http://[0:0:0:0:0:0:0:1]/x", true}, - - // Non-local URLs. - {"http://foo.com/", false}, - {"http://localhost.i/", false}, - {"http://www.google.com/", false}, - {"http://192.168.0.1/", false}, - - // Try with different protocols. - {"ftp://127.0.0.1/x", true}, - {"ftp://foobar.com/x", false}, - - // This is a bit of a gray-area, but GURL does not strip trailing dots - // in host-names, so the following are considered non-local. - {"http://www./x", false}, - {"http://localhost./x", false}, - }; - - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { - SCOPED_TRACE(StringPrintf("Test[%d]: %s", i, tests[i].url)); - bool is_local = ProxyService::IsLocalName(GURL(tests[i].url)); - EXPECT_EQ(tests[i].expected_is_local, is_local); - } -} - } // namespace net + +#endif // NET_PROXY_MOCK_PROXY_RESOLVER_H_ diff --git a/net/proxy/proxy_service_unittest.cc b/net/proxy/proxy_service_unittest.cc index 3b3eb49..f4deb67 100644 --- a/net/proxy/proxy_service_unittest.cc +++ b/net/proxy/proxy_service_unittest.cc @@ -9,6 +9,7 @@ #include "googleurl/src/gurl.h" #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" +#include "net/proxy/mock_proxy_resolver.h" #include "net/proxy/proxy_config_service.h" #include "net/proxy/proxy_resolver.h" #include "net/proxy/proxy_script_fetcher.h" @@ -36,156 +37,6 @@ class MockProxyConfigService: public ProxyConfigService { ProxyConfig config; }; -// Asynchronous mock proxy resolver. All requests complete asynchronously, -// user must call Request::CompleteNow() on a pending request to signal it. -class MockAsyncProxyResolverBase : public ProxyResolver { - public: - class Request : public base::RefCounted<Request> { - public: - Request(MockAsyncProxyResolverBase* resolver, - const GURL& url, - ProxyInfo* results, - CompletionCallback* callback) - : resolver_(resolver), - url_(url), - results_(results), - callback_(callback), - origin_loop_(MessageLoop::current()) { - } - - const GURL& url() const { return url_; } - ProxyInfo* results() const { return results_; } - CompletionCallback* callback() const { return callback_; } - - void CompleteNow(int rv) { - CompletionCallback* callback = callback_; - - // May delete |this|. - resolver_->RemovePendingRequest(this); - - callback->Run(rv); - } - - private: - MockAsyncProxyResolverBase* resolver_; - const GURL url_; - ProxyInfo* results_; - CompletionCallback* callback_; - MessageLoop* origin_loop_; - }; - - class SetPacScriptRequest { - public: - SetPacScriptRequest(MockAsyncProxyResolverBase* resolver, - const GURL& pac_url, - const std::string& pac_bytes, - CompletionCallback* callback) - : resolver_(resolver), - pac_url_(pac_url), - pac_bytes_(pac_bytes), - callback_(callback), - origin_loop_(MessageLoop::current()) { - } - - const GURL& pac_url() const { return pac_url_; } - const std::string& pac_bytes() const { return pac_bytes_; } - - void CompleteNow(int rv) { - CompletionCallback* callback = callback_; - - // Will delete |this|. - resolver_->RemovePendingSetPacScriptRequest(this); - - callback->Run(rv); - } - - private: - MockAsyncProxyResolverBase* resolver_; - const GURL pac_url_; - const std::string pac_bytes_; - CompletionCallback* callback_; - MessageLoop* origin_loop_; - }; - - typedef std::vector<scoped_refptr<Request> > RequestsList; - - // ProxyResolver implementation: - virtual int GetProxyForURL(const GURL& url, - ProxyInfo* results, - CompletionCallback* callback, - RequestHandle* request_handle) { - scoped_refptr<Request> request = new Request(this, url, results, callback); - pending_requests_.push_back(request); - - if (request_handle) - *request_handle = reinterpret_cast<RequestHandle>(request.get()); - - // Test code completes the request by calling request->CompleteNow(). - return ERR_IO_PENDING; - } - - virtual void CancelRequest(RequestHandle request_handle) { - scoped_refptr<Request> request = reinterpret_cast<Request*>(request_handle); - cancelled_requests_.push_back(request); - RemovePendingRequest(request); - } - - virtual int SetPacScript(const GURL& pac_url, - const std::string& pac_bytes, - CompletionCallback* callback) { - EXPECT_EQ(NULL, pending_set_pac_script_request_.get()); - pending_set_pac_script_request_.reset( - new SetPacScriptRequest(this, pac_url, pac_bytes, callback)); - // Finished when user calls SetPacScriptRequest::CompleteNow(). - return ERR_IO_PENDING; - } - - const RequestsList& pending_requests() const { - return pending_requests_; - } - - const RequestsList& cancelled_requests() const { - return cancelled_requests_; - } - - SetPacScriptRequest* pending_set_pac_script_request() const { - return pending_set_pac_script_request_.get(); - } - - void RemovePendingRequest(Request* request) { - RequestsList::iterator it = std::find( - pending_requests_.begin(), pending_requests_.end(), request); - DCHECK(it != pending_requests_.end()); - pending_requests_.erase(it); - } - - void RemovePendingSetPacScriptRequest(SetPacScriptRequest* request) { - EXPECT_EQ(request, pending_set_pac_script_request()); - pending_set_pac_script_request_.reset(); - } - - protected: - explicit MockAsyncProxyResolverBase(bool expects_pac_bytes) - : ProxyResolver(expects_pac_bytes) {} - - private: - RequestsList pending_requests_; - RequestsList cancelled_requests_; - scoped_ptr<SetPacScriptRequest> pending_set_pac_script_request_; -}; - -class MockAsyncProxyResolver : public MockAsyncProxyResolverBase { - public: - MockAsyncProxyResolver() - : MockAsyncProxyResolverBase(false /*expects_pac_bytes*/) {} -}; - -class MockAsyncProxyResolverExpectsBytes : public MockAsyncProxyResolverBase { - public: - MockAsyncProxyResolverExpectsBytes() - : MockAsyncProxyResolverBase(true /*expects_pac_bytes*/) {} -}; - } // namespace // A mock ProxyScriptFetcher. No result will be returned to the fetch client |