// Copyright (c) 2009 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_host_and_port;
const char* expected_pac_string;
} tests[] = {
// HTTP proxy URIs:
{
"foopy:10", // No scheme.
"foopy:10",
net::ProxyServer::SCHEME_HTTP,
"foopy",
10,
"foopy:10",
"PROXY foopy:10"
},
{
"http://foopy", // No port.
"foopy:80",
net::ProxyServer::SCHEME_HTTP,
"foopy",
80,
"foopy:80",
"PROXY foopy:80"
},
{
"http://foopy:10",
"foopy:10",
net::ProxyServer::SCHEME_HTTP,
"foopy",
10,
"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,
"[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,
"[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,
"[::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,
"[::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,
"foopy:1080",
"SOCKS foopy:1080"
},
{
"socks4://foopy:10",
"socks4://foopy:10",
net::ProxyServer::SCHEME_SOCKS4,
"foopy",
10,
"foopy:10",
"SOCKS foopy:10"
},
// SOCKS5 proxy URIs
{
"socks5://foopy", // No port.
"socks5://foopy:1080",
net::ProxyServer::SCHEME_SOCKS5,
"foopy",
1080,
"foopy:1080",
"SOCKS5 foopy:1080"
},
{
"socks5://foopy:10",
"socks5://foopy:10",
net::ProxyServer::SCHEME_SOCKS5,
"foopy",
10,
"foopy:10",
"SOCKS5 foopy:10"
},
// SOCKS proxy URIs (should default to SOCKS4)
{
"socks://foopy", // No port.
"socks4://foopy:1080",
net::ProxyServer::SCHEME_SOCKS4,
"foopy",
1080,
"foopy:1080",
"SOCKS foopy:1080"
},
{
"socks://foopy:10",
"socks4://foopy:10",
net::ProxyServer::SCHEME_SOCKS4,
"foopy",
10,
"foopy:10",
"SOCKS foopy: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.HostNoBrackets());
EXPECT_EQ(tests[i].expected_port, uri.port());
EXPECT_EQ(tests[i].expected_host_and_port, uri.host_and_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.
"https://blah", // "https" is not a valid proxy scheme.
};
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://",
},
};
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.
"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());
}
}