| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/net_util.h" | 5 #include "net/base/net_util.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/files/file_path.h" | |
| 12 #include "base/format_macros.h" | 11 #include "base/format_macros.h" |
| 13 #include "base/scoped_native_library.h" | |
| 14 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/strings/string_util.h" | |
| 16 #include "base/strings/stringprintf.h" | |
| 17 #include "base/strings/sys_string_conversions.h" | |
| 18 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
| 19 #include "base/sys_byteorder.h" | |
| 20 #include "base/time/time.h" | 14 #include "base/time/time.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 22 #include "url/gurl.h" | 16 #include "url/gurl.h" |
| 23 | 17 |
| 24 #if defined(OS_WIN) | |
| 25 #include <iphlpapi.h> | |
| 26 #include <objbase.h> | |
| 27 #include "base/win/windows_version.h" | |
| 28 #elif !defined(OS_ANDROID) | |
| 29 #include <net/if.h> | |
| 30 #endif // OS_WIN | |
| 31 | |
| 32 using base::ASCIIToUTF16; | 18 using base::ASCIIToUTF16; |
| 33 using base::WideToUTF16; | 19 using base::WideToUTF16; |
| 34 | 20 |
| 35 namespace net { | 21 namespace net { |
| 36 | 22 |
| 37 namespace { | 23 namespace { |
| 38 | 24 |
| 39 static const size_t kNpos = base::string16::npos; | 25 static const size_t kNpos = base::string16::npos; |
| 40 | 26 |
| 41 struct HeaderCase { | |
| 42 const char* header_name; | |
| 43 const char* expected; | |
| 44 }; | |
| 45 | |
| 46 struct HeaderParamCase { | |
| 47 const char* header_name; | |
| 48 const char* param_name; | |
| 49 const char* expected; | |
| 50 }; | |
| 51 | |
| 52 const char* kLanguages[] = { | 27 const char* kLanguages[] = { |
| 53 "", "en", "zh-CN", "ja", "ko", | 28 "", "en", "zh-CN", "ja", "ko", |
| 54 "he", "ar", "ru", "el", "fr", | 29 "he", "ar", "ru", "el", "fr", |
| 55 "de", "pt", "sv", "th", "hi", | 30 "de", "pt", "sv", "th", "hi", |
| 56 "de,en", "el,en", "zh-TW,en", "ko,ja", "he,ru,en", | 31 "de,en", "el,en", "zh-TW,en", "ko,ja", "he,ru,en", |
| 57 "zh,ru,en" | 32 "zh,ru,en" |
| 58 }; | 33 }; |
| 59 | 34 |
| 60 struct IDNTestCase { | 35 struct IDNTestCase { |
| 61 const char* input; | 36 const char* input; |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 false, false, true, false, false, | 346 false, false, true, false, false, |
| 372 true}}, | 347 true}}, |
| 373 #endif | 348 #endif |
| 374 }; | 349 }; |
| 375 | 350 |
| 376 struct AdjustOffsetCase { | 351 struct AdjustOffsetCase { |
| 377 size_t input_offset; | 352 size_t input_offset; |
| 378 size_t output_offset; | 353 size_t output_offset; |
| 379 }; | 354 }; |
| 380 | 355 |
| 381 struct CompliantHostCase { | |
| 382 const char* host; | |
| 383 const char* desired_tld; | |
| 384 bool expected_output; | |
| 385 }; | |
| 386 | |
| 387 struct UrlTestData { | 356 struct UrlTestData { |
| 388 const char* description; | 357 const char* description; |
| 389 const char* input; | 358 const char* input; |
| 390 const char* languages; | 359 const char* languages; |
| 391 FormatUrlTypes format_types; | 360 FormatUrlTypes format_types; |
| 392 UnescapeRule::Type escape_rules; | 361 UnescapeRule::Type escape_rules; |
| 393 const wchar_t* output; // Use |wchar_t| to handle Unicode constants easily. | 362 const wchar_t* output; // Use |wchar_t| to handle Unicode constants easily. |
| 394 size_t prefix_len; | 363 size_t prefix_len; |
| 395 }; | 364 }; |
| 396 | 365 |
| 397 // Fills in sockaddr for the given 32-bit address (IPv4.) | |
| 398 // |bytes| should be an array of length 4. | |
| 399 void MakeIPv4Address(const uint8* bytes, int port, SockaddrStorage* storage) { | |
| 400 memset(&storage->addr_storage, 0, sizeof(storage->addr_storage)); | |
| 401 storage->addr_len = sizeof(struct sockaddr_in); | |
| 402 struct sockaddr_in* addr4 = reinterpret_cast<sockaddr_in*>(storage->addr); | |
| 403 addr4->sin_port = base::HostToNet16(port); | |
| 404 addr4->sin_family = AF_INET; | |
| 405 memcpy(&addr4->sin_addr, bytes, 4); | |
| 406 } | |
| 407 | |
| 408 // Fills in sockaddr for the given 128-bit address (IPv6.) | |
| 409 // |bytes| should be an array of length 16. | |
| 410 void MakeIPv6Address(const uint8* bytes, int port, SockaddrStorage* storage) { | |
| 411 memset(&storage->addr_storage, 0, sizeof(storage->addr_storage)); | |
| 412 storage->addr_len = sizeof(struct sockaddr_in6); | |
| 413 struct sockaddr_in6* addr6 = reinterpret_cast<sockaddr_in6*>(storage->addr); | |
| 414 addr6->sin6_port = base::HostToNet16(port); | |
| 415 addr6->sin6_family = AF_INET6; | |
| 416 memcpy(&addr6->sin6_addr, bytes, 16); | |
| 417 } | |
| 418 | |
| 419 // A helper for IDN*{Fast,Slow}. | 366 // A helper for IDN*{Fast,Slow}. |
| 420 // Append "::<language list>" to |expected| and |actual| to make it | 367 // Append "::<language list>" to |expected| and |actual| to make it |
| 421 // easy to tell which sub-case fails without debugging. | 368 // easy to tell which sub-case fails without debugging. |
| 422 void AppendLanguagesToOutputs(const char* languages, | 369 void AppendLanguagesToOutputs(const char* languages, |
| 423 base::string16* expected, | 370 base::string16* expected, |
| 424 base::string16* actual) { | 371 base::string16* actual) { |
| 425 base::string16 to_append = ASCIIToUTF16("::") + ASCIIToUTF16(languages); | 372 base::string16 to_append = ASCIIToUTF16("::") + ASCIIToUTF16(languages); |
| 426 expected->append(to_append); | 373 expected->append(to_append); |
| 427 actual->append(to_append); | 374 actual->append(to_append); |
| 428 } | 375 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 454 for (size_t i = 0; i < url_length; ++i) | 401 for (size_t i = 0; i < url_length; ++i) |
| 455 VerboseExpect(output_offsets[i], offsets[i], url_string, i, formatted_url); | 402 VerboseExpect(output_offsets[i], offsets[i], url_string, i, formatted_url); |
| 456 VerboseExpect(formatted_url.length(), offsets[url_length], url_string, | 403 VerboseExpect(formatted_url.length(), offsets[url_length], url_string, |
| 457 url_length, formatted_url); | 404 url_length, formatted_url); |
| 458 VerboseExpect(base::string16::npos, offsets[url_length + 1], url_string, | 405 VerboseExpect(base::string16::npos, offsets[url_length + 1], url_string, |
| 459 500000, formatted_url); | 406 500000, formatted_url); |
| 460 VerboseExpect(base::string16::npos, offsets[url_length + 2], url_string, | 407 VerboseExpect(base::string16::npos, offsets[url_length + 2], url_string, |
| 461 std::string::npos, formatted_url); | 408 std::string::npos, formatted_url); |
| 462 } | 409 } |
| 463 | 410 |
| 464 // Helper to strignize an IP number (used to define expectations). | |
| 465 std::string DumpIPNumber(const IPAddressNumber& v) { | |
| 466 std::string out; | |
| 467 for (size_t i = 0; i < v.size(); ++i) { | |
| 468 if (i != 0) | |
| 469 out.append(","); | |
| 470 out.append(base::IntToString(static_cast<int>(v[i]))); | |
| 471 } | |
| 472 return out; | |
| 473 } | |
| 474 | |
| 475 } // anonymous namespace | 411 } // anonymous namespace |
| 476 | 412 |
| 477 TEST(NetUtilTest, GetIdentityFromURL) { | |
| 478 struct { | |
| 479 const char* input_url; | |
| 480 const char* expected_username; | |
| 481 const char* expected_password; | |
| 482 } tests[] = { | |
| 483 { | |
| 484 "http://username:password@google.com", | |
| 485 "username", | |
| 486 "password", | |
| 487 }, | |
| 488 { // Test for http://crbug.com/19200 | |
| 489 "http://username:p@ssword@google.com", | |
| 490 "username", | |
| 491 "p@ssword", | |
| 492 }, | |
| 493 { // Special URL characters should be unescaped. | |
| 494 "http://username:p%3fa%26s%2fs%23@google.com", | |
| 495 "username", | |
| 496 "p?a&s/s#", | |
| 497 }, | |
| 498 { // Username contains %20. | |
| 499 "http://use rname:password@google.com", | |
| 500 "use rname", | |
| 501 "password", | |
| 502 }, | |
| 503 { // Keep %00 as is. | |
| 504 "http://use%00rname:password@google.com", | |
| 505 "use%00rname", | |
| 506 "password", | |
| 507 }, | |
| 508 { // Use a '+' in the username. | |
| 509 "http://use+rname:password@google.com", | |
| 510 "use+rname", | |
| 511 "password", | |
| 512 }, | |
| 513 { // Use a '&' in the password. | |
| 514 "http://username:p&ssword@google.com", | |
| 515 "username", | |
| 516 "p&ssword", | |
| 517 }, | |
| 518 }; | |
| 519 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | |
| 520 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i, | |
| 521 tests[i].input_url)); | |
| 522 GURL url(tests[i].input_url); | |
| 523 | |
| 524 base::string16 username, password; | |
| 525 GetIdentityFromURL(url, &username, &password); | |
| 526 | |
| 527 EXPECT_EQ(ASCIIToUTF16(tests[i].expected_username), username); | |
| 528 EXPECT_EQ(ASCIIToUTF16(tests[i].expected_password), password); | |
| 529 } | |
| 530 } | |
| 531 | |
| 532 // Try extracting a username which was encoded with UTF8. | |
| 533 TEST(NetUtilTest, GetIdentityFromURL_UTF8) { | |
| 534 GURL url(WideToUTF16(L"http://foo:\x4f60\x597d@blah.com")); | |
| 535 | |
| 536 EXPECT_EQ("foo", url.username()); | |
| 537 EXPECT_EQ("%E4%BD%A0%E5%A5%BD", url.password()); | |
| 538 | |
| 539 // Extract the unescaped identity. | |
| 540 base::string16 username, password; | |
| 541 GetIdentityFromURL(url, &username, &password); | |
| 542 | |
| 543 // Verify that it was decoded as UTF8. | |
| 544 EXPECT_EQ(ASCIIToUTF16("foo"), username); | |
| 545 EXPECT_EQ(WideToUTF16(L"\x4f60\x597d"), password); | |
| 546 } | |
| 547 | |
| 548 // Just a bunch of fake headers. | |
| 549 const char* google_headers = | |
| 550 "HTTP/1.1 200 OK\n" | |
| 551 "Content-TYPE: text/html; charset=utf-8\n" | |
| 552 "Content-disposition: attachment; filename=\"download.pdf\"\n" | |
| 553 "Content-Length: 378557\n" | |
| 554 "X-Google-Google1: 314159265\n" | |
| 555 "X-Google-Google2: aaaa2:7783,bbb21:9441\n" | |
| 556 "X-Google-Google4: home\n" | |
| 557 "Transfer-Encoding: chunked\n" | |
| 558 "Set-Cookie: HEHE_AT=6666x66beef666x6-66xx6666x66; Path=/mail\n" | |
| 559 "Set-Cookie: HEHE_HELP=owned:0;Path=/\n" | |
| 560 "Set-Cookie: S=gmail=Xxx-beefbeefbeef_beefb:gmail_yj=beefbeef000beefbee" | |
| 561 "fbee:gmproxy=bee-fbeefbe; Domain=.google.com; Path=/\n" | |
| 562 "X-Google-Google2: /one/two/three/four/five/six/seven-height/nine:9411\n" | |
| 563 "Server: GFE/1.3\n" | |
| 564 "Transfer-Encoding: chunked\n" | |
| 565 "Date: Mon, 13 Nov 2006 21:38:09 GMT\n" | |
| 566 "Expires: Tue, 14 Nov 2006 19:23:58 GMT\n" | |
| 567 "X-Malformed: bla; arg=test\"\n" | |
| 568 "X-Malformed2: bla; arg=\n" | |
| 569 "X-Test: bla; arg1=val1; arg2=val2"; | |
| 570 | |
| 571 TEST(NetUtilTest, GetSpecificHeader) { | |
| 572 const HeaderCase tests[] = { | |
| 573 {"content-type", "text/html; charset=utf-8"}, | |
| 574 {"CONTENT-LENGTH", "378557"}, | |
| 575 {"Date", "Mon, 13 Nov 2006 21:38:09 GMT"}, | |
| 576 {"Bad-Header", ""}, | |
| 577 {"", ""}, | |
| 578 }; | |
| 579 | |
| 580 // Test first with google_headers. | |
| 581 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | |
| 582 std::string result = | |
| 583 GetSpecificHeader(google_headers, tests[i].header_name); | |
| 584 EXPECT_EQ(result, tests[i].expected); | |
| 585 } | |
| 586 | |
| 587 // Test again with empty headers. | |
| 588 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | |
| 589 std::string result = GetSpecificHeader(std::string(), tests[i].header_name); | |
| 590 EXPECT_EQ(result, std::string()); | |
| 591 } | |
| 592 } | |
| 593 | |
| 594 TEST(NetUtilTest, IDNToUnicodeFast) { | 413 TEST(NetUtilTest, IDNToUnicodeFast) { |
| 595 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(idn_cases); i++) { | 414 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(idn_cases); i++) { |
| 596 for (size_t j = 0; j < arraysize(kLanguages); j++) { | 415 for (size_t j = 0; j < arraysize(kLanguages); j++) { |
| 597 // ja || zh-TW,en || ko,ja -> IDNToUnicodeSlow | 416 // ja || zh-TW,en || ko,ja -> IDNToUnicodeSlow |
| 598 if (j == 3 || j == 17 || j == 18) | 417 if (j == 3 || j == 17 || j == 18) |
| 599 continue; | 418 continue; |
| 600 base::string16 output(IDNToUnicode(idn_cases[i].input, kLanguages[j])); | 419 base::string16 output(IDNToUnicode(idn_cases[i].input, kLanguages[j])); |
| 601 base::string16 expected(idn_cases[i].unicode_allowed[j] ? | 420 base::string16 expected(idn_cases[i].unicode_allowed[j] ? |
| 602 WideToUTF16(idn_cases[i].unicode_output) : | 421 WideToUTF16(idn_cases[i].unicode_output) : |
| 603 ASCIIToUTF16(idn_cases[i].input)); | 422 ASCIIToUTF16(idn_cases[i].input)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 616 base::string16 output(IDNToUnicode(idn_cases[i].input, kLanguages[j])); | 435 base::string16 output(IDNToUnicode(idn_cases[i].input, kLanguages[j])); |
| 617 base::string16 expected(idn_cases[i].unicode_allowed[j] ? | 436 base::string16 expected(idn_cases[i].unicode_allowed[j] ? |
| 618 WideToUTF16(idn_cases[i].unicode_output) : | 437 WideToUTF16(idn_cases[i].unicode_output) : |
| 619 ASCIIToUTF16(idn_cases[i].input)); | 438 ASCIIToUTF16(idn_cases[i].input)); |
| 620 AppendLanguagesToOutputs(kLanguages[j], &expected, &output); | 439 AppendLanguagesToOutputs(kLanguages[j], &expected, &output); |
| 621 EXPECT_EQ(expected, output); | 440 EXPECT_EQ(expected, output); |
| 622 } | 441 } |
| 623 } | 442 } |
| 624 } | 443 } |
| 625 | 444 |
| 626 TEST(NetUtilTest, CompliantHost) { | |
| 627 const CompliantHostCase compliant_host_cases[] = { | |
| 628 {"", "", false}, | |
| 629 {"a", "", true}, | |
| 630 {"-", "", false}, | |
| 631 {".", "", false}, | |
| 632 {"9", "", true}, | |
| 633 {"9a", "", true}, | |
| 634 {"a.", "", true}, | |
| 635 {"a.a", "", true}, | |
| 636 {"9.a", "", true}, | |
| 637 {"a.9", "", true}, | |
| 638 {"_9a", "", false}, | |
| 639 {"-9a", "", false}, | |
| 640 {"-9a", "a", true}, | |
| 641 {"a.a9", "", true}, | |
| 642 {"a.-a9", "", false}, | |
| 643 {"a+9a", "", false}, | |
| 644 {"-a.a9", "", true}, | |
| 645 {"1-.a-b", "", true}, | |
| 646 {"1_.a-b", "", false}, | |
| 647 {"1-2.a_b", "", true}, | |
| 648 {"a.b.c.d.e", "", true}, | |
| 649 {"1.2.3.4.5", "", true}, | |
| 650 {"1.2.3.4.5.", "", true}, | |
| 651 }; | |
| 652 | |
| 653 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(compliant_host_cases); ++i) { | |
| 654 EXPECT_EQ(compliant_host_cases[i].expected_output, | |
| 655 IsCanonicalizedHostCompliant(compliant_host_cases[i].host, | |
| 656 compliant_host_cases[i].desired_tld)); | |
| 657 } | |
| 658 } | |
| 659 | |
| 660 TEST(NetUtilTest, StripWWW) { | 445 TEST(NetUtilTest, StripWWW) { |
| 661 EXPECT_EQ(base::string16(), StripWWW(base::string16())); | 446 EXPECT_EQ(base::string16(), StripWWW(base::string16())); |
| 662 EXPECT_EQ(base::string16(), StripWWW(ASCIIToUTF16("www."))); | 447 EXPECT_EQ(base::string16(), StripWWW(ASCIIToUTF16("www."))); |
| 663 EXPECT_EQ(ASCIIToUTF16("blah"), StripWWW(ASCIIToUTF16("www.blah"))); | 448 EXPECT_EQ(ASCIIToUTF16("blah"), StripWWW(ASCIIToUTF16("www.blah"))); |
| 664 EXPECT_EQ(ASCIIToUTF16("blah"), StripWWW(ASCIIToUTF16("blah"))); | 449 EXPECT_EQ(ASCIIToUTF16("blah"), StripWWW(ASCIIToUTF16("blah"))); |
| 665 } | 450 } |
| 666 | 451 |
| 667 // This is currently a windows specific function. | 452 // This is currently a windows specific function. |
| 668 #if defined(OS_WIN) | 453 #if defined(OS_WIN) |
| 669 namespace { | 454 namespace { |
| 670 | 455 |
| 671 struct GetDirectoryListingEntryCase { | 456 struct GetDirectoryListingEntryCase { |
| 672 const wchar_t* name; | 457 const wchar_t* name; |
| 673 const char* raw_bytes; | 458 const char* raw_bytes; |
| 674 bool is_dir; | 459 bool is_dir; |
| 675 int64 filesize; | 460 int64 filesize; |
| 676 base::Time time; | 461 base::Time time; |
| 677 const char* expected; | 462 const char* expected; |
| 678 }; | 463 }; |
| 679 | 464 |
| 680 } // namespace | 465 } // namespace |
| 466 |
| 681 TEST(NetUtilTest, GetDirectoryListingEntry) { | 467 TEST(NetUtilTest, GetDirectoryListingEntry) { |
| 682 const GetDirectoryListingEntryCase test_cases[] = { | 468 const GetDirectoryListingEntryCase test_cases[] = { |
| 683 {L"Foo", | 469 {L"Foo", |
| 684 "", | 470 "", |
| 685 false, | 471 false, |
| 686 10000, | 472 10000, |
| 687 base::Time(), | 473 base::Time(), |
| 688 "<script>addRow(\"Foo\",\"Foo\",0,\"9.8 kB\",\"\");</script>\n"}, | 474 "<script>addRow(\"Foo\",\"Foo\",0,\"9.8 kB\",\"\");</script>\n"}, |
| 689 {L"quo\"tes", | 475 {L"quo\"tes", |
| 690 "", | 476 "", |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 test_cases[i].raw_bytes, | 512 test_cases[i].raw_bytes, |
| 727 test_cases[i].is_dir, | 513 test_cases[i].is_dir, |
| 728 test_cases[i].filesize, | 514 test_cases[i].filesize, |
| 729 test_cases[i].time); | 515 test_cases[i].time); |
| 730 EXPECT_EQ(test_cases[i].expected, results); | 516 EXPECT_EQ(test_cases[i].expected, results); |
| 731 } | 517 } |
| 732 } | 518 } |
| 733 | 519 |
| 734 #endif | 520 #endif |
| 735 | 521 |
| 736 TEST(NetUtilTest, ParseHostAndPort) { | |
| 737 const struct { | |
| 738 const char* input; | |
| 739 bool success; | |
| 740 const char* expected_host; | |
| 741 int expected_port; | |
| 742 } tests[] = { | |
| 743 // Valid inputs: | |
| 744 {"foo:10", true, "foo", 10}, | |
| 745 {"foo", true, "foo", -1}, | |
| 746 { | |
| 747 "[1080:0:0:0:8:800:200C:4171]:11", | |
| 748 true, | |
| 749 "[1080:0:0:0:8:800:200C:4171]", | |
| 750 11, | |
| 751 }, | |
| 752 // Invalid inputs: | |
| 753 {"foo:bar", false, "", -1}, | |
| 754 {"foo:", false, "", -1}, | |
| 755 {":", false, "", -1}, | |
| 756 {":80", false, "", -1}, | |
| 757 {"", false, "", -1}, | |
| 758 {"porttoolong:300000", false, "", -1}, | |
| 759 {"usrname@host", false, "", -1}, | |
| 760 {"usrname:password@host", false, "", -1}, | |
| 761 {":password@host", false, "", -1}, | |
| 762 {":password@host:80", false, "", -1}, | |
| 763 {":password@host", false, "", -1}, | |
| 764 {"@host", false, "", -1}, | |
| 765 }; | |
| 766 | |
| 767 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | |
| 768 std::string host; | |
| 769 int port; | |
| 770 bool ok = ParseHostAndPort(tests[i].input, &host, &port); | |
| 771 | |
| 772 EXPECT_EQ(tests[i].success, ok); | |
| 773 | |
| 774 if (tests[i].success) { | |
| 775 EXPECT_EQ(tests[i].expected_host, host); | |
| 776 EXPECT_EQ(tests[i].expected_port, port); | |
| 777 } | |
| 778 } | |
| 779 } | |
| 780 | |
| 781 TEST(NetUtilTest, GetHostAndPort) { | |
| 782 const struct { | |
| 783 GURL url; | |
| 784 const char* expected_host_and_port; | |
| 785 } tests[] = { | |
| 786 { GURL("http://www.foo.com/x"), "www.foo.com:80"}, | |
| 787 { GURL("http://www.foo.com:21/x"), "www.foo.com:21"}, | |
| 788 | |
| 789 // For IPv6 literals should always include the brackets. | |
| 790 { GURL("http://[1::2]/x"), "[1::2]:80"}, | |
| 791 { GURL("http://[::a]:33/x"), "[::a]:33"}, | |
| 792 }; | |
| 793 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | |
| 794 std::string host_and_port = GetHostAndPort(tests[i].url); | |
| 795 EXPECT_EQ(std::string(tests[i].expected_host_and_port), host_and_port); | |
| 796 } | |
| 797 } | |
| 798 | |
| 799 TEST(NetUtilTest, GetHostAndOptionalPort) { | |
| 800 const struct { | |
| 801 GURL url; | |
| 802 const char* expected_host_and_port; | |
| 803 } tests[] = { | |
| 804 { GURL("http://www.foo.com/x"), "www.foo.com"}, | |
| 805 { GURL("http://www.foo.com:21/x"), "www.foo.com:21"}, | |
| 806 | |
| 807 // For IPv6 literals should always include the brackets. | |
| 808 { GURL("http://[1::2]/x"), "[1::2]"}, | |
| 809 { GURL("http://[::a]:33/x"), "[::a]:33"}, | |
| 810 }; | |
| 811 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | |
| 812 std::string host_and_port = GetHostAndOptionalPort(tests[i].url); | |
| 813 EXPECT_EQ(std::string(tests[i].expected_host_and_port), host_and_port); | |
| 814 } | |
| 815 } | |
| 816 | |
| 817 TEST(NetUtilTest, IPAddressToString) { | |
| 818 uint8 addr1[4] = {0, 0, 0, 0}; | |
| 819 EXPECT_EQ("0.0.0.0", IPAddressToString(addr1, sizeof(addr1))); | |
| 820 | |
| 821 uint8 addr2[4] = {192, 168, 0, 1}; | |
| 822 EXPECT_EQ("192.168.0.1", IPAddressToString(addr2, sizeof(addr2))); | |
| 823 | |
| 824 uint8 addr3[16] = {0xFE, 0xDC, 0xBA, 0x98}; | |
| 825 EXPECT_EQ("fedc:ba98::", IPAddressToString(addr3, sizeof(addr3))); | |
| 826 } | |
| 827 | |
| 828 TEST(NetUtilTest, IPAddressToStringWithPort) { | |
| 829 uint8 addr1[4] = {0, 0, 0, 0}; | |
| 830 EXPECT_EQ("0.0.0.0:3", IPAddressToStringWithPort(addr1, sizeof(addr1), 3)); | |
| 831 | |
| 832 uint8 addr2[4] = {192, 168, 0, 1}; | |
| 833 EXPECT_EQ("192.168.0.1:99", | |
| 834 IPAddressToStringWithPort(addr2, sizeof(addr2), 99)); | |
| 835 | |
| 836 uint8 addr3[16] = {0xFE, 0xDC, 0xBA, 0x98}; | |
| 837 EXPECT_EQ("[fedc:ba98::]:8080", | |
| 838 IPAddressToStringWithPort(addr3, sizeof(addr3), 8080)); | |
| 839 } | |
| 840 | |
| 841 TEST(NetUtilTest, NetAddressToString_IPv4) { | |
| 842 const struct { | |
| 843 uint8 addr[4]; | |
| 844 const char* result; | |
| 845 } tests[] = { | |
| 846 {{0, 0, 0, 0}, "0.0.0.0"}, | |
| 847 {{127, 0, 0, 1}, "127.0.0.1"}, | |
| 848 {{192, 168, 0, 1}, "192.168.0.1"}, | |
| 849 }; | |
| 850 | |
| 851 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | |
| 852 SockaddrStorage storage; | |
| 853 MakeIPv4Address(tests[i].addr, 80, &storage); | |
| 854 std::string result = NetAddressToString(storage.addr, storage.addr_len); | |
| 855 EXPECT_EQ(std::string(tests[i].result), result); | |
| 856 } | |
| 857 } | |
| 858 | |
| 859 TEST(NetUtilTest, NetAddressToString_IPv6) { | |
| 860 const struct { | |
| 861 uint8 addr[16]; | |
| 862 const char* result; | |
| 863 } tests[] = { | |
| 864 {{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0xFE, 0xDC, 0xBA, | |
| 865 0x98, 0x76, 0x54, 0x32, 0x10}, | |
| 866 "fedc:ba98:7654:3210:fedc:ba98:7654:3210"}, | |
| 867 }; | |
| 868 | |
| 869 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | |
| 870 SockaddrStorage storage; | |
| 871 MakeIPv6Address(tests[i].addr, 80, &storage); | |
| 872 EXPECT_EQ(std::string(tests[i].result), | |
| 873 NetAddressToString(storage.addr, storage.addr_len)); | |
| 874 } | |
| 875 } | |
| 876 | |
| 877 TEST(NetUtilTest, NetAddressToStringWithPort_IPv4) { | |
| 878 uint8 addr[] = {127, 0, 0, 1}; | |
| 879 SockaddrStorage storage; | |
| 880 MakeIPv4Address(addr, 166, &storage); | |
| 881 std::string result = NetAddressToStringWithPort(storage.addr, | |
| 882 storage.addr_len); | |
| 883 EXPECT_EQ("127.0.0.1:166", result); | |
| 884 } | |
| 885 | |
| 886 TEST(NetUtilTest, NetAddressToStringWithPort_IPv6) { | |
| 887 uint8 addr[] = { | |
| 888 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0xFE, 0xDC, 0xBA, | |
| 889 0x98, 0x76, 0x54, 0x32, 0x10 | |
| 890 }; | |
| 891 SockaddrStorage storage; | |
| 892 MakeIPv6Address(addr, 361, &storage); | |
| 893 std::string result = NetAddressToStringWithPort(storage.addr, | |
| 894 storage.addr_len); | |
| 895 | |
| 896 // May fail on systems that don't support IPv6. | |
| 897 if (!result.empty()) | |
| 898 EXPECT_EQ("[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:361", result); | |
| 899 } | |
| 900 | |
| 901 TEST(NetUtilTest, GetHostName) { | |
| 902 // We can't check the result of GetHostName() directly, since the result | |
| 903 // will differ across machines. Our goal here is to simply exercise the | |
| 904 // code path, and check that things "look about right". | |
| 905 std::string hostname = GetHostName(); | |
| 906 EXPECT_FALSE(hostname.empty()); | |
| 907 } | |
| 908 | |
| 909 TEST(NetUtilTest, FormatUrl) { | 522 TEST(NetUtilTest, FormatUrl) { |
| 910 FormatUrlTypes default_format_type = kFormatUrlOmitUsernamePassword; | 523 FormatUrlTypes default_format_type = kFormatUrlOmitUsernamePassword; |
| 911 const UrlTestData tests[] = { | 524 const UrlTestData tests[] = { |
| 912 {"Empty URL", "", "", default_format_type, UnescapeRule::NORMAL, L"", 0}, | 525 {"Empty URL", "", "", default_format_type, UnescapeRule::NORMAL, L"", 0}, |
| 913 | 526 |
| 914 {"Simple URL", | 527 {"Simple URL", |
| 915 "http://www.google.com/", "", default_format_type, UnescapeRule::NORMAL, | 528 "http://www.google.com/", "", default_format_type, UnescapeRule::NORMAL, |
| 916 L"http://www.google.com/", 7}, | 529 L"http://www.google.com/", 7}, |
| 917 | 530 |
| 918 {"With a port number and a reference", | 531 {"With a port number and a reference", |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1448 UnescapeRule::NORMAL, omit_http_start_with_ftp_offsets); | 1061 UnescapeRule::NORMAL, omit_http_start_with_ftp_offsets); |
| 1449 | 1062 |
| 1450 const size_t omit_all_offsets[] = { | 1063 const size_t omit_all_offsets[] = { |
| 1451 0, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 0, kNpos, kNpos, kNpos, kNpos, | 1064 0, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 0, kNpos, kNpos, kNpos, kNpos, |
| 1452 0, 1, 2, 3, 4, 5, 6, 7 | 1065 0, 1, 2, 3, 4, 5, 6, 7 |
| 1453 }; | 1066 }; |
| 1454 CheckAdjustedOffsets("http://user@foo.com/", "en", kFormatUrlOmitAll, | 1067 CheckAdjustedOffsets("http://user@foo.com/", "en", kFormatUrlOmitAll, |
| 1455 UnescapeRule::NORMAL, omit_all_offsets); | 1068 UnescapeRule::NORMAL, omit_all_offsets); |
| 1456 } | 1069 } |
| 1457 | 1070 |
| 1458 TEST(NetUtilTest, SimplifyUrlForRequest) { | |
| 1459 struct { | |
| 1460 const char* input_url; | |
| 1461 const char* expected_simplified_url; | |
| 1462 } tests[] = { | |
| 1463 { | |
| 1464 // Reference section should be stripped. | |
| 1465 "http://www.google.com:78/foobar?query=1#hash", | |
| 1466 "http://www.google.com:78/foobar?query=1", | |
| 1467 }, | |
| 1468 { | |
| 1469 // Reference section can itself contain #. | |
| 1470 "http://192.168.0.1?query=1#hash#10#11#13#14", | |
| 1471 "http://192.168.0.1?query=1", | |
| 1472 }, | |
| 1473 { // Strip username/password. | |
| 1474 "http://user:pass@google.com", | |
| 1475 "http://google.com/", | |
| 1476 }, | |
| 1477 { // Strip both the reference and the username/password. | |
| 1478 "http://user:pass@google.com:80/sup?yo#X#X", | |
| 1479 "http://google.com/sup?yo", | |
| 1480 }, | |
| 1481 { // Try an HTTPS URL -- strip both the reference and the username/password. | |
| 1482 "https://user:pass@google.com:80/sup?yo#X#X", | |
| 1483 "https://google.com:80/sup?yo", | |
| 1484 }, | |
| 1485 { // Try an FTP URL -- strip both the reference and the username/password. | |
| 1486 "ftp://user:pass@google.com:80/sup?yo#X#X", | |
| 1487 "ftp://google.com:80/sup?yo", | |
| 1488 }, | |
| 1489 { // Try a nonstandard URL | |
| 1490 "foobar://user:pass@google.com:80/sup?yo#X#X", | |
| 1491 "foobar://user:pass@google.com:80/sup?yo", | |
| 1492 }, | |
| 1493 }; | |
| 1494 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | |
| 1495 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i, | |
| 1496 tests[i].input_url)); | |
| 1497 GURL input_url(GURL(tests[i].input_url)); | |
| 1498 GURL expected_url(GURL(tests[i].expected_simplified_url)); | |
| 1499 EXPECT_EQ(expected_url, SimplifyUrlForRequest(input_url)); | |
| 1500 } | |
| 1501 } | |
| 1502 | |
| 1503 TEST(NetUtilTest, SetExplicitlyAllowedPortsTest) { | |
| 1504 std::string invalid[] = { "1,2,a", "'1','2'", "1, 2, 3", "1 0,11,12" }; | |
| 1505 std::string valid[] = { "", "1", "1,2", "1,2,3", "10,11,12,13" }; | |
| 1506 | |
| 1507 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(invalid); ++i) { | |
| 1508 SetExplicitlyAllowedPorts(invalid[i]); | |
| 1509 EXPECT_EQ(0, static_cast<int>(GetCountOfExplicitlyAllowedPorts())); | |
| 1510 } | |
| 1511 | |
| 1512 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(valid); ++i) { | |
| 1513 SetExplicitlyAllowedPorts(valid[i]); | |
| 1514 EXPECT_EQ(i, GetCountOfExplicitlyAllowedPorts()); | |
| 1515 } | |
| 1516 } | |
| 1517 | |
| 1518 TEST(NetUtilTest, GetHostOrSpecFromURL) { | |
| 1519 EXPECT_EQ("example.com", | |
| 1520 GetHostOrSpecFromURL(GURL("http://example.com/test"))); | |
| 1521 EXPECT_EQ("example.com", | |
| 1522 GetHostOrSpecFromURL(GURL("http://example.com./test"))); | |
| 1523 EXPECT_EQ("file:///tmp/test.html", | |
| 1524 GetHostOrSpecFromURL(GURL("file:///tmp/test.html"))); | |
| 1525 } | |
| 1526 | |
| 1527 TEST(NetUtilTest, GetAddressFamily) { | |
| 1528 IPAddressNumber number; | |
| 1529 EXPECT_TRUE(ParseIPLiteralToNumber("192.168.0.1", &number)); | |
| 1530 EXPECT_EQ(ADDRESS_FAMILY_IPV4, GetAddressFamily(number)); | |
| 1531 EXPECT_TRUE(ParseIPLiteralToNumber("1:abcd::3:4:ff", &number)); | |
| 1532 EXPECT_EQ(ADDRESS_FAMILY_IPV6, GetAddressFamily(number)); | |
| 1533 } | |
| 1534 | |
| 1535 // Test that invalid IP literals fail to parse. | |
| 1536 TEST(NetUtilTest, ParseIPLiteralToNumber_FailParse) { | |
| 1537 IPAddressNumber number; | |
| 1538 | |
| 1539 EXPECT_FALSE(ParseIPLiteralToNumber("bad value", &number)); | |
| 1540 EXPECT_FALSE(ParseIPLiteralToNumber("bad:value", &number)); | |
| 1541 EXPECT_FALSE(ParseIPLiteralToNumber(std::string(), &number)); | |
| 1542 EXPECT_FALSE(ParseIPLiteralToNumber("192.168.0.1:30", &number)); | |
| 1543 EXPECT_FALSE(ParseIPLiteralToNumber(" 192.168.0.1 ", &number)); | |
| 1544 EXPECT_FALSE(ParseIPLiteralToNumber("[::1]", &number)); | |
| 1545 } | |
| 1546 | |
| 1547 // Test parsing an IPv4 literal. | |
| 1548 TEST(NetUtilTest, ParseIPLiteralToNumber_IPv4) { | |
| 1549 IPAddressNumber number; | |
| 1550 EXPECT_TRUE(ParseIPLiteralToNumber("192.168.0.1", &number)); | |
| 1551 EXPECT_EQ("192,168,0,1", DumpIPNumber(number)); | |
| 1552 EXPECT_EQ("192.168.0.1", IPAddressToString(number)); | |
| 1553 } | |
| 1554 | |
| 1555 // Test parsing an IPv6 literal. | |
| 1556 TEST(NetUtilTest, ParseIPLiteralToNumber_IPv6) { | |
| 1557 IPAddressNumber number; | |
| 1558 EXPECT_TRUE(ParseIPLiteralToNumber("1:abcd::3:4:ff", &number)); | |
| 1559 EXPECT_EQ("0,1,171,205,0,0,0,0,0,0,0,3,0,4,0,255", DumpIPNumber(number)); | |
| 1560 EXPECT_EQ("1:abcd::3:4:ff", IPAddressToString(number)); | |
| 1561 } | |
| 1562 | |
| 1563 // Test mapping an IPv4 address to an IPv6 address. | |
| 1564 TEST(NetUtilTest, ConvertIPv4NumberToIPv6Number) { | |
| 1565 IPAddressNumber ipv4_number; | |
| 1566 EXPECT_TRUE(ParseIPLiteralToNumber("192.168.0.1", &ipv4_number)); | |
| 1567 | |
| 1568 IPAddressNumber ipv6_number = | |
| 1569 ConvertIPv4NumberToIPv6Number(ipv4_number); | |
| 1570 | |
| 1571 // ::ffff:192.168.0.1 | |
| 1572 EXPECT_EQ("0,0,0,0,0,0,0,0,0,0,255,255,192,168,0,1", | |
| 1573 DumpIPNumber(ipv6_number)); | |
| 1574 EXPECT_EQ("::ffff:c0a8:1", IPAddressToString(ipv6_number)); | |
| 1575 } | |
| 1576 | |
| 1577 TEST(NetUtilTest, IsIPv4Mapped) { | |
| 1578 IPAddressNumber ipv4_number; | |
| 1579 EXPECT_TRUE(ParseIPLiteralToNumber("192.168.0.1", &ipv4_number)); | |
| 1580 EXPECT_FALSE(IsIPv4Mapped(ipv4_number)); | |
| 1581 | |
| 1582 IPAddressNumber ipv6_number; | |
| 1583 EXPECT_TRUE(ParseIPLiteralToNumber("::1", &ipv4_number)); | |
| 1584 EXPECT_FALSE(IsIPv4Mapped(ipv6_number)); | |
| 1585 | |
| 1586 IPAddressNumber ipv4mapped_number; | |
| 1587 EXPECT_TRUE(ParseIPLiteralToNumber("::ffff:0101:1", &ipv4mapped_number)); | |
| 1588 EXPECT_TRUE(IsIPv4Mapped(ipv4mapped_number)); | |
| 1589 } | |
| 1590 | |
| 1591 TEST(NetUtilTest, ConvertIPv4MappedToIPv4) { | |
| 1592 IPAddressNumber ipv4mapped_number; | |
| 1593 EXPECT_TRUE(ParseIPLiteralToNumber("::ffff:0101:1", &ipv4mapped_number)); | |
| 1594 IPAddressNumber expected; | |
| 1595 EXPECT_TRUE(ParseIPLiteralToNumber("1.1.0.1", &expected)); | |
| 1596 IPAddressNumber result = ConvertIPv4MappedToIPv4(ipv4mapped_number); | |
| 1597 EXPECT_EQ(expected, result); | |
| 1598 } | |
| 1599 | |
| 1600 // Test parsing invalid CIDR notation literals. | |
| 1601 TEST(NetUtilTest, ParseCIDRBlock_Invalid) { | |
| 1602 const char* bad_literals[] = { | |
| 1603 "foobar", | |
| 1604 "", | |
| 1605 "192.168.0.1", | |
| 1606 "::1", | |
| 1607 "/", | |
| 1608 "/1", | |
| 1609 "1", | |
| 1610 "192.168.1.1/-1", | |
| 1611 "192.168.1.1/33", | |
| 1612 "::1/-3", | |
| 1613 "a::3/129", | |
| 1614 "::1/x", | |
| 1615 "192.168.0.1//11" | |
| 1616 }; | |
| 1617 | |
| 1618 for (size_t i = 0; i < arraysize(bad_literals); ++i) { | |
| 1619 IPAddressNumber ip_number; | |
| 1620 size_t prefix_length_in_bits; | |
| 1621 | |
| 1622 EXPECT_FALSE(ParseCIDRBlock(bad_literals[i], | |
| 1623 &ip_number, | |
| 1624 &prefix_length_in_bits)); | |
| 1625 } | |
| 1626 } | |
| 1627 | |
| 1628 // Test parsing a valid CIDR notation literal. | |
| 1629 TEST(NetUtilTest, ParseCIDRBlock_Valid) { | |
| 1630 IPAddressNumber ip_number; | |
| 1631 size_t prefix_length_in_bits; | |
| 1632 | |
| 1633 EXPECT_TRUE(ParseCIDRBlock("192.168.0.1/11", | |
| 1634 &ip_number, | |
| 1635 &prefix_length_in_bits)); | |
| 1636 | |
| 1637 EXPECT_EQ("192,168,0,1", DumpIPNumber(ip_number)); | |
| 1638 EXPECT_EQ(11u, prefix_length_in_bits); | |
| 1639 } | |
| 1640 | |
| 1641 TEST(NetUtilTest, IPNumberMatchesPrefix) { | |
| 1642 struct { | |
| 1643 const char* cidr_literal; | |
| 1644 const char* ip_literal; | |
| 1645 bool expected_to_match; | |
| 1646 } tests[] = { | |
| 1647 // IPv4 prefix with IPv4 inputs. | |
| 1648 { | |
| 1649 "10.10.1.32/27", | |
| 1650 "10.10.1.44", | |
| 1651 true | |
| 1652 }, | |
| 1653 { | |
| 1654 "10.10.1.32/27", | |
| 1655 "10.10.1.90", | |
| 1656 false | |
| 1657 }, | |
| 1658 { | |
| 1659 "10.10.1.32/27", | |
| 1660 "10.10.1.90", | |
| 1661 false | |
| 1662 }, | |
| 1663 | |
| 1664 // IPv6 prefix with IPv6 inputs. | |
| 1665 { | |
| 1666 "2001:db8::/32", | |
| 1667 "2001:DB8:3:4::5", | |
| 1668 true | |
| 1669 }, | |
| 1670 { | |
| 1671 "2001:db8::/32", | |
| 1672 "2001:c8::", | |
| 1673 false | |
| 1674 }, | |
| 1675 | |
| 1676 // IPv6 prefix with IPv4 inputs. | |
| 1677 { | |
| 1678 "2001:db8::/33", | |
| 1679 "192.168.0.1", | |
| 1680 false | |
| 1681 }, | |
| 1682 { | |
| 1683 "::ffff:192.168.0.1/112", | |
| 1684 "192.168.33.77", | |
| 1685 true | |
| 1686 }, | |
| 1687 | |
| 1688 // IPv4 prefix with IPv6 inputs. | |
| 1689 { | |
| 1690 "10.11.33.44/16", | |
| 1691 "::ffff:0a0b:89", | |
| 1692 true | |
| 1693 }, | |
| 1694 { | |
| 1695 "10.11.33.44/16", | |
| 1696 "::ffff:10.12.33.44", | |
| 1697 false | |
| 1698 }, | |
| 1699 }; | |
| 1700 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | |
| 1701 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s, %s", i, | |
| 1702 tests[i].cidr_literal, | |
| 1703 tests[i].ip_literal)); | |
| 1704 | |
| 1705 IPAddressNumber ip_number; | |
| 1706 EXPECT_TRUE(ParseIPLiteralToNumber(tests[i].ip_literal, &ip_number)); | |
| 1707 | |
| 1708 IPAddressNumber ip_prefix; | |
| 1709 size_t prefix_length_in_bits; | |
| 1710 | |
| 1711 EXPECT_TRUE(ParseCIDRBlock(tests[i].cidr_literal, | |
| 1712 &ip_prefix, | |
| 1713 &prefix_length_in_bits)); | |
| 1714 | |
| 1715 EXPECT_EQ(tests[i].expected_to_match, | |
| 1716 IPNumberMatchesPrefix(ip_number, | |
| 1717 ip_prefix, | |
| 1718 prefix_length_in_bits)); | |
| 1719 } | |
| 1720 } | |
| 1721 | |
| 1722 TEST(NetUtilTest, IsLocalhost) { | |
| 1723 EXPECT_TRUE(net::IsLocalhost("localhost")); | |
| 1724 EXPECT_TRUE(net::IsLocalhost("localhost.localdomain")); | |
| 1725 EXPECT_TRUE(net::IsLocalhost("localhost6")); | |
| 1726 EXPECT_TRUE(net::IsLocalhost("localhost6.localdomain6")); | |
| 1727 EXPECT_TRUE(net::IsLocalhost("127.0.0.1")); | |
| 1728 EXPECT_TRUE(net::IsLocalhost("127.0.1.0")); | |
| 1729 EXPECT_TRUE(net::IsLocalhost("127.1.0.0")); | |
| 1730 EXPECT_TRUE(net::IsLocalhost("127.0.0.255")); | |
| 1731 EXPECT_TRUE(net::IsLocalhost("127.0.255.0")); | |
| 1732 EXPECT_TRUE(net::IsLocalhost("127.255.0.0")); | |
| 1733 EXPECT_TRUE(net::IsLocalhost("::1")); | |
| 1734 EXPECT_TRUE(net::IsLocalhost("0:0:0:0:0:0:0:1")); | |
| 1735 | |
| 1736 EXPECT_FALSE(net::IsLocalhost("localhostx")); | |
| 1737 EXPECT_FALSE(net::IsLocalhost("foo.localdomain")); | |
| 1738 EXPECT_FALSE(net::IsLocalhost("localhost6x")); | |
| 1739 EXPECT_FALSE(net::IsLocalhost("localhost.localdomain6")); | |
| 1740 EXPECT_FALSE(net::IsLocalhost("localhost6.localdomain")); | |
| 1741 EXPECT_FALSE(net::IsLocalhost("127.0.0.1.1")); | |
| 1742 EXPECT_FALSE(net::IsLocalhost(".127.0.0.255")); | |
| 1743 EXPECT_FALSE(net::IsLocalhost("::2")); | |
| 1744 EXPECT_FALSE(net::IsLocalhost("::1:1")); | |
| 1745 EXPECT_FALSE(net::IsLocalhost("0:0:0:0:1:0:0:1")); | |
| 1746 EXPECT_FALSE(net::IsLocalhost("::1:1")); | |
| 1747 EXPECT_FALSE(net::IsLocalhost("0:0:0:0:0:0:0:0:1")); | |
| 1748 } | |
| 1749 | |
| 1750 // Verify GetNetworkList(). | |
| 1751 TEST(NetUtilTest, GetNetworkList) { | |
| 1752 NetworkInterfaceList list; | |
| 1753 ASSERT_TRUE(GetNetworkList(&list, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES)); | |
| 1754 for (NetworkInterfaceList::iterator it = list.begin(); | |
| 1755 it != list.end(); ++it) { | |
| 1756 // Verify that the names are not empty. | |
| 1757 EXPECT_FALSE(it->name.empty()); | |
| 1758 EXPECT_FALSE(it->friendly_name.empty()); | |
| 1759 | |
| 1760 // Verify that the address is correct. | |
| 1761 EXPECT_TRUE(it->address.size() == kIPv4AddressSize || | |
| 1762 it->address.size() == kIPv6AddressSize) | |
| 1763 << "Invalid address of size " << it->address.size(); | |
| 1764 bool all_zeroes = true; | |
| 1765 for (size_t i = 0; i < it->address.size(); ++i) { | |
| 1766 if (it->address[i] != 0) { | |
| 1767 all_zeroes = false; | |
| 1768 break; | |
| 1769 } | |
| 1770 } | |
| 1771 EXPECT_FALSE(all_zeroes); | |
| 1772 EXPECT_GT(it->network_prefix, 1u); | |
| 1773 EXPECT_LE(it->network_prefix, it->address.size() * 8); | |
| 1774 | |
| 1775 #if defined(OS_WIN) | |
| 1776 // On Windows |name| is NET_LUID. | |
| 1777 base::ScopedNativeLibrary phlpapi_lib( | |
| 1778 base::FilePath(FILE_PATH_LITERAL("iphlpapi.dll"))); | |
| 1779 ASSERT_TRUE(phlpapi_lib.is_valid()); | |
| 1780 typedef NETIO_STATUS (WINAPI* ConvertInterfaceIndexToLuid)(NET_IFINDEX, | |
| 1781 PNET_LUID); | |
| 1782 ConvertInterfaceIndexToLuid interface_to_luid = | |
| 1783 reinterpret_cast<ConvertInterfaceIndexToLuid>( | |
| 1784 phlpapi_lib.GetFunctionPointer("ConvertInterfaceIndexToLuid")); | |
| 1785 | |
| 1786 typedef NETIO_STATUS (WINAPI* ConvertInterfaceLuidToGuid)(NET_LUID*, | |
| 1787 GUID*); | |
| 1788 ConvertInterfaceLuidToGuid luid_to_guid = | |
| 1789 reinterpret_cast<ConvertInterfaceLuidToGuid>( | |
| 1790 phlpapi_lib.GetFunctionPointer("ConvertInterfaceLuidToGuid")); | |
| 1791 | |
| 1792 if (interface_to_luid && luid_to_guid) { | |
| 1793 NET_LUID luid; | |
| 1794 EXPECT_EQ(interface_to_luid(it->interface_index, &luid), NO_ERROR); | |
| 1795 GUID guid; | |
| 1796 EXPECT_EQ(luid_to_guid(&luid, &guid), NO_ERROR); | |
| 1797 LPOLESTR name; | |
| 1798 StringFromCLSID(guid, &name); | |
| 1799 EXPECT_STREQ(base::UTF8ToWide(it->name).c_str(), name); | |
| 1800 CoTaskMemFree(name); | |
| 1801 continue; | |
| 1802 } else { | |
| 1803 EXPECT_LT(base::win::GetVersion(), base::win::VERSION_VISTA); | |
| 1804 EXPECT_LT(it->interface_index, 1u << 24u); // Must fit 0.x.x.x. | |
| 1805 EXPECT_NE(it->interface_index, 0u); // 0 means to use default. | |
| 1806 } | |
| 1807 if (it->type == NetworkChangeNotifier::CONNECTION_WIFI) { | |
| 1808 EXPECT_NE(WIFI_PHY_LAYER_PROTOCOL_NONE, GetWifiPHYLayerProtocol()); | |
| 1809 } | |
| 1810 #elif !defined(OS_ANDROID) | |
| 1811 char name[IF_NAMESIZE]; | |
| 1812 EXPECT_TRUE(if_indextoname(it->interface_index, name)); | |
| 1813 EXPECT_STREQ(it->name.c_str(), name); | |
| 1814 #endif | |
| 1815 } | |
| 1816 } | |
| 1817 | |
| 1818 struct NonUniqueNameTestData { | |
| 1819 bool is_unique; | |
| 1820 const char* hostname; | |
| 1821 }; | |
| 1822 | |
| 1823 // Google Test pretty-printer. | |
| 1824 void PrintTo(const NonUniqueNameTestData& data, std::ostream* os) { | |
| 1825 ASSERT_TRUE(data.hostname); | |
| 1826 *os << " hostname: " << testing::PrintToString(data.hostname) | |
| 1827 << "; is_unique: " << testing::PrintToString(data.is_unique); | |
| 1828 } | |
| 1829 | |
| 1830 const NonUniqueNameTestData kNonUniqueNameTestData[] = { | |
| 1831 // Domains under ICANN-assigned domains. | |
| 1832 { true, "google.com" }, | |
| 1833 { true, "google.co.uk" }, | |
| 1834 // Domains under private registries. | |
| 1835 { true, "appspot.com" }, | |
| 1836 { true, "test.appspot.com" }, | |
| 1837 // Unreserved IPv4 addresses (in various forms). | |
| 1838 { true, "8.8.8.8" }, | |
| 1839 { true, "99.64.0.0" }, | |
| 1840 { true, "212.15.0.0" }, | |
| 1841 { true, "212.15" }, | |
| 1842 { true, "212.15.0" }, | |
| 1843 { true, "3557752832" }, | |
| 1844 // Reserved IPv4 addresses (in various forms). | |
| 1845 { false, "192.168.0.0" }, | |
| 1846 { false, "192.168.0.6" }, | |
| 1847 { false, "10.0.0.5" }, | |
| 1848 { false, "10.0" }, | |
| 1849 { false, "10.0.0" }, | |
| 1850 { false, "3232235526" }, | |
| 1851 // Unreserved IPv6 addresses. | |
| 1852 { true, "FFC0:ba98:7654:3210:FEDC:BA98:7654:3210" }, | |
| 1853 { true, "2000:ba98:7654:2301:EFCD:BA98:7654:3210" }, | |
| 1854 // Reserved IPv6 addresses. | |
| 1855 { false, "::192.9.5.5" }, | |
| 1856 { false, "FEED::BEEF" }, | |
| 1857 { false, "FEC0:ba98:7654:3210:FEDC:BA98:7654:3210" }, | |
| 1858 // 'internal'/non-IANA assigned domains. | |
| 1859 { false, "intranet" }, | |
| 1860 { false, "intranet." }, | |
| 1861 { false, "intranet.example" }, | |
| 1862 { false, "host.intranet.example" }, | |
| 1863 // gTLDs under discussion, but not yet assigned. | |
| 1864 { false, "intranet.corp" }, | |
| 1865 { false, "example.tech" }, | |
| 1866 { false, "intranet.internal" }, | |
| 1867 // Invalid host names are treated as unique - but expected to be | |
| 1868 // filtered out before then. | |
| 1869 { true, "junk)(£)$*!@~#" }, | |
| 1870 { true, "w$w.example.com" }, | |
| 1871 { true, "nocolonsallowed:example" }, | |
| 1872 { true, "[::4.5.6.9]" }, | |
| 1873 }; | |
| 1874 | |
| 1875 class NetUtilNonUniqueNameTest | |
| 1876 : public testing::TestWithParam<NonUniqueNameTestData> { | |
| 1877 public: | |
| 1878 virtual ~NetUtilNonUniqueNameTest() {} | |
| 1879 | |
| 1880 protected: | |
| 1881 bool IsUnique(const std::string& hostname) { | |
| 1882 return !IsHostnameNonUnique(hostname); | |
| 1883 } | |
| 1884 }; | |
| 1885 | |
| 1886 // Test that internal/non-unique names are properly identified as such, but | |
| 1887 // that IP addresses and hosts beneath registry-controlled domains are flagged | |
| 1888 // as unique names. | |
| 1889 TEST_P(NetUtilNonUniqueNameTest, IsHostnameNonUnique) { | |
| 1890 const NonUniqueNameTestData& test_data = GetParam(); | |
| 1891 | |
| 1892 EXPECT_EQ(test_data.is_unique, IsUnique(test_data.hostname)); | |
| 1893 } | |
| 1894 | |
| 1895 INSTANTIATE_TEST_CASE_P(, NetUtilNonUniqueNameTest, | |
| 1896 testing::ValuesIn(kNonUniqueNameTestData)); | |
| 1897 | |
| 1898 } // namespace net | 1071 } // namespace net |
| OLD | NEW |