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. 4 5 // Functions for canonicalizing "filesystem:file:" URLs. 6 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" 13 14 namespace url { 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 Parsed& parsed, 24 CharsetConverter* charset_converter, 25 CanonOutput* output, 26 Parsed* new_parsed) { 27 // filesystem only uses {scheme, path, query, ref} -- clear the rest. 28 new_parsed->username.reset(); 29 new_parsed->password.reset(); 30 new_parsed->host.reset(); 31 new_parsed->port.reset(); 32 33 const Parsed* inner_parsed = parsed.inner_parsed(); 34 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 (CompareSchemeComponent(spec, inner_parsed->scheme, url::kFileScheme)) { 47 new_inner_parsed.scheme.begin = output->length(); 48 output->Append("file://", 7); 49 new_inner_parsed.scheme.len = 4; 50 success &= CanonicalizePath(spec, inner_parsed->path, output, 51 &new_inner_parsed.path); 52 } else if (IsStandard(spec, inner_parsed->scheme)) { 53 success = CanonicalizeStandardURL(spec, parsed.inner_parsed()->Length(), 54 *parsed.inner_parsed(), charset_converter, 55 output, &new_inner_parsed); 56 } else { 57 // TODO(ericu): The URL is wrong, but should we try to output more of what 58 // we were given? Echoing back filesystem:mailto etc. doesn't seem all that 59 // useful. 60 return false; 61 } 62 // The filesystem type must be more than just a leading slash for validity. 63 success &= parsed.inner_parsed()->path.len > 1; 64 65 success &= CanonicalizePath(source.path, parsed.path, output, 66 &new_parsed->path); 67 68 // Ignore failures for query/ref since the URL can probably still be loaded. 69 CanonicalizeQuery(source.query, parsed.query, charset_converter, 70 output, &new_parsed->query); 71 CanonicalizeRef(source.ref, parsed.ref, output, &new_parsed->ref); 72 if (success) 73 new_parsed->set_inner_parsed(new_inner_parsed); 74 75 return success; 76 } 77 78 } // namespace 79 80 bool CanonicalizeFileSystemURL(const char* spec, 81 int spec_len, 82 const Parsed& parsed, 83 CharsetConverter* charset_converter, 84 CanonOutput* output, 85 Parsed* new_parsed) { 86 return DoCanonicalizeFileSystemURL<char, unsigned char>( 87 spec, URLComponentSource<char>(spec), parsed, charset_converter, output, 88 new_parsed); 89 } 90 91 bool CanonicalizeFileSystemURL(const base::char16* spec, 92 int spec_len, 93 const Parsed& parsed, 94 CharsetConverter* charset_converter, 95 CanonOutput* output, 96 Parsed* new_parsed) { 97 return DoCanonicalizeFileSystemURL<base::char16, base::char16>( 98 spec, URLComponentSource<base::char16>(spec), parsed, charset_converter, 99 output, new_parsed); 100 } 101 102 bool ReplaceFileSystemURL(const char* base, 103 const Parsed& base_parsed, 104 const Replacements<char>& replacements, 105 CharsetConverter* charset_converter, 106 CanonOutput* output, 107 Parsed* new_parsed) { 108 URLComponentSource<char> source(base); 109 Parsed parsed(base_parsed); 110 SetupOverrideComponents(base, replacements, &source, &parsed); 111 return DoCanonicalizeFileSystemURL<char, unsigned char>( 112 base, source, parsed, charset_converter, output, new_parsed); 113 } 114 115 bool ReplaceFileSystemURL(const char* base, 116 const Parsed& base_parsed, 117 const Replacements<base::char16>& replacements, 118 CharsetConverter* charset_converter, 119 CanonOutput* output, 120 Parsed* new_parsed) { 121 RawCanonOutput<1024> utf8; 122 URLComponentSource<char> source(base); 123 Parsed parsed(base_parsed); 124 SetupUTF16OverrideComponents(base, replacements, &utf8, &source, &parsed); 125 return DoCanonicalizeFileSystemURL<char, unsigned char>( 126 base, source, parsed, charset_converter, output, new_parsed); 127 } 128 129 } // namespace url 130