1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/basictypes.h" 6 #include "net/proxy/proxy_server.h" 7 #include "testing/gtest/include/gtest/gtest.h" 8 9 // Test the creation of ProxyServer using ProxyServer::FromURI, which parses 10 // inputs of the form [<scheme>"://"]<host>[":"<port>]. Verify that each part 11 // was labelled correctly, and the accessors all give the right data. 12 TEST(ProxyServerTest, FromURI) { 13 const struct { 14 const char* input_uri; 15 const char* expected_uri; 16 net::ProxyServer::Scheme expected_scheme; 17 const char* expected_host; 18 int expected_port; 19 const char* expected_pac_string; 20 } tests[] = { 21 // HTTP proxy URIs: 22 { 23 "foopy:10", // No scheme. 24 "foopy:10", 25 net::ProxyServer::SCHEME_HTTP, 26 "foopy", 27 10, 28 "PROXY foopy:10" 29 }, 30 { 31 "http://foopy", // No port. 32 "foopy:80", 33 net::ProxyServer::SCHEME_HTTP, 34 "foopy", 35 80, 36 "PROXY foopy:80" 37 }, 38 { 39 "http://foopy:10", 40 "foopy:10", 41 net::ProxyServer::SCHEME_HTTP, 42 "foopy", 43 10, 44 "PROXY foopy:10" 45 }, 46 47 // IPv6 HTTP proxy URIs: 48 { 49 "[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:10", // No scheme. 50 "[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:10", 51 net::ProxyServer::SCHEME_HTTP, 52 "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", 53 10, 54 "PROXY [FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:10" 55 }, 56 { 57 "http://[3ffe:2a00:100:7031::1]", // No port. 58 "[3ffe:2a00:100:7031::1]:80", 59 net::ProxyServer::SCHEME_HTTP, 60 "3ffe:2a00:100:7031::1", 61 80, 62 "PROXY [3ffe:2a00:100:7031::1]:80" 63 }, 64 { 65 "http://[::192.9.5.5]", 66 "[::192.9.5.5]:80", 67 net::ProxyServer::SCHEME_HTTP, 68 "::192.9.5.5", 69 80, 70 "PROXY [::192.9.5.5]:80" 71 }, 72 { 73 "http://[::FFFF:129.144.52.38]:80", 74 "[::FFFF:129.144.52.38]:80", 75 net::ProxyServer::SCHEME_HTTP, 76 "::FFFF:129.144.52.38", 77 80, 78 "PROXY [::FFFF:129.144.52.38]:80" 79 }, 80 81 // SOCKS4 proxy URIs: 82 { 83 "socks4://foopy", // No port. 84 "socks4://foopy:1080", 85 net::ProxyServer::SCHEME_SOCKS4, 86 "foopy", 87 1080, 88 "SOCKS foopy:1080" 89 }, 90 { 91 "socks4://foopy:10", 92 "socks4://foopy:10", 93 net::ProxyServer::SCHEME_SOCKS4, 94 "foopy", 95 10, 96 "SOCKS foopy:10" 97 }, 98 99 // SOCKS5 proxy URIs 100 { 101 "socks5://foopy", // No port. 102 "socks5://foopy:1080", 103 net::ProxyServer::SCHEME_SOCKS5, 104 "foopy", 105 1080, 106 "SOCKS5 foopy:1080" 107 }, 108 { 109 "socks5://foopy:10", 110 "socks5://foopy:10", 111 net::ProxyServer::SCHEME_SOCKS5, 112 "foopy", 113 10, 114 "SOCKS5 foopy:10" 115 }, 116 117 // SOCKS proxy URIs (should default to SOCKS5) 118 { 119 "socks://foopy", // No port. 120 "socks5://foopy:1080", 121 net::ProxyServer::SCHEME_SOCKS5, 122 "foopy", 123 1080, 124 "SOCKS5 foopy:1080" 125 }, 126 { 127 "socks://foopy:10", 128 "socks5://foopy:10", 129 net::ProxyServer::SCHEME_SOCKS5, 130 "foopy", 131 10, 132 "SOCKS5 foopy:10" 133 }, 134 135 // HTTPS proxy URIs: 136 { 137 "https://foopy", // No port 138 "https://foopy:443", 139 net::ProxyServer::SCHEME_HTTPS, 140 "foopy", 141 443, 142 "HTTPS foopy:443" 143 }, 144 { 145 "https://foopy:10", // Non-standard port 146 "https://foopy:10", 147 net::ProxyServer::SCHEME_HTTPS, 148 "foopy", 149 10, 150 "HTTPS foopy:10" 151 }, 152 { 153 "https://1.2.3.4:10", // IP Address 154 "https://1.2.3.4:10", 155 net::ProxyServer::SCHEME_HTTPS, 156 "1.2.3.4", 157 10, 158 "HTTPS 1.2.3.4:10" 159 }, 160 }; 161 162 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 163 net::ProxyServer uri = 164 net::ProxyServer::FromURI(tests[i].input_uri, 165 net::ProxyServer::SCHEME_HTTP); 166 EXPECT_TRUE(uri.is_valid()); 167 EXPECT_FALSE(uri.is_direct()); 168 EXPECT_EQ(tests[i].expected_uri, uri.ToURI()); 169 EXPECT_EQ(tests[i].expected_scheme, uri.scheme()); 170 EXPECT_EQ(tests[i].expected_host, uri.host_port_pair().host()); 171 EXPECT_EQ(tests[i].expected_port, uri.host_port_pair().port()); 172 EXPECT_EQ(tests[i].expected_pac_string, uri.ToPacString()); 173 } 174 } 175 176 TEST(ProxyServerTest, DefaultConstructor) { 177 net::ProxyServer proxy_server; 178 EXPECT_FALSE(proxy_server.is_valid()); 179 } 180 181 // Test parsing of the special URI form "direct://". Analagous to the "DIRECT" 182 // entry in a PAC result. 183 TEST(ProxyServerTest, Direct) { 184 net::ProxyServer uri = 185 net::ProxyServer::FromURI("direct://", net::ProxyServer::SCHEME_HTTP); 186 EXPECT_TRUE(uri.is_valid()); 187 EXPECT_TRUE(uri.is_direct()); 188 EXPECT_EQ("direct://", uri.ToURI()); 189 EXPECT_EQ("DIRECT", uri.ToPacString()); 190 } 191 192 // Test parsing some invalid inputs. 193 TEST(ProxyServerTest, Invalid) { 194 const char* tests[] = { 195 "", 196 " ", 197 "dddf:", // not a valid port 198 "dddd:d", // not a valid port 199 "http://", // not a valid host/port. 200 "direct://xyz", // direct is not allowed a host/port. 201 "http:/", // ambiguous, but will fail because of bad port. 202 "http:", // ambiguous, but will fail because of bad port. 203 }; 204 205 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 206 net::ProxyServer uri = 207 net::ProxyServer::FromURI(tests[i], net::ProxyServer::SCHEME_HTTP); 208 EXPECT_FALSE(uri.is_valid()); 209 EXPECT_FALSE(uri.is_direct()); 210 EXPECT_FALSE(uri.is_http()); 211 EXPECT_FALSE(uri.is_socks()); 212 } 213 } 214 215 // Test that LWS (SP | HT) is disregarded from the ends. 216 TEST(ProxyServerTest, Whitespace) { 217 const char* tests[] = { 218 " foopy:80", 219 "foopy:80 \t", 220 " \tfoopy:80 ", 221 }; 222 223 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 224 net::ProxyServer uri = 225 net::ProxyServer::FromURI(tests[i], net::ProxyServer::SCHEME_HTTP); 226 EXPECT_EQ("foopy:80", uri.ToURI()); 227 } 228 } 229 230 // Test parsing a ProxyServer from a PAC representation. 231 TEST(ProxyServerTest, FromPACString) { 232 const struct { 233 const char* input_pac; 234 const char* expected_uri; 235 } tests[] = { 236 { 237 "PROXY foopy:10", 238 "foopy:10", 239 }, 240 { 241 " PROXY foopy:10 ", 242 "foopy:10", 243 }, 244 { 245 "pRoXy foopy:10", 246 "foopy:10", 247 }, 248 { 249 "PROXY foopy", // No port. 250 "foopy:80", 251 }, 252 { 253 "socks foopy", 254 "socks4://foopy:1080", 255 }, 256 { 257 "socks4 foopy", 258 "socks4://foopy:1080", 259 }, 260 { 261 "socks5 foopy", 262 "socks5://foopy:1080", 263 }, 264 { 265 "socks5 foopy:11", 266 "socks5://foopy:11", 267 }, 268 { 269 " direct ", 270 "direct://", 271 }, 272 { 273 "https foopy", 274 "https://foopy:443", 275 }, 276 { 277 "https foopy:10", 278 "https://foopy:10", 279 }, 280 }; 281 282 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 283 net::ProxyServer uri = net::ProxyServer::FromPacString(tests[i].input_pac); 284 EXPECT_TRUE(uri.is_valid()); 285 EXPECT_EQ(tests[i].expected_uri, uri.ToURI()); 286 } 287 } 288 289 // Test parsing a ProxyServer from an invalid PAC representation. 290 TEST(ProxyServerTest, FromPACStringInvalid) { 291 const char* tests[] = { 292 "PROXY", // missing host/port. 293 "HTTPS", // missing host/port. 294 "SOCKS", // missing host/port. 295 "DIRECT foopy:10", // direct cannot have host/port. 296 }; 297 298 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 299 net::ProxyServer uri = net::ProxyServer::FromPacString(tests[i]); 300 EXPECT_FALSE(uri.is_valid()); 301 } 302 } 303 304 TEST(ProxyServerTest, ComparatorAndEquality) { 305 struct { 306 // Inputs. 307 const char* server1; 308 const char* server2; 309 310 // Expectation. 311 // -1 means server1 is less than server2 312 // 0 means server1 equals server2 313 // 1 means server1 is greater than server2 314 int expected_comparison; 315 } tests[] = { 316 { // Equal. 317 "foo:11", 318 "http://foo:11", 319 0 320 }, 321 { // Port is different. 322 "foo:333", 323 "foo:444", 324 -1 325 }, 326 { // Host is different. 327 "foo:33", 328 "bar:33", 329 1 330 }, 331 { // Scheme is different. 332 "socks4://foo:33", 333 "http://foo:33", 334 1 335 }, 336 }; 337 338 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 339 // Parse the expected inputs to ProxyServer instances. 340 const net::ProxyServer server1 = 341 net::ProxyServer::FromURI( 342 tests[i].server1, net::ProxyServer::SCHEME_HTTP); 343 344 const net::ProxyServer server2 = 345 net::ProxyServer::FromURI( 346 tests[i].server2, net::ProxyServer::SCHEME_HTTP); 347 348 switch (tests[i].expected_comparison) { 349 case -1: 350 EXPECT_TRUE(server1 < server2); 351 EXPECT_FALSE(server2 < server1); 352 EXPECT_FALSE(server2 == server1); 353 break; 354 case 0: 355 EXPECT_FALSE(server1 < server2); 356 EXPECT_FALSE(server2 < server1); 357 EXPECT_TRUE(server2 == server1); 358 break; 359 case 1: 360 EXPECT_FALSE(server1 < server2); 361 EXPECT_TRUE(server2 < server1); 362 EXPECT_FALSE(server2 == server1); 363 break; 364 default: 365 FAIL() << "Invalid expectation. Can be only -1, 0, 1"; 366 } 367 } 368 } 369