url_canon.h 42 KB

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