Index: net/proxy/proxy_resolver_js_bindings_unittest.cc |
=================================================================== |
--- net/proxy/proxy_resolver_js_bindings_unittest.cc (revision 29974) |
+++ net/proxy/proxy_resolver_js_bindings_unittest.cc (working copy) |
@@ -2,7 +2,16 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include "build/build_config.h" |
+ |
+#if defined(OS_WIN) |
+#include <ws2tcpip.h> |
+#else |
+#include <netdb.h> |
+#endif |
+ |
#include "base/scoped_ptr.h" |
+#include "net/base/address_list.h" |
#include "net/base/mock_host_resolver.h" |
#include "net/base/net_errors.h" |
#include "net/base/net_util.h" |
@@ -12,6 +21,67 @@ |
namespace net { |
namespace { |
+// This is a HostResolver that synchronously resolves all hosts to the |
+// following address list of length 3: |
+// 192.168.1.1 |
+// 172.22.34.1 |
+// 200.100.1.2 |
+class MockHostResolverWithMultipleResults : public HostResolver { |
+ public: |
+ // HostResolver methods: |
+ virtual int Resolve(const RequestInfo& info, |
+ AddressList* addresses, |
+ CompletionCallback* callback, |
+ RequestHandle* out_req, |
+ LoadLog* load_log) { |
+ // Build up the result list (in reverse). |
+ AddressList temp_list = ResolveIPLiteral("200.100.1.2"); |
+ temp_list = PrependAddressToList("172.22.34.1", temp_list); |
+ temp_list = PrependAddressToList("192.168.1.1", temp_list); |
+ *addresses = temp_list; |
+ return OK; |
+ } |
+ virtual void CancelRequest(RequestHandle req) {} |
+ virtual void AddObserver(Observer* observer) {} |
+ virtual void RemoveObserver(Observer* observer) {} |
+ virtual HostCache* GetHostCache() { return NULL; } |
+ virtual void Shutdown() {} |
+ |
+ private: |
+ // Resolves an IP literal to an address list. |
+ AddressList ResolveIPLiteral(const char* ip_literal) { |
+ AddressList result; |
+ int rv = SystemHostResolverProc(ip_literal, |
+ ADDRESS_FAMILY_UNSPECIFIED, |
+ &result); |
+ EXPECT_EQ(OK, rv); |
+ EXPECT_EQ(NULL, result.head()->ai_next); |
+ return result; |
+ } |
+ |
+ // Builds an AddressList that is |ip_literal| + |address_list|. |
+ // |orig_list| must not be empty. |
+ AddressList PrependAddressToList(const char* ip_literal, |
+ const AddressList& orig_list) { |
+ // Build an addrinfo for |ip_literal|. |
+ AddressList result = ResolveIPLiteral(ip_literal); |
+ |
+ struct addrinfo* result_head = const_cast<struct addrinfo*>(result.head()); |
+ |
+ // Temporarily append |orig_list| to |result|. |
+ result_head->ai_next = const_cast<struct addrinfo*>(orig_list.head()); |
+ |
+ // Make a copy of the concatenated list. |
+ AddressList concatenated; |
+ concatenated.Copy(result.head()); |
+ |
+ // Restore |result| (so it is freed properly). |
+ result_head->ai_next = NULL; |
+ |
+ return concatenated; |
+ } |
+}; |
+ |
TEST(ProxyResolverJSBindingsTest, DnsResolve) { |
scoped_refptr<MockHostResolver> host_resolver(new MockHostResolver); |
@@ -21,6 +91,7 @@ |
// Empty string is not considered a valid host (even though on some systems |
// requesting this will resolve to localhost). |
+ host_resolver->rules()->AddSimulatedFailure(""); |
EXPECT_EQ("", bindings->DnsResolve("")); |
// Should call through to the HostResolver. |
@@ -48,10 +119,19 @@ |
EXPECT_EQ("127.0.0.1", my_ip_address); |
} |
-// Tests that myIpAddress() and dnsResolve() pass the flag |
-// ADDRESS_FAMILY_IPV4 to the host resolver, as we don't want them |
-// to return IPv6 results. |
-TEST(ProxyResolverJSBindingsTest, DontUseIPv6) { |
+// Tests that the regular PAC functions restrict results to IPv4, |
+// but that the Microsoft extensions to PAC do not. We test this |
+// by seeing whether ADDRESS_FAMILY_IPV4 or ADDRESS_FAMILY_UNSPECIFIED |
+// was passed into to the host resolver. |
+// |
+// Restricted to IPv4 address family: |
+// myIpAddress() |
+// dnsResolve() |
+// |
+// Unrestricted address family: |
+// myIpAddressEx() |
+// dnsResolveEx() |
+TEST(ProxyResolverJSBindingsTest, RestrictAddressFamily) { |
scoped_refptr<MockHostResolver> host_resolver(new MockHostResolver); |
// Get a hold of a DefaultJSBindings* (it is a hidden impl class). |
@@ -67,7 +147,9 @@ |
host_resolver->rules()->AddRuleForAddressFamily( |
"*", ADDRESS_FAMILY_IPV4, "192.168.1.2"); |
host_resolver->rules()->AddRuleForAddressFamily( |
- "*", ADDRESS_FAMILY_UNSPECIFIED, "192.168.2.1"); |
+ "foo", ADDRESS_FAMILY_UNSPECIFIED, "192.168.2.1"); |
+ host_resolver->rules()->AddRuleForAddressFamily( |
+ "*", ADDRESS_FAMILY_UNSPECIFIED, "192.168.2.2"); |
// Verify that our mock setups works as expected, and we get different results |
// depending if the address family was IPV4_ONLY or not. |
@@ -81,10 +163,32 @@ |
EXPECT_EQ("192.168.1.1", NetAddressToString(address_list.head())); |
// Now the actual test. |
- EXPECT_EQ("192.168.1.2", bindings->MyIpAddress()); |
- EXPECT_EQ("192.168.1.1", bindings->DnsResolve("foo")); |
- EXPECT_EQ("192.168.1.2", bindings->DnsResolve("foo2")); |
+ EXPECT_EQ("192.168.1.2", bindings->MyIpAddress()); // IPv4 restricted. |
+ EXPECT_EQ("192.168.1.1", bindings->DnsResolve("foo")); // IPv4 restricted. |
+ EXPECT_EQ("192.168.1.2", bindings->DnsResolve("foo2")); // IPv4 restricted. |
+ |
+ EXPECT_EQ("192.168.2.2", bindings->MyIpAddressEx()); // Unrestricted. |
+ EXPECT_EQ("192.168.2.1", bindings->DnsResolveEx("foo")); // Unrestricted. |
+ EXPECT_EQ("192.168.2.2", bindings->DnsResolveEx("foo2")); // Unrestricted. |
} |
+// Test that myIpAddressEx() and dnsResolveEx() both return a semi-colon |
+// separated list of addresses (as opposed to the non-Ex versions which |
+// just return the first result). |
+TEST(ProxyResolverJSBindingsTest, ExFunctionsReturnList) { |
+ scoped_refptr<HostResolver> host_resolver( |
+ new MockHostResolverWithMultipleResults); |
+ |
+ // Get a hold of a DefaultJSBindings* (it is a hidden impl class). |
+ scoped_ptr<ProxyResolverJSBindings> bindings( |
+ ProxyResolverJSBindings::CreateDefault(host_resolver, NULL)); |
+ |
+ EXPECT_EQ("192.168.1.1;172.22.34.1;200.100.1.2", |
+ bindings->MyIpAddressEx()); |
+ |
+ EXPECT_EQ("192.168.1.1;172.22.34.1;200.100.1.2", |
+ bindings->DnsResolveEx("FOO")); |
+} |
+ |
} // namespace |
} // namespace net |