blob: dd928fcbea1794f91a04ca5e911d506f94b02f5c [file] [log] [blame]
[email protected]51bcc5d2013-04-24 01:41:371// Copyright 2013 The Chromium Authors. All rights reserved.
[email protected]07abf6ab2013-04-10 21:41:042// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
[email protected]e7bba5f82013-04-10 20:10:524
avic0c60312015-12-21 21:03:505#include <stddef.h>
6
Lei Zhangddedb062021-06-17 18:11:417#include "base/cxx17_backports.h"
Lukasz Anforowiczc664e8b2020-04-13 20:08:558#include "base/strings/string_number_conversions.h"
brettw1b8582f2016-11-03 20:37:179#include "base/strings/utf_string_conversions.h"
[email protected]e7bba5f82013-04-10 20:10:5210#include "testing/gtest/include/gtest/gtest.h"
[email protected]318076b2013-04-18 21:19:4511#include "url/gurl.h"
Lukasz Anforowicz875905b42021-01-12 16:54:5112#include "url/gurl_abstract_tests.h"
Lukasz Anforowiczc664e8b2020-04-13 20:08:5513#include "url/origin.h"
[email protected]318076b2013-04-18 21:19:4514#include "url/url_canon.h"
15#include "url/url_test_utils.h"
[email protected]e7bba5f82013-04-10 20:10:5216
[email protected]0318f922014-04-22 00:09:2317namespace url {
18
[email protected]e7bba5f82013-04-10 20:10:5219namespace {
20
21template<typename CHAR>
[email protected]0318f922014-04-22 00:09:2322void SetupReplacement(
23 void (Replacements<CHAR>::*func)(const CHAR*, const Component&),
24 Replacements<CHAR>* replacements,
25 const CHAR* str) {
[email protected]e7bba5f82013-04-10 20:10:5226 if (str) {
[email protected]0318f922014-04-22 00:09:2327 Component comp;
[email protected]e7bba5f82013-04-10 20:10:5228 if (str[0])
29 comp.len = static_cast<int>(strlen(str));
30 (replacements->*func)(str, comp);
31 }
32}
33
34// Returns the canonicalized string for the given URL string for the
35// GURLTest.Types test.
36std::string TypesTestCase(const char* src) {
37 GURL gurl(src);
38 return gurl.possibly_invalid_spec();
39}
40
41} // namespace
42
[email protected]47e365d2014-05-02 00:02:2543// Different types of URLs should be handled differently, and handed off to
44// different canonicalizers.
[email protected]e7bba5f82013-04-10 20:10:5245TEST(GURLTest, Types) {
46 // URLs with unknown schemes should be treated as path URLs, even when they
47 // have things like "://".
48 EXPECT_EQ("something:///HOSTNAME.com/",
49 TypesTestCase("something:///HOSTNAME.com/"));
50
qyearsley2bc727d2015-08-14 20:17:1551 // Conversely, URLs with known schemes should always trigger standard URL
52 // handling.
[email protected]e7bba5f82013-04-10 20:10:5253 EXPECT_EQ("http://hostname.com/", TypesTestCase("http:HOSTNAME.com"));
54 EXPECT_EQ("http://hostname.com/", TypesTestCase("http:/HOSTNAME.com"));
55 EXPECT_EQ("http://hostname.com/", TypesTestCase("http://HOSTNAME.com"));
56 EXPECT_EQ("http://hostname.com/", TypesTestCase("http:///HOSTNAME.com"));
57
58#ifdef WIN32
qyearsley2bc727d2015-08-14 20:17:1559 // URLs that look like Windows absolute path specs.
[email protected]e7bba5f82013-04-10 20:10:5260 EXPECT_EQ("file:///C:/foo.txt", TypesTestCase("c:\\foo.txt"));
61 EXPECT_EQ("file:///Z:/foo.txt", TypesTestCase("Z|foo.txt"));
62 EXPECT_EQ("file://server/foo.txt", TypesTestCase("\\\\server\\foo.txt"));
63 EXPECT_EQ("file://server/foo.txt", TypesTestCase("//server/foo.txt"));
64#endif
65}
66
qyearsley2bc727d2015-08-14 20:17:1567// Test the basic creation and querying of components in a GURL. We assume that
[email protected]e7bba5f82013-04-10 20:10:5268// the parser is already tested and works, so we are mostly interested if the
69// object does the right thing with the results.
70TEST(GURLTest, Components) {
Jan Wilken Dörrie2c470ea2021-03-22 22:26:2471 GURL empty_url(u"");
mblsha93895b12016-01-18 14:07:5272 EXPECT_TRUE(empty_url.is_empty());
73 EXPECT_FALSE(empty_url.is_valid());
74
Jan Wilken Dörrie2c470ea2021-03-22 22:26:2475 GURL url(u"http://user:[email protected]:99/foo;bar?q=a#ref");
mblsha93895b12016-01-18 14:07:5276 EXPECT_FALSE(url.is_empty());
[email protected]e7bba5f82013-04-10 20:10:5277 EXPECT_TRUE(url.is_valid());
78 EXPECT_TRUE(url.SchemeIs("http"));
79 EXPECT_FALSE(url.SchemeIsFile());
80
81 // This is the narrow version of the URL, which should match the wide input.
82 EXPECT_EQ("http://user:[email protected]:99/foo;bar?q=a#ref", url.spec());
83
84 EXPECT_EQ("http", url.scheme());
85 EXPECT_EQ("user", url.username());
86 EXPECT_EQ("pass", url.password());
87 EXPECT_EQ("google.com", url.host());
88 EXPECT_EQ("99", url.port());
89 EXPECT_EQ(99, url.IntPort());
90 EXPECT_EQ("/foo;bar", url.path());
91 EXPECT_EQ("q=a", url.query());
92 EXPECT_EQ("ref", url.ref());
[email protected]e9185c82014-04-18 10:06:5093
94 // Test parsing userinfo with special characters.
95 GURL url_special_pass("http://user:%40!$&'()*+,;=:@google.com:12345");
96 EXPECT_TRUE(url_special_pass.is_valid());
97 // GURL canonicalizes some delimiters.
98 EXPECT_EQ("%40!$&%27()*+,%3B%3D%3A", url_special_pass.password());
99 EXPECT_EQ("google.com", url_special_pass.host());
100 EXPECT_EQ("12345", url_special_pass.port());
[email protected]e7bba5f82013-04-10 20:10:52101}
102
103TEST(GURLTest, Empty) {
104 GURL url;
105 EXPECT_FALSE(url.is_valid());
106 EXPECT_EQ("", url.spec());
107
108 EXPECT_EQ("", url.scheme());
109 EXPECT_EQ("", url.username());
110 EXPECT_EQ("", url.password());
111 EXPECT_EQ("", url.host());
112 EXPECT_EQ("", url.port());
[email protected]0318f922014-04-22 00:09:23113 EXPECT_EQ(PORT_UNSPECIFIED, url.IntPort());
[email protected]e7bba5f82013-04-10 20:10:52114 EXPECT_EQ("", url.path());
115 EXPECT_EQ("", url.query());
116 EXPECT_EQ("", url.ref());
117}
118
119TEST(GURLTest, Copy) {
Peter Kastingcc07b332021-05-07 22:58:25120 GURL url(u"http://user:[email protected]:99/foo;bar?q=a#ref");
[email protected]e7bba5f82013-04-10 20:10:52121
122 GURL url2(url);
123 EXPECT_TRUE(url2.is_valid());
124
125 EXPECT_EQ("http://user:[email protected]:99/foo;bar?q=a#ref", url2.spec());
126 EXPECT_EQ("http", url2.scheme());
127 EXPECT_EQ("user", url2.username());
128 EXPECT_EQ("pass", url2.password());
129 EXPECT_EQ("google.com", url2.host());
130 EXPECT_EQ("99", url2.port());
131 EXPECT_EQ(99, url2.IntPort());
132 EXPECT_EQ("/foo;bar", url2.path());
133 EXPECT_EQ("q=a", url2.query());
134 EXPECT_EQ("ref", url2.ref());
135
136 // Copying of invalid URL should be invalid
137 GURL invalid;
138 GURL invalid2(invalid);
139 EXPECT_FALSE(invalid2.is_valid());
140 EXPECT_EQ("", invalid2.spec());
141 EXPECT_EQ("", invalid2.scheme());
142 EXPECT_EQ("", invalid2.username());
143 EXPECT_EQ("", invalid2.password());
144 EXPECT_EQ("", invalid2.host());
145 EXPECT_EQ("", invalid2.port());
[email protected]0318f922014-04-22 00:09:23146 EXPECT_EQ(PORT_UNSPECIFIED, invalid2.IntPort());
[email protected]e7bba5f82013-04-10 20:10:52147 EXPECT_EQ("", invalid2.path());
148 EXPECT_EQ("", invalid2.query());
149 EXPECT_EQ("", invalid2.ref());
150}
151
[email protected]8093a31b2013-10-24 21:56:33152TEST(GURLTest, Assign) {
Peter Kastingcc07b332021-05-07 22:58:25153 GURL url(u"http://user:[email protected]:99/foo;bar?q=a#ref");
[email protected]8093a31b2013-10-24 21:56:33154
155 GURL url2;
156 url2 = url;
157 EXPECT_TRUE(url2.is_valid());
158
159 EXPECT_EQ("http://user:[email protected]:99/foo;bar?q=a#ref", url2.spec());
160 EXPECT_EQ("http", url2.scheme());
161 EXPECT_EQ("user", url2.username());
162 EXPECT_EQ("pass", url2.password());
163 EXPECT_EQ("google.com", url2.host());
164 EXPECT_EQ("99", url2.port());
165 EXPECT_EQ(99, url2.IntPort());
166 EXPECT_EQ("/foo;bar", url2.path());
167 EXPECT_EQ("q=a", url2.query());
168 EXPECT_EQ("ref", url2.ref());
169
170 // Assignment of invalid URL should be invalid
171 GURL invalid;
172 GURL invalid2;
173 invalid2 = invalid;
174 EXPECT_FALSE(invalid2.is_valid());
175 EXPECT_EQ("", invalid2.spec());
176 EXPECT_EQ("", invalid2.scheme());
177 EXPECT_EQ("", invalid2.username());
178 EXPECT_EQ("", invalid2.password());
179 EXPECT_EQ("", invalid2.host());
180 EXPECT_EQ("", invalid2.port());
[email protected]0318f922014-04-22 00:09:23181 EXPECT_EQ(PORT_UNSPECIFIED, invalid2.IntPort());
[email protected]8093a31b2013-10-24 21:56:33182 EXPECT_EQ("", invalid2.path());
183 EXPECT_EQ("", invalid2.query());
184 EXPECT_EQ("", invalid2.ref());
185}
186
qyearsley2bc727d2015-08-14 20:17:15187// This is a regression test for http://crbug.com/309975.
[email protected]8093a31b2013-10-24 21:56:33188TEST(GURLTest, SelfAssign) {
189 GURL a("filesystem:http://example.com/temporary/");
190 // This should not crash.
Hans Wennborg792903f2018-04-09 11:20:06191 a = *&a; // The *& defeats Clang's -Wself-assign warning.
[email protected]8093a31b2013-10-24 21:56:33192}
193
[email protected]e7bba5f82013-04-10 20:10:52194TEST(GURLTest, CopyFileSystem) {
Peter Kastingcc07b332021-05-07 22:58:25195 GURL url(u"filesystem:https://user:[email protected]:99/t/foo;bar?q=a#ref");
[email protected]e7bba5f82013-04-10 20:10:52196
197 GURL url2(url);
198 EXPECT_TRUE(url2.is_valid());
199
Nick Carterff69a102018-04-04 00:15:17200 EXPECT_EQ("filesystem:https://google.com:99/t/foo;bar?q=a#ref", url2.spec());
[email protected]e7bba5f82013-04-10 20:10:52201 EXPECT_EQ("filesystem", url2.scheme());
202 EXPECT_EQ("", url2.username());
203 EXPECT_EQ("", url2.password());
204 EXPECT_EQ("", url2.host());
205 EXPECT_EQ("", url2.port());
[email protected]0318f922014-04-22 00:09:23206 EXPECT_EQ(PORT_UNSPECIFIED, url2.IntPort());
[email protected]e7bba5f82013-04-10 20:10:52207 EXPECT_EQ("/foo;bar", url2.path());
208 EXPECT_EQ("q=a", url2.query());
209 EXPECT_EQ("ref", url2.ref());
210
211 const GURL* inner = url2.inner_url();
212 ASSERT_TRUE(inner);
213 EXPECT_EQ("https", inner->scheme());
Nick Carterff69a102018-04-04 00:15:17214 EXPECT_EQ("", inner->username());
215 EXPECT_EQ("", inner->password());
[email protected]e7bba5f82013-04-10 20:10:52216 EXPECT_EQ("google.com", inner->host());
217 EXPECT_EQ("99", inner->port());
218 EXPECT_EQ(99, inner->IntPort());
219 EXPECT_EQ("/t", inner->path());
220 EXPECT_EQ("", inner->query());
221 EXPECT_EQ("", inner->ref());
222}
223
[email protected]e9185c82014-04-18 10:06:50224TEST(GURLTest, IsValid) {
225 const char* valid_cases[] = {
Lukasz Anforowiczc664e8b2020-04-13 20:08:55226 "http://google.com",
227 "unknown://google.com",
228 "http://user:[email protected]",
229 "http://google.com:12345",
230 "http://google.com:0", // 0 is a valid port
231 "http://google.com/path",
232 "http://google.com//path",
233 "http://google.com?k=v#fragment",
234 "http://user:[email protected]:12345/path?k=v#fragment",
235 "http:/path",
236 "http:path",
[email protected]e9185c82014-04-18 10:06:50237 };
Avi Drissmana92b3be2018-12-24 21:55:29238 for (size_t i = 0; i < base::size(valid_cases); i++) {
[email protected]e9185c82014-04-18 10:06:50239 EXPECT_TRUE(GURL(valid_cases[i]).is_valid())
240 << "Case: " << valid_cases[i];
241 }
242
243 const char* invalid_cases[] = {
Lukasz Anforowiczc664e8b2020-04-13 20:08:55244 "http://?k=v",
245 "http:://google.com",
246 "http//google.com",
247 "http://google.com:12three45",
248 "file://server:123", // file: URLs cannot have a port
249 "file://server:0",
250 "://google.com",
251 "path",
[email protected]e9185c82014-04-18 10:06:50252 };
Avi Drissmana92b3be2018-12-24 21:55:29253 for (size_t i = 0; i < base::size(invalid_cases); i++) {
[email protected]e9185c82014-04-18 10:06:50254 EXPECT_FALSE(GURL(invalid_cases[i]).is_valid())
255 << "Case: " << invalid_cases[i];
256 }
257}
258
259TEST(GURLTest, ExtraSlashesBeforeAuthority) {
qyearsley2bc727d2015-08-14 20:17:15260 // According to RFC3986, the hierarchical part for URI with an authority
261 // must use only two slashes; GURL intentionally just ignores extra slashes
262 // if there are more than 2, and parses the following part as an authority.
[email protected]e9185c82014-04-18 10:06:50263 GURL url("http:///host");
264 EXPECT_EQ("host", url.host());
265 EXPECT_EQ("/", url.path());
266}
267
Chris Palmerdbbe438522021-03-04 21:14:32268// Given invalid URLs, we should still get most of the components.
[email protected]e9185c82014-04-18 10:06:50269TEST(GURLTest, ComponentGettersWorkEvenForInvalidURL) {
Chris Palmerdbbe438522021-03-04 21:14:32270 constexpr struct InvalidURLTestExpectations {
271 const char* url;
272 const char* spec;
273 const char* scheme;
274 const char* host;
275 const char* port;
276 const char* path;
277 // Extend as needed...
278 } expectations[] = {
279 {
280 "http:google.com:foo",
281 "http://google.com:foo/",
282 "http",
283 "google.com",
284 "foo",
285 "/",
286 },
287 {
288 "https:google.com:foo",
289 "https://google.com:foo/",
290 "https",
291 "google.com",
292 "foo",
293 "/",
294 },
295 };
[email protected]e7bba5f82013-04-10 20:10:52296
Chris Palmerdbbe438522021-03-04 21:14:32297 for (const auto& e : expectations) {
298 const GURL url(e.url);
299 EXPECT_FALSE(url.is_valid());
300 EXPECT_EQ(e.spec, url.possibly_invalid_spec());
301 EXPECT_EQ(e.scheme, url.scheme());
302 EXPECT_EQ("", url.username());
303 EXPECT_EQ("", url.password());
304 EXPECT_EQ(e.host, url.host());
305 EXPECT_EQ(e.port, url.port());
306 EXPECT_EQ(PORT_INVALID, url.IntPort());
307 EXPECT_EQ(e.path, url.path());
308 EXPECT_EQ("", url.query());
309 EXPECT_EQ("", url.ref());
310 }
[email protected]e7bba5f82013-04-10 20:10:52311}
312
313TEST(GURLTest, Resolve) {
314 // The tricky cases for relative URL resolving are tested in the
315 // canonicalizer unit test. Here, we just test that the GURL integration
316 // works properly.
317 struct ResolveCase {
318 const char* base;
319 const char* relative;
320 bool expected_valid;
321 const char* expected;
322 } resolve_cases[] = {
Lukasz Anforowicz4300c8afe2020-03-03 01:36:38323 {"http://www.google.com/", "foo.html", true,
324 "http://www.google.com/foo.html"},
325 {"http://www.google.com/foo/", "bar", true,
326 "http://www.google.com/foo/bar"},
327 {"http://www.google.com/foo/", "/bar", true, "http://www.google.com/bar"},
328 {"http://www.google.com/foo", "bar", true, "http://www.google.com/bar"},
329 {"http://www.google.com/", "http://images.google.com/foo.html", true,
330 "http://images.google.com/foo.html"},
331 {"http://www.google.com/", "http://images.\tgoogle.\ncom/\rfoo.html",
332 true, "http://images.google.com/foo.html"},
333 {"http://www.google.com/blah/bloo?c#d", "../../../hello/./world.html?a#b",
334 true, "http://www.google.com/hello/world.html?a#b"},
335 {"http://www.google.com/foo#bar", "#com", true,
336 "http://www.google.com/foo#com"},
337 {"http://www.google.com/", "Https:images.google.com", true,
338 "https://images.google.com/"},
[email protected]e7bba5f82013-04-10 20:10:52339 // A non-standard base can be replaced with a standard absolute URL.
Lukasz Anforowicz4300c8afe2020-03-03 01:36:38340 {"data:blahblah", "http://google.com/", true, "http://google.com/"},
341 {"data:blahblah", "http:google.com", true, "http://google.com/"},
Chris Palmerdbbe438522021-03-04 21:14:32342 {"data:blahblah", "https:google.com", true, "https://google.com/"},
[email protected]e7bba5f82013-04-10 20:10:52343 // Filesystem URLs have different paths to test.
Lukasz Anforowicz4300c8afe2020-03-03 01:36:38344 {"filesystem:http://www.google.com/type/", "foo.html", true,
345 "filesystem:http://www.google.com/type/foo.html"},
346 {"filesystem:http://www.google.com/type/", "../foo.html", true,
347 "filesystem:http://www.google.com/type/foo.html"},
348 // https://crbug.com/530123 - scheme validation (e.g. are "10.0.0.7:"
349 // or "x1:" valid schemes) when deciding if |relative| is an absolute url.
350 {"file:///some/dir/ip-relative.html", "10.0.0.7:8080/foo.html", true,
351 "file:///some/dir/10.0.0.7:8080/foo.html"},
352 {"file:///some/dir/", "1://host", true, "file:///some/dir/1://host"},
353 {"file:///some/dir/", "x1://host", true, "x1://host"},
354 {"file:///some/dir/", "X1://host", true, "x1://host"},
355 {"file:///some/dir/", "x.://host", true, "x.://host"},
356 {"file:///some/dir/", "x+://host", true, "x+://host"},
357 {"file:///some/dir/", "x-://host", true, "x-://host"},
358 {"file:///some/dir/", "x!://host", true, "file:///some/dir/x!://host"},
359 {"file:///some/dir/", "://host", true, "file:///some/dir/://host"},
[email protected]e7bba5f82013-04-10 20:10:52360 };
361
Avi Drissmana92b3be2018-12-24 21:55:29362 for (size_t i = 0; i < base::size(resolve_cases); i++) {
[email protected]e7bba5f82013-04-10 20:10:52363 // 8-bit code path.
364 GURL input(resolve_cases[i].base);
365 GURL output = input.Resolve(resolve_cases[i].relative);
366 EXPECT_EQ(resolve_cases[i].expected_valid, output.is_valid()) << i;
367 EXPECT_EQ(resolve_cases[i].expected, output.spec()) << i;
368 EXPECT_EQ(output.SchemeIsFileSystem(), output.inner_url() != NULL);
369
370 // Wide code path.
brettw1b8582f2016-11-03 20:37:17371 GURL inputw(base::UTF8ToUTF16(resolve_cases[i].base));
[email protected]e7bba5f82013-04-10 20:10:52372 GURL outputw =
brettw1b8582f2016-11-03 20:37:17373 input.Resolve(base::UTF8ToUTF16(resolve_cases[i].relative));
[email protected]e7bba5f82013-04-10 20:10:52374 EXPECT_EQ(resolve_cases[i].expected_valid, outputw.is_valid()) << i;
375 EXPECT_EQ(resolve_cases[i].expected, outputw.spec()) << i;
376 EXPECT_EQ(outputw.SchemeIsFileSystem(), outputw.inner_url() != NULL);
377 }
378}
379
380TEST(GURLTest, GetOrigin) {
381 struct TestCase {
382 const char* input;
383 const char* expected;
384 } cases[] = {
Nick Carter8aa718ed2018-09-07 21:39:51385 {"http://www.google.com", "http://www.google.com/"},
386 {"javascript:window.alert(\"hello,world\");", ""},
387 {"http://user:[email protected]:21/blah#baz",
388 "http://www.google.com:21/"},
389 {"http://[email protected]", "http://www.google.com/"},
390 {"http://:[email protected]", "http://www.google.com/"},
391 {"http://:@www.google.com", "http://www.google.com/"},
392 {"filesystem:http://www.google.com/temp/foo?q#b",
393 "http://www.google.com/"},
394 {"filesystem:http://user:[email protected]:21/blah#baz",
395 "http://google.com:21/"},
396 {"blob:null/guid-goes-here", ""},
397 {"blob:http://origin/guid-goes-here", "" /* should be http://origin/ */},
[email protected]e7bba5f82013-04-10 20:10:52398 };
Avi Drissmana92b3be2018-12-24 21:55:29399 for (size_t i = 0; i < base::size(cases); i++) {
[email protected]e7bba5f82013-04-10 20:10:52400 GURL url(cases[i].input);
401 GURL origin = url.GetOrigin();
402 EXPECT_EQ(cases[i].expected, origin.spec());
403 }
404}
405
[email protected]6b775ee2014-03-20 20:27:25406TEST(GURLTest, GetAsReferrer) {
407 struct TestCase {
408 const char* input;
409 const char* expected;
410 } cases[] = {
411 {"http://www.google.com", "http://www.google.com/"},
412 {"http://user:[email protected]:21/blah#baz", "http://www.google.com:21/blah"},
413 {"http://[email protected]", "http://www.google.com/"},
414 {"http://:[email protected]", "http://www.google.com/"},
415 {"http://:@www.google.com", "http://www.google.com/"},
416 {"http://www.google.com/temp/foo?q#b", "http://www.google.com/temp/foo?q"},
jochen42450392014-11-24 19:47:22417 {"not a url", ""},
418 {"unknown-scheme://foo.html", ""},
419 {"file:///tmp/test.html", ""},
420 {"https://www.google.com", "https://www.google.com/"},
[email protected]6b775ee2014-03-20 20:27:25421 };
Avi Drissmana92b3be2018-12-24 21:55:29422 for (size_t i = 0; i < base::size(cases); i++) {
[email protected]6b775ee2014-03-20 20:27:25423 GURL url(cases[i].input);
424 GURL origin = url.GetAsReferrer();
425 EXPECT_EQ(cases[i].expected, origin.spec());
426 }
427}
428
[email protected]e7bba5f82013-04-10 20:10:52429TEST(GURLTest, GetWithEmptyPath) {
430 struct TestCase {
431 const char* input;
432 const char* expected;
433 } cases[] = {
434 {"http://www.google.com", "http://www.google.com/"},
435 {"javascript:window.alert(\"hello, world\");", ""},
436 {"http://www.google.com/foo/bar.html?baz=22", "http://www.google.com/"},
437 {"filesystem:http://www.google.com/temporary/bar.html?baz=22", "filesystem:http://www.google.com/temporary/"},
438 {"filesystem:file:///temporary/bar.html?baz=22", "filesystem:file:///temporary/"},
439 };
440
Avi Drissmana92b3be2018-12-24 21:55:29441 for (size_t i = 0; i < base::size(cases); i++) {
[email protected]e7bba5f82013-04-10 20:10:52442 GURL url(cases[i].input);
443 GURL empty_path = url.GetWithEmptyPath();
444 EXPECT_EQ(cases[i].expected, empty_path.spec());
445 }
446}
447
Giovanni Ortuño Urquidi61b24eda2017-08-09 08:13:10448TEST(GURLTest, GetWithoutFilename) {
449 struct TestCase {
450 const char* input;
451 const char* expected;
452 } cases[] = {
453 // Common Standard URLs.
454 {"https://www.google.com", "https://www.google.com/"},
455 {"https://www.google.com/", "https://www.google.com/"},
456 {"https://www.google.com/maps.htm", "https://www.google.com/"},
457 {"https://www.google.com/maps/", "https://www.google.com/maps/"},
458 {"https://www.google.com/index.html", "https://www.google.com/"},
459 {"https://www.google.com/index.html?q=maps", "https://www.google.com/"},
460 {"https://www.google.com/index.html#maps/", "https://www.google.com/"},
461 {"https://foo:[email protected]/maps.htm", "https://foo:[email protected]/"},
462 {"https://www.google.com/maps/au/index.html", "https://www.google.com/maps/au/"},
463 {"https://www.google.com/maps/au/north", "https://www.google.com/maps/au/"},
464 {"https://www.google.com/maps/au/north/", "https://www.google.com/maps/au/north/"},
465 {"https://www.google.com/maps/au/index.html?q=maps#fragment/", "https://www.google.com/maps/au/"},
466 {"http://www.google.com:8000/maps/au/index.html?q=maps#fragment/", "http://www.google.com:8000/maps/au/"},
467 {"https://www.google.com/maps/au/north/?q=maps#fragment", "https://www.google.com/maps/au/north/"},
468 {"https://www.google.com/maps/au/north?q=maps#fragment", "https://www.google.com/maps/au/"},
469 // Less common standard URLs.
470 {"filesystem:http://www.google.com/temporary/bar.html?baz=22", "filesystem:http://www.google.com/temporary/"},
471 {"file:///temporary/bar.html?baz=22","file:///temporary/"},
472 {"ftp://foo/test/index.html", "ftp://foo/test/"},
473 {"gopher://foo/test/index.html", "gopher://foo/test/"},
474 {"ws://foo/test/index.html", "ws://foo/test/"},
475 // Non-standard, hierarchical URLs.
476 {"chrome://foo/bar.html", "chrome://foo/"},
477 {"httpa://foo/test/index.html", "httpa://foo/test/"},
478 // Non-standard, non-hierarchical URLs.
479 {"blob:https://foo.bar/test/index.html", ""},
480 {"about:blank", ""},
481 {"data:foobar", ""},
482 {"scheme:opaque_data", ""},
483 // Invalid URLs.
484 {"foobar", ""},
485 };
486
Avi Drissmana92b3be2018-12-24 21:55:29487 for (size_t i = 0; i < base::size(cases); i++) {
Giovanni Ortuño Urquidi61b24eda2017-08-09 08:13:10488 GURL url(cases[i].input);
489 GURL without_filename = url.GetWithoutFilename();
490 EXPECT_EQ(cases[i].expected, without_filename.spec()) << i;
491 }
492}
493
[email protected]e7bba5f82013-04-10 20:10:52494TEST(GURLTest, Replacements) {
qyearsley2bc727d2015-08-14 20:17:15495 // The URL canonicalizer replacement test will handle most of these case.
[email protected]e7bba5f82013-04-10 20:10:52496 // The most important thing to do here is to check that the proper
497 // canonicalizer gets called based on the scheme of the input.
498 struct ReplaceCase {
499 const char* base;
500 const char* scheme;
501 const char* username;
502 const char* password;
503 const char* host;
504 const char* port;
505 const char* path;
506 const char* query;
507 const char* ref;
508 const char* expected;
509 } replace_cases[] = {
Keishi Hattori27f19de2020-11-17 05:53:12510 {"http://www.google.com/foo/bar.html?foo#bar", nullptr, nullptr, nullptr,
511 nullptr, nullptr, "/", "", "", "http://www.google.com/"},
mmenke73cea7e4a2016-06-13 19:04:57512 {"http://www.google.com/foo/bar.html?foo#bar", "javascript", "", "", "",
513 "", "window.open('foo');", "", "", "javascript:window.open('foo');"},
Keishi Hattori27f19de2020-11-17 05:53:12514 {"file:///C:/foo/bar.txt", "http", nullptr, nullptr, "www.google.com",
515 "99", "/foo", "search", "ref",
516 "http://www.google.com:99/foo?search#ref"},
[email protected]e7bba5f82013-04-10 20:10:52517#ifdef WIN32
mmenke73cea7e4a2016-06-13 19:04:57518 {"http://www.google.com/foo/bar.html?foo#bar", "file", "", "", "", "",
519 "c:\\", "", "", "file:///C:/"},
[email protected]e7bba5f82013-04-10 20:10:52520#endif
Keishi Hattori27f19de2020-11-17 05:53:12521 {"filesystem:http://www.google.com/foo/bar.html?foo#bar", nullptr,
522 nullptr, nullptr, nullptr, nullptr, "/", "", "",
523 "filesystem:http://www.google.com/foo/"},
mmenke73cea7e4a2016-06-13 19:04:57524 // Lengthen the URL instead of shortening it, to test creation of
525 // inner_url.
Keishi Hattori27f19de2020-11-17 05:53:12526 {"filesystem:http://www.google.com/foo/", nullptr, nullptr, nullptr,
527 nullptr, nullptr, "bar.html", "foo", "bar",
mmenke73cea7e4a2016-06-13 19:04:57528 "filesystem:http://www.google.com/foo/bar.html?foo#bar"},
[email protected]e7bba5f82013-04-10 20:10:52529 };
530
Avi Drissmana92b3be2018-12-24 21:55:29531 for (size_t i = 0; i < base::size(replace_cases); i++) {
[email protected]e7bba5f82013-04-10 20:10:52532 const ReplaceCase& cur = replace_cases[i];
533 GURL url(cur.base);
534 GURL::Replacements repl;
535 SetupReplacement(&GURL::Replacements::SetScheme, &repl, cur.scheme);
536 SetupReplacement(&GURL::Replacements::SetUsername, &repl, cur.username);
537 SetupReplacement(&GURL::Replacements::SetPassword, &repl, cur.password);
538 SetupReplacement(&GURL::Replacements::SetHost, &repl, cur.host);
539 SetupReplacement(&GURL::Replacements::SetPort, &repl, cur.port);
540 SetupReplacement(&GURL::Replacements::SetPath, &repl, cur.path);
541 SetupReplacement(&GURL::Replacements::SetQuery, &repl, cur.query);
542 SetupReplacement(&GURL::Replacements::SetRef, &repl, cur.ref);
543 GURL output = url.ReplaceComponents(repl);
544
545 EXPECT_EQ(replace_cases[i].expected, output.spec());
mmenke73cea7e4a2016-06-13 19:04:57546
[email protected]e7bba5f82013-04-10 20:10:52547 EXPECT_EQ(output.SchemeIsFileSystem(), output.inner_url() != NULL);
mmenke73cea7e4a2016-06-13 19:04:57548 if (output.SchemeIsFileSystem()) {
549 // TODO(mmenke): inner_url()->spec() is currently the same as the spec()
550 // for the GURL itself. This should be fixed.
551 // See https://crbug.com/619596
552 EXPECT_EQ(replace_cases[i].expected, output.inner_url()->spec());
553 }
[email protected]e7bba5f82013-04-10 20:10:52554 }
555}
556
[email protected]369e84f72013-11-23 01:53:52557TEST(GURLTest, ClearFragmentOnDataUrl) {
558 // http://crbug.com/291747 - a data URL may legitimately have trailing
559 // whitespace in the spec after the ref is cleared. Test this does not trigger
[email protected]0318f922014-04-22 00:09:23560 // the Parsed importing validation DCHECK in GURL.
[email protected]369e84f72013-11-23 01:53:52561 GURL url(" data: one ? two # three ");
562
563 // By default the trailing whitespace will have been stripped.
Timothy Gub443c712021-07-31 00:10:02564 EXPECT_EQ("data: one ?%20two%20#%20three", url.spec());
[email protected]369e84f72013-11-23 01:53:52565 GURL::Replacements repl;
566 repl.ClearRef();
567 GURL url_no_ref = url.ReplaceComponents(repl);
568
Timothy Gub443c712021-07-31 00:10:02569 EXPECT_EQ("data: one ?%20two%20", url_no_ref.spec());
[email protected]369e84f72013-11-23 01:53:52570
qyearsley2bc727d2015-08-14 20:17:15571 // Importing a parsed URL via this constructor overload will retain trailing
[email protected]369e84f72013-11-23 01:53:52572 // whitespace.
573 GURL import_url(url_no_ref.spec(),
574 url_no_ref.parsed_for_possibly_invalid_spec(),
575 url_no_ref.is_valid());
576 EXPECT_EQ(url_no_ref, import_url);
Timothy Gub443c712021-07-31 00:10:02577 EXPECT_EQ(import_url.query(), "%20two%20");
[email protected]369e84f72013-11-23 01:53:52578}
579
[email protected]e7bba5f82013-04-10 20:10:52580TEST(GURLTest, PathForRequest) {
581 struct TestCase {
582 const char* input;
583 const char* expected;
584 const char* inner_expected;
585 } cases[] = {
Keishi Hattori27f19de2020-11-17 05:53:12586 {"http://www.google.com", "/", nullptr},
587 {"http://www.google.com/", "/", nullptr},
588 {"http://www.google.com/foo/bar.html?baz=22", "/foo/bar.html?baz=22",
589 nullptr},
590 {"http://www.google.com/foo/bar.html#ref", "/foo/bar.html", nullptr},
591 {"http://www.google.com/foo/bar.html?query#ref", "/foo/bar.html?query",
592 nullptr},
593 {"filesystem:http://www.google.com/temporary/foo/bar.html?query#ref",
594 "/foo/bar.html?query", "/temporary"},
595 {"filesystem:http://www.google.com/temporary/foo/bar.html?query",
596 "/foo/bar.html?query", "/temporary"},
[email protected]e7bba5f82013-04-10 20:10:52597 };
598
Avi Drissmana92b3be2018-12-24 21:55:29599 for (size_t i = 0; i < base::size(cases); i++) {
[email protected]e7bba5f82013-04-10 20:10:52600 GURL url(cases[i].input);
David Van Cleve5f374442019-11-06 15:01:17601 EXPECT_EQ(cases[i].expected, url.PathForRequest());
602 EXPECT_EQ(cases[i].expected, url.PathForRequestPiece());
[email protected]e7bba5f82013-04-10 20:10:52603 EXPECT_EQ(cases[i].inner_expected == NULL, url.inner_url() == NULL);
David Van Cleve5f374442019-11-06 15:01:17604 if (url.inner_url() && cases[i].inner_expected) {
[email protected]e7bba5f82013-04-10 20:10:52605 EXPECT_EQ(cases[i].inner_expected, url.inner_url()->PathForRequest());
David Van Cleve5f374442019-11-06 15:01:17606 EXPECT_EQ(cases[i].inner_expected,
607 url.inner_url()->PathForRequestPiece());
608 }
[email protected]e7bba5f82013-04-10 20:10:52609 }
610}
611
612TEST(GURLTest, EffectiveIntPort) {
613 struct PortTest {
614 const char* spec;
615 int expected_int_port;
616 } port_tests[] = {
617 // http
618 {"http://www.google.com/", 80},
619 {"http://www.google.com:80/", 80},
620 {"http://www.google.com:443/", 443},
621
622 // https
623 {"https://www.google.com/", 443},
624 {"https://www.google.com:443/", 443},
625 {"https://www.google.com:80/", 80},
626
627 // ftp
628 {"ftp://www.google.com/", 21},
629 {"ftp://www.google.com:21/", 21},
630 {"ftp://www.google.com:80/", 80},
631
[email protected]e7bba5f82013-04-10 20:10:52632 // file - no port
[email protected]0318f922014-04-22 00:09:23633 {"file://www.google.com/", PORT_UNSPECIFIED},
634 {"file://www.google.com:443/", PORT_UNSPECIFIED},
[email protected]e7bba5f82013-04-10 20:10:52635
636 // data - no port
[email protected]0318f922014-04-22 00:09:23637 {"data:www.google.com:90", PORT_UNSPECIFIED},
638 {"data:www.google.com", PORT_UNSPECIFIED},
[email protected]e7bba5f82013-04-10 20:10:52639
640 // filesystem - no port
[email protected]0318f922014-04-22 00:09:23641 {"filesystem:http://www.google.com:90/t/foo", PORT_UNSPECIFIED},
642 {"filesystem:file:///t/foo", PORT_UNSPECIFIED},
[email protected]e7bba5f82013-04-10 20:10:52643 };
644
Avi Drissmana92b3be2018-12-24 21:55:29645 for (size_t i = 0; i < base::size(port_tests); i++) {
[email protected]e7bba5f82013-04-10 20:10:52646 GURL url(port_tests[i].spec);
647 EXPECT_EQ(port_tests[i].expected_int_port, url.EffectiveIntPort());
648 }
649}
650
651TEST(GURLTest, IPAddress) {
652 struct IPTest {
653 const char* spec;
654 bool expected_ip;
655 } ip_tests[] = {
656 {"http://www.google.com/", false},
657 {"http://192.168.9.1/", true},
658 {"http://192.168.9.1.2/", false},
659 {"http://192.168.m.1/", false},
660 {"http://2001:db8::1/", false},
661 {"http://[2001:db8::1]/", true},
662 {"", false},
663 {"some random input!", false},
664 };
665
Avi Drissmana92b3be2018-12-24 21:55:29666 for (size_t i = 0; i < base::size(ip_tests); i++) {
[email protected]e7bba5f82013-04-10 20:10:52667 GURL url(ip_tests[i].spec);
668 EXPECT_EQ(ip_tests[i].expected_ip, url.HostIsIPAddress());
669 }
670}
671
672TEST(GURLTest, HostNoBrackets) {
673 struct TestCase {
674 const char* input;
675 const char* expected_host;
676 const char* expected_plainhost;
677 } cases[] = {
678 {"http://www.google.com", "www.google.com", "www.google.com"},
679 {"http://[2001:db8::1]/", "[2001:db8::1]", "2001:db8::1"},
680 {"http://[::]/", "[::]", "::"},
681
682 // Don't require a valid URL, but don't crash either.
683 {"http://[]/", "[]", ""},
684 {"http://[x]/", "[x]", "x"},
685 {"http://[x/", "[x", "[x"},
686 {"http://x]/", "x]", "x]"},
687 {"http://[/", "[", "["},
688 {"http://]/", "]", "]"},
689 {"", "", ""},
690 };
Avi Drissmana92b3be2018-12-24 21:55:29691 for (size_t i = 0; i < base::size(cases); i++) {
[email protected]e7bba5f82013-04-10 20:10:52692 GURL url(cases[i].input);
693 EXPECT_EQ(cases[i].expected_host, url.host());
694 EXPECT_EQ(cases[i].expected_plainhost, url.HostNoBrackets());
ricea1c0de2f2017-07-03 08:21:43695 EXPECT_EQ(cases[i].expected_plainhost, url.HostNoBracketsPiece());
[email protected]e7bba5f82013-04-10 20:10:52696 }
697}
698
699TEST(GURLTest, DomainIs) {
qyearsley7ffaa682015-08-03 07:03:49700 GURL url_1("http://google.com/foo");
701 EXPECT_TRUE(url_1.DomainIs("google.com"));
[email protected]e7bba5f82013-04-10 20:10:52702
qyearsley7ffaa682015-08-03 07:03:49703 // Subdomain and port are ignored.
704 GURL url_2("http://www.google.com:99/foo");
705 EXPECT_TRUE(url_2.DomainIs("google.com"));
[email protected]e7bba5f82013-04-10 20:10:52706
qyearsley7ffaa682015-08-03 07:03:49707 // Different top-level domain.
708 GURL url_3("http://www.google.com.cn/foo");
709 EXPECT_FALSE(url_3.DomainIs("google.com"));
[email protected]e7bba5f82013-04-10 20:10:52710
qyearsley7ffaa682015-08-03 07:03:49711 // Different host name.
712 GURL url_4("http://www.iamnotgoogle.com/foo");
713 EXPECT_FALSE(url_4.DomainIs("google.com"));
[email protected]e7bba5f82013-04-10 20:10:52714
qyearsley7ffaa682015-08-03 07:03:49715 // The input must be lower-cased otherwise DomainIs returns false.
716 GURL url_5("http://www.google.com/foo");
717 EXPECT_FALSE(url_5.DomainIs("Google.com"));
[email protected]e7bba5f82013-04-10 20:10:52718
qyearsley7ffaa682015-08-03 07:03:49719 // If the URL is invalid, DomainIs returns false.
720 GURL invalid_url("google.com");
721 EXPECT_FALSE(invalid_url.is_valid());
722 EXPECT_FALSE(invalid_url.DomainIs("google.com"));
Charles Harrison81dc2fb2017-08-30 23:41:12723
724 GURL url_with_escape_chars("https://www.,.test");
725 EXPECT_TRUE(url_with_escape_chars.is_valid());
726 EXPECT_EQ(url_with_escape_chars.host(), "www.%2C.test");
727 EXPECT_TRUE(url_with_escape_chars.DomainIs("%2C.test"));
qyearsley7ffaa682015-08-03 07:03:49728}
[email protected]e7bba5f82013-04-10 20:10:52729
qyearsley7ffaa682015-08-03 07:03:49730TEST(GURLTest, DomainIsTerminatingDotBehavior) {
731 // If the host part ends with a dot, it matches input domains
732 // with or without a dot.
733 GURL url_with_dot("http://www.google.com./foo");
734 EXPECT_TRUE(url_with_dot.DomainIs("google.com"));
735 EXPECT_TRUE(url_with_dot.DomainIs("google.com."));
736 EXPECT_TRUE(url_with_dot.DomainIs(".com"));
737 EXPECT_TRUE(url_with_dot.DomainIs(".com."));
[email protected]e7bba5f82013-04-10 20:10:52738
qyearsley7ffaa682015-08-03 07:03:49739 // But, if the host name doesn't end with a dot and the input
740 // domain does, then it's considered to not match.
741 GURL url_without_dot("http://google.com/foo");
742 EXPECT_FALSE(url_without_dot.DomainIs("google.com."));
[email protected]e7bba5f82013-04-10 20:10:52743
qyearsley7ffaa682015-08-03 07:03:49744 // If the URL ends with two dots, it doesn't match.
745 GURL url_with_two_dots("http://www.google.com../foo");
746 EXPECT_FALSE(url_with_two_dots.DomainIs("google.com"));
747}
[email protected]e7bba5f82013-04-10 20:10:52748
qyearsley7ffaa682015-08-03 07:03:49749TEST(GURLTest, DomainIsWithFilesystemScheme) {
750 GURL url_1("filesystem:http://www.google.com:99/foo/");
751 EXPECT_TRUE(url_1.DomainIs("google.com"));
[email protected]e7bba5f82013-04-10 20:10:52752
qyearsley7ffaa682015-08-03 07:03:49753 GURL url_2("filesystem:http://www.iamnotgoogle.com/foo/");
754 EXPECT_FALSE(url_2.DomainIs("google.com"));
[email protected]e7bba5f82013-04-10 20:10:52755}
756
757// Newlines should be stripped from inputs.
758TEST(GURLTest, Newlines) {
759 // Constructor.
760 GURL url_1(" \t ht\ntp://\twww.goo\rgle.com/as\ndf \n ");
761 EXPECT_EQ("http://www.google.com/asdf", url_1.spec());
Mike West9e5ae902017-05-24 15:17:50762 EXPECT_FALSE(
763 url_1.parsed_for_possibly_invalid_spec().potentially_dangling_markup);
[email protected]e7bba5f82013-04-10 20:10:52764
765 // Relative path resolver.
766 GURL url_2 = url_1.Resolve(" \n /fo\to\r ");
767 EXPECT_EQ("http://www.google.com/foo", url_2.spec());
Mike West9e5ae902017-05-24 15:17:50768 EXPECT_FALSE(
769 url_2.parsed_for_possibly_invalid_spec().potentially_dangling_markup);
770
771 // Constructor.
772 GURL url_3(" \t ht\ntp://\twww.goo\rgle.com/as\ndf< \n ");
773 EXPECT_EQ("http://www.google.com/asdf%3C", url_3.spec());
774 EXPECT_TRUE(
775 url_3.parsed_for_possibly_invalid_spec().potentially_dangling_markup);
776
777 // Relative path resolver.
778 GURL url_4 = url_1.Resolve(" \n /fo\to<\r ");
779 EXPECT_EQ("http://www.google.com/foo%3C", url_4.spec());
780 EXPECT_TRUE(
781 url_4.parsed_for_possibly_invalid_spec().potentially_dangling_markup);
[email protected]e7bba5f82013-04-10 20:10:52782
783 // Note that newlines are NOT stripped from ReplaceComponents.
784}
785
786TEST(GURLTest, IsStandard) {
787 GURL a("http:foo/bar");
788 EXPECT_TRUE(a.IsStandard());
789
790 GURL b("foo:bar/baz");
791 EXPECT_FALSE(b.IsStandard());
792
793 GURL c("foo://bar/baz");
794 EXPECT_FALSE(c.IsStandard());
blundell5ef36cb2016-06-27 15:37:14795
796 GURL d("cid:bar@baz");
797 EXPECT_FALSE(d.IsStandard());
[email protected]e7bba5f82013-04-10 20:10:52798}
[email protected]9690b992013-11-22 07:40:46799
800TEST(GURLTest, SchemeIsHTTPOrHTTPS) {
801 EXPECT_TRUE(GURL("http://bar/").SchemeIsHTTPOrHTTPS());
802 EXPECT_TRUE(GURL("HTTPS://BAR").SchemeIsHTTPOrHTTPS());
803 EXPECT_FALSE(GURL("ftp://bar/").SchemeIsHTTPOrHTTPS());
804}
805
806TEST(GURLTest, SchemeIsWSOrWSS) {
807 EXPECT_TRUE(GURL("WS://BAR/").SchemeIsWSOrWSS());
808 EXPECT_TRUE(GURL("wss://bar/").SchemeIsWSOrWSS());
809 EXPECT_FALSE(GURL("http://bar/").SchemeIsWSOrWSS());
810}
[email protected]0318f922014-04-22 00:09:23811
jww04480402016-10-25 02:50:33812TEST(GURLTest, SchemeIsCryptographic) {
813 EXPECT_TRUE(GURL("https://foo.bar.com/").SchemeIsCryptographic());
814 EXPECT_TRUE(GURL("HTTPS://foo.bar.com/").SchemeIsCryptographic());
815 EXPECT_TRUE(GURL("HtTpS://foo.bar.com/").SchemeIsCryptographic());
816
817 EXPECT_TRUE(GURL("wss://foo.bar.com/").SchemeIsCryptographic());
818 EXPECT_TRUE(GURL("WSS://foo.bar.com/").SchemeIsCryptographic());
819 EXPECT_TRUE(GURL("WsS://foo.bar.com/").SchemeIsCryptographic());
820
jww04480402016-10-25 02:50:33821 EXPECT_FALSE(GURL("http://foo.bar.com/").SchemeIsCryptographic());
822 EXPECT_FALSE(GURL("ws://foo.bar.com/").SchemeIsCryptographic());
jww04480402016-10-25 02:50:33823}
824
Maks Orlovich44525ce2019-02-25 14:17:58825TEST(GURLTest, SchemeIsCryptographicStatic) {
826 EXPECT_TRUE(GURL::SchemeIsCryptographic("https"));
827 EXPECT_TRUE(GURL::SchemeIsCryptographic("wss"));
828 EXPECT_FALSE(GURL::SchemeIsCryptographic("http"));
829 EXPECT_FALSE(GURL::SchemeIsCryptographic("ws"));
830 EXPECT_FALSE(GURL::SchemeIsCryptographic("ftp"));
831}
832
amogh.bihaniee85a112014-09-01 06:06:51833TEST(GURLTest, SchemeIsBlob) {
834 EXPECT_TRUE(GURL("BLOB://BAR/").SchemeIsBlob());
835 EXPECT_TRUE(GURL("blob://bar/").SchemeIsBlob());
836 EXPECT_FALSE(GURL("http://bar/").SchemeIsBlob());
837}
838
Stephen McGruer35fad072018-11-21 15:09:19839// Tests that the 'content' of the URL is properly extracted. This can be
840// complex in cases such as multiple schemes (view-source:http:) or for
841// javascript URLs. See GURL::GetContent for more details.
842TEST(GURLTest, ContentForNonStandardURLs) {
mkwst414920e2015-07-28 05:30:07843 struct TestCase {
844 const char* url;
845 const char* expected;
846 } cases[] = {
847 {"null", ""},
848 {"not-a-standard-scheme:this is arbitrary content",
849 "this is arbitrary content"},
Stephen McGruer35fad072018-11-21 15:09:19850
851 // When there are multiple schemes, only the first is excluded from the
852 // content. Note also that for e.g. 'http://', the '//' is part of the
853 // content not the scheme.
mkwst414920e2015-07-28 05:30:07854 {"view-source:http://example.com/path", "http://example.com/path"},
855 {"blob:http://example.com/GUID", "http://example.com/GUID"},
856 {"blob://http://example.com/GUID", "//http://example.com/GUID"},
857 {"blob:http://user:[email protected]/GUID",
858 "http://user:[email protected]/GUID"},
859
Stephen McGruer35fad072018-11-21 15:09:19860 // The octothorpe character ('#') marks the end of the URL content, and
861 // the start of the fragment. It should not be included in the content.
Stephen McGruerb52ebdc2018-10-31 22:06:04862 {"http://www.example.com/GUID#ref", "www.example.com/GUID"},
863 {"http://me:[email protected]/GUID/#ref", "me:[email protected]/GUID/"},
864 {"data:text/html,Question?<div style=\"color: #bad\">idea</div>",
Timothy Gub443c712021-07-31 00:10:02865 "text/html,Question?%3Cdiv%20style=%22color:%20"},
Stephen McGruerb52ebdc2018-10-31 22:06:04866
867 // TODO(mkwst): This seems like a bug. https://crbug.com/513600
868 {"filesystem:http://example.com/path", "/"},
869
870 // Javascript URLs include '#' symbols in their content.
871 {"javascript:#", "#"},
872 {"javascript:alert('#');", "alert('#');"},
873 };
874
875 for (const auto& test : cases) {
876 GURL url(test.url);
877 EXPECT_EQ(test.expected, url.GetContent()) << test.url;
878 }
879}
880
Stephen McGruer35fad072018-11-21 15:09:19881// Tests that the URL path is properly extracted for unusual URLs. This can be
882// complex in cases such as multiple schemes (view-source:http:) or when
883// octothorpes ('#') are involved.
Stephen McGruerb52ebdc2018-10-31 22:06:04884TEST(GURLTest, PathForNonStandardURLs) {
885 struct TestCase {
886 const char* url;
887 const char* expected;
888 } cases[] = {
889 {"null", ""},
890 {"not-a-standard-scheme:this is arbitrary content",
891 "this is arbitrary content"},
892 {"view-source:http://example.com/path", "http://example.com/path"},
893 {"blob:http://example.com/GUID", "http://example.com/GUID"},
894 {"blob://http://example.com/GUID", "//http://example.com/GUID"},
895 {"blob:http://user:[email protected]/GUID",
896 "http://user:[email protected]/GUID"},
897
898 {"http://www.example.com/GUID#ref", "/GUID"},
899 {"http://me:[email protected]/GUID/#ref", "/GUID/"},
900 {"data:text/html,Question?<div style=\"color: #bad\">idea</div>",
901 "text/html,Question"},
902
mkwst414920e2015-07-28 05:30:07903 // TODO(mkwst): This seems like a bug. https://crbug.com/513600
904 {"filesystem:http://example.com/path", "/"},
905 };
906
907 for (const auto& test : cases) {
908 GURL url(test.url);
909 EXPECT_EQ(test.expected, url.path()) << test.url;
mkwst414920e2015-07-28 05:30:07910 }
911}
912
clamy12bca18b2017-02-10 15:33:07913TEST(GURLTest, EqualsIgnoringRef) {
914 const struct {
915 const char* url_a;
916 const char* url_b;
917 bool are_equals;
918 } kTestCases[] = {
919 // No ref.
920 {"http://a.com", "http://a.com", true},
921 {"http://a.com", "http://b.com", false},
922
923 // Same Ref.
924 {"http://a.com#foo", "http://a.com#foo", true},
925 {"http://a.com#foo", "http://b.com#foo", false},
926
927 // Different Refs.
928 {"http://a.com#foo", "http://a.com#bar", true},
929 {"http://a.com#foo", "http://b.com#bar", false},
930
931 // One has a ref, the other doesn't.
932 {"http://a.com#foo", "http://a.com", true},
933 {"http://a.com#foo", "http://b.com", false},
934
935 // Empty refs.
936 {"http://a.com#", "http://a.com#", true},
937 {"http://a.com#", "http://a.com", true},
938
939 // URLs that differ only by their last character.
940 {"http://aaa", "http://aab", false},
941 {"http://aaa#foo", "http://aab#foo", false},
942
943 // Different size of the part before the ref.
944 {"http://123#a", "http://123456#a", false},
945
946 // Blob URLs
947 {"blob:http://a.com#foo", "blob:http://a.com#foo", true},
948 {"blob:http://a.com#foo", "blob:http://a.com#bar", true},
949 {"blob:http://a.com#foo", "blob:http://b.com#bar", false},
950
951 // Filesystem URLs
952 {"filesystem:http://a.com#foo", "filesystem:http://a.com#foo", true},
953 {"filesystem:http://a.com#foo", "filesystem:http://a.com#bar", true},
954 {"filesystem:http://a.com#foo", "filesystem:http://b.com#bar", false},
arthursonzogni313d530f2017-12-13 13:05:29955
956 // Data URLs
957 {"data:text/html,a#foo", "data:text/html,a#bar", true},
958 {"data:text/html,a#foo", "data:text/html,a#foo", true},
959 {"data:text/html,a#foo", "data:text/html,b#foo", false},
clamy12bca18b2017-02-10 15:33:07960 };
961
962 for (const auto& test_case : kTestCases) {
963 SCOPED_TRACE(testing::Message()
964 << std::endl
965 << "url_a = " << test_case.url_a << std::endl
966 << "url_b = " << test_case.url_b << std::endl);
967 // A versus B.
968 EXPECT_EQ(test_case.are_equals,
969 GURL(test_case.url_a).EqualsIgnoringRef(GURL(test_case.url_b)));
970 // B versus A.
971 EXPECT_EQ(test_case.are_equals,
972 GURL(test_case.url_b).EqualsIgnoringRef(GURL(test_case.url_a)));
973 }
974}
975
Lukasz Anforowicz68c21772018-01-13 03:42:44976TEST(GURLTest, DebugAlias) {
977 GURL url("https://foo.com/bar");
978 DEBUG_ALIAS_FOR_GURL(url_debug_alias, url);
979 EXPECT_STREQ("https://foo.com/bar", url_debug_alias);
980}
981
Nico Weber465eee62021-03-18 07:33:52982TEST(GURLTest, InvalidHost) {
983 // This contains an invalid percent escape (%T%) and also a valid
984 // percent escape that's not 7-bit ascii (%ae), so that the unescaped
985 // host contains both an invalid percent escape and invalid UTF-8.
986 GURL url("http://%T%Ae");
987
988 EXPECT_FALSE(url.is_valid());
989 EXPECT_TRUE(url.SchemeIs(url::kHttpScheme));
990
991 // The invalid percent escape becomes an escaped percent sign (%25), and the
992 // invalid UTF-8 character becomes REPLACEMENT CHARACTER' (U+FFFD) encoded as
993 // UTF-8.
994 EXPECT_EQ(url.host_piece(), "%25t%EF%BF%BD");
995}
996
Lukasz Anforowiczc664e8b2020-04-13 20:08:55997TEST(GURLTest, PortZero) {
998 GURL port_zero_url("http://127.0.0.1:0/blah");
999
1000 // https://url.spec.whatwg.org/#port-state says that the port 1) consists of
1001 // ASCII digits (this excludes negative numbers) and 2) cannot be greater than
1002 // 2^16-1. This means that port=0 should be valid.
1003 EXPECT_TRUE(port_zero_url.is_valid());
1004 EXPECT_EQ("0", port_zero_url.port());
1005 EXPECT_EQ("127.0.0.1", port_zero_url.host());
1006 EXPECT_EQ("http", port_zero_url.scheme());
1007
1008 // https://crbug.com/1065532: SchemeHostPort would previously incorrectly
1009 // consider port=0 to be invalid.
1010 SchemeHostPort scheme_host_port(port_zero_url);
1011 EXPECT_TRUE(scheme_host_port.IsValid());
1012 EXPECT_EQ(port_zero_url.scheme(), scheme_host_port.scheme());
1013 EXPECT_EQ(port_zero_url.host(), scheme_host_port.host());
1014 EXPECT_EQ(port_zero_url.port(),
1015 base::NumberToString(scheme_host_port.port()));
1016
1017 // https://crbug.com/1065532: The SchemeHostPort problem above would lead to
1018 // bizarre results below - resolved origin would incorrectly be returned as an
1019 // opaque origin derived from |another_origin|.
1020 url::Origin another_origin = url::Origin::Create(GURL("http://other.com"));
1021 url::Origin resolved_origin =
1022 url::Origin::Resolve(port_zero_url, another_origin);
1023 EXPECT_FALSE(resolved_origin.opaque());
1024 EXPECT_EQ(port_zero_url.scheme(), resolved_origin.scheme());
1025 EXPECT_EQ(port_zero_url.host(), resolved_origin.host());
1026 EXPECT_EQ(port_zero_url.port(), base::NumberToString(resolved_origin.port()));
1027
1028 // port=0 and default HTTP port are different.
1029 GURL default_port("http://127.0.0.1/foo");
1030 EXPECT_EQ(0, SchemeHostPort(port_zero_url).port());
1031 EXPECT_EQ(80, SchemeHostPort(default_port).port());
1032 url::Origin default_port_origin = url::Origin::Create(default_port);
1033 EXPECT_FALSE(default_port_origin.IsSameOriginWith(resolved_origin));
1034}
1035
Lukasz Anforowicz123987f2021-01-25 19:17:291036class GURLTestTraits {
Lukasz Anforowicz875905b42021-01-12 16:54:511037 public:
Lukasz Anforowicz123987f2021-01-25 19:17:291038 using UrlType = GURL;
Lukasz Anforowicz875905b42021-01-12 16:54:511039
Lukasz Anforowicz123987f2021-01-25 19:17:291040 static UrlType CreateUrlFromString(base::StringPiece s) { return GURL(s); }
1041 static bool IsAboutBlank(const UrlType& url) { return url.IsAboutBlank(); }
1042 static bool IsAboutSrcdoc(const UrlType& url) { return url.IsAboutSrcdoc(); }
Lukasz Anforowicz875905b42021-01-12 16:54:511043
Lukasz Anforowicz123987f2021-01-25 19:17:291044 // Only static members.
1045 GURLTestTraits() = delete;
Lukasz Anforowicz875905b42021-01-12 16:54:511046};
1047
1048INSTANTIATE_TYPED_TEST_SUITE_P(GURL, AbstractUrlTest, GURLTestTraits);
1049
[email protected]0318f922014-04-22 00:09:231050} // namespace url