diff options
author | darin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-11 15:40:23 +0000 |
---|---|---|
committer | darin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-11 15:40:23 +0000 |
commit | 928fb58bd99536f16df3739329cbade0853b3309 (patch) | |
tree | 7a6433d25d9c5303614f05b6b39cb49e60468d12 /net/proxy/proxy_service_unittest.cc | |
parent | 6723f835ff0247e5bffad9e92d8d42a8c3ae1b3b (diff) | |
download | chromium_src-928fb58bd99536f16df3739329cbade0853b3309.zip chromium_src-928fb58bd99536f16df3739329cbade0853b3309.tar.gz chromium_src-928fb58bd99536f16df3739329cbade0853b3309.tar.bz2 |
Rename HttpProxy* classes to Proxy*. Move them into a net/proxy/ subdirectory.
I'm making this change because proxy resolution is really not specific to the HTTP protocol. We need to use the proxy service in our FTP implementation, for example. I made a separate directory instead of just putting these in base, because I anticipate more files once we have our own PAC implementation.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@651 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/proxy/proxy_service_unittest.cc')
-rw-r--r-- | net/proxy/proxy_service_unittest.cc | 408 |
1 files changed, 408 insertions, 0 deletions
diff --git a/net/proxy/proxy_service_unittest.cc b/net/proxy/proxy_service_unittest.cc new file mode 100644 index 0000000..f4b9292 --- /dev/null +++ b/net/proxy/proxy_service_unittest.cc @@ -0,0 +1,408 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "googleurl/src/gurl.h" +#include "net/base/net_errors.h" +#include "net/proxy/proxy_service.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class MockProxyResolver : public net::ProxyResolver { + public: + MockProxyResolver() : fail_get_proxy_for_url(false) { + config.reset(new net::ProxyConfig); + } + virtual int GetProxyConfig(net::ProxyConfig* results) { + *results = *(config.get()); + return net::OK; + } + virtual int GetProxyForURL(const std::wstring& query_url, + const std::wstring& pac_url, + net::ProxyInfo* results) { + if (pac_url != config->pac_url) + return net::ERR_INVALID_ARGUMENT; + if (fail_get_proxy_for_url) + return net::ERR_FAILED; + if (GURL(query_url).host() == info_predicate_query_host) { + results->Use(info); + } else { + results->UseDirect(); + } + return net::OK; + } + scoped_ptr<net::ProxyConfig> config; + net::ProxyInfo info; + + // info is only returned if query_url in GetProxyForURL matches this: + std::string info_predicate_query_host; + + // If true, then GetProxyForURL will fail, which simulates failure to + // download or execute the PAC file. + bool fail_get_proxy_for_url; +}; + +} // namespace + +TEST(ProxyServiceTest, Direct) { + MockProxyResolver resolver; + net::ProxyService service(&resolver); + + GURL url("http://www.google.com/"); + + net::ProxyInfo info; + int rv = service.ResolveProxy(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_TRUE(info.is_direct()); +} + +TEST(ProxyServiceTest, PAC) { + MockProxyResolver resolver; + resolver.config->pac_url = L"http://foopy/proxy.pac"; + resolver.info.UseNamedProxy(L"foopy"); + resolver.info_predicate_query_host = "www.google.com"; + + net::ProxyService service(&resolver); + + GURL url("http://www.google.com/"); + + net::ProxyInfo info; + int rv = service.ResolveProxy(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_FALSE(info.is_direct()); + EXPECT_EQ(info.proxy_server(), L"foopy"); +} + +TEST(ProxyServiceTest, PAC_FailoverToDirect) { + MockProxyResolver resolver; + resolver.config->pac_url = L"http://foopy/proxy.pac"; + resolver.info.UseNamedProxy(L"foopy:8080"); + resolver.info_predicate_query_host = "www.google.com"; + + net::ProxyService service(&resolver); + + GURL url("http://www.google.com/"); + + net::ProxyInfo info; + int rv = service.ResolveProxy(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_FALSE(info.is_direct()); + EXPECT_EQ(info.proxy_server(), L"foopy:8080"); + + // Now, imagine that connecting to foopy:8080 fails. + rv = service.ReconsiderProxyAfterError(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_TRUE(info.is_direct()); +} + +TEST(ProxyServiceTest, PAC_FailsToDownload) { + // Test what happens when we fail to download the PAC URL. + + MockProxyResolver resolver; + resolver.config->pac_url = L"http://foopy/proxy.pac"; + resolver.info.UseNamedProxy(L"foopy:8080"); + resolver.info_predicate_query_host = "www.google.com"; + resolver.fail_get_proxy_for_url = true; + + net::ProxyService service(&resolver); + + GURL url("http://www.google.com/"); + net::ProxyInfo info; + int rv = service.ResolveProxy(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_TRUE(info.is_direct()); + + rv = service.ResolveProxy(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_TRUE(info.is_direct()); + + resolver.fail_get_proxy_for_url = false; + resolver.info.UseNamedProxy(L"foopy_valid:8080"); + + // But, if that fails, then we should give the proxy config another shot + // since we have never tried it with this URL before. + rv = service.ReconsiderProxyAfterError(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_FALSE(info.is_direct()); + EXPECT_EQ(info.proxy_server(), L"foopy_valid:8080"); +} + +TEST(ProxyServiceTest, ProxyFallback) { + // Test what happens when we specify multiple proxy servers and some of them + // are bad. + + MockProxyResolver resolver; + resolver.config->pac_url = L"http://foopy/proxy.pac"; + resolver.info.UseNamedProxy(L"foopy1:8080;foopy2:9090"); + resolver.info_predicate_query_host = "www.google.com"; + resolver.fail_get_proxy_for_url = false; + + net::ProxyService service(&resolver); + + GURL url("http://www.google.com/"); + + // Get the proxy information. + net::ProxyInfo info; + int rv = service.ResolveProxy(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_FALSE(info.is_direct()); + + // The first item is valid. + EXPECT_EQ(info.proxy_server(), L"foopy1:8080"); + + // Fake an error on the proxy. + rv = service.ReconsiderProxyAfterError(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + + // The second proxy should be specified. + EXPECT_EQ(info.proxy_server(), L"foopy2:9090"); + + // Create a new resolver that returns 3 proxies. The second one is already + // known to be bad. + resolver.config->pac_url = L"http://foopy/proxy.pac"; + resolver.info.UseNamedProxy(L"foopy3:7070;foopy1:8080;foopy2:9090"); + resolver.info_predicate_query_host = "www.google.com"; + resolver.fail_get_proxy_for_url = false; + + rv = service.ResolveProxy(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_FALSE(info.is_direct()); + EXPECT_EQ(info.proxy_server(), L"foopy3:7070"); + + // We fake another error. It should now try the third one. + rv = service.ReconsiderProxyAfterError(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_EQ(info.proxy_server(), L"foopy2:9090"); + + // Fake another error, the last proxy is gone, the list should now be empty. + rv = service.ReconsiderProxyAfterError(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); // We try direct. + EXPECT_TRUE(info.is_direct()); + + // If it fails again, we don't have anything else to try. + rv = service.ReconsiderProxyAfterError(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::ERR_FAILED); // We try direct. + + // TODO(nsylvain): Test that the proxy can be retried after the delay. +} + +TEST(ProxyServiceTest, ProxyFallback_NewSettings) { + // Test proxy failover when new settings are available. + + MockProxyResolver resolver; + resolver.config->pac_url = L"http://foopy/proxy.pac"; + resolver.info.UseNamedProxy(L"foopy1:8080;foopy2:9090"); + resolver.info_predicate_query_host = "www.google.com"; + resolver.fail_get_proxy_for_url = false; + + net::ProxyService service(&resolver); + + GURL url("http://www.google.com/"); + + // Get the proxy information. + net::ProxyInfo info; + int rv = service.ResolveProxy(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_FALSE(info.is_direct()); + + // The first item is valid. + EXPECT_EQ(info.proxy_server(), L"foopy1:8080"); + + // Fake an error on the proxy, and also a new configuration on the proxy. + resolver.config.reset(new net::ProxyConfig); + resolver.config->pac_url = L"http://foopy-new/proxy.pac"; + + rv = service.ReconsiderProxyAfterError(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + + // The first proxy is still there since the configuration changed. + EXPECT_EQ(info.proxy_server(), L"foopy1:8080"); + + // We fake another error. It should now ignore the first one. + rv = service.ReconsiderProxyAfterError(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_EQ(info.proxy_server(), L"foopy2:9090"); + + // We simulate a new configuration. + resolver.config.reset(new net::ProxyConfig); + resolver.config->pac_url = L"http://foopy-new2/proxy.pac"; + + // We fake anothe error. It should go back to the first proxy. + rv = service.ReconsiderProxyAfterError(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_EQ(info.proxy_server(), L"foopy1:8080"); +} + +TEST(ProxyServiceTest, ProxyFallback_BadConfig) { + // Test proxy failover when the configuration is bad. + + MockProxyResolver resolver; + resolver.config->pac_url = L"http://foopy/proxy.pac"; + resolver.info.UseNamedProxy(L"foopy1:8080;foopy2:9090"); + resolver.info_predicate_query_host = "www.google.com"; + resolver.fail_get_proxy_for_url = false; + + net::ProxyService service(&resolver); + + GURL url("http://www.google.com/"); + + // Get the proxy information. + net::ProxyInfo info; + int rv = service.ResolveProxy(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_FALSE(info.is_direct()); + + // The first item is valid. + EXPECT_EQ(info.proxy_server(), L"foopy1:8080"); + + // Fake a proxy error. + rv = service.ReconsiderProxyAfterError(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + + // The first proxy is ignored, and the second one is selected. + EXPECT_FALSE(info.is_direct()); + EXPECT_EQ(info.proxy_server(), L"foopy2:9090"); + + // Fake a PAC failure. + net::ProxyInfo info2; + resolver.fail_get_proxy_for_url = true; + rv = service.ResolveProxy(url, &info2, NULL, NULL); + EXPECT_EQ(rv, net::OK); + + // No proxy servers are returned. It's a direct connection. + EXPECT_TRUE(info2.is_direct()); + + // The PAC is now fixed and will return a proxy server. + // It should also clear the list of bad proxies. + resolver.fail_get_proxy_for_url = false; + + // Try to resolve, it will still return "direct" because we have no reason + // to check the config since everything works. + net::ProxyInfo info3; + rv = service.ResolveProxy(url, &info3, NULL, NULL); + EXPECT_EQ(rv, net::OK); + 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. + rv = service.ReconsiderProxyAfterError(url, &info3, NULL, NULL); + EXPECT_EQ(rv, net::OK); + + // The first proxy is still there since the list of bad proxies got cleared. + EXPECT_FALSE(info3.is_direct()); + EXPECT_EQ(info3.proxy_server(), L"foopy1:8080"); +} + +TEST(ProxyServiceTest, ProxyBypassList) { + // Test what happens when a proxy bypass list is specified. + + MockProxyResolver resolver; + resolver.config->proxy_server = L"foopy1:8080;foopy2:9090"; + resolver.config->auto_detect = false; + resolver.config->proxy_bypass = L"<local>"; + + net::ProxyService service(&resolver); + GURL url("http://www.google.com/"); + // Get the proxy information. + net::ProxyInfo info; + int rv = service.ResolveProxy(url, &info, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_FALSE(info.is_direct()); + + net::ProxyService service1(&resolver); + GURL test_url1("local"); + net::ProxyInfo info1; + rv = service1.ResolveProxy(test_url1, &info1, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_TRUE(info1.is_direct()); + + resolver.config->proxy_bypass = L"<local>;*.org"; + net::ProxyService service2(&resolver); + GURL test_url2("http://www.webkit.org"); + net::ProxyInfo info2; + rv = service2.ResolveProxy(test_url2, &info2, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_TRUE(info2.is_direct()); + + resolver.config->proxy_bypass = L"<local>;*.org;7*"; + net::ProxyService service3(&resolver); + GURL test_url3("http://74.125.19.147"); + net::ProxyInfo info3; + rv = service3.ResolveProxy(test_url3, &info3, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_TRUE(info3.is_direct()); + + resolver.config->proxy_bypass = L"<local>;*.org;"; + net::ProxyService service4(&resolver); + GURL test_url4("http://www.msn.com"); + net::ProxyInfo info4; + rv = service4.ResolveProxy(test_url4, &info4, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_FALSE(info4.is_direct()); +} + +TEST(ProxyServiceTest, PerProtocolProxyTests) { + MockProxyResolver resolver; + resolver.config->proxy_server = L"http=foopy1:8080;https=foopy2:8080"; + resolver.config->auto_detect = false; + + net::ProxyService service1(&resolver); + GURL test_url1("http://www.msn.com"); + net::ProxyInfo info1; + int rv = service1.ResolveProxy(test_url1, &info1, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_FALSE(info1.is_direct()); + EXPECT_TRUE(info1.proxy_server() == L"foopy1:8080"); + + net::ProxyService service2(&resolver); + GURL test_url2("ftp://ftp.google.com"); + net::ProxyInfo info2; + rv = service2.ResolveProxy(test_url2, &info2, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_TRUE(info2.is_direct()); + EXPECT_TRUE(info2.proxy_server() == L""); + + net::ProxyService service3(&resolver); + GURL test_url3("https://webbranch.techcu.com"); + net::ProxyInfo info3; + rv = service3.ResolveProxy(test_url3, &info3, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_FALSE(info3.is_direct()); + EXPECT_TRUE(info3.proxy_server() == L"foopy2:8080"); + + resolver.config->proxy_server = L"foopy1:8080"; + net::ProxyService service4(&resolver); + GURL test_url4("www.microsoft.com"); + net::ProxyInfo info4; + rv = service4.ResolveProxy(test_url4, &info4, NULL, NULL); + EXPECT_EQ(rv, net::OK); + EXPECT_FALSE(info4.is_direct()); + EXPECT_TRUE(info4.proxy_server() == L"foopy1:8080"); +} |