[email protected] | 51bcc5d | 2013-04-24 01:41:37 | [diff] [blame^] | 1 | // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
[email protected] | e7bba5f8 | 2013-04-10 20:10:52 | [diff] [blame] | 4 | |
| 5 | // Functions for canonicalizing "filesystem:file:" URLs. |
| 6 | |
[email protected] | 318076b | 2013-04-18 21:19:45 | [diff] [blame] | 7 | #include "url/url_canon.h" |
| 8 | #include "url/url_canon_internal.h" |
| 9 | #include "url/url_file.h" |
| 10 | #include "url/url_parse_internal.h" |
| 11 | #include "url/url_util.h" |
| 12 | #include "url/url_util_internal.h" |
[email protected] | e7bba5f8 | 2013-04-10 20:10:52 | [diff] [blame] | 13 | |
| 14 | namespace url_canon { |
| 15 | |
| 16 | namespace { |
| 17 | |
| 18 | // We use the URLComponentSource for the outer URL, as it can have replacements, |
| 19 | // whereas the inner_url can't, so it uses spec. |
| 20 | template<typename CHAR, typename UCHAR> |
| 21 | bool DoCanonicalizeFileSystemURL(const CHAR* spec, |
| 22 | const URLComponentSource<CHAR>& source, |
| 23 | const url_parse::Parsed& parsed, |
| 24 | CharsetConverter* charset_converter, |
| 25 | CanonOutput* output, |
| 26 | url_parse::Parsed* new_parsed) { |
| 27 | // filesystem only uses {scheme, path, query, ref} -- clear the rest. |
| 28 | new_parsed->username = url_parse::Component(); |
| 29 | new_parsed->password = url_parse::Component(); |
| 30 | new_parsed->host = url_parse::Component(); |
| 31 | new_parsed->port = url_parse::Component(); |
| 32 | |
| 33 | const url_parse::Parsed* inner_parsed = parsed.inner_parsed(); |
| 34 | url_parse::Parsed new_inner_parsed; |
| 35 | |
| 36 | // Scheme (known, so we don't bother running it through the more |
| 37 | // complicated scheme canonicalizer). |
| 38 | new_parsed->scheme.begin = output->length(); |
| 39 | output->Append("filesystem:", 11); |
| 40 | new_parsed->scheme.len = 10; |
| 41 | |
| 42 | if (!parsed.inner_parsed() || !parsed.inner_parsed()->scheme.is_valid()) |
| 43 | return false; |
| 44 | |
| 45 | bool success = true; |
| 46 | if (url_util::CompareSchemeComponent(spec, inner_parsed->scheme, |
| 47 | url_util::kFileScheme)) { |
| 48 | new_inner_parsed.scheme.begin = output->length(); |
| 49 | output->Append("file://", 7); |
| 50 | new_inner_parsed.scheme.len = 4; |
| 51 | success &= CanonicalizePath(spec, inner_parsed->path, output, |
| 52 | &new_inner_parsed.path); |
| 53 | } else if (url_util::IsStandard(spec, inner_parsed->scheme)) { |
| 54 | success = |
| 55 | url_canon::CanonicalizeStandardURL(spec, |
| 56 | parsed.inner_parsed()->Length(), |
| 57 | *parsed.inner_parsed(), |
| 58 | charset_converter, output, |
| 59 | &new_inner_parsed); |
| 60 | } else { |
| 61 | // TODO(ericu): The URL is wrong, but should we try to output more of what |
| 62 | // we were given? Echoing back filesystem:mailto etc. doesn't seem all that |
| 63 | // useful. |
| 64 | return false; |
| 65 | } |
| 66 | // The filesystem type must be more than just a leading slash for validity. |
| 67 | success &= parsed.inner_parsed()->path.len > 1; |
| 68 | |
| 69 | success &= CanonicalizePath(source.path, parsed.path, output, |
| 70 | &new_parsed->path); |
| 71 | |
| 72 | // Ignore failures for query/ref since the URL can probably still be loaded. |
| 73 | CanonicalizeQuery(source.query, parsed.query, charset_converter, |
| 74 | output, &new_parsed->query); |
| 75 | CanonicalizeRef(source.ref, parsed.ref, output, &new_parsed->ref); |
| 76 | if (success) |
| 77 | new_parsed->set_inner_parsed(new_inner_parsed); |
| 78 | |
| 79 | return success; |
| 80 | } |
| 81 | |
| 82 | } // namespace |
| 83 | |
| 84 | bool CanonicalizeFileSystemURL(const char* spec, |
| 85 | int spec_len, |
| 86 | const url_parse::Parsed& parsed, |
| 87 | CharsetConverter* charset_converter, |
| 88 | CanonOutput* output, |
| 89 | url_parse::Parsed* new_parsed) { |
| 90 | return DoCanonicalizeFileSystemURL<char, unsigned char>( |
| 91 | spec, URLComponentSource<char>(spec), parsed, charset_converter, output, |
| 92 | new_parsed); |
| 93 | } |
| 94 | |
| 95 | bool CanonicalizeFileSystemURL(const char16* spec, |
| 96 | int spec_len, |
| 97 | const url_parse::Parsed& parsed, |
| 98 | CharsetConverter* charset_converter, |
| 99 | CanonOutput* output, |
| 100 | url_parse::Parsed* new_parsed) { |
| 101 | return DoCanonicalizeFileSystemURL<char16, char16>( |
| 102 | spec, URLComponentSource<char16>(spec), parsed, charset_converter, output, |
| 103 | new_parsed); |
| 104 | } |
| 105 | |
| 106 | bool ReplaceFileSystemURL(const char* base, |
| 107 | const url_parse::Parsed& base_parsed, |
| 108 | const Replacements<char>& replacements, |
| 109 | CharsetConverter* charset_converter, |
| 110 | CanonOutput* output, |
| 111 | url_parse::Parsed* new_parsed) { |
| 112 | URLComponentSource<char> source(base); |
| 113 | url_parse::Parsed parsed(base_parsed); |
| 114 | SetupOverrideComponents(base, replacements, &source, &parsed); |
| 115 | return DoCanonicalizeFileSystemURL<char, unsigned char>( |
| 116 | base, source, parsed, charset_converter, output, new_parsed); |
| 117 | } |
| 118 | |
| 119 | bool ReplaceFileSystemURL(const char* base, |
| 120 | const url_parse::Parsed& base_parsed, |
| 121 | const Replacements<char16>& replacements, |
| 122 | CharsetConverter* charset_converter, |
| 123 | CanonOutput* output, |
| 124 | url_parse::Parsed* new_parsed) { |
| 125 | RawCanonOutput<1024> utf8; |
| 126 | URLComponentSource<char> source(base); |
| 127 | url_parse::Parsed parsed(base_parsed); |
| 128 | SetupUTF16OverrideComponents(base, replacements, &utf8, &source, &parsed); |
| 129 | return DoCanonicalizeFileSystemURL<char, unsigned char>( |
| 130 | base, source, parsed, charset_converter, output, new_parsed); |
| 131 | } |
| 132 | |
| 133 | } // namespace url_canon |