// Copyright (c) 2010 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.
#include "base/basictypes.h"
#include "net/proxy/proxy_server.h"
#include "testing/gtest/include/gtest/gtest.h"
// Test the creation of ProxyServer using ProxyServer::FromURI, which parses
// inputs of the form [<scheme>"://"]<host>[":"<port>]. Verify that each part
// was labelled correctly, and the accessors all give the right data.
TEST(ProxyServerTest, FromURI) {
const struct {
const char* input_uri;
const char* expected_uri;
net::ProxyServer::Scheme expected_scheme;
const char* expected_host;
int expected_port;
const char* expected_pac_string;
} tests[] = {
// HTTP proxy URIs:
{
"foopy:10", // No scheme.
"foopy:10",
net::ProxyServer::SCHEME_HTTP,
"foopy",
10,
"PROXY foopy:10"
},
{
"http://foopy", // No port.
"foopy:80",
net::ProxyServer::SCHEME_HTTP,
"foopy",
80,
"PROXY foopy:80"
},
{
"http://foopy:10",
"foopy:10",
net::ProxyServer::SCHEME_HTTP,
"foopy",
10,
"PROXY foopy:10"
},
// IPv6 HTTP proxy URIs:
{
"[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:10", // No scheme.
"[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:10",
net::ProxyServer::SCHEME_HTTP,
"FEDC:BA98:7654:3210:FEDC:BA98:7654:3210",
10,
"PROXY [FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:10"
},
{
"http://[3ffe:2a00:100:7031::1]", // No port.
"[3ffe:2a00:100:7031::1]:80",
net::ProxyServer::SCHEME_HTTP,
"3ffe:2a00:100:7031::1",
80,
"PROXY [3ffe:2a00:100:7031::1]:80"
},
{
"http://[::192.9.5.5]",
"[::192.9.5.5]:80",
net::ProxyServer::SCHEME_HTTP,
"::192.9.5.5",
80,
"PROXY [::192.9.5.5]:80"
},
{
"http://[::FFFF:129.144.52.38]:80",
"[::FFFF:129.144.52.38]:80",
net::ProxyServer::SCHEME_HTTP,
"::FFFF:129.144.52.38",
80,
"PROXY [::FFFF:129.144.52.38]:80"
},
// SOCKS4 proxy URIs:
{
"socks4://foopy", // No port.
"socks4://foopy:1080",
net::ProxyServer::SCHEME_SOCKS4,
"foopy",
1080,
"SOCKS foopy:1080"
},
{
"socks4://foopy:10",
"socks4://foopy:10",
net::ProxyServer::SCHEME_SOCKS4,
"foopy",
10,
"SOCKS foopy:10"
},
// SOCKS5 proxy URIs
{
"socks5://foopy", // No port.
"socks5://foopy:1080",
net::ProxyServer::SCHEME_SOCKS5,
"foopy",
1080,
"SOCKS5 foopy:1080"
},
{
"socks5://foopy:10",
"socks5://foopy:10",
net::ProxyServer::SCHEME_SOCKS5,
"foopy",
10,
"SOCKS5 foopy:10"
},
// SOCKS proxy URIs (should default to SOCKS5)
{
"socks://foopy", // No port.
"socks5://foopy:1080",
net::ProxyServer::SCHEME_SOCKS5,
"foopy",
1080,
"SOCKS5 foopy:1080"
},
{
"socks://foopy:10",
"socks5://foopy:10",
net::ProxyServer::SCHEME_SOCKS5,
"foopy",
10,
"SOCKS5 foopy:10"
},
// HTTPS proxy URIs:
{
"https://foopy", // No port
"https://foopy:443",
net::ProxyServer::SCHEME_HTTPS,
"foopy",
443,
"HTTPS foopy:443"
},
{
"https://foopy:10", // Non-standard port
"https://foopy:10",
net::ProxyServer::SCHEME_HTTPS,
"foopy",
10,
"HTTPS foopy:10"
},
{
"https://1.2.3.4:10", // IP Address
"https://1.2.3.4:10",
net::ProxyServer::SCHEME_HTTPS,
"1.2.3.4",
10,
"HTTPS 1.2.3.4:10"
},
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
net::ProxyServer uri =
net::ProxyServer::FromURI(tests[i].input_uri,
net::ProxyServer::SCHEME_HTTP);
EXPECT_TRUE(uri.is_valid());
EXPECT_FALSE(uri.is_direct());
EXPECT_EQ(tests[i].expected_uri, uri.ToURI());
EXPECT_EQ(tests[i].expected_scheme, uri.scheme());
EXPECT_EQ(tests[i].expected_host, uri.host_port_pair().host());
EXPECT_EQ(tests[i].expected_port, uri.host_port_pair().port());
EXPECT_EQ(tests[i].expected_pac_string, uri.ToPacString());
}
}
TEST(ProxyServerTest, DefaultConstructor) {
net::ProxyServer proxy_server;
EXPECT_FALSE(proxy_server.is_valid());
}
// Test parsing of the special URI form "direct://". Analagous to the "DIRECT"
// entry in a PAC result.
TEST(ProxyServerTest, Direct) {
net::ProxyServer uri =
net::ProxyServer::FromURI("direct://", net::ProxyServer::SCHEME_HTTP);
EXPECT_TRUE(uri.is_valid());
EXPECT_TRUE(uri.is_direct());
EXPECT_EQ("direct://", uri.ToURI());
EXPECT_EQ("DIRECT", uri.ToPacString());
}
// Test parsing some invalid inputs.
TEST(ProxyServerTest, Invalid) {
const char* tests[] = {
"",
" ",
"dddf:", // not a valid port
"dddd:d", // not a valid port
"http://", // not a valid host/port.
"direct://xyz", // direct is not allowed a host/port.
"http:/", // ambiguous, but will fail because of bad port.
"http:", // ambiguous, but will fail because of bad port.
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
net::ProxyServer uri =
net::ProxyServer::FromURI(tests[i], net::ProxyServer::SCHEME_HTTP);
EXPECT_FALSE(uri.is_valid());
EXPECT_FALSE(uri.is_direct());
EXPECT_FALSE(uri.is_http());
EXPECT_FALSE(uri.is_socks());
}
}
// Test that LWS (SP | HT) is disregarded from the ends.
TEST(ProxyServerTest, Whitespace) {
const char* tests[] = {
" foopy:80",
"foopy:80 \t",
" \tfoopy:80 ",
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
net::ProxyServer uri =
net::ProxyServer::FromURI(tests[i], net::ProxyServer::SCHEME_HTTP);
EXPECT_EQ("foopy:80", uri.ToURI());
}
}
// Test parsing a ProxyServer from a PAC representation.
TEST(ProxyServerTest, FromPACString) {
const struct {
const char* input_pac;
const char* expected_uri;
} tests[] = {
{
"PROXY foopy:10",
"foopy:10",
},
{
" PROXY foopy:10 ",
"foopy:10",
},
{
"pRoXy foopy:10",
"foopy:10",
},
{
"PROXY foopy", // No port.
"foopy:80",
},
{
"socks foopy",
"socks4://foopy:1080",
},
{
"socks4 foopy",
"socks4://foopy:1080",
},
{
"socks5 foopy",
"socks5://foopy:1080",
},
{
"socks5 foopy:11",
"socks5://foopy:11",
},
{
" direct ",
"direct://",
},
{
"https foopy",
"https://foopy:443",
},
{
"https foopy:10",
"https://foopy:10",
},
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
net::ProxyServer uri = net::ProxyServer::FromPacString(tests[i].input_pac);
EXPECT_TRUE(uri.is_valid());
EXPECT_EQ(tests[i].expected_uri, uri.ToURI());
}
}
// Test parsing a ProxyServer from an invalid PAC representation.
TEST(ProxyServerTest, FromPACStringInvalid) {
const char* tests[] = {
"PROXY", // missing host/port.
"HTTPS", // missing host/port.
"SOCKS", // missing host/port.
"DIRECT foopy:10", // direct cannot have host/port.
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
net::ProxyServer uri = net::ProxyServer::FromPacString(tests[i]);
EXPECT_FALSE(uri.is_valid());
}
}
TEST(ProxyServerTest, ComparatorAndEquality) {
struct {
// Inputs.
const char* server1;
const char* server2;
// Expectation.
// -1 means server1 is less than server2
// 0 means server1 equals server2
// 1 means server1 is greater than server2
int expected_comparison;
} tests[] = {
{ // Equal.
"foo:11",
"http://foo:11",
0
},
{ // Port is different.
"foo:333",
"foo:444",
-1
},
{ // Host is different.
"foo:33",
"bar:33",
1
},
{ // Scheme is different.
"socks4://foo:33",
"http://foo:33",
1
},
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
// Parse the expected inputs to ProxyServer instances.
const net::ProxyServer server1 =
net::ProxyServer::FromURI(
tests[i].server1, net::ProxyServer::SCHEME_HTTP);
const net::ProxyServer server2 =
net::ProxyServer::FromURI(
tests[i].server2, net::ProxyServer::SCHEME_HTTP);
switch (tests[i].expected_comparison) {
case -1:
EXPECT_TRUE(server1 < server2);
EXPECT_FALSE(server2 < server1);
EXPECT_FALSE(server2 == server1);
break;
case 0:
EXPECT_FALSE(server1 < server2);
EXPECT_FALSE(server2 < server1);
EXPECT_TRUE(server2 == server1);
break;
case 1:
EXPECT_FALSE(server1 < server2);
EXPECT_TRUE(server2 < server1);
EXPECT_FALSE(server2 == server1);
break;
default:
FAIL() << "Invalid expectation. Can be only -1, 0, 1";
}
}
}