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.
5 // Functions for canonicalizing "filesystem:file:" URLs.
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"
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
,
24 CharsetConverter
* charset_converter
,
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();
33 const Parsed
* inner_parsed
= parsed
.inner_parsed();
34 Parsed new_inner_parsed
;
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;
42 if (!parsed
.inner_parsed() || !parsed
.inner_parsed()->scheme
.is_valid())
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
);
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
62 // The filesystem type must be more than just a leading slash for validity.
63 success
&= parsed
.inner_parsed()->path
.len
> 1;
65 success
&= CanonicalizePath(source
.path
, parsed
.path
, output
,
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
);
73 new_parsed
->set_inner_parsed(new_inner_parsed
);
80 bool CanonicalizeFileSystemURL(const char* spec
,
83 CharsetConverter
* charset_converter
,
86 return DoCanonicalizeFileSystemURL
<char, unsigned char>(
87 spec
, URLComponentSource
<char>(spec
), parsed
, charset_converter
, output
,
91 bool CanonicalizeFileSystemURL(const base::char16
* spec
,
94 CharsetConverter
* charset_converter
,
97 return DoCanonicalizeFileSystemURL
<base::char16
, base::char16
>(
98 spec
, URLComponentSource
<base::char16
>(spec
), parsed
, charset_converter
,
102 bool ReplaceFileSystemURL(const char* base
,
103 const Parsed
& base_parsed
,
104 const Replacements
<char>& replacements
,
105 CharsetConverter
* charset_converter
,
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
);
115 bool ReplaceFileSystemURL(const char* base
,
116 const Parsed
& base_parsed
,
117 const Replacements
<base::char16
>& replacements
,
118 CharsetConverter
* charset_converter
,
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
);