url_canon_filesystemurl.cc 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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. // Functions for canonicalizing "filesystem:file:" URLs.
  5. #include "url/url_canon.h"
  6. #include "url/url_canon_internal.h"
  7. #include "url/url_file.h"
  8. #include "url/url_parse_internal.h"
  9. #include "url/url_util.h"
  10. #include "url/url_util_internal.h"
  11. namespace url {
  12. namespace {
  13. // We use the URLComponentSource for the outer URL, as it can have replacements,
  14. // whereas the inner_url can't, so it uses spec.
  15. template<typename CHAR, typename UCHAR>
  16. bool DoCanonicalizeFileSystemURL(const CHAR* spec,
  17. const URLComponentSource<CHAR>& source,
  18. const Parsed& parsed,
  19. CharsetConverter* charset_converter,
  20. CanonOutput* output,
  21. Parsed* new_parsed) {
  22. // filesystem only uses {scheme, path, query, ref} -- clear the rest.
  23. new_parsed->username.reset();
  24. new_parsed->password.reset();
  25. new_parsed->host.reset();
  26. new_parsed->port.reset();
  27. const Parsed* inner_parsed = parsed.inner_parsed();
  28. Parsed new_inner_parsed;
  29. // Scheme (known, so we don't bother running it through the more
  30. // complicated scheme canonicalizer).
  31. new_parsed->scheme.begin = output->length();
  32. output->Append("filesystem:", 11);
  33. new_parsed->scheme.len = 10;
  34. if (!inner_parsed || !inner_parsed->scheme.is_valid())
  35. return false;
  36. bool success = true;
  37. SchemeType inner_scheme_type = SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION;
  38. if (CompareSchemeComponent(spec, inner_parsed->scheme, url::kFileScheme)) {
  39. new_inner_parsed.scheme.begin = output->length();
  40. output->Append("file://", 7);
  41. new_inner_parsed.scheme.len = 4;
  42. success &= CanonicalizePath(spec, inner_parsed->path, output,
  43. &new_inner_parsed.path);
  44. } else if (GetStandardSchemeType(spec, inner_parsed->scheme,
  45. &inner_scheme_type)) {
  46. if (inner_scheme_type == SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION) {
  47. // Strip out the user information from the inner URL, if any.
  48. inner_scheme_type = SCHEME_WITH_HOST_AND_PORT;
  49. }
  50. success = CanonicalizeStandardURL(
  51. spec, inner_parsed->Length(), *inner_parsed, inner_scheme_type,
  52. charset_converter, output, &new_inner_parsed);
  53. } else {
  54. // TODO(ericu): The URL is wrong, but should we try to output more of what
  55. // we were given? Echoing back filesystem:mailto etc. doesn't seem all that
  56. // useful.
  57. return false;
  58. }
  59. // The filesystem type must be more than just a leading slash for validity.
  60. success &= new_inner_parsed.path.len > 1;
  61. success &= CanonicalizePath(source.path, parsed.path, output,
  62. &new_parsed->path);
  63. // Ignore failures for query/ref since the URL can probably still be loaded.
  64. CanonicalizeQuery(source.query, parsed.query, charset_converter,
  65. output, &new_parsed->query);
  66. CanonicalizeRef(source.ref, parsed.ref, output, &new_parsed->ref);
  67. if (success)
  68. new_parsed->set_inner_parsed(new_inner_parsed);
  69. return success;
  70. }
  71. } // namespace
  72. bool CanonicalizeFileSystemURL(const char* spec,
  73. int spec_len,
  74. const Parsed& parsed,
  75. CharsetConverter* charset_converter,
  76. CanonOutput* output,
  77. Parsed* new_parsed) {
  78. return DoCanonicalizeFileSystemURL<char, unsigned char>(
  79. spec, URLComponentSource<char>(spec), parsed, charset_converter, output,
  80. new_parsed);
  81. }
  82. bool CanonicalizeFileSystemURL(const char16_t* spec,
  83. int spec_len,
  84. const Parsed& parsed,
  85. CharsetConverter* charset_converter,
  86. CanonOutput* output,
  87. Parsed* new_parsed) {
  88. return DoCanonicalizeFileSystemURL<char16_t, char16_t>(
  89. spec, URLComponentSource<char16_t>(spec), parsed, charset_converter,
  90. output, new_parsed);
  91. }
  92. bool ReplaceFileSystemURL(const char* base,
  93. const Parsed& base_parsed,
  94. const Replacements<char>& replacements,
  95. CharsetConverter* charset_converter,
  96. CanonOutput* output,
  97. Parsed* new_parsed) {
  98. URLComponentSource<char> source(base);
  99. Parsed parsed(base_parsed);
  100. SetupOverrideComponents(base, replacements, &source, &parsed);
  101. return DoCanonicalizeFileSystemURL<char, unsigned char>(
  102. base, source, parsed, charset_converter, output, new_parsed);
  103. }
  104. bool ReplaceFileSystemURL(const char* base,
  105. const Parsed& base_parsed,
  106. const Replacements<char16_t>& replacements,
  107. CharsetConverter* charset_converter,
  108. CanonOutput* output,
  109. Parsed* new_parsed) {
  110. RawCanonOutput<1024> utf8;
  111. URLComponentSource<char> source(base);
  112. Parsed parsed(base_parsed);
  113. SetupUTF16OverrideComponents(base, replacements, &utf8, &source, &parsed);
  114. return DoCanonicalizeFileSystemURL<char, unsigned char>(
  115. base, source, parsed, charset_converter, output, new_parsed);
  116. }
  117. } // namespace url