• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2010 The Chromium Authors
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 "net/base/proxy_server.h"
6 
7 #include "base/strings/string_number_conversions.h"
8 #include "net/base/proxy_string_util.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "third_party/abseil-cpp/absl/types/optional.h"
11 
12 namespace net {
13 
14 namespace {
15 
TEST(ProxyServerTest,DefaultConstructor)16 TEST(ProxyServerTest, DefaultConstructor) {
17   ProxyServer proxy_server;
18   EXPECT_FALSE(proxy_server.is_valid());
19 }
20 
TEST(ProxyServerTest,FromSchemeHostAndPort)21 TEST(ProxyServerTest, FromSchemeHostAndPort) {
22   const struct {
23     const ProxyServer::Scheme input_scheme;
24     const char* const input_host;
25     const absl::optional<uint16_t> input_port;
26     const char* const input_port_str;
27     const char* const expected_host;
28     const uint16_t expected_port;
29   } tests[] = {
30       {ProxyServer::SCHEME_HTTP, "foopy", 80, "80", "foopy", 80},
31 
32       // Non-standard port
33       {ProxyServer::SCHEME_HTTP, "foopy", 10, "10", "foopy", 10},
34       {ProxyServer::SCHEME_HTTP, "foopy", 0, "0", "foopy", 0},
35 
36       // Hostname canonicalization
37       {ProxyServer::SCHEME_HTTP, "FoOpY", 80, "80", "foopy", 80},
38       {ProxyServer::SCHEME_HTTP, "f\u00fcpy", 80, "80", "xn--fpy-hoa", 80},
39 
40       // IPv4 literal
41       {ProxyServer::SCHEME_HTTP, "1.2.3.4", 80, "80", "1.2.3.4", 80},
42 
43       // IPv4 literal canonicalization
44       {ProxyServer::SCHEME_HTTP, "127.1", 80, "80", "127.0.0.1", 80},
45       {ProxyServer::SCHEME_HTTP, "0x7F.0x1", 80, "80", "127.0.0.1", 80},
46       {ProxyServer::SCHEME_HTTP, "0177.01", 80, "80", "127.0.0.1", 80},
47 
48       // IPv6 literal
49       {ProxyServer::SCHEME_HTTP, "[3ffe:2a00:100:7031::1]", 80, "80",
50        "[3ffe:2a00:100:7031::1]", 80},
51       {ProxyServer::SCHEME_HTTP, "3ffe:2a00:100:7031::1", 80, "80",
52        "[3ffe:2a00:100:7031::1]", 80},
53 
54       // IPv6 literal canonicalization
55       {ProxyServer::SCHEME_HTTP, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", 80,
56        "80", "[fedc:ba98:7654:3210:fedc:ba98:7654:3210]", 80},
57       {ProxyServer::SCHEME_HTTP, "::192.9.5.5", 80, "80", "[::c009:505]", 80},
58 
59       // Other schemes
60       {ProxyServer::SCHEME_HTTPS, "foopy", 111, "111", "foopy", 111},
61       {ProxyServer::SCHEME_QUIC, "foopy", 111, "111", "foopy", 111},
62       {ProxyServer::SCHEME_SOCKS4, "foopy", 111, "111", "foopy", 111},
63       {ProxyServer::SCHEME_SOCKS5, "foopy", 111, "111", "foopy", 111},
64 
65       // Default ports
66       {ProxyServer::SCHEME_HTTP, "foopy", absl::nullopt, "", "foopy", 80},
67       {ProxyServer::SCHEME_HTTPS, "foopy", absl::nullopt, "", "foopy", 443},
68       {ProxyServer::SCHEME_QUIC, "foopy", absl::nullopt, "", "foopy", 443},
69       {ProxyServer::SCHEME_SOCKS4, "foopy", absl::nullopt, "", "foopy", 1080},
70       {ProxyServer::SCHEME_SOCKS5, "foopy", absl::nullopt, "", "foopy", 1080},
71   };
72 
73   for (size_t i = 0; i < std::size(tests); ++i) {
74     SCOPED_TRACE(base::NumberToString(i) + ": " + tests[i].input_host + ":" +
75                  base::NumberToString(tests[i].input_port.value_or(-1)));
76     auto proxy = ProxyServer::FromSchemeHostAndPort(
77         tests[i].input_scheme, tests[i].input_host, tests[i].input_port);
78 
79     ASSERT_TRUE(proxy.is_valid());
80     EXPECT_EQ(proxy.scheme(), tests[i].input_scheme);
81     EXPECT_EQ(proxy.GetHost(), tests[i].expected_host);
82     EXPECT_EQ(proxy.GetPort(), tests[i].expected_port);
83 
84     auto proxy_from_string_port = ProxyServer::FromSchemeHostAndPort(
85         tests[i].input_scheme, tests[i].input_host, tests[i].input_port_str);
86     EXPECT_TRUE(proxy_from_string_port.is_valid());
87     EXPECT_EQ(proxy, proxy_from_string_port);
88   }
89 }
90 
TEST(ProxyServerTest,InvalidHostname)91 TEST(ProxyServerTest, InvalidHostname) {
92   const char* const tests[]{
93       "",
94       "[]",
95       "[foo]",
96       "foo:",
97       "foo:80",
98       ":",
99       "http://foo",
100       "3ffe:2a00:100:7031::1]",
101       "[3ffe:2a00:100:7031::1",
102       "foo.80",
103   };
104 
105   for (size_t i = 0; i < std::size(tests); ++i) {
106     SCOPED_TRACE(base::NumberToString(i) + ": " + tests[i]);
107     auto proxy = ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTP,
108                                                     tests[i], 80);
109     EXPECT_FALSE(proxy.is_valid());
110   }
111 }
112 
TEST(ProxyServerTest,InvalidPort)113 TEST(ProxyServerTest, InvalidPort) {
114   const char* const tests[]{
115       "-1",
116       "65536",
117       "foo",
118       "0x35",
119   };
120 
121   for (size_t i = 0; i < std::size(tests); ++i) {
122     SCOPED_TRACE(base::NumberToString(i) + ": " + tests[i]);
123     auto proxy = ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTP,
124                                                     "foopy", tests[i]);
125     EXPECT_FALSE(proxy.is_valid());
126   }
127 }
128 
TEST(ProxyServerTest,ComparatorAndEquality)129 TEST(ProxyServerTest, ComparatorAndEquality) {
130   const struct {
131     // Inputs.
132     ProxyServer server1;
133     ProxyServer server2;
134 
135     // Expectation.
136     //   -1 means server1 is less than server2
137     //    0 means server1 equals server2
138     //    1 means server1 is greater than server2
139     int expected_comparison;
140   } kTests[] = {
141       {// Equal.
142        ProxyUriToProxyServer("foo:11", ProxyServer::SCHEME_HTTP),
143        ProxyUriToProxyServer("http://foo:11", ProxyServer::SCHEME_HTTP), 0},
144       {// Port is different.
145        ProxyUriToProxyServer("foo:333", ProxyServer::SCHEME_HTTP),
146        ProxyUriToProxyServer("foo:444", ProxyServer::SCHEME_HTTP), -1},
147       {// Host is different.
148        ProxyUriToProxyServer("foo:33", ProxyServer::SCHEME_HTTP),
149        ProxyUriToProxyServer("bar:33", ProxyServer::SCHEME_HTTP), 1},
150       {// Scheme is different.
151        ProxyUriToProxyServer("socks4://foo:33", ProxyServer::SCHEME_HTTP),
152        ProxyUriToProxyServer("http://foo:33", ProxyServer::SCHEME_HTTP), 1},
153   };
154 
155   for (const auto& test : kTests) {
156     EXPECT_TRUE(test.server1.is_valid());
157     EXPECT_TRUE(test.server2.is_valid());
158 
159     switch (test.expected_comparison) {
160       case -1:
161         EXPECT_TRUE(test.server1 < test.server2);
162         EXPECT_FALSE(test.server2 < test.server1);
163         EXPECT_FALSE(test.server2 == test.server1);
164         EXPECT_FALSE(test.server1 == test.server2);
165         break;
166       case 0:
167         EXPECT_FALSE(test.server1 < test.server2);
168         EXPECT_FALSE(test.server2 < test.server1);
169         EXPECT_TRUE(test.server2 == test.server1);
170         EXPECT_TRUE(test.server1 == test.server2);
171         break;
172       case 1:
173         EXPECT_FALSE(test.server1 < test.server2);
174         EXPECT_TRUE(test.server2 < test.server1);
175         EXPECT_FALSE(test.server2 == test.server1);
176         EXPECT_FALSE(test.server1 == test.server2);
177         break;
178       default:
179         FAIL() << "Invalid expectation. Can be only -1, 0, 1";
180     }
181   }
182 }
183 
184 // Tests the various "is_*()" methods on ProxyServer.
TEST(ProxyServerTest,Properties)185 TEST(ProxyServerTest, Properties) {
186   // HTTP proxy.
187   {
188     auto proxy = PacResultElementToProxyServer("PROXY foo");
189     ASSERT_TRUE(proxy.is_valid());
190     EXPECT_TRUE(proxy.is_http());
191     EXPECT_FALSE(proxy.is_https());
192     EXPECT_TRUE(proxy.is_http_like());
193     EXPECT_FALSE(proxy.is_secure_http_like());
194   }
195 
196   // HTTPS proxy.
197   {
198     auto proxy = PacResultElementToProxyServer("HTTPS foo");
199     ASSERT_TRUE(proxy.is_valid());
200     EXPECT_FALSE(proxy.is_http());
201     EXPECT_TRUE(proxy.is_https());
202     EXPECT_TRUE(proxy.is_http_like());
203     EXPECT_TRUE(proxy.is_secure_http_like());
204   }
205 
206   // QUIC proxy.
207   {
208     auto proxy = PacResultElementToProxyServer("QUIC foo");
209     ASSERT_TRUE(proxy.is_valid());
210     EXPECT_FALSE(proxy.is_http());
211     EXPECT_FALSE(proxy.is_https());
212     EXPECT_TRUE(proxy.is_http_like());
213     EXPECT_TRUE(proxy.is_secure_http_like());
214   }
215 
216   // SOCKS5 proxy.
217   {
218     auto proxy = PacResultElementToProxyServer("SOCKS5 foo");
219     ASSERT_TRUE(proxy.is_valid());
220     EXPECT_FALSE(proxy.is_http());
221     EXPECT_FALSE(proxy.is_https());
222     EXPECT_FALSE(proxy.is_http_like());
223     EXPECT_FALSE(proxy.is_secure_http_like());
224   }
225 
226   // DIRECT
227   {
228     auto proxy = PacResultElementToProxyServer("DIRECT");
229     ASSERT_TRUE(proxy.is_valid());
230     EXPECT_FALSE(proxy.is_http());
231     EXPECT_FALSE(proxy.is_https());
232     EXPECT_FALSE(proxy.is_http_like());
233     EXPECT_FALSE(proxy.is_secure_http_like());
234   }
235 }
236 
237 }  // namespace
238 
239 }  // namespace net
240