1 // Copyright 2012 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/host_port_pair.h"
6
7 #include <optional>
8
9 #include "base/values.h"
10 #include "net/test/gtest_util.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "url/gurl.h"
14 #include "url/scheme_host_port.h"
15
16 using std::string;
17 using testing::Optional;
18
19 namespace net {
20
21 namespace {
22
23 struct TestData {
24 string host;
25 uint16_t port;
26 string to_string;
27 string host_for_url;
28 } tests[] = {
29 { "www.google.com", 80, "www.google.com:80", "www.google.com" },
30 { "www.google.com", 443, "www.google.com:443", "www.google.com" },
31 { "127.0.0.1", 80, "127.0.0.1:80", "127.0.0.1" },
32 { "192.168.1.1", 80, "192.168.1.1:80", "192.168.1.1" },
33 { "::1", 80, "[::1]:80", "[::1]" },
34 { "2001:db8::42", 80, "[2001:db8::42]:80", "[2001:db8::42]" },
35 };
36
TEST(HostPortPairTest,Parsing)37 TEST(HostPortPairTest, Parsing) {
38 HostPortPair foo("foo.com", 10);
39 string foo_str = foo.ToString();
40 EXPECT_EQ("foo.com:10", foo_str);
41 HostPortPair bar = HostPortPair::FromString(foo_str);
42 EXPECT_TRUE(foo.Equals(bar));
43 }
44
TEST(HostPortPairTest,ParsingIpv6)45 TEST(HostPortPairTest, ParsingIpv6) {
46 HostPortPair foo("2001:db8::42", 100);
47 string foo_str = foo.ToString();
48 EXPECT_EQ("[2001:db8::42]:100", foo_str);
49 HostPortPair bar = HostPortPair::FromString(foo_str);
50 EXPECT_TRUE(foo.Equals(bar));
51 }
52
TEST(HostPortPairTest,BadString)53 TEST(HostPortPairTest, BadString) {
54 const char* kBadStrings[] = {"foo.com", "foo.com:",
55 "foo.com:2:3", "bar.com:two",
56 "www.google.com:-1", "www.google.com:+1",
57 "127.0.0.1:65536", "[2001:db8::42]:65536",
58 "[2001:db8::42", "2001:db8::42",
59 "2001:db8::42:100", "[2001:db8::42]"};
60
61 for (const auto* const test : kBadStrings) {
62 SCOPED_TRACE(test);
63 HostPortPair foo = HostPortPair::FromString(test);
64 EXPECT_TRUE(foo.host().empty());
65 EXPECT_EQ(0, foo.port());
66 }
67 }
68
TEST(HostPortPairTest,Emptiness)69 TEST(HostPortPairTest, Emptiness) {
70 HostPortPair foo;
71 EXPECT_TRUE(foo.IsEmpty());
72 foo = HostPortPair::FromString("foo.com:8080");
73 EXPECT_FALSE(foo.IsEmpty());
74 }
75
TEST(HostPortPairTest,ToString)76 TEST(HostPortPairTest, ToString) {
77 for (const auto& test : tests) {
78 HostPortPair foo(test.host, test.port);
79 EXPECT_EQ(test.to_string, foo.ToString());
80 }
81
82 // Test empty hostname.
83 HostPortPair foo(string(), 10);
84 }
85
TEST(HostPortPairTest,HostForURL)86 TEST(HostPortPairTest, HostForURL) {
87 for (const auto& test : tests) {
88 HostPortPair foo(test.host, test.port);
89 EXPECT_EQ(test.host_for_url, foo.HostForURL());
90 }
91
92 // Test hostname with null character.
93 string bar_hostname("a\0.\0com", 7);
94 HostPortPair bar(bar_hostname, 80);
95 string expected_error("Host has a null char: a%00.%00com");
96 EXPECT_DFATAL(bar.HostForURL(), expected_error);
97 }
98
TEST(HostPortPairTest,LessThan)99 TEST(HostPortPairTest, LessThan) {
100 HostPortPair a_10("a.com", 10);
101 HostPortPair a_11("a.com", 11);
102 HostPortPair b_10("b.com", 10);
103 HostPortPair b_11("b.com", 11);
104
105 EXPECT_FALSE(a_10 < a_10);
106 EXPECT_TRUE(a_10 < a_11);
107 EXPECT_TRUE(a_10 < b_10);
108 EXPECT_TRUE(a_10 < b_11);
109
110 EXPECT_FALSE(a_11 < a_10);
111 EXPECT_FALSE(a_11 < b_10);
112
113 EXPECT_FALSE(b_10 < a_10);
114 EXPECT_TRUE(b_10 < a_11);
115
116 EXPECT_FALSE(b_11 < a_10);
117 }
118
TEST(HostPortPairTest,Equals)119 TEST(HostPortPairTest, Equals) {
120 HostPortPair a_10("a.com", 10);
121 HostPortPair a_11("a.com", 11);
122 HostPortPair b_10("b.com", 10);
123 HostPortPair b_11("b.com", 11);
124
125 HostPortPair new_a_10("a.com", 10);
126
127 EXPECT_TRUE(new_a_10.Equals(a_10));
128 EXPECT_FALSE(new_a_10.Equals(a_11));
129 EXPECT_FALSE(new_a_10.Equals(b_10));
130 EXPECT_FALSE(new_a_10.Equals(b_11));
131 }
132
TEST(HostPortPairTest,ParsesFromUrl)133 TEST(HostPortPairTest, ParsesFromUrl) {
134 HostPortPair parsed = HostPortPair::FromURL(GURL("https://foo.test:1250"));
135 HostPortPair expected("foo.test", 1250);
136
137 EXPECT_EQ(parsed, expected);
138 }
139
TEST(HostPortPairTest,ParsesFromUrlWithIpv6Brackets)140 TEST(HostPortPairTest, ParsesFromUrlWithIpv6Brackets) {
141 HostPortPair parsed = HostPortPair::FromURL(GURL("https://[::1]"));
142 HostPortPair expected("::1", 443);
143
144 EXPECT_EQ(parsed, expected);
145 }
146
TEST(HostPortPairTest,ParsesFromSchemeHostPort)147 TEST(HostPortPairTest, ParsesFromSchemeHostPort) {
148 HostPortPair parsed = HostPortPair::FromSchemeHostPort(
149 url::SchemeHostPort("ws", "bar.test", 111));
150 HostPortPair expected("bar.test", 111);
151
152 EXPECT_EQ(parsed, expected);
153 }
154
TEST(HostPortPairTest,ParsesFromSchemeHostPortWithIpv6Brackets)155 TEST(HostPortPairTest, ParsesFromSchemeHostPortWithIpv6Brackets) {
156 HostPortPair parsed = HostPortPair::FromSchemeHostPort(
157 url::SchemeHostPort("wss", "[::1022]", 112));
158 HostPortPair expected("::1022", 112);
159
160 EXPECT_EQ(parsed, expected);
161 }
162
TEST(HostPortPairTest,RoundtripThroughValue)163 TEST(HostPortPairTest, RoundtripThroughValue) {
164 HostPortPair pair("foo.test", 1456);
165 base::Value value = pair.ToValue();
166
167 EXPECT_THAT(HostPortPair::FromValue(value), Optional(pair));
168 }
169
TEST(HostPortPairTest,DeserializeGarbageValue)170 TEST(HostPortPairTest, DeserializeGarbageValue) {
171 base::Value value(43);
172 EXPECT_FALSE(HostPortPair::FromValue(value).has_value());
173 }
174
TEST(HostPortPairTest,DeserializeMalformedValues)175 TEST(HostPortPairTest, DeserializeMalformedValues) {
176 base::Value valid_value = HostPortPair("foo.test", 123).ToValue();
177 ASSERT_TRUE(HostPortPair::FromValue(valid_value).has_value());
178
179 base::Value missing_host = valid_value.Clone();
180 ASSERT_TRUE(missing_host.GetDict().Remove("host"));
181 EXPECT_FALSE(HostPortPair::FromValue(missing_host).has_value());
182
183 base::Value missing_port = valid_value.Clone();
184 ASSERT_TRUE(missing_port.GetDict().Remove("port"));
185 EXPECT_FALSE(HostPortPair::FromValue(missing_port).has_value());
186
187 base::Value negative_port = valid_value.Clone();
188 *negative_port.GetDict().Find("port") = base::Value(-1);
189 EXPECT_FALSE(HostPortPair::FromValue(negative_port).has_value());
190
191 base::Value large_port = valid_value.Clone();
192 *large_port.GetDict().Find("port") = base::Value(66000);
193 EXPECT_FALSE(HostPortPair::FromValue(large_port).has_value());
194 }
195
196 } // namespace
197
198 } // namespace net
199