url_util.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  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. #ifndef URL_URL_UTIL_H_
  5. #define URL_URL_UTIL_H_
  6. #include <memory>
  7. #include <string>
  8. #include <vector>
  9. #include "base/component_export.h"
  10. #include "base/strings/string_piece.h"
  11. #include "url/third_party/mozilla/url_parse.h"
  12. #include "url/url_canon.h"
  13. #include "url/url_constants.h"
  14. namespace url {
  15. // Init ------------------------------------------------------------------------
  16. // Used for tests that need to reset schemes. Note that this can only be used
  17. // in conjunction with ScopedSchemeRegistryForTests.
  18. COMPONENT_EXPORT(URL) void ClearSchemesForTests();
  19. class ScopedSchemeRegistryInternal;
  20. // Stores the SchemeRegistry upon creation, allowing tests to modify a copy of
  21. // it, and restores the original SchemeRegistry when deleted.
  22. class COMPONENT_EXPORT(URL) ScopedSchemeRegistryForTests {
  23. public:
  24. ScopedSchemeRegistryForTests();
  25. ~ScopedSchemeRegistryForTests();
  26. private:
  27. std::unique_ptr<ScopedSchemeRegistryInternal> internal_;
  28. };
  29. // Schemes ---------------------------------------------------------------------
  30. // Changes the behavior of SchemeHostPort / Origin to allow non-standard schemes
  31. // to be specified, instead of canonicalizing them to an invalid SchemeHostPort
  32. // or opaque Origin, respectively. This is used for Android WebView backwards
  33. // compatibility, which allows the use of custom schemes: content hosted in
  34. // Android WebView assumes that one URL with a non-standard scheme will be
  35. // same-origin to another URL with the same non-standard scheme.
  36. //
  37. // Not thread-safe.
  38. COMPONENT_EXPORT(URL) void EnableNonStandardSchemesForAndroidWebView();
  39. // Whether or not SchemeHostPort and Origin allow non-standard schemes.
  40. COMPONENT_EXPORT(URL) bool AllowNonStandardSchemesForAndroidWebView();
  41. // The following Add*Scheme method are not threadsafe and can not be called
  42. // concurrently with any other url_util function. They will assert if the lists
  43. // of schemes have been locked (see LockSchemeRegistries), or used.
  44. // Adds an application-defined scheme to the internal list of "standard-format"
  45. // URL schemes. A standard-format scheme adheres to what RFC 3986 calls "generic
  46. // URI syntax" (https://tools.ietf.org/html/rfc3986#section-3).
  47. COMPONENT_EXPORT(URL)
  48. void AddStandardScheme(const char* new_scheme, SchemeType scheme_type);
  49. // Returns the list of schemes registered for "standard" URLs. Note, this
  50. // should not be used if you just need to check if your protocol is standard
  51. // or not. Instead use the IsStandard() function above as its much more
  52. // efficient. This function should only be used where you need to perform
  53. // other operations against the standard scheme list.
  54. COMPONENT_EXPORT(URL)
  55. std::vector<std::string> GetStandardSchemes();
  56. // Adds an application-defined scheme to the internal list of schemes allowed
  57. // for referrers.
  58. COMPONENT_EXPORT(URL)
  59. void AddReferrerScheme(const char* new_scheme, SchemeType scheme_type);
  60. // Adds an application-defined scheme to the list of schemes that do not trigger
  61. // mixed content warnings.
  62. COMPONENT_EXPORT(URL) void AddSecureScheme(const char* new_scheme);
  63. COMPONENT_EXPORT(URL) const std::vector<std::string>& GetSecureSchemes();
  64. // Adds an application-defined scheme to the list of schemes that normal pages
  65. // cannot link to or access (i.e., with the same security rules as those applied
  66. // to "file" URLs).
  67. COMPONENT_EXPORT(URL) void AddLocalScheme(const char* new_scheme);
  68. COMPONENT_EXPORT(URL) const std::vector<std::string>& GetLocalSchemes();
  69. // Adds an application-defined scheme to the list of schemes that cause pages
  70. // loaded with them to not have access to pages loaded with any other URL
  71. // scheme.
  72. COMPONENT_EXPORT(URL) void AddNoAccessScheme(const char* new_scheme);
  73. COMPONENT_EXPORT(URL) const std::vector<std::string>& GetNoAccessSchemes();
  74. // Adds an application-defined scheme to the list of schemes that can be sent
  75. // CORS requests.
  76. COMPONENT_EXPORT(URL) void AddCorsEnabledScheme(const char* new_scheme);
  77. COMPONENT_EXPORT(URL) const std::vector<std::string>& GetCorsEnabledSchemes();
  78. // Adds an application-defined scheme to the list of web schemes that can be
  79. // used by web to store data (e.g. cookies, local storage, ...). This is
  80. // to differentiate them from schemes that can store data but are not used on
  81. // web (e.g. application's internal schemes) or schemes that are used on web but
  82. // cannot store data.
  83. COMPONENT_EXPORT(URL) void AddWebStorageScheme(const char* new_scheme);
  84. COMPONENT_EXPORT(URL) const std::vector<std::string>& GetWebStorageSchemes();
  85. // Adds an application-defined scheme to the list of schemes that can bypass the
  86. // Content-Security-Policy (CSP) checks.
  87. COMPONENT_EXPORT(URL) void AddCSPBypassingScheme(const char* new_scheme);
  88. COMPONENT_EXPORT(URL) const std::vector<std::string>& GetCSPBypassingSchemes();
  89. // Adds an application-defined scheme to the list of schemes that are strictly
  90. // empty documents, allowing them to commit synchronously.
  91. COMPONENT_EXPORT(URL) void AddEmptyDocumentScheme(const char* new_scheme);
  92. COMPONENT_EXPORT(URL) const std::vector<std::string>& GetEmptyDocumentSchemes();
  93. // Adds a scheme with a predefined default handler.
  94. //
  95. // This pair of strings must be normalized protocol handler parameters as
  96. // described in the Custom Handler specification.
  97. // https://html.spec.whatwg.org/multipage/system-state.html#normalize-protocol-handler-parameters
  98. COMPONENT_EXPORT(URL)
  99. void AddPredefinedHandlerScheme(const char* new_scheme, const char* handler);
  100. COMPONENT_EXPORT(URL)
  101. std::vector<std::pair<std::string, std::string>> GetPredefinedHandlerSchemes();
  102. // Sets a flag to prevent future calls to Add*Scheme from succeeding.
  103. //
  104. // This is designed to help prevent errors for multithreaded applications.
  105. // Normal usage would be to call Add*Scheme for your custom schemes at
  106. // the beginning of program initialization, and then LockSchemeRegistries. This
  107. // prevents future callers from mistakenly calling Add*Scheme when the
  108. // program is running with multiple threads, where such usage would be
  109. // dangerous.
  110. //
  111. // We could have had Add*Scheme use a lock instead, but that would add
  112. // some platform-specific dependencies we don't otherwise have now, and is
  113. // overkill considering the normal usage is so simple.
  114. COMPONENT_EXPORT(URL) void LockSchemeRegistries();
  115. // Locates the scheme in the given string and places it into |found_scheme|,
  116. // which may be NULL to indicate the caller does not care about the range.
  117. //
  118. // Returns whether the given |compare| scheme matches the scheme found in the
  119. // input (if any). The |compare| scheme must be a valid canonical scheme or
  120. // the result of the comparison is undefined.
  121. COMPONENT_EXPORT(URL)
  122. bool FindAndCompareScheme(const char* str,
  123. int str_len,
  124. const char* compare,
  125. Component* found_scheme);
  126. COMPONENT_EXPORT(URL)
  127. bool FindAndCompareScheme(const char16_t* str,
  128. int str_len,
  129. const char* compare,
  130. Component* found_scheme);
  131. inline bool FindAndCompareScheme(const std::string& str,
  132. const char* compare,
  133. Component* found_scheme) {
  134. return FindAndCompareScheme(str.data(), static_cast<int>(str.size()),
  135. compare, found_scheme);
  136. }
  137. inline bool FindAndCompareScheme(const std::u16string& str,
  138. const char* compare,
  139. Component* found_scheme) {
  140. return FindAndCompareScheme(str.data(), static_cast<int>(str.size()),
  141. compare, found_scheme);
  142. }
  143. // Returns true if the given scheme identified by |scheme| within |spec| is in
  144. // the list of known standard-format schemes (see AddStandardScheme).
  145. COMPONENT_EXPORT(URL)
  146. bool IsStandard(const char* spec, const Component& scheme);
  147. COMPONENT_EXPORT(URL)
  148. bool IsStandard(const char16_t* spec, const Component& scheme);
  149. // Returns true if the given scheme identified by |scheme| within |spec| is in
  150. // the list of allowed schemes for referrers (see AddReferrerScheme).
  151. COMPONENT_EXPORT(URL)
  152. bool IsReferrerScheme(const char* spec, const Component& scheme);
  153. // Returns true and sets |type| to the SchemeType of the given scheme
  154. // identified by |scheme| within |spec| if the scheme is in the list of known
  155. // standard-format schemes (see AddStandardScheme).
  156. COMPONENT_EXPORT(URL)
  157. bool GetStandardSchemeType(const char* spec,
  158. const Component& scheme,
  159. SchemeType* type);
  160. COMPONENT_EXPORT(URL)
  161. bool GetStandardSchemeType(const char16_t* spec,
  162. const Component& scheme,
  163. SchemeType* type);
  164. // Hosts ----------------------------------------------------------------------
  165. // Returns true if the |canonical_host| matches or is in the same domain as the
  166. // given |canonical_domain| string. For example, if the canonicalized hostname
  167. // is "www.google.com", this will return true for "com", "google.com", and
  168. // "www.google.com" domains.
  169. //
  170. // If either of the input StringPieces is empty, the return value is false. The
  171. // input domain should match host canonicalization rules. i.e. it should be
  172. // lowercase except for escape chars.
  173. COMPONENT_EXPORT(URL)
  174. bool DomainIs(base::StringPiece canonical_host,
  175. base::StringPiece canonical_domain);
  176. // Returns true if the hostname is an IP address. Note: this function isn't very
  177. // cheap, as it must re-parse the host to verify.
  178. COMPONENT_EXPORT(URL) bool HostIsIPAddress(base::StringPiece host);
  179. // URL library wrappers --------------------------------------------------------
  180. // Parses the given spec according to the extracted scheme type. Normal users
  181. // should use the URL object, although this may be useful if performance is
  182. // critical and you don't want to do the heap allocation for the std::string.
  183. //
  184. // As with the Canonicalize* functions, the charset converter can
  185. // be NULL to use UTF-8 (it will be faster in this case).
  186. //
  187. // Returns true if a valid URL was produced, false if not. On failure, the
  188. // output and parsed structures will still be filled and will be consistent,
  189. // but they will not represent a loadable URL.
  190. COMPONENT_EXPORT(URL)
  191. bool Canonicalize(const char* spec,
  192. int spec_len,
  193. bool trim_path_end,
  194. CharsetConverter* charset_converter,
  195. CanonOutput* output,
  196. Parsed* output_parsed);
  197. COMPONENT_EXPORT(URL)
  198. bool Canonicalize(const char16_t* spec,
  199. int spec_len,
  200. bool trim_path_end,
  201. CharsetConverter* charset_converter,
  202. CanonOutput* output,
  203. Parsed* output_parsed);
  204. // Resolves a potentially relative URL relative to the given parsed base URL.
  205. // The base MUST be valid. The resulting canonical URL and parsed information
  206. // will be placed in to the given out variables.
  207. //
  208. // The relative need not be relative. If we discover that it's absolute, this
  209. // will produce a canonical version of that URL. See Canonicalize() for more
  210. // about the charset_converter.
  211. //
  212. // Returns true if the output is valid, false if the input could not produce
  213. // a valid URL.
  214. COMPONENT_EXPORT(URL)
  215. bool ResolveRelative(const char* base_spec,
  216. int base_spec_len,
  217. const Parsed& base_parsed,
  218. const char* relative,
  219. int relative_length,
  220. CharsetConverter* charset_converter,
  221. CanonOutput* output,
  222. Parsed* output_parsed);
  223. COMPONENT_EXPORT(URL)
  224. bool ResolveRelative(const char* base_spec,
  225. int base_spec_len,
  226. const Parsed& base_parsed,
  227. const char16_t* relative,
  228. int relative_length,
  229. CharsetConverter* charset_converter,
  230. CanonOutput* output,
  231. Parsed* output_parsed);
  232. // Replaces components in the given VALID input URL. The new canonical URL info
  233. // is written to output and out_parsed.
  234. //
  235. // Returns true if the resulting URL is valid.
  236. COMPONENT_EXPORT(URL)
  237. bool ReplaceComponents(const char* spec,
  238. int spec_len,
  239. const Parsed& parsed,
  240. const Replacements<char>& replacements,
  241. CharsetConverter* charset_converter,
  242. CanonOutput* output,
  243. Parsed* out_parsed);
  244. COMPONENT_EXPORT(URL)
  245. bool ReplaceComponents(const char* spec,
  246. int spec_len,
  247. const Parsed& parsed,
  248. const Replacements<char16_t>& replacements,
  249. CharsetConverter* charset_converter,
  250. CanonOutput* output,
  251. Parsed* out_parsed);
  252. // String helper functions -----------------------------------------------------
  253. enum class DecodeURLMode {
  254. // UTF-8 decode only. Invalid byte sequences are replaced with U+FFFD.
  255. kUTF8,
  256. // Try UTF-8 decoding. If the input contains byte sequences invalid
  257. // for UTF-8, apply byte to Unicode mapping.
  258. kUTF8OrIsomorphic,
  259. };
  260. // Unescapes the given string using URL escaping rules.
  261. COMPONENT_EXPORT(URL)
  262. void DecodeURLEscapeSequences(const char* input,
  263. int length,
  264. DecodeURLMode mode,
  265. CanonOutputW* output);
  266. // Escapes the given string as defined by the JS method encodeURIComponent. See
  267. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURIComponent
  268. COMPONENT_EXPORT(URL)
  269. void EncodeURIComponent(const char* input, int length, CanonOutput* output);
  270. } // namespace url
  271. #endif // URL_URL_UTIL_H_