OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <map> | 7 #include <map> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/i18n/time_formatting.h" | 10 #include "base/i18n/time_formatting.h" |
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
569 output_component->reset(); | 569 output_component->reset(); |
570 } | 570 } |
571 } | 571 } |
572 | 572 |
573 } // namespace | 573 } // namespace |
574 | 574 |
575 const FormatUrlType kFormatUrlOmitNothing = 0; | 575 const FormatUrlType kFormatUrlOmitNothing = 0; |
576 const FormatUrlType kFormatUrlOmitUsernamePassword = 1 << 0; | 576 const FormatUrlType kFormatUrlOmitUsernamePassword = 1 << 0; |
577 const FormatUrlType kFormatUrlOmitHTTP = 1 << 1; | 577 const FormatUrlType kFormatUrlOmitHTTP = 1 << 1; |
578 const FormatUrlType kFormatUrlOmitTrailingSlashOnBareHostname = 1 << 2; | 578 const FormatUrlType kFormatUrlOmitTrailingSlashOnBareHostname = 1 << 2; |
579 const FormatUrlType kFormatUrlOmitScheme = 1 << 3; | |
felt
2015/05/13 22:50:14
nit: spaces -- should this line up with the others
palmer
2015/05/14 18:18:01
This is what "git cl format" gives me. (Sigh.) I'l
| |
580 const FormatUrlType kFormatUrlOmitPort = 1 << 4; | |
579 const FormatUrlType kFormatUrlOmitAll = kFormatUrlOmitUsernamePassword | | 581 const FormatUrlType kFormatUrlOmitAll = kFormatUrlOmitUsernamePassword | |
580 kFormatUrlOmitHTTP | kFormatUrlOmitTrailingSlashOnBareHostname; | 582 kFormatUrlOmitHTTP | kFormatUrlOmitTrailingSlashOnBareHostname; |
581 | 583 |
582 base::string16 IDNToUnicode(const std::string& host, | 584 base::string16 IDNToUnicode(const std::string& host, |
583 const std::string& languages) { | 585 const std::string& languages) { |
584 return IDNToUnicodeWithAdjustments(host, languages, NULL); | 586 return IDNToUnicodeWithAdjustments(host, languages, NULL); |
585 } | 587 } |
586 | 588 |
587 std::string GetDirectoryListingEntry(const base::string16& name, | 589 std::string GetDirectoryListingEntry(const base::string16& name, |
588 const std::string& raw_bytes, | 590 const std::string& raw_bytes, |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
680 return FormatViewSourceUrl(url, languages, format_types, | 682 return FormatViewSourceUrl(url, languages, format_types, |
681 unescape_rules, new_parsed, prefix_end, | 683 unescape_rules, new_parsed, prefix_end, |
682 adjustments); | 684 adjustments); |
683 } | 685 } |
684 | 686 |
685 // We handle both valid and invalid URLs (this will give us the spec | 687 // We handle both valid and invalid URLs (this will give us the spec |
686 // regardless of validity). | 688 // regardless of validity). |
687 const std::string& spec = url.possibly_invalid_spec(); | 689 const std::string& spec = url.possibly_invalid_spec(); |
688 const url::Parsed& parsed = url.parsed_for_possibly_invalid_spec(); | 690 const url::Parsed& parsed = url.parsed_for_possibly_invalid_spec(); |
689 | 691 |
690 // Scheme & separators. These are ASCII. | 692 // Scheme & separators. These are ASCII. Scheme removal occurs at the end. |
691 base::string16 url_string; | 693 base::string16 url_string; |
692 url_string.insert( | 694 url_string.insert( |
693 url_string.end(), spec.begin(), | 695 url_string.end(), spec.begin(), |
694 spec.begin() + parsed.CountCharactersBefore(url::Parsed::USERNAME, true)); | 696 spec.begin() + parsed.CountCharactersBefore(url::Parsed::USERNAME, true)); |
695 const char kHTTP[] = "http://"; | |
696 const char kFTP[] = "ftp."; | |
697 // url_fixer::FixupURL() treats "ftp.foo.com" as ftp://ftp.foo.com. This | |
698 // means that if we trim "http://" off a URL whose host starts with "ftp." and | |
699 // the user inputs this into any field subject to fixup (which is basically | |
700 // all input fields), the meaning would be changed. (In fact, often the | |
701 // formatted URL is directly pre-filled into an input field.) For this reason | |
702 // we avoid stripping "http://" in this case. | |
703 bool omit_http = (format_types & kFormatUrlOmitHTTP) && | |
704 EqualsASCII(url_string, kHTTP) && | |
705 !StartsWithASCII(url.host(), kFTP, true); | |
706 new_parsed->scheme = parsed.scheme; | 697 new_parsed->scheme = parsed.scheme; |
707 | 698 |
708 // Username & password. | 699 // Username & password. |
709 if ((format_types & kFormatUrlOmitUsernamePassword) != 0) { | 700 if ((format_types & kFormatUrlOmitUsernamePassword) != 0) { |
710 // Remove the username and password fields. We don't want to display those | 701 // Remove the username and password fields. We don't want to display those |
711 // to the user since they can be used for attacks, | 702 // to the user since they can be used for attacks, |
712 // e.g. "http://google.com:search@evil.ru/" | 703 // e.g. "http://google.com:search@evil.ru/" |
713 new_parsed->username.reset(); | 704 new_parsed->username.reset(); |
714 new_parsed->password.reset(); | 705 new_parsed->password.reset(); |
715 // Update the adjustments based on removed username and/or password. | 706 // Update the adjustments based on removed username and/or password. |
(...skipping 30 matching lines...) Expand all Loading... | |
746 } | 737 } |
747 if (prefix_end) | 738 if (prefix_end) |
748 *prefix_end = static_cast<size_t>(url_string.length()); | 739 *prefix_end = static_cast<size_t>(url_string.length()); |
749 | 740 |
750 // Host. | 741 // Host. |
751 AppendFormattedComponent(spec, parsed.host, HostComponentTransform(languages), | 742 AppendFormattedComponent(spec, parsed.host, HostComponentTransform(languages), |
752 &url_string, &new_parsed->host, adjustments); | 743 &url_string, &new_parsed->host, adjustments); |
753 | 744 |
754 // Port. | 745 // Port. |
755 if (parsed.port.is_nonempty()) { | 746 if (parsed.port.is_nonempty()) { |
756 url_string.push_back(':'); | 747 if (!(format_types & kFormatUrlOmitPort)) { |
757 new_parsed->port.begin = url_string.length(); | 748 url_string.push_back(':'); |
758 url_string.insert(url_string.end(), | 749 new_parsed->port.begin = url_string.length(); |
759 spec.begin() + parsed.port.begin, | 750 url_string.insert(url_string.end(), spec.begin() + parsed.port.begin, |
760 spec.begin() + parsed.port.end()); | 751 spec.begin() + parsed.port.end()); |
761 new_parsed->port.len = url_string.length() - new_parsed->port.begin; | 752 new_parsed->port.len = url_string.length() - new_parsed->port.begin; |
753 } else { | |
754 if (parsed.port.len > 0) { | |
755 adjustments->push_back(base::OffsetAdjuster::Adjustment( | |
756 parsed.port.begin, parsed.port.len, 0)); | |
asanka
2015/05/14 03:42:47
We are also dropping the colon.
palmer
2015/05/14 18:18:01
I'm going to change this code; it's triggering a D
| |
757 } | |
758 } | |
762 } else { | 759 } else { |
763 new_parsed->port.reset(); | 760 new_parsed->port.reset(); |
764 } | 761 } |
765 | 762 |
766 // Path & query. Both get the same general unescape & convert treatment. | 763 // Path & query. Both get the same general unescape & convert treatment. |
767 if (!(format_types & kFormatUrlOmitTrailingSlashOnBareHostname) || | 764 if (!(format_types & kFormatUrlOmitTrailingSlashOnBareHostname) || |
768 !CanStripTrailingSlash(url)) { | 765 !CanStripTrailingSlash(url)) { |
769 AppendFormattedComponent(spec, parsed.path, | 766 AppendFormattedComponent(spec, parsed.path, |
770 NonHostComponentTransform(unescape_rules), | 767 NonHostComponentTransform(unescape_rules), |
771 &url_string, &new_parsed->path, adjustments); | 768 &url_string, &new_parsed->path, adjustments); |
772 } else { | 769 } else { |
773 if (parsed.path.len > 0) { | 770 if (parsed.path.len > 0) { |
774 adjustments->push_back(base::OffsetAdjuster::Adjustment( | 771 adjustments->push_back(base::OffsetAdjuster::Adjustment( |
775 parsed.path.begin, parsed.path.len, 0)); | 772 parsed.path.begin, parsed.path.len, 0)); |
776 } | 773 } |
777 } | 774 } |
778 if (parsed.query.is_valid()) | 775 if (parsed.query.is_valid()) |
779 url_string.push_back('?'); | 776 url_string.push_back('?'); |
780 AppendFormattedComponent(spec, parsed.query, | 777 AppendFormattedComponent(spec, parsed.query, |
781 NonHostComponentTransform(unescape_rules), | 778 NonHostComponentTransform(unescape_rules), |
782 &url_string, &new_parsed->query, adjustments); | 779 &url_string, &new_parsed->query, adjustments); |
783 | 780 |
784 // Ref. This is valid, unescaped UTF-8, so we can just convert. | 781 // Ref. This is valid, unescaped UTF-8, so we can just convert. |
785 if (parsed.ref.is_valid()) | 782 if (parsed.ref.is_valid()) |
786 url_string.push_back('#'); | 783 url_string.push_back('#'); |
787 AppendFormattedComponent(spec, parsed.ref, | 784 AppendFormattedComponent(spec, parsed.ref, |
788 NonHostComponentTransform(UnescapeRule::NONE), | 785 NonHostComponentTransform(UnescapeRule::NONE), |
789 &url_string, &new_parsed->ref, adjustments); | 786 &url_string, &new_parsed->ref, adjustments); |
790 | 787 |
791 // If we need to strip out http do it after the fact. | 788 // Strip out the scheme, after the fact. |
792 if (omit_http && StartsWith(url_string, base::ASCIIToUTF16(kHTTP), true)) { | 789 bool omit_all_schemes = !!(format_types & kFormatUrlOmitScheme); |
793 const size_t kHTTPSize = arraysize(kHTTP) - 1; | 790 // url_fixer::FixupURL() treats "ftp.foo.com" as ftp://ftp.foo.com. This |
794 url_string = url_string.substr(kHTTPSize); | 791 // means that if we trim "http://" off a URL whose host starts with "ftp." and |
792 // the user inputs this into any field subject to fixup (which is basically | |
793 // all input fields), the meaning would be changed. (In fact, often the | |
794 // formatted URL is directly pre-filled into an input field.) For this reason | |
795 // we avoid stripping "http://" in this case. | |
796 bool omit_http = (format_types & kFormatUrlOmitHTTP) && | |
797 url.SchemeIs("http") && | |
798 !StartsWithASCII(url.host(), "ftp.", true); | |
799 if (omit_all_schemes || omit_http) { | |
800 const int scheme_size = | |
801 parsed.CountCharactersBefore(url::Parsed::USERNAME, true); | |
802 url_string = url_string.substr(scheme_size); | |
795 // Because offsets in the |adjustments| are already calculated with respect | 803 // Because offsets in the |adjustments| are already calculated with respect |
796 // to the string with the http:// prefix in it, those offsets remain correct | 804 // to the string with the scheme prefix in it, those offsets remain correct |
797 // after stripping the prefix. The only thing necessary is to add an | 805 // after stripping the prefix. The only thing necessary is to add an |
798 // adjustment to reflect the stripped prefix. | 806 // adjustment to reflect the stripped prefix. |
799 adjustments->insert(adjustments->begin(), | 807 adjustments->insert(adjustments->begin(), |
800 base::OffsetAdjuster::Adjustment(0, kHTTPSize, 0)); | 808 base::OffsetAdjuster::Adjustment(0, scheme_size, 0)); |
801 | 809 |
802 if (prefix_end) | 810 if (prefix_end) |
803 *prefix_end -= kHTTPSize; | 811 *prefix_end -= scheme_size; |
804 | 812 |
805 // Adjust new_parsed. | |
806 DCHECK(new_parsed->scheme.is_valid()); | 813 DCHECK(new_parsed->scheme.is_valid()); |
807 int delta = -(new_parsed->scheme.len + 3); // +3 for ://. | 814 DCHECK_EQ(scheme_size, new_parsed->scheme.len + 3); |
808 new_parsed->scheme.reset(); | 815 new_parsed->scheme.reset(); |
809 AdjustAllComponentsButScheme(delta, new_parsed); | 816 AdjustAllComponentsButScheme(-scheme_size, new_parsed); |
810 } | 817 } |
811 | 818 |
812 return url_string; | 819 return url_string; |
813 } | 820 } |
814 | 821 |
815 base::string16 FormatUrl(const GURL& url, | 822 base::string16 FormatUrl(const GURL& url, |
816 const std::string& languages, | 823 const std::string& languages, |
817 FormatUrlTypes format_types, | 824 FormatUrlTypes format_types, |
818 UnescapeRule::Type unescape_rules, | 825 UnescapeRule::Type unescape_rules, |
819 url::Parsed* new_parsed, | 826 url::Parsed* new_parsed, |
820 size_t* prefix_end, | 827 size_t* prefix_end, |
821 size_t* offset_for_adjustment) { | 828 size_t* offset_for_adjustment) { |
822 Offsets offsets; | 829 Offsets offsets; |
823 if (offset_for_adjustment) | 830 if (offset_for_adjustment) |
824 offsets.push_back(*offset_for_adjustment); | 831 offsets.push_back(*offset_for_adjustment); |
825 base::string16 result = FormatUrlWithOffsets(url, languages, format_types, | 832 base::string16 result = FormatUrlWithOffsets(url, languages, format_types, |
826 unescape_rules, new_parsed, prefix_end, &offsets); | 833 unescape_rules, new_parsed, prefix_end, &offsets); |
827 if (offset_for_adjustment) | 834 if (offset_for_adjustment) |
828 *offset_for_adjustment = offsets[0]; | 835 *offset_for_adjustment = offsets[0]; |
829 return result; | 836 return result; |
830 } | 837 } |
831 | 838 |
839 base::string16 FormatOriginForDisplay(const GURL& url, | |
840 const std::string& languages, | |
841 bool omit_scheme) { | |
842 if (!url.IsStandard()) | |
843 return FormatUrl(url, languages); | |
844 | |
845 if (url.SchemeIsFile()) { | |
846 // TODO(palmer): Determine whether to encode this policy in GURL::GetOrigin. | |
847 return (omit_scheme ? base::ASCIIToUTF16("") | |
848 : base::ASCIIToUTF16("file://")) + | |
849 base::UTF8ToUTF16(url.path()); | |
850 } | |
851 | |
852 if (url.SchemeIsFileSystem()) { | |
853 // TODO(palmer): Determine whether to encode this policy in GURL::GetOrigin. | |
854 const GURL inner_url(url.spec().substr(strlen("filesystem:"))); | |
855 return base::ASCIIToUTF16("filesystem:") + | |
felt
2015/05/13 22:50:14
will this sometimes yield filesystem:url instead o
palmer
2015/05/14 18:10:05
It yields filesystem:url, as it should. (See tests
| |
856 FormatOriginForDisplay(inner_url, languages, omit_scheme); | |
857 } | |
858 | |
859 GURL display_origin = url.GetOrigin(); | |
860 | |
861 FormatUrlTypes format_types = kFormatUrlOmitUsernamePassword | | |
862 kFormatUrlOmitTrailingSlashOnBareHostname; | |
863 if (omit_scheme) | |
864 format_types |= kFormatUrlOmitScheme; | |
865 | |
866 const int default_port = url::DefaultPortForScheme( | |
867 display_origin.scheme().c_str(), display_origin.scheme().length()); | |
868 if (display_origin.IntPort() == default_port) | |
869 format_types |= kFormatUrlOmitPort; | |
870 | |
871 return FormatUrl(display_origin, languages, format_types, | |
872 UnescapeRule::SPACES, nullptr, nullptr, nullptr); | |
873 } | |
874 | |
832 } // namespace net | 875 } // namespace net |
OLD | NEW |