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