blob: e0b9c91c660bb15769cd0f3768dad980bad2ce8c [file] [log] [blame]
// 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 "net/base/proxy_server.h"
#include "base/stl_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace {
// 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* const input_uri;
const char* const expected_uri;
ProxyServer::Scheme expected_scheme;
const char* const expected_host;
int expected_port;
const char* const expected_pac_string;
} tests[] = {
// HTTP proxy URIs:
{"foopy:10", // No scheme.
"foopy:10",
ProxyServer::SCHEME_HTTP,
"foopy",
10,
"PROXY foopy:10"},
{"http://foopy", // No port.
"foopy:80",
ProxyServer::SCHEME_HTTP,
"foopy",
80,
"PROXY foopy:80"},
{"http://foopy:10",
"foopy:10",
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",
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",
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",
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",
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",
ProxyServer::SCHEME_SOCKS4,
"foopy",
1080,
"SOCKS foopy:1080"},
{"socks4://foopy:10",
"socks4://foopy:10",
ProxyServer::SCHEME_SOCKS4,
"foopy",
10,
"SOCKS foopy:10"},
// SOCKS5 proxy URIs
{"socks5://foopy", // No port.
"socks5://foopy:1080",
ProxyServer::SCHEME_SOCKS5,
"foopy",
1080,
"SOCKS5 foopy:1080"},
{"socks5://foopy:10",
"socks5://foopy:10",
ProxyServer::SCHEME_SOCKS5,
"foopy",
10,
"SOCKS5 foopy:10"},
// SOCKS proxy URIs (should default to SOCKS5)
{"socks://foopy", // No port.
"socks5://foopy:1080",
ProxyServer::SCHEME_SOCKS5,
"foopy",
1080,
"SOCKS5 foopy:1080"},
{"socks://foopy:10",
"socks5://foopy:10",
ProxyServer::SCHEME_SOCKS5,
"foopy",
10,
"SOCKS5 foopy:10"},
// HTTPS proxy URIs:
{"https://foopy", // No port
"https://foopy:443",
ProxyServer::SCHEME_HTTPS,
"foopy",
443,
"HTTPS foopy:443"},
{"https://foopy:10", // Non-standard port
"https://foopy:10",
ProxyServer::SCHEME_HTTPS,
"foopy",
10,
"HTTPS foopy:10"},
{"https://1.2.3.4:10", // IP Address
"https://1.2.3.4:10",
ProxyServer::SCHEME_HTTPS,
"1.2.3.4",
10,
"HTTPS 1.2.3.4:10"},
};
for (size_t i = 0; i < base::size(tests); ++i) {
ProxyServer uri =
ProxyServer::FromURI(tests[i].input_uri, 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) {
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) {
ProxyServer uri = ProxyServer::FromURI("direct://", 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* const 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 < base::size(tests); ++i) {
ProxyServer uri = ProxyServer::FromURI(tests[i], 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* const tests[] = {
" foopy:80",
"foopy:80 \t",
" \tfoopy:80 ",
};
for (size_t i = 0; i < base::size(tests); ++i) {
ProxyServer uri = ProxyServer::FromURI(tests[i], ProxyServer::SCHEME_HTTP);
EXPECT_EQ("foopy:80", uri.ToURI());
}
}
// Test parsing a ProxyServer from a PAC representation.
TEST(ProxyServerTest, FromPACString) {
const struct {
const char* const input_pac;
const char* const 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 < base::size(tests); ++i) {
ProxyServer uri = 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* const 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 < base::size(tests); ++i) {
ProxyServer uri = ProxyServer::FromPacString(tests[i]);
EXPECT_FALSE(uri.is_valid());
}
}
TEST(ProxyServerTest, ComparatorAndEquality) {
const struct {
// Inputs.
ProxyServer server1;
ProxyServer server2;
// Expectation.
// -1 means server1 is less than server2
// 0 means server1 equals server2
// 1 means server1 is greater than server2
int expected_comparison;
} kTests[] = {
{// Equal.
ProxyServer::FromURI("foo:11", ProxyServer::SCHEME_HTTP),
ProxyServer::FromURI("http://foo:11", ProxyServer::SCHEME_HTTP), 0},
{// Port is different.
ProxyServer::FromURI("foo:333", ProxyServer::SCHEME_HTTP),
ProxyServer::FromURI("foo:444", ProxyServer::SCHEME_HTTP), -1},
{// Host is different.
ProxyServer::FromURI("foo:33", ProxyServer::SCHEME_HTTP),
ProxyServer::FromURI("bar:33", ProxyServer::SCHEME_HTTP), 1},
{// Scheme is different.
ProxyServer::FromURI("socks4://foo:33", ProxyServer::SCHEME_HTTP),
ProxyServer::FromURI("http://foo:33", ProxyServer::SCHEME_HTTP), 1},
{// Trusted is different.
ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("foo", 33),
false /* is_trusted_proxy */),
ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("foo", 33),
true /* is_trusted_proxy */),
-1},
};
for (const auto& test : kTests) {
EXPECT_TRUE(test.server1.is_valid());
EXPECT_TRUE(test.server2.is_valid());
switch (test.expected_comparison) {
case -1:
EXPECT_TRUE(test.server1 < test.server2);
EXPECT_FALSE(test.server2 < test.server1);
EXPECT_FALSE(test.server2 == test.server1);
EXPECT_FALSE(test.server1 == test.server2);
break;
case 0:
EXPECT_FALSE(test.server1 < test.server2);
EXPECT_FALSE(test.server2 < test.server1);
EXPECT_TRUE(test.server2 == test.server1);
EXPECT_TRUE(test.server1 == test.server2);
break;
case 1:
EXPECT_FALSE(test.server1 < test.server2);
EXPECT_TRUE(test.server2 < test.server1);
EXPECT_FALSE(test.server2 == test.server1);
EXPECT_FALSE(test.server1 == test.server2);
break;
default:
FAIL() << "Invalid expectation. Can be only -1, 0, 1";
}
}
}
} // namespace
} // namespace net