url_canon.h 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029
  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_CANON_H_
  5. #define URL_URL_CANON_H_
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include "base/component_export.h"
  9. #include "base/export_template.h"
  10. #include "base/memory/raw_ptr_exclusion.h"
  11. #include "base/numerics/clamped_math.h"
  12. #include "url/third_party/mozilla/url_parse.h"
  13. namespace url {
  14. // Canonicalizer output -------------------------------------------------------
  15. // Base class for the canonicalizer output, this maintains a buffer and
  16. // supports simple resizing and append operations on it.
  17. //
  18. // It is VERY IMPORTANT that no virtual function calls be made on the common
  19. // code path. We only have two virtual function calls, the destructor and a
  20. // resize function that is called when the existing buffer is not big enough.
  21. // The derived class is then in charge of setting up our buffer which we will
  22. // manage.
  23. template<typename T>
  24. class CanonOutputT {
  25. public:
  26. CanonOutputT() = default;
  27. virtual ~CanonOutputT() = default;
  28. // Implemented to resize the buffer. This function should update the buffer
  29. // pointer to point to the new buffer, and any old data up to |cur_len_| in
  30. // the buffer must be copied over.
  31. //
  32. // The new size |sz| must be larger than buffer_len_.
  33. virtual void Resize(size_t sz) = 0;
  34. // Accessor for returning a character at a given position. The input offset
  35. // must be in the valid range.
  36. inline T at(size_t offset) const { return buffer_[offset]; }
  37. // Sets the character at the given position. The given position MUST be less
  38. // than the length().
  39. inline void set(size_t offset, T ch) { buffer_[offset] = ch; }
  40. // Returns the number of characters currently in the buffer.
  41. inline size_t length() const { return cur_len_; }
  42. // Returns the current capacity of the buffer. The length() is the number of
  43. // characters that have been declared to be written, but the capacity() is
  44. // the number that can be written without reallocation. If the caller must
  45. // write many characters at once, it can make sure there is enough capacity,
  46. // write the data, then use set_size() to declare the new length().
  47. size_t capacity() const { return buffer_len_; }
  48. // Called by the user of this class to get the output. The output will NOT
  49. // be NULL-terminated. Call length() to get the
  50. // length.
  51. const T* data() const {
  52. return buffer_;
  53. }
  54. T* data() {
  55. return buffer_;
  56. }
  57. // Shortens the URL to the new length. Used for "backing up" when processing
  58. // relative paths. This can also be used if an external function writes a lot
  59. // of data to the buffer (when using the "Raw" version below) beyond the end,
  60. // to declare the new length.
  61. //
  62. // This MUST NOT be used to expand the size of the buffer beyond capacity().
  63. void set_length(size_t new_len) { cur_len_ = new_len; }
  64. // This is the most performance critical function, since it is called for
  65. // every character.
  66. void push_back(T ch) {
  67. // In VC2005, putting this common case first speeds up execution
  68. // dramatically because this branch is predicted as taken.
  69. if (cur_len_ < buffer_len_) {
  70. buffer_[cur_len_] = ch;
  71. cur_len_++;
  72. return;
  73. }
  74. // Grow the buffer to hold at least one more item. Hopefully we won't have
  75. // to do this very often.
  76. if (!Grow(1))
  77. return;
  78. // Actually do the insertion.
  79. buffer_[cur_len_] = ch;
  80. cur_len_++;
  81. }
  82. // Appends the given string to the output.
  83. void Append(const T* str, size_t str_len) {
  84. if (str_len > buffer_len_ - cur_len_) {
  85. if (!Grow(str_len - (buffer_len_ - cur_len_)))
  86. return;
  87. }
  88. for (size_t i = 0; i < str_len; i++)
  89. buffer_[cur_len_ + i] = str[i];
  90. cur_len_ += str_len;
  91. }
  92. void ReserveSizeIfNeeded(size_t estimated_size) {
  93. // Reserve a bit extra to account for escaped chars.
  94. if (estimated_size > buffer_len_)
  95. Resize((base::ClampedNumeric<size_t>(estimated_size) + 8).RawValue());
  96. }
  97. protected:
  98. // Grows the given buffer so that it can fit at least |min_additional|
  99. // characters. Returns true if the buffer could be resized, false on OOM.
  100. bool Grow(size_t min_additional) {
  101. static const size_t kMinBufferLen = 16;
  102. size_t new_len = (buffer_len_ == 0) ? kMinBufferLen : buffer_len_;
  103. do {
  104. if (new_len >= (1 << 30)) // Prevent overflow below.
  105. return false;
  106. new_len *= 2;
  107. } while (new_len < buffer_len_ + min_additional);
  108. Resize(new_len);
  109. return true;
  110. }
  111. // `buffer_` is not a raw_ptr<...> for performance reasons (based on analysis
  112. // of sampling profiler data).
  113. RAW_PTR_EXCLUSION T* buffer_ = nullptr;
  114. size_t buffer_len_ = 0;
  115. // Used characters in the buffer.
  116. size_t cur_len_ = 0;
  117. };
  118. // Simple implementation of the CanonOutput using new[]. This class
  119. // also supports a static buffer so if it is allocated on the stack, most
  120. // URLs can be canonicalized with no heap allocations.
  121. template<typename T, int fixed_capacity = 1024>
  122. class RawCanonOutputT : public CanonOutputT<T> {
  123. public:
  124. RawCanonOutputT() : CanonOutputT<T>() {
  125. this->buffer_ = fixed_buffer_;
  126. this->buffer_len_ = fixed_capacity;
  127. }
  128. ~RawCanonOutputT() override {
  129. if (this->buffer_ != fixed_buffer_)
  130. delete[] this->buffer_;
  131. }
  132. void Resize(size_t sz) override {
  133. T* new_buf = new T[sz];
  134. memcpy(new_buf, this->buffer_,
  135. sizeof(T) * (this->cur_len_ < sz ? this->cur_len_ : sz));
  136. if (this->buffer_ != fixed_buffer_)
  137. delete[] this->buffer_;
  138. this->buffer_ = new_buf;
  139. this->buffer_len_ = sz;
  140. }
  141. protected:
  142. T fixed_buffer_[fixed_capacity];
  143. };
  144. // Explicitely instantiate commonly used instatiations.
  145. extern template class EXPORT_TEMPLATE_DECLARE(COMPONENT_EXPORT(URL))
  146. CanonOutputT<char>;
  147. extern template class EXPORT_TEMPLATE_DECLARE(COMPONENT_EXPORT(URL))
  148. CanonOutputT<char16_t>;
  149. // Normally, all canonicalization output is in narrow characters. We support
  150. // the templates so it can also be used internally if a wide buffer is
  151. // required.
  152. typedef CanonOutputT<char> CanonOutput;
  153. typedef CanonOutputT<char16_t> CanonOutputW;
  154. template<int fixed_capacity>
  155. class RawCanonOutput : public RawCanonOutputT<char, fixed_capacity> {};
  156. template <int fixed_capacity>
  157. class RawCanonOutputW : public RawCanonOutputT<char16_t, fixed_capacity> {};
  158. // Character set converter ----------------------------------------------------
  159. //
  160. // Converts query strings into a custom encoding. The embedder can supply an
  161. // implementation of this class to interface with their own character set
  162. // conversion libraries.
  163. //
  164. // Embedders will want to see the unit test for the ICU version.
  165. class COMPONENT_EXPORT(URL) CharsetConverter {
  166. public:
  167. CharsetConverter() {}
  168. virtual ~CharsetConverter() {}
  169. // Converts the given input string from UTF-16 to whatever output format the
  170. // converter supports. This is used only for the query encoding conversion,
  171. // which does not fail. Instead, the converter should insert "invalid
  172. // character" characters in the output for invalid sequences, and do the
  173. // best it can.
  174. //
  175. // If the input contains a character not representable in the output
  176. // character set, the converter should append the HTML entity sequence in
  177. // decimal, (such as "&#20320;") with escaping of the ampersand, number
  178. // sign, and semicolon (in the previous example it would be
  179. // "%26%2320320%3B"). This rule is based on what IE does in this situation.
  180. virtual void ConvertFromUTF16(const char16_t* input,
  181. int input_len,
  182. CanonOutput* output) = 0;
  183. };
  184. // Schemes --------------------------------------------------------------------
  185. // Types of a scheme representing the requirements on the data represented by
  186. // the authority component of a URL with the scheme.
  187. enum SchemeType {
  188. // The authority component of a URL with the scheme has the form
  189. // "username:password@host:port". The username and password entries are
  190. // optional; the host may not be empty. The default value of the port can be
  191. // omitted in serialization. This type occurs with network schemes like http,
  192. // https, and ftp.
  193. SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION,
  194. // The authority component of a URL with the scheme has the form "host:port",
  195. // and does not include username or password. The default value of the port
  196. // can be omitted in serialization. Used by inner URLs of filesystem URLs of
  197. // origins with network hosts, from which the username and password are
  198. // stripped.
  199. SCHEME_WITH_HOST_AND_PORT,
  200. // The authority component of an URL with the scheme has the form "host", and
  201. // does not include port, username, or password. Used when the hosts are not
  202. // network addresses; for example, schemes used internally by the browser.
  203. SCHEME_WITH_HOST,
  204. // A URL with the scheme doesn't have the authority component.
  205. SCHEME_WITHOUT_AUTHORITY,
  206. };
  207. // Whitespace -----------------------------------------------------------------
  208. // Searches for whitespace that should be removed from the middle of URLs, and
  209. // removes it. Removed whitespace are tabs and newlines, but NOT spaces. Spaces
  210. // are preserved, which is what most browsers do. A pointer to the output will
  211. // be returned, and the length of that output will be in |output_len|.
  212. //
  213. // This should be called before parsing if whitespace removal is desired (which
  214. // it normally is when you are canonicalizing).
  215. //
  216. // If no whitespace is removed, this function will not use the buffer and will
  217. // return a pointer to the input, to avoid the extra copy. If modification is
  218. // required, the given |buffer| will be used and the returned pointer will
  219. // point to the beginning of the buffer.
  220. //
  221. // Therefore, callers should not use the buffer, since it may actually be empty,
  222. // use the computed pointer and |*output_len| instead.
  223. //
  224. // If |input| contained both removable whitespace and a raw `<` character,
  225. // |potentially_dangling_markup| will be set to `true`. Otherwise, it will be
  226. // left untouched.
  227. COMPONENT_EXPORT(URL)
  228. const char* RemoveURLWhitespace(const char* input,
  229. int input_len,
  230. CanonOutputT<char>* buffer,
  231. int* output_len,
  232. bool* potentially_dangling_markup);
  233. COMPONENT_EXPORT(URL)
  234. const char16_t* RemoveURLWhitespace(const char16_t* input,
  235. int input_len,
  236. CanonOutputT<char16_t>* buffer,
  237. int* output_len,
  238. bool* potentially_dangling_markup);
  239. // IDN ------------------------------------------------------------------------
  240. // Converts the Unicode input representing a hostname to ASCII using IDN rules.
  241. // The output must fall in the ASCII range, but will be encoded in UTF-16.
  242. //
  243. // On success, the output will be filled with the ASCII host name and it will
  244. // return true. Unlike most other canonicalization functions, this assumes that
  245. // the output is empty. The beginning of the host will be at offset 0, and
  246. // the length of the output will be set to the length of the new host name.
  247. //
  248. // On error, returns false. The output in this case is undefined.
  249. COMPONENT_EXPORT(URL)
  250. bool IDNToASCII(const char16_t* src, int src_len, CanonOutputW* output);
  251. // Piece-by-piece canonicalizers ----------------------------------------------
  252. //
  253. // These individual canonicalizers append the canonicalized versions of the
  254. // corresponding URL component to the given CanonOutput. The spec and the
  255. // previously-identified range of that component are the input. The range of
  256. // the canonicalized component will be written to the output component.
  257. //
  258. // These functions all append to the output so they can be chained. Make sure
  259. // the output is empty when you start.
  260. //
  261. // These functions returns boolean values indicating success. On failure, they
  262. // will attempt to write something reasonable to the output so that, if
  263. // displayed to the user, they will recognise it as something that's messed up.
  264. // Nothing more should ever be done with these invalid URLs, however.
  265. // Scheme: Appends the scheme and colon to the URL. The output component will
  266. // indicate the range of characters up to but not including the colon.
  267. //
  268. // Canonical URLs always have a scheme. If the scheme is not present in the
  269. // input, this will just write the colon to indicate an empty scheme. Does not
  270. // append slashes which will be needed before any authority components for most
  271. // URLs.
  272. //
  273. // The 8-bit version requires UTF-8 encoding.
  274. COMPONENT_EXPORT(URL)
  275. bool CanonicalizeScheme(const char* spec,
  276. const Component& scheme,
  277. CanonOutput* output,
  278. Component* out_scheme);
  279. COMPONENT_EXPORT(URL)
  280. bool CanonicalizeScheme(const char16_t* spec,
  281. const Component& scheme,
  282. CanonOutput* output,
  283. Component* out_scheme);
  284. // User info: username/password. If present, this will add the delimiters so
  285. // the output will be "<username>:<password>@" or "<username>@". Empty
  286. // username/password pairs, or empty passwords, will get converted to
  287. // nonexistent in the canonical version.
  288. //
  289. // The components for the username and password refer to ranges in the
  290. // respective source strings. Usually, these will be the same string, which
  291. // is legal as long as the two components don't overlap.
  292. //
  293. // The 8-bit version requires UTF-8 encoding.
  294. COMPONENT_EXPORT(URL)
  295. bool CanonicalizeUserInfo(const char* username_source,
  296. const Component& username,
  297. const char* password_source,
  298. const Component& password,
  299. CanonOutput* output,
  300. Component* out_username,
  301. Component* out_password);
  302. COMPONENT_EXPORT(URL)
  303. bool CanonicalizeUserInfo(const char16_t* username_source,
  304. const Component& username,
  305. const char16_t* password_source,
  306. const Component& password,
  307. CanonOutput* output,
  308. Component* out_username,
  309. Component* out_password);
  310. // This structure holds detailed state exported from the IP/Host canonicalizers.
  311. // Additional fields may be added as callers require them.
  312. struct CanonHostInfo {
  313. CanonHostInfo() : family(NEUTRAL), num_ipv4_components(0), out_host() {}
  314. // Convenience function to test if family is an IP address.
  315. bool IsIPAddress() const { return family == IPV4 || family == IPV6; }
  316. // This field summarizes how the input was classified by the canonicalizer.
  317. enum Family {
  318. NEUTRAL, // - Doesn't resemble an IP address. As far as the IP
  319. // canonicalizer is concerned, it should be treated as a
  320. // hostname.
  321. BROKEN, // - Almost an IP, but was not canonicalized. This could be an
  322. // IPv4 address where truncation occurred, or something
  323. // containing the special characters :[] which did not parse
  324. // as an IPv6 address. Never attempt to connect to this
  325. // address, because it might actually succeed!
  326. IPV4, // - Successfully canonicalized as an IPv4 address.
  327. IPV6, // - Successfully canonicalized as an IPv6 address.
  328. };
  329. Family family;
  330. // If |family| is IPV4, then this is the number of nonempty dot-separated
  331. // components in the input text, from 1 to 4. If |family| is not IPV4,
  332. // this value is undefined.
  333. int num_ipv4_components;
  334. // Location of host within the canonicalized output.
  335. // CanonicalizeIPAddress() only sets this field if |family| is IPV4 or IPV6.
  336. // CanonicalizeHostVerbose() always sets it.
  337. Component out_host;
  338. // |address| contains the parsed IP Address (if any) in its first
  339. // AddressLength() bytes, in network order. If IsIPAddress() is false
  340. // AddressLength() will return zero and the content of |address| is undefined.
  341. unsigned char address[16];
  342. // Convenience function to calculate the length of an IP address corresponding
  343. // to the current IP version in |family|, if any. For use with |address|.
  344. int AddressLength() const {
  345. return family == IPV4 ? 4 : (family == IPV6 ? 16 : 0);
  346. }
  347. };
  348. // Host.
  349. //
  350. // The 8-bit version requires UTF-8 encoding. Use this version when you only
  351. // need to know whether canonicalization succeeded.
  352. COMPONENT_EXPORT(URL)
  353. bool CanonicalizeHost(const char* spec,
  354. const Component& host,
  355. CanonOutput* output,
  356. Component* out_host);
  357. COMPONENT_EXPORT(URL)
  358. bool CanonicalizeHost(const char16_t* spec,
  359. const Component& host,
  360. CanonOutput* output,
  361. Component* out_host);
  362. // Extended version of CanonicalizeHost, which returns additional information.
  363. // Use this when you need to know whether the hostname was an IP address.
  364. // A successful return is indicated by host_info->family != BROKEN. See the
  365. // definition of CanonHostInfo above for details.
  366. COMPONENT_EXPORT(URL)
  367. void CanonicalizeHostVerbose(const char* spec,
  368. const Component& host,
  369. CanonOutput* output,
  370. CanonHostInfo* host_info);
  371. COMPONENT_EXPORT(URL)
  372. void CanonicalizeHostVerbose(const char16_t* spec,
  373. const Component& host,
  374. CanonOutput* output,
  375. CanonHostInfo* host_info);
  376. // Canonicalizes a string according to the host canonicalization rules. Unlike
  377. // CanonicalizeHost, this will not check for IP addresses which can change the
  378. // meaning (and canonicalization) of the components. This means it is possible
  379. // to call this for sub-components of a host name without corruption.
  380. //
  381. // As an example, "01.02.03.04.com" is a canonical hostname. If you called
  382. // CanonicalizeHost on the substring "01.02.03.04" it will get "fixed" to
  383. // "1.2.3.4" which will produce an invalid host name when reassembled. This
  384. // can happen more than one might think because all numbers by themselves are
  385. // considered IP addresses; so "5" canonicalizes to "0.0.0.5".
  386. //
  387. // Be careful: Because Punycode works on each dot-separated substring as a
  388. // unit, you should only pass this function substrings that represent complete
  389. // dot-separated subcomponents of the original host. Even if you have ASCII
  390. // input, percent-escaped characters will have different meanings if split in
  391. // the middle.
  392. //
  393. // Returns true if the host was valid. This function will treat a 0-length
  394. // host as valid (because it's designed to be used for substrings) while the
  395. // full version above will mark empty hosts as broken.
  396. COMPONENT_EXPORT(URL)
  397. bool CanonicalizeHostSubstring(const char* spec,
  398. const Component& host,
  399. CanonOutput* output);
  400. COMPONENT_EXPORT(URL)
  401. bool CanonicalizeHostSubstring(const char16_t* spec,
  402. const Component& host,
  403. CanonOutput* output);
  404. // IP addresses.
  405. //
  406. // Tries to interpret the given host name as an IPv4 or IPv6 address. If it is
  407. // an IP address, it will canonicalize it as such, appending it to |output|.
  408. // Additional status information is returned via the |*host_info| parameter.
  409. // See the definition of CanonHostInfo above for details.
  410. //
  411. // This is called AUTOMATICALLY from the host canonicalizer, which ensures that
  412. // the input is unescaped and name-prepped, etc. It should not normally be
  413. // necessary or wise to call this directly.
  414. COMPONENT_EXPORT(URL)
  415. void CanonicalizeIPAddress(const char* spec,
  416. const Component& host,
  417. CanonOutput* output,
  418. CanonHostInfo* host_info);
  419. COMPONENT_EXPORT(URL)
  420. void CanonicalizeIPAddress(const char16_t* spec,
  421. const Component& host,
  422. CanonOutput* output,
  423. CanonHostInfo* host_info);
  424. // Port: this function will add the colon for the port if a port is present.
  425. // The caller can pass PORT_UNSPECIFIED as the
  426. // default_port_for_scheme argument if there is no default port.
  427. //
  428. // The 8-bit version requires UTF-8 encoding.
  429. COMPONENT_EXPORT(URL)
  430. bool CanonicalizePort(const char* spec,
  431. const Component& port,
  432. int default_port_for_scheme,
  433. CanonOutput* output,
  434. Component* out_port);
  435. COMPONENT_EXPORT(URL)
  436. bool CanonicalizePort(const char16_t* spec,
  437. const Component& port,
  438. int default_port_for_scheme,
  439. CanonOutput* output,
  440. Component* out_port);
  441. // Returns the default port for the given canonical scheme, or PORT_UNSPECIFIED
  442. // if the scheme is unknown. Based on https://url.spec.whatwg.org/#default-port
  443. COMPONENT_EXPORT(URL)
  444. int DefaultPortForScheme(const char* scheme, int scheme_len);
  445. // Path. If the input does not begin in a slash (including if the input is
  446. // empty), we'll prepend a slash to the path to make it canonical.
  447. //
  448. // The 8-bit version assumes UTF-8 encoding, but does not verify the validity
  449. // of the UTF-8 (i.e., you can have invalid UTF-8 sequences, invalid
  450. // characters, etc.). Normally, URLs will come in as UTF-16, so this isn't
  451. // an issue. Somebody giving us an 8-bit path is responsible for generating
  452. // the path that the server expects (we'll escape high-bit characters), so
  453. // if something is invalid, it's their problem.
  454. COMPONENT_EXPORT(URL)
  455. bool CanonicalizePath(const char* spec,
  456. const Component& path,
  457. CanonOutput* output,
  458. Component* out_path);
  459. COMPONENT_EXPORT(URL)
  460. bool CanonicalizePath(const char16_t* spec,
  461. const Component& path,
  462. CanonOutput* output,
  463. Component* out_path);
  464. // Like CanonicalizePath(), but does not assume that its operating on the
  465. // entire path. It therefore does not prepend a slash, etc.
  466. COMPONENT_EXPORT(URL)
  467. bool CanonicalizePartialPath(const char* spec,
  468. const Component& path,
  469. CanonOutput* output,
  470. Component* out_path);
  471. COMPONENT_EXPORT(URL)
  472. bool CanonicalizePartialPath(const char16_t* spec,
  473. const Component& path,
  474. CanonOutput* output,
  475. Component* out_path);
  476. // Canonicalizes the input as a file path. This is like CanonicalizePath except
  477. // that it also handles Windows drive specs. For example, the path can begin
  478. // with "c|\" and it will get properly canonicalized to "C:/".
  479. // The string will be appended to |*output| and |*out_path| will be updated.
  480. //
  481. // The 8-bit version requires UTF-8 encoding.
  482. COMPONENT_EXPORT(URL)
  483. bool FileCanonicalizePath(const char* spec,
  484. const Component& path,
  485. CanonOutput* output,
  486. Component* out_path);
  487. COMPONENT_EXPORT(URL)
  488. bool FileCanonicalizePath(const char16_t* spec,
  489. const Component& path,
  490. CanonOutput* output,
  491. Component* out_path);
  492. // Query: Prepends the ? if needed.
  493. //
  494. // The 8-bit version requires the input to be UTF-8 encoding. Incorrectly
  495. // encoded characters (in UTF-8 or UTF-16) will be replaced with the Unicode
  496. // "invalid character." This function can not fail, we always just try to do
  497. // our best for crazy input here since web pages can set it themselves.
  498. //
  499. // This will convert the given input into the output encoding that the given
  500. // character set converter object provides. The converter will only be called
  501. // if necessary, for ASCII input, no conversions are necessary.
  502. //
  503. // The converter can be NULL. In this case, the output encoding will be UTF-8.
  504. COMPONENT_EXPORT(URL)
  505. void CanonicalizeQuery(const char* spec,
  506. const Component& query,
  507. CharsetConverter* converter,
  508. CanonOutput* output,
  509. Component* out_query);
  510. COMPONENT_EXPORT(URL)
  511. void CanonicalizeQuery(const char16_t* spec,
  512. const Component& query,
  513. CharsetConverter* converter,
  514. CanonOutput* output,
  515. Component* out_query);
  516. // Ref: Prepends the # if needed. The output will be UTF-8 (this is the only
  517. // canonicalizer that does not produce ASCII output). The output is
  518. // guaranteed to be valid UTF-8.
  519. //
  520. // This function will not fail. If the input is invalid UTF-8/UTF-16, we'll use
  521. // the "Unicode replacement character" for the confusing bits and copy the rest.
  522. COMPONENT_EXPORT(URL)
  523. void CanonicalizeRef(const char* spec,
  524. const Component& path,
  525. CanonOutput* output,
  526. Component* out_path);
  527. COMPONENT_EXPORT(URL)
  528. void CanonicalizeRef(const char16_t* spec,
  529. const Component& path,
  530. CanonOutput* output,
  531. Component* out_path);
  532. // Full canonicalizer ---------------------------------------------------------
  533. //
  534. // These functions replace any string contents, rather than append as above.
  535. // See the above piece-by-piece functions for information specific to
  536. // canonicalizing individual components.
  537. //
  538. // The output will be ASCII except the reference fragment, which may be UTF-8.
  539. //
  540. // The 8-bit versions require UTF-8 encoding.
  541. // Use for standard URLs with authorities and paths.
  542. COMPONENT_EXPORT(URL)
  543. bool CanonicalizeStandardURL(const char* spec,
  544. int spec_len,
  545. const Parsed& parsed,
  546. SchemeType scheme_type,
  547. CharsetConverter* query_converter,
  548. CanonOutput* output,
  549. Parsed* new_parsed);
  550. COMPONENT_EXPORT(URL)
  551. bool CanonicalizeStandardURL(const char16_t* spec,
  552. int spec_len,
  553. const Parsed& parsed,
  554. SchemeType scheme_type,
  555. CharsetConverter* query_converter,
  556. CanonOutput* output,
  557. Parsed* new_parsed);
  558. // Use for file URLs.
  559. COMPONENT_EXPORT(URL)
  560. bool CanonicalizeFileURL(const char* spec,
  561. int spec_len,
  562. const Parsed& parsed,
  563. CharsetConverter* query_converter,
  564. CanonOutput* output,
  565. Parsed* new_parsed);
  566. COMPONENT_EXPORT(URL)
  567. bool CanonicalizeFileURL(const char16_t* spec,
  568. int spec_len,
  569. const Parsed& parsed,
  570. CharsetConverter* query_converter,
  571. CanonOutput* output,
  572. Parsed* new_parsed);
  573. // Use for filesystem URLs.
  574. COMPONENT_EXPORT(URL)
  575. bool CanonicalizeFileSystemURL(const char* spec,
  576. int spec_len,
  577. const Parsed& parsed,
  578. CharsetConverter* query_converter,
  579. CanonOutput* output,
  580. Parsed* new_parsed);
  581. COMPONENT_EXPORT(URL)
  582. bool CanonicalizeFileSystemURL(const char16_t* spec,
  583. int spec_len,
  584. const Parsed& parsed,
  585. CharsetConverter* query_converter,
  586. CanonOutput* output,
  587. Parsed* new_parsed);
  588. // Use for path URLs such as javascript. This does not modify the path in any
  589. // way, for example, by escaping it.
  590. COMPONENT_EXPORT(URL)
  591. bool CanonicalizePathURL(const char* spec,
  592. int spec_len,
  593. const Parsed& parsed,
  594. CanonOutput* output,
  595. Parsed* new_parsed);
  596. COMPONENT_EXPORT(URL)
  597. bool CanonicalizePathURL(const char16_t* spec,
  598. int spec_len,
  599. const Parsed& parsed,
  600. CanonOutput* output,
  601. Parsed* new_parsed);
  602. // Use to canonicalize just the path component of a "path" URL; e.g. the
  603. // path of a javascript URL.
  604. COMPONENT_EXPORT(URL)
  605. void CanonicalizePathURLPath(const char* source,
  606. const Component& component,
  607. CanonOutput* output,
  608. Component* new_component);
  609. COMPONENT_EXPORT(URL)
  610. void CanonicalizePathURLPath(const char16_t* source,
  611. const Component& component,
  612. CanonOutput* output,
  613. Component* new_component);
  614. // Use for mailto URLs. This "canonicalizes" the URL into a path and query
  615. // component. It does not attempt to merge "to" fields. It uses UTF-8 for
  616. // the query encoding if there is a query. This is because a mailto URL is
  617. // really intended for an external mail program, and the encoding of a page,
  618. // etc. which would influence a query encoding normally are irrelevant.
  619. COMPONENT_EXPORT(URL)
  620. bool CanonicalizeMailtoURL(const char* spec,
  621. int spec_len,
  622. const Parsed& parsed,
  623. CanonOutput* output,
  624. Parsed* new_parsed);
  625. COMPONENT_EXPORT(URL)
  626. bool CanonicalizeMailtoURL(const char16_t* spec,
  627. int spec_len,
  628. const Parsed& parsed,
  629. CanonOutput* output,
  630. Parsed* new_parsed);
  631. // Part replacer --------------------------------------------------------------
  632. // Internal structure used for storing separate strings for each component.
  633. // The basic canonicalization functions use this structure internally so that
  634. // component replacement (different strings for different components) can be
  635. // treated on the same code path as regular canonicalization (the same string
  636. // for each component).
  637. //
  638. // A Parsed structure usually goes along with this. Those components identify
  639. // offsets within these strings, so that they can all be in the same string,
  640. // or spread arbitrarily across different ones.
  641. //
  642. // This structures does not own any data. It is the caller's responsibility to
  643. // ensure that the data the pointers point to stays in scope and is not
  644. // modified.
  645. template<typename CHAR>
  646. struct URLComponentSource {
  647. // Constructor normally used by callers wishing to replace components. This
  648. // will make them all NULL, which is no replacement. The caller would then
  649. // override the components they want to replace.
  650. URLComponentSource()
  651. : scheme(nullptr),
  652. username(nullptr),
  653. password(nullptr),
  654. host(nullptr),
  655. port(nullptr),
  656. path(nullptr),
  657. query(nullptr),
  658. ref(nullptr) {}
  659. // Constructor normally used internally to initialize all the components to
  660. // point to the same spec.
  661. explicit URLComponentSource(const CHAR* default_value)
  662. : scheme(default_value),
  663. username(default_value),
  664. password(default_value),
  665. host(default_value),
  666. port(default_value),
  667. path(default_value),
  668. query(default_value),
  669. ref(default_value) {
  670. }
  671. const CHAR* scheme;
  672. const CHAR* username;
  673. const CHAR* password;
  674. const CHAR* host;
  675. const CHAR* port;
  676. const CHAR* path;
  677. const CHAR* query;
  678. const CHAR* ref;
  679. };
  680. // This structure encapsulates information on modifying a URL. Each component
  681. // may either be left unchanged, replaced, or deleted.
  682. //
  683. // By default, each component is unchanged. For those components that should be
  684. // modified, call either Set* or Clear* to modify it.
  685. //
  686. // The string passed to Set* functions DOES NOT GET COPIED AND MUST BE KEPT
  687. // IN SCOPE BY THE CALLER for as long as this object exists!
  688. //
  689. // Prefer the 8-bit replacement version if possible since it is more efficient.
  690. template<typename CHAR>
  691. class Replacements {
  692. public:
  693. Replacements() {
  694. }
  695. // Scheme
  696. void SetScheme(const CHAR* s, const Component& comp) {
  697. sources_.scheme = s;
  698. components_.scheme = comp;
  699. }
  700. // Note: we don't have a ClearScheme since this doesn't make any sense.
  701. bool IsSchemeOverridden() const { return sources_.scheme != NULL; }
  702. // Username
  703. void SetUsername(const CHAR* s, const Component& comp) {
  704. sources_.username = s;
  705. components_.username = comp;
  706. }
  707. void ClearUsername() {
  708. sources_.username = Placeholder();
  709. components_.username = Component();
  710. }
  711. bool IsUsernameOverridden() const { return sources_.username != NULL; }
  712. // Password
  713. void SetPassword(const CHAR* s, const Component& comp) {
  714. sources_.password = s;
  715. components_.password = comp;
  716. }
  717. void ClearPassword() {
  718. sources_.password = Placeholder();
  719. components_.password = Component();
  720. }
  721. bool IsPasswordOverridden() const { return sources_.password != NULL; }
  722. // Host
  723. void SetHost(const CHAR* s, const Component& comp) {
  724. sources_.host = s;
  725. components_.host = comp;
  726. }
  727. void ClearHost() {
  728. sources_.host = Placeholder();
  729. components_.host = Component();
  730. }
  731. bool IsHostOverridden() const { return sources_.host != NULL; }
  732. // Port
  733. void SetPort(const CHAR* s, const Component& comp) {
  734. sources_.port = s;
  735. components_.port = comp;
  736. }
  737. void ClearPort() {
  738. sources_.port = Placeholder();
  739. components_.port = Component();
  740. }
  741. bool IsPortOverridden() const { return sources_.port != NULL; }
  742. // Path
  743. void SetPath(const CHAR* s, const Component& comp) {
  744. sources_.path = s;
  745. components_.path = comp;
  746. }
  747. void ClearPath() {
  748. sources_.path = Placeholder();
  749. components_.path = Component();
  750. }
  751. bool IsPathOverridden() const { return sources_.path != NULL; }
  752. // Query
  753. void SetQuery(const CHAR* s, const Component& comp) {
  754. sources_.query = s;
  755. components_.query = comp;
  756. }
  757. void ClearQuery() {
  758. sources_.query = Placeholder();
  759. components_.query = Component();
  760. }
  761. bool IsQueryOverridden() const { return sources_.query != NULL; }
  762. // Ref
  763. void SetRef(const CHAR* s, const Component& comp) {
  764. sources_.ref = s;
  765. components_.ref = comp;
  766. }
  767. void ClearRef() {
  768. sources_.ref = Placeholder();
  769. components_.ref = Component();
  770. }
  771. bool IsRefOverridden() const { return sources_.ref != NULL; }
  772. // Getters for the internal data. See the variables below for how the
  773. // information is encoded.
  774. const URLComponentSource<CHAR>& sources() const { return sources_; }
  775. const Parsed& components() const { return components_; }
  776. private:
  777. // Returns a pointer to a static empty string that is used as a placeholder
  778. // to indicate a component should be deleted (see below).
  779. const CHAR* Placeholder() {
  780. static const CHAR empty_cstr = 0;
  781. return &empty_cstr;
  782. }
  783. // We support three states:
  784. //
  785. // Action | Source Component
  786. // -----------------------+--------------------------------------------------
  787. // Don't change component | NULL (unused)
  788. // Replace component | (replacement string) (replacement component)
  789. // Delete component | (non-NULL) (invalid component: (0,-1))
  790. //
  791. // We use a pointer to the empty string for the source when the component
  792. // should be deleted.
  793. URLComponentSource<CHAR> sources_;
  794. Parsed components_;
  795. };
  796. // The base must be an 8-bit canonical URL.
  797. COMPONENT_EXPORT(URL)
  798. bool ReplaceStandardURL(const char* base,
  799. const Parsed& base_parsed,
  800. const Replacements<char>& replacements,
  801. SchemeType scheme_type,
  802. CharsetConverter* query_converter,
  803. CanonOutput* output,
  804. Parsed* new_parsed);
  805. COMPONENT_EXPORT(URL)
  806. bool ReplaceStandardURL(const char* base,
  807. const Parsed& base_parsed,
  808. const Replacements<char16_t>& replacements,
  809. SchemeType scheme_type,
  810. CharsetConverter* query_converter,
  811. CanonOutput* output,
  812. Parsed* new_parsed);
  813. // Filesystem URLs can only have the path, query, or ref replaced.
  814. // All other components will be ignored.
  815. COMPONENT_EXPORT(URL)
  816. bool ReplaceFileSystemURL(const char* base,
  817. const Parsed& base_parsed,
  818. const Replacements<char>& replacements,
  819. CharsetConverter* query_converter,
  820. CanonOutput* output,
  821. Parsed* new_parsed);
  822. COMPONENT_EXPORT(URL)
  823. bool ReplaceFileSystemURL(const char* base,
  824. const Parsed& base_parsed,
  825. const Replacements<char16_t>& replacements,
  826. CharsetConverter* query_converter,
  827. CanonOutput* output,
  828. Parsed* new_parsed);
  829. // Replacing some parts of a file URL is not permitted. Everything except
  830. // the host, path, query, and ref will be ignored.
  831. COMPONENT_EXPORT(URL)
  832. bool ReplaceFileURL(const char* base,
  833. const Parsed& base_parsed,
  834. const Replacements<char>& replacements,
  835. CharsetConverter* query_converter,
  836. CanonOutput* output,
  837. Parsed* new_parsed);
  838. COMPONENT_EXPORT(URL)
  839. bool ReplaceFileURL(const char* base,
  840. const Parsed& base_parsed,
  841. const Replacements<char16_t>& replacements,
  842. CharsetConverter* query_converter,
  843. CanonOutput* output,
  844. Parsed* new_parsed);
  845. // Path URLs can only have the scheme and path replaced. All other components
  846. // will be ignored.
  847. COMPONENT_EXPORT(URL)
  848. bool ReplacePathURL(const char* base,
  849. const Parsed& base_parsed,
  850. const Replacements<char>& replacements,
  851. CanonOutput* output,
  852. Parsed* new_parsed);
  853. COMPONENT_EXPORT(URL)
  854. bool ReplacePathURL(const char* base,
  855. const Parsed& base_parsed,
  856. const Replacements<char16_t>& replacements,
  857. CanonOutput* output,
  858. Parsed* new_parsed);
  859. // Mailto URLs can only have the scheme, path, and query replaced.
  860. // All other components will be ignored.
  861. COMPONENT_EXPORT(URL)
  862. bool ReplaceMailtoURL(const char* base,
  863. const Parsed& base_parsed,
  864. const Replacements<char>& replacements,
  865. CanonOutput* output,
  866. Parsed* new_parsed);
  867. COMPONENT_EXPORT(URL)
  868. bool ReplaceMailtoURL(const char* base,
  869. const Parsed& base_parsed,
  870. const Replacements<char16_t>& replacements,
  871. CanonOutput* output,
  872. Parsed* new_parsed);
  873. // Relative URL ---------------------------------------------------------------
  874. // Given an input URL or URL fragment |fragment|, determines if it is a
  875. // relative or absolute URL and places the result into |*is_relative|. If it is
  876. // relative, the relevant portion of the URL will be placed into
  877. // |*relative_component| (there may have been trimmed whitespace, for example).
  878. // This value is passed to ResolveRelativeURL. If the input is not relative,
  879. // this value is UNDEFINED (it may be changed by the function).
  880. //
  881. // Returns true on success (we successfully determined the URL is relative or
  882. // not). Failure means that the combination of URLs doesn't make any sense.
  883. //
  884. // The base URL should always be canonical, therefore is ASCII.
  885. COMPONENT_EXPORT(URL)
  886. bool IsRelativeURL(const char* base,
  887. const Parsed& base_parsed,
  888. const char* fragment,
  889. int fragment_len,
  890. bool is_base_hierarchical,
  891. bool* is_relative,
  892. Component* relative_component);
  893. COMPONENT_EXPORT(URL)
  894. bool IsRelativeURL(const char* base,
  895. const Parsed& base_parsed,
  896. const char16_t* fragment,
  897. int fragment_len,
  898. bool is_base_hierarchical,
  899. bool* is_relative,
  900. Component* relative_component);
  901. // Given a canonical parsed source URL, a URL fragment known to be relative,
  902. // and the identified relevant portion of the relative URL (computed by
  903. // IsRelativeURL), this produces a new parsed canonical URL in |output| and
  904. // |out_parsed|.
  905. //
  906. // It also requires a flag indicating whether the base URL is a file: URL
  907. // which triggers additional logic.
  908. //
  909. // The base URL should be canonical and have a host (may be empty for file
  910. // URLs) and a path. If it doesn't have these, we can't resolve relative
  911. // URLs off of it and will return the base as the output with an error flag.
  912. // Because it is canonical is should also be ASCII.
  913. //
  914. // The query charset converter follows the same rules as CanonicalizeQuery.
  915. //
  916. // Returns true on success. On failure, the output will be "something
  917. // reasonable" that will be consistent and valid, just probably not what
  918. // was intended by the web page author or caller.
  919. COMPONENT_EXPORT(URL)
  920. bool ResolveRelativeURL(const char* base_url,
  921. const Parsed& base_parsed,
  922. bool base_is_file,
  923. const char* relative_url,
  924. const Component& relative_component,
  925. CharsetConverter* query_converter,
  926. CanonOutput* output,
  927. Parsed* out_parsed);
  928. COMPONENT_EXPORT(URL)
  929. bool ResolveRelativeURL(const char* base_url,
  930. const Parsed& base_parsed,
  931. bool base_is_file,
  932. const char16_t* relative_url,
  933. const Component& relative_component,
  934. CharsetConverter* query_converter,
  935. CanonOutput* output,
  936. Parsed* out_parsed);
  937. } // namespace url
  938. #endif // URL_URL_CANON_H_