OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include "build/build_config.h" |
| 6 |
| 7 #if defined(OS_WIN) |
| 8 #include <ws2tcpip.h> |
| 9 #else |
| 10 #include <netdb.h> |
| 11 #endif |
| 12 |
5 #include "base/scoped_ptr.h" | 13 #include "base/scoped_ptr.h" |
| 14 #include "net/base/address_list.h" |
6 #include "net/base/mock_host_resolver.h" | 15 #include "net/base/mock_host_resolver.h" |
7 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" |
8 #include "net/base/net_util.h" | 17 #include "net/base/net_util.h" |
9 #include "net/proxy/proxy_resolver_js_bindings.h" | 18 #include "net/proxy/proxy_resolver_js_bindings.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
11 | 20 |
12 namespace net { | 21 namespace net { |
13 namespace { | 22 namespace { |
14 | 23 |
| 24 // This is a HostResolver that synchronously resolves all hosts to the |
| 25 // following address list of length 3: |
| 26 // 192.168.1.1 |
| 27 // 172.22.34.1 |
| 28 // 200.100.1.2 |
| 29 class MockHostResolverWithMultipleResults : public HostResolver { |
| 30 public: |
| 31 // HostResolver methods: |
| 32 virtual int Resolve(const RequestInfo& info, |
| 33 AddressList* addresses, |
| 34 CompletionCallback* callback, |
| 35 RequestHandle* out_req, |
| 36 LoadLog* load_log) { |
| 37 // Build up the result list (in reverse). |
| 38 AddressList temp_list = ResolveIPLiteral("200.100.1.2"); |
| 39 temp_list = PrependAddressToList("172.22.34.1", temp_list); |
| 40 temp_list = PrependAddressToList("192.168.1.1", temp_list); |
| 41 *addresses = temp_list; |
| 42 return OK; |
| 43 } |
| 44 virtual void CancelRequest(RequestHandle req) {} |
| 45 virtual void AddObserver(Observer* observer) {} |
| 46 virtual void RemoveObserver(Observer* observer) {} |
| 47 virtual HostCache* GetHostCache() { return NULL; } |
| 48 virtual void Shutdown() {} |
| 49 |
| 50 private: |
| 51 // Resolves an IP literal to an address list. |
| 52 AddressList ResolveIPLiteral(const char* ip_literal) { |
| 53 AddressList result; |
| 54 int rv = SystemHostResolverProc(ip_literal, |
| 55 ADDRESS_FAMILY_UNSPECIFIED, |
| 56 &result); |
| 57 EXPECT_EQ(OK, rv); |
| 58 EXPECT_EQ(NULL, result.head()->ai_next); |
| 59 return result; |
| 60 } |
| 61 |
| 62 // Builds an AddressList that is |ip_literal| + |address_list|. |
| 63 // |orig_list| must not be empty. |
| 64 AddressList PrependAddressToList(const char* ip_literal, |
| 65 const AddressList& orig_list) { |
| 66 // Build an addrinfo for |ip_literal|. |
| 67 AddressList result = ResolveIPLiteral(ip_literal); |
| 68 |
| 69 struct addrinfo* result_head = const_cast<struct addrinfo*>(result.head()); |
| 70 |
| 71 // Temporarily append |orig_list| to |result|. |
| 72 result_head->ai_next = const_cast<struct addrinfo*>(orig_list.head()); |
| 73 |
| 74 // Make a copy of the concatenated list. |
| 75 AddressList concatenated; |
| 76 concatenated.Copy(result.head()); |
| 77 |
| 78 // Restore |result| (so it is freed properly). |
| 79 result_head->ai_next = NULL; |
| 80 |
| 81 return concatenated; |
| 82 } |
| 83 }; |
| 84 |
15 TEST(ProxyResolverJSBindingsTest, DnsResolve) { | 85 TEST(ProxyResolverJSBindingsTest, DnsResolve) { |
16 scoped_refptr<MockHostResolver> host_resolver(new MockHostResolver); | 86 scoped_refptr<MockHostResolver> host_resolver(new MockHostResolver); |
17 | 87 |
18 // Get a hold of a DefaultJSBindings* (it is a hidden impl class). | 88 // Get a hold of a DefaultJSBindings* (it is a hidden impl class). |
19 scoped_ptr<ProxyResolverJSBindings> bindings( | 89 scoped_ptr<ProxyResolverJSBindings> bindings( |
20 ProxyResolverJSBindings::CreateDefault(host_resolver, NULL)); | 90 ProxyResolverJSBindings::CreateDefault(host_resolver, NULL)); |
21 | 91 |
22 // Empty string is not considered a valid host (even though on some systems | 92 // Empty string is not considered a valid host (even though on some systems |
23 // requesting this will resolve to localhost). | 93 // requesting this will resolve to localhost). |
| 94 host_resolver->rules()->AddSimulatedFailure(""); |
24 EXPECT_EQ("", bindings->DnsResolve("")); | 95 EXPECT_EQ("", bindings->DnsResolve("")); |
25 | 96 |
26 // Should call through to the HostResolver. | 97 // Should call through to the HostResolver. |
27 host_resolver->rules()->AddRule("google.com", "192.168.1.1"); | 98 host_resolver->rules()->AddRule("google.com", "192.168.1.1"); |
28 EXPECT_EQ("192.168.1.1", bindings->DnsResolve("google.com")); | 99 EXPECT_EQ("192.168.1.1", bindings->DnsResolve("google.com")); |
29 | 100 |
30 // Resolve failures should give empty string. | 101 // Resolve failures should give empty string. |
31 host_resolver->rules()->AddSimulatedFailure("fail"); | 102 host_resolver->rules()->AddSimulatedFailure("fail"); |
32 EXPECT_EQ("", bindings->DnsResolve("fail")); | 103 EXPECT_EQ("", bindings->DnsResolve("fail")); |
33 | 104 |
34 // TODO(eroman): would be nice to have an IPV6 test here too, but that | 105 // TODO(eroman): would be nice to have an IPV6 test here too, but that |
35 // won't work on all systems. | 106 // won't work on all systems. |
36 } | 107 } |
37 | 108 |
38 TEST(ProxyResolverJSBindingsTest, MyIpAddress) { | 109 TEST(ProxyResolverJSBindingsTest, MyIpAddress) { |
39 // Get a hold of a DefaultJSBindings* (it is a hidden impl class). | 110 // Get a hold of a DefaultJSBindings* (it is a hidden impl class). |
40 scoped_ptr<ProxyResolverJSBindings> bindings( | 111 scoped_ptr<ProxyResolverJSBindings> bindings( |
41 ProxyResolverJSBindings::CreateDefault( | 112 ProxyResolverJSBindings::CreateDefault( |
42 new MockHostResolver, NULL)); | 113 new MockHostResolver, NULL)); |
43 | 114 |
44 // Our IP address is always going to be 127.0.0.1, since we are using a | 115 // Our IP address is always going to be 127.0.0.1, since we are using a |
45 // mock host resolver. | 116 // mock host resolver. |
46 std::string my_ip_address = bindings->MyIpAddress(); | 117 std::string my_ip_address = bindings->MyIpAddress(); |
47 | 118 |
48 EXPECT_EQ("127.0.0.1", my_ip_address); | 119 EXPECT_EQ("127.0.0.1", my_ip_address); |
49 } | 120 } |
50 | 121 |
51 // Tests that myIpAddress() and dnsResolve() pass the flag | 122 // Tests that the regular PAC functions restrict results to IPv4, |
52 // ADDRESS_FAMILY_IPV4 to the host resolver, as we don't want them | 123 // but that the Microsoft extensions to PAC do not. We test this |
53 // to return IPv6 results. | 124 // by seeing whether ADDRESS_FAMILY_IPV4 or ADDRESS_FAMILY_UNSPECIFIED |
54 TEST(ProxyResolverJSBindingsTest, DontUseIPv6) { | 125 // was passed into to the host resolver. |
| 126 // |
| 127 // Restricted to IPv4 address family: |
| 128 // myIpAddress() |
| 129 // dnsResolve() |
| 130 // |
| 131 // Unrestricted address family: |
| 132 // myIpAddressEx() |
| 133 // dnsResolveEx() |
| 134 TEST(ProxyResolverJSBindingsTest, RestrictAddressFamily) { |
55 scoped_refptr<MockHostResolver> host_resolver(new MockHostResolver); | 135 scoped_refptr<MockHostResolver> host_resolver(new MockHostResolver); |
56 | 136 |
57 // Get a hold of a DefaultJSBindings* (it is a hidden impl class). | 137 // Get a hold of a DefaultJSBindings* (it is a hidden impl class). |
58 scoped_ptr<ProxyResolverJSBindings> bindings( | 138 scoped_ptr<ProxyResolverJSBindings> bindings( |
59 ProxyResolverJSBindings::CreateDefault( | 139 ProxyResolverJSBindings::CreateDefault( |
60 host_resolver, NULL)); | 140 host_resolver, NULL)); |
61 | 141 |
62 // Make it so requests resolve to particular address patterns based on family: | 142 // Make it so requests resolve to particular address patterns based on family: |
63 // IPV4_ONLY --> 192.168.1.* | 143 // IPV4_ONLY --> 192.168.1.* |
64 // UNSPECIFIED --> 192.168.2.1 | 144 // UNSPECIFIED --> 192.168.2.1 |
65 host_resolver->rules()->AddRuleForAddressFamily( | 145 host_resolver->rules()->AddRuleForAddressFamily( |
66 "foo", ADDRESS_FAMILY_IPV4, "192.168.1.1"); | 146 "foo", ADDRESS_FAMILY_IPV4, "192.168.1.1"); |
67 host_resolver->rules()->AddRuleForAddressFamily( | 147 host_resolver->rules()->AddRuleForAddressFamily( |
68 "*", ADDRESS_FAMILY_IPV4, "192.168.1.2"); | 148 "*", ADDRESS_FAMILY_IPV4, "192.168.1.2"); |
69 host_resolver->rules()->AddRuleForAddressFamily( | 149 host_resolver->rules()->AddRuleForAddressFamily( |
70 "*", ADDRESS_FAMILY_UNSPECIFIED, "192.168.2.1"); | 150 "foo", ADDRESS_FAMILY_UNSPECIFIED, "192.168.2.1"); |
| 151 host_resolver->rules()->AddRuleForAddressFamily( |
| 152 "*", ADDRESS_FAMILY_UNSPECIFIED, "192.168.2.2"); |
71 | 153 |
72 // Verify that our mock setups works as expected, and we get different results | 154 // Verify that our mock setups works as expected, and we get different results |
73 // depending if the address family was IPV4_ONLY or not. | 155 // depending if the address family was IPV4_ONLY or not. |
74 HostResolver::RequestInfo info("foo", 80); | 156 HostResolver::RequestInfo info("foo", 80); |
75 AddressList address_list; | 157 AddressList address_list; |
76 EXPECT_EQ(OK, host_resolver->Resolve(info, &address_list, NULL, NULL, NULL)); | 158 EXPECT_EQ(OK, host_resolver->Resolve(info, &address_list, NULL, NULL, NULL)); |
77 EXPECT_EQ("192.168.2.1", NetAddressToString(address_list.head())); | 159 EXPECT_EQ("192.168.2.1", NetAddressToString(address_list.head())); |
78 | 160 |
79 info.set_address_family(ADDRESS_FAMILY_IPV4); | 161 info.set_address_family(ADDRESS_FAMILY_IPV4); |
80 EXPECT_EQ(OK, host_resolver->Resolve(info, &address_list, NULL, NULL, NULL)); | 162 EXPECT_EQ(OK, host_resolver->Resolve(info, &address_list, NULL, NULL, NULL)); |
81 EXPECT_EQ("192.168.1.1", NetAddressToString(address_list.head())); | 163 EXPECT_EQ("192.168.1.1", NetAddressToString(address_list.head())); |
82 | 164 |
83 // Now the actual test. | 165 // Now the actual test. |
84 EXPECT_EQ("192.168.1.2", bindings->MyIpAddress()); | 166 EXPECT_EQ("192.168.1.2", bindings->MyIpAddress()); // IPv4 restricted. |
85 EXPECT_EQ("192.168.1.1", bindings->DnsResolve("foo")); | 167 EXPECT_EQ("192.168.1.1", bindings->DnsResolve("foo")); // IPv4 restricted. |
86 EXPECT_EQ("192.168.1.2", bindings->DnsResolve("foo2")); | 168 EXPECT_EQ("192.168.1.2", bindings->DnsResolve("foo2")); // IPv4 restricted. |
| 169 |
| 170 EXPECT_EQ("192.168.2.2", bindings->MyIpAddressEx()); // Unrestricted. |
| 171 EXPECT_EQ("192.168.2.1", bindings->DnsResolveEx("foo")); // Unrestricted. |
| 172 EXPECT_EQ("192.168.2.2", bindings->DnsResolveEx("foo2")); // Unrestricted. |
| 173 } |
| 174 |
| 175 // Test that myIpAddressEx() and dnsResolveEx() both return a semi-colon |
| 176 // separated list of addresses (as opposed to the non-Ex versions which |
| 177 // just return the first result). |
| 178 TEST(ProxyResolverJSBindingsTest, ExFunctionsReturnList) { |
| 179 scoped_refptr<HostResolver> host_resolver( |
| 180 new MockHostResolverWithMultipleResults); |
| 181 |
| 182 // Get a hold of a DefaultJSBindings* (it is a hidden impl class). |
| 183 scoped_ptr<ProxyResolverJSBindings> bindings( |
| 184 ProxyResolverJSBindings::CreateDefault(host_resolver, NULL)); |
| 185 |
| 186 EXPECT_EQ("192.168.1.1;172.22.34.1;200.100.1.2", |
| 187 bindings->MyIpAddressEx()); |
| 188 |
| 189 EXPECT_EQ("192.168.1.1;172.22.34.1;200.100.1.2", |
| 190 bindings->DnsResolveEx("FOO")); |
87 } | 191 } |
88 | 192 |
89 } // namespace | 193 } // namespace |
90 } // namespace net | 194 } // namespace net |
OLD | NEW |