url_view_base.hpp 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743
  1. //
  2. // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
  3. // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // Official repository: https://github.com/boostorg/url
  9. //
  10. #ifndef BOOST_URL_URL_VIEW_BASE_HPP
  11. #define BOOST_URL_URL_VIEW_BASE_HPP
  12. #include <boost/url/detail/config.hpp>
  13. #include <boost/url/authority_view.hpp>
  14. #include <boost/url/host_type.hpp>
  15. #include <boost/url/ipv4_address.hpp>
  16. #include <boost/url/ipv6_address.hpp>
  17. #include <boost/url/params_view.hpp>
  18. #include <boost/url/params_encoded_view.hpp>
  19. #include <boost/url/pct_string_view.hpp>
  20. #include <boost/url/scheme.hpp>
  21. #include <boost/url/segments_encoded_view.hpp>
  22. #include <boost/url/segments_view.hpp>
  23. #include <boost/url/detail/url_impl.hpp>
  24. #include <boost/url/grammar/string_token.hpp>
  25. #include <boost/assert.hpp>
  26. #include <cstddef>
  27. #include <cstdint>
  28. #include <iosfwd>
  29. #include <memory>
  30. #include <string>
  31. #include <utility>
  32. namespace boost {
  33. namespace urls {
  34. #ifndef BOOST_URL_DOCS
  35. namespace detail {
  36. struct pattern;
  37. }
  38. #endif
  39. /** Common functionality for containers
  40. This base class is used by the library
  41. to provide common member functions for
  42. containers. This cannot be instantiated
  43. directly; Instead, use one of the
  44. containers or functions:
  45. @par Containers
  46. @li @ref url
  47. @li @ref url_view
  48. @li @ref static_url
  49. @par Functions
  50. @li @ref parse_absolute_uri
  51. @li @ref parse_origin_form
  52. @li @ref parse_relative_ref
  53. @li @ref parse_uri
  54. @li @ref parse_uri_reference
  55. */
  56. class BOOST_SYMBOL_VISIBLE
  57. url_view_base
  58. : private detail::parts_base
  59. {
  60. detail::url_impl impl_;
  61. detail::url_impl const* pi_;
  62. friend class url;
  63. friend class url_base;
  64. friend class url_view;
  65. friend class static_url_base;
  66. friend class params_base;
  67. friend class params_encoded_base;
  68. friend class params_encoded_ref;
  69. friend class params_encoded_view;
  70. friend class params_ref;
  71. friend class params_view;
  72. friend class segments_base;
  73. friend class segments_encoded_base;
  74. friend class segments_encoded_ref;
  75. friend class segments_encoded_view;
  76. friend class segments_ref;
  77. friend class segments_view;
  78. friend struct detail::pattern;
  79. struct shared_impl;
  80. BOOST_URL_DECL
  81. url_view_base() noexcept;
  82. BOOST_URL_DECL
  83. explicit url_view_base(
  84. detail::url_impl const&) noexcept;
  85. ~url_view_base() = default;
  86. url_view_base(
  87. url_view_base const& o) noexcept
  88. : impl_(o.impl_)
  89. , pi_(o.pi_)
  90. {
  91. if (pi_ == &o.impl_)
  92. pi_ = &impl_;
  93. }
  94. url_view_base& operator=(
  95. url_view_base const&) = delete;
  96. #ifndef BOOST_URL_DOCS
  97. public:
  98. #endif
  99. BOOST_URL_DECL
  100. std::size_t
  101. digest(std::size_t = 0) const noexcept;
  102. public:
  103. //--------------------------------------------
  104. //
  105. // Observers
  106. //
  107. //--------------------------------------------
  108. /** Return the maximum number of characters possible
  109. This represents the largest number
  110. of characters that are theoretically
  111. possible to represent in a url,
  112. not including any null terminator.
  113. In practice the actual possible size
  114. may be lower than this number.
  115. @par Complexity
  116. Constant.
  117. @par Exception Safety
  118. Throws nothing.
  119. */
  120. static
  121. constexpr
  122. std::size_t
  123. max_size() noexcept
  124. {
  125. return BOOST_URL_MAX_SIZE;
  126. }
  127. /** Return the number of characters in the url
  128. This function returns the number of
  129. characters in the url's encoded string,
  130. not including any null terminator,
  131. if present.
  132. @par Example
  133. @code
  134. assert( url_view( "file:///Program%20Files" ).size() == 23 );
  135. @endcode
  136. @par Complexity
  137. Constant.
  138. @par Exception Safety
  139. Throws nothing.
  140. */
  141. std::size_t
  142. size() const noexcept
  143. {
  144. return pi_->offset(id_end);
  145. }
  146. /** Return true if the url is empty
  147. The empty string matches the
  148. <em>relative-ref</em> grammar.
  149. @par Example
  150. @code
  151. assert( url_view( "" ).empty() );
  152. @endcode
  153. @par Complexity
  154. Constant.
  155. @par Exception Safety
  156. Throws nothing.
  157. @par BNF
  158. @code
  159. relative-ref = relative-part [ "?" query ] [ "#" fragment ]
  160. relative-part = "//" authority path-abempty
  161. / path-absolute
  162. / path-noscheme
  163. / path-empty
  164. @endcode
  165. @par Specification
  166. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.2"
  167. >4.2. Relative Reference (rfc3986)</a>
  168. */
  169. bool
  170. empty() const noexcept
  171. {
  172. return pi_->offset(id_end) == 0;
  173. }
  174. /** Return a pointer to the url's character buffer
  175. This function returns a pointer to
  176. the first character of the url, which
  177. is not guaranteed to be null-terminated.
  178. @par Complexity
  179. Constant.
  180. @par Exception Safety
  181. Throws nothing.
  182. */
  183. char const*
  184. data() const noexcept
  185. {
  186. return pi_->cs_;
  187. }
  188. /** Return the url string
  189. This function returns the entire url,
  190. which may contain percent escapes.
  191. @par Example
  192. @code
  193. assert( url_view( "http://www.example.com" ).buffer() == "http://www.example.com" );
  194. @endcode
  195. @par Complexity
  196. Constant.
  197. @par Exception Safety
  198. Throws nothing.
  199. */
  200. string_view
  201. buffer() const noexcept
  202. {
  203. return string_view(
  204. data(), size());
  205. }
  206. /** Return the URL as a string_view
  207. @par Complexity
  208. Constant.
  209. @par Exception Safety
  210. Throws nothing.
  211. */
  212. operator string_view() const noexcept
  213. {
  214. return buffer();
  215. }
  216. /** Return a shared, persistent copy of the url
  217. This function returns a read-only copy of
  218. the url, with shared lifetime. The returned
  219. value owns (persists) the underlying string.
  220. The algorithm used to create the value
  221. minimizes the number of individual memory
  222. allocations, making it more efficient than
  223. when using direct standard library functions.
  224. @par Example
  225. @code
  226. std::shared_ptr< url_view const > sp;
  227. {
  228. std::string s( "http://example.com" );
  229. url_view u( s ); // u references characters in s
  230. assert( u.data() == s.data() ); // same buffer
  231. sp = u.persist();
  232. assert( sp->data() != s.data() ); // different buffer
  233. assert( sp->buffer() == s); // same contents
  234. // s is destroyed and thus u
  235. // becomes invalid, but sp remains valid.
  236. }
  237. @endcode
  238. @par Complexity
  239. Linear in `this->size()`.
  240. @par Exception Safety
  241. Calls to allocate may throw.
  242. */
  243. BOOST_URL_DECL
  244. std::shared_ptr<
  245. url_view const> persist() const;
  246. //--------------------------------------------
  247. //
  248. // Scheme
  249. //
  250. //--------------------------------------------
  251. /** Return true a scheme is present
  252. This function returns true if this
  253. contains a scheme.
  254. @par Example
  255. @code
  256. assert( url_view( "http://www.example.com" ).has_scheme() );
  257. @endcode
  258. @par Complexity
  259. Constant.
  260. @par Exception Safety
  261. Throws nothing.
  262. @par BNF
  263. @code
  264. URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
  265. absolute-URI = scheme ":" hier-part [ "?" query ]
  266. scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
  267. @endcode
  268. @par Specification
  269. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1"
  270. >3.1. Scheme (rfc3986)</a>
  271. @see
  272. @ref scheme,
  273. @ref scheme_id.
  274. */
  275. BOOST_URL_DECL
  276. bool
  277. has_scheme() const noexcept;
  278. /** Return the scheme
  279. This function returns the scheme if it
  280. exists, without a trailing colon (':').
  281. Otherwise it returns an empty string.
  282. Note that schemes are case-insensitive,
  283. and the canonical form is lowercased.
  284. @par Example
  285. @code
  286. assert( url_view( "http://www.example.com" ).scheme() == "http" );
  287. @endcode
  288. @par Exception Safety
  289. Throws nothing.
  290. @par BNF
  291. @code
  292. scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
  293. URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
  294. absolute-URI = scheme ":" hier-part [ "?" query ]
  295. @endcode
  296. @par Specification
  297. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1"
  298. >3.1. Scheme (rfc3986)</a>
  299. @see
  300. @ref has_scheme,
  301. @ref scheme_id.
  302. */
  303. BOOST_URL_DECL
  304. string_view
  305. scheme() const noexcept;
  306. /** Return the scheme
  307. This function returns a value which
  308. depends on the scheme in the url:
  309. @li If the scheme is a well-known
  310. scheme, corresponding value from
  311. the enumeration @ref urls::scheme
  312. is returned.
  313. @li If a scheme is present but is not
  314. a well-known scheme, the value
  315. returned is @ref urls::scheme::unknown.
  316. @li Otherwise, if the scheme is absent
  317. the value returned is
  318. @ref urls::scheme::none.
  319. @par Example
  320. @code
  321. assert( url_view( "wss://www.example.com/crypto.cgi" ).scheme_id() == scheme::wss );
  322. @endcode
  323. @par Complexity
  324. Constant.
  325. @par Exception Safety
  326. Throws nothing.
  327. @par BNF
  328. @code
  329. URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
  330. absolute-URI = scheme ":" hier-part [ "?" query ]
  331. scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
  332. @endcode
  333. @par Specification
  334. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1"
  335. >3.1. Scheme (rfc3986)</a>
  336. @see
  337. @ref has_scheme,
  338. @ref scheme.
  339. */
  340. BOOST_URL_DECL
  341. urls::scheme
  342. scheme_id() const noexcept;
  343. //--------------------------------------------
  344. //
  345. // Authority
  346. //
  347. //--------------------------------------------
  348. /** Return true if an authority is present
  349. This function returns true if the url
  350. contains an authority. The presence of
  351. an authority is denoted by a double
  352. slash ("//") at the beginning or after
  353. the scheme.
  354. @par Example
  355. @code
  356. assert( url_view( "http://www.example.com/index.htm" ).has_authority() );
  357. @endcode
  358. @par Complexity
  359. Constant.
  360. @par Exception Safety
  361. Throws nothing.
  362. @par BNF
  363. @code
  364. authority = [ userinfo "@" ] host [ ":" port ]
  365. URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
  366. absolute-URI = scheme ":" hier-part [ "?" query ]
  367. URI-reference = URI / relative-ref
  368. relative-ref = relative-part [ "?" query ] [ "#" fragment ]
  369. hier-part = "//" authority path-abempty
  370. ; (more...)
  371. relative-part = "//" authority path-abempty
  372. ; (more...)
  373. @endcode
  374. @par Specification
  375. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2"
  376. >3.2. Authority (rfc3986)</a>
  377. @see
  378. @ref authority,
  379. @ref encoded_authority.
  380. */
  381. bool
  382. has_authority() const noexcept
  383. {
  384. return pi_->len(id_user) > 0;
  385. }
  386. /** Return the authority
  387. This function returns the authority as
  388. an @ref authority_view.
  389. @par Example
  390. @code
  391. authority_view a = url_view( "https://www.example.com:8080/index.htm" ).authority();
  392. @endcode
  393. @par Complexity
  394. Constant.
  395. @par Exception Safety
  396. Throws nothing.
  397. @par BNF
  398. @code
  399. authority = [ userinfo "@" ] host [ ":" port ]
  400. @endcode
  401. @par Specification
  402. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2"
  403. >3.2. Authority (rfc3986)</a>
  404. @see
  405. @ref encoded_authority,
  406. @ref has_authority.
  407. */
  408. BOOST_URL_DECL
  409. authority_view
  410. authority() const noexcept;
  411. /** Return the authority.
  412. If present, this function returns a
  413. string representing the authority (which
  414. may be empty).
  415. Otherwise it returns an empty string.
  416. The returned string may contain
  417. percent escapes.
  418. @par Example
  419. @code
  420. assert( url_view( "file://Network%20Drive/My%2DFiles" ).encoded_authority() == "Network%20Drive" );
  421. @endcode
  422. @par Complexity
  423. Constant.
  424. @par Exception Safety
  425. Throws nothing.
  426. @par BNF
  427. @code
  428. authority = [ userinfo "@" ] host [ ":" port ]
  429. @endcode
  430. @par Specification
  431. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2"
  432. >3.2. Authority (rfc3986)</a>
  433. @see
  434. @ref authority,
  435. @ref has_authority.
  436. */
  437. BOOST_URL_DECL
  438. pct_string_view
  439. encoded_authority() const noexcept;
  440. //--------------------------------------------
  441. //
  442. // Userinfo
  443. //
  444. //--------------------------------------------
  445. /** Return true if a userinfo is present
  446. This function returns true if this
  447. contains a userinfo.
  448. @par Example
  449. @code
  450. assert( url_view( "http://jane%2Ddoe:pass@example.com" ).has_userinfo() );
  451. @endcode
  452. @par Complexity
  453. Constant.
  454. @par Exception Safety
  455. Throws nothing.
  456. @par BNF
  457. @code
  458. userinfo = user [ ":" [ password ] ]
  459. authority = [ userinfo "@" ] host [ ":" port ]
  460. @endcode
  461. @par Specification
  462. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"
  463. >3.2.1. User Information (rfc3986)</a>
  464. @see
  465. @ref has_password,
  466. @ref encoded_password,
  467. @ref encoded_user,
  468. @ref encoded_userinfo,
  469. @ref password,
  470. @ref user,
  471. @ref userinfo.
  472. */
  473. BOOST_URL_DECL
  474. bool
  475. has_userinfo() const noexcept;
  476. /** Return true if a password is present
  477. This function returns true if the
  478. userinfo is present and contains
  479. a password.
  480. @par Example
  481. @code
  482. assert( url_view( "http://jane%2Ddoe:pass@example.com" ).has_password() );
  483. @endcode
  484. @par Complexity
  485. Constant.
  486. @par Exception Safety
  487. Throws nothing.
  488. @par BNF
  489. @code
  490. userinfo = user [ ":" [ password ] ]
  491. user = *( unreserved / pct-encoded / sub-delims )
  492. password = *( unreserved / pct-encoded / sub-delims / ":" )
  493. @endcode
  494. @par Specification
  495. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"
  496. >3.2.1. User Information (rfc3986)</a>
  497. @see
  498. @ref has_userinfo,
  499. @ref encoded_password,
  500. @ref encoded_user,
  501. @ref encoded_userinfo,
  502. @ref password,
  503. @ref user,
  504. @ref userinfo.
  505. */
  506. BOOST_URL_DECL
  507. bool
  508. has_password() const noexcept;
  509. /** Return the userinfo
  510. If present, this function returns a
  511. string representing the userinfo (which
  512. may be empty).
  513. Otherwise it returns an empty string.
  514. Any percent-escapes in the string are
  515. decoded first.
  516. @note
  517. This function uses the string token
  518. return type customization. Depending on
  519. the token passed, the return type and
  520. behavior of the function can be different.
  521. See @ref string_token::return_string
  522. for more information.
  523. @par Example
  524. @code
  525. assert( url_view( "http://jane%2Ddoe:pass@example.com" ).userinfo() == "jane-doe:pass" );
  526. @endcode
  527. @par Complexity
  528. Linear in `this->userinfo().size()`.
  529. @par Exception Safety
  530. Calls to allocate may throw.
  531. @return When called with no arguments,
  532. a value of type `std::string` is
  533. returned. Otherwise, the return type
  534. and meaning depends on the string token
  535. passed to the function.
  536. @par BNF
  537. @code
  538. userinfo = user [ ":" [ password ] ]
  539. authority = [ userinfo "@" ] host [ ":" port ]
  540. @endcode
  541. @par Specification
  542. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"
  543. >3.2.1. User Information (rfc3986)</a>
  544. @see
  545. @ref has_password,
  546. @ref has_userinfo,
  547. @ref encoded_password,
  548. @ref encoded_user,
  549. @ref encoded_userinfo,
  550. @ref password,
  551. @ref user.
  552. */
  553. template<BOOST_URL_STRTOK_TPARAM>
  554. BOOST_URL_STRTOK_RETURN
  555. userinfo(
  556. BOOST_URL_STRTOK_ARG(token)) const
  557. {
  558. encoding_opts opt;
  559. opt.space_as_plus = false;
  560. return encoded_userinfo().decode(
  561. opt, std::move(token));
  562. }
  563. /** Return the userinfo
  564. If present, this function returns a
  565. string representing the userinfo (which
  566. may be empty).
  567. Otherwise it returns an empty string.
  568. The returned string may contain
  569. percent escapes.
  570. @par Example
  571. @code
  572. assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_userinfo() == "jane%2Ddoe:pass" );
  573. @endcode
  574. @par Complexity
  575. Constant.
  576. @par Exception Safety
  577. Throws nothing
  578. @par BNF
  579. @code
  580. userinfo = user [ ":" [ password ] ]
  581. authority = [ userinfo "@" ] host [ ":" port ]
  582. @endcode
  583. @par Specification
  584. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"
  585. >3.2.1. User Information (rfc3986)</a>
  586. @see
  587. @ref has_password,
  588. @ref has_userinfo,
  589. @ref encoded_password,
  590. @ref encoded_user,
  591. @ref password,
  592. @ref user,
  593. @ref userinfo.
  594. */
  595. BOOST_URL_DECL
  596. pct_string_view
  597. encoded_userinfo() const noexcept;
  598. //--------------------------------------------
  599. /** Return the user
  600. If present, this function returns a
  601. string representing the user (which
  602. may be empty).
  603. Otherwise it returns an empty string.
  604. Any percent-escapes in the string are
  605. decoded first.
  606. @par Example
  607. @code
  608. assert( url_view( "http://jane%2Ddoe:pass@example.com" ).user() == "jane-doe" );
  609. @endcode
  610. @par Complexity
  611. Linear in `this->user().size()`.
  612. @par Exception Safety
  613. Calls to allocate may throw.
  614. @par BNF
  615. @code
  616. userinfo = user [ ":" [ password ] ]
  617. user = *( unreserved / pct-encoded / sub-delims )
  618. password = *( unreserved / pct-encoded / sub-delims / ":" )
  619. @endcode
  620. @par Specification
  621. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"
  622. >3.2.1. User Information (rfc3986)</a>
  623. @see
  624. @ref has_password,
  625. @ref has_userinfo,
  626. @ref encoded_password,
  627. @ref encoded_user,
  628. @ref encoded_userinfo,
  629. @ref password,
  630. @ref userinfo.
  631. */
  632. template<BOOST_URL_STRTOK_TPARAM>
  633. BOOST_URL_STRTOK_RETURN
  634. user(
  635. BOOST_URL_STRTOK_ARG(token)) const
  636. {
  637. encoding_opts opt;
  638. opt.space_as_plus = false;
  639. return encoded_user().decode(
  640. opt, std::move(token));
  641. }
  642. /** Return the user
  643. If present, this function returns a
  644. string representing the user (which
  645. may be empty).
  646. Otherwise it returns an empty string.
  647. The returned string may contain
  648. percent escapes.
  649. @par Example
  650. @code
  651. assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_user() == "jane%2Ddoe" );
  652. @endcode
  653. @par Complexity
  654. Constant.
  655. @par Exception Safety
  656. Throws nothing.
  657. @par BNF
  658. @code
  659. userinfo = user [ ":" [ password ] ]
  660. user = *( unreserved / pct-encoded / sub-delims )
  661. password = *( unreserved / pct-encoded / sub-delims / ":" )
  662. @endcode
  663. @par Specification
  664. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"
  665. >3.2.1. User Information (rfc3986)</a>
  666. @see
  667. @ref has_password,
  668. @ref has_userinfo,
  669. @ref encoded_password,
  670. @ref encoded_userinfo,
  671. @ref password,
  672. @ref user,
  673. @ref userinfo.
  674. */
  675. BOOST_URL_DECL
  676. pct_string_view
  677. encoded_user() const noexcept;
  678. /** Return the password
  679. If present, this function returns a
  680. string representing the password (which
  681. may be an empty string).
  682. Otherwise it returns an empty string.
  683. Any percent-escapes in the string are
  684. decoded first.
  685. @par Example
  686. @code
  687. assert( url_view( "http://jane%2Ddoe:pass@example.com" ).password() == "pass" );
  688. @endcode
  689. @par Complexity
  690. Linear in `this->password().size()`.
  691. @par Exception Safety
  692. Calls to allocate may throw.
  693. @par BNF
  694. @code
  695. userinfo = user [ ":" [ password ] ]
  696. user = *( unreserved / pct-encoded / sub-delims )
  697. password = *( unreserved / pct-encoded / sub-delims / ":" )
  698. @endcode
  699. @par Specification
  700. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"
  701. >3.2.1. User Information (rfc3986)</a>
  702. @see
  703. @ref has_password,
  704. @ref has_userinfo,
  705. @ref encoded_password,
  706. @ref encoded_user,
  707. @ref encoded_userinfo,
  708. @ref user,
  709. @ref userinfo.
  710. */
  711. template<BOOST_URL_STRTOK_TPARAM>
  712. BOOST_URL_STRTOK_RETURN
  713. password(
  714. BOOST_URL_STRTOK_ARG(token)) const
  715. {
  716. encoding_opts opt;
  717. opt.space_as_plus = false;
  718. return encoded_password().decode(
  719. opt, std::move(token));
  720. }
  721. /** Return the password
  722. This function returns the password portion
  723. of the userinfo as a percent-encoded string.
  724. @par Example
  725. @code
  726. assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_password() == "pass" );
  727. @endcode
  728. @par Complexity
  729. Constant.
  730. @par Exception Safety
  731. Throws nothing.
  732. @par BNF
  733. @code
  734. userinfo = user [ ":" [ password ] ]
  735. user = *( unreserved / pct-encoded / sub-delims )
  736. password = *( unreserved / pct-encoded / sub-delims / ":" )
  737. @endcode
  738. @par Specification
  739. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"
  740. >3.2.1. User Information (rfc3986)</a>
  741. @see
  742. @ref has_password,
  743. @ref has_userinfo,
  744. @ref encoded_user,
  745. @ref encoded_userinfo,
  746. @ref password,
  747. @ref user,
  748. @ref userinfo.
  749. */
  750. BOOST_URL_DECL
  751. pct_string_view
  752. encoded_password() const noexcept;
  753. //--------------------------------------------
  754. //
  755. // Host
  756. //
  757. //--------------------------------------------
  758. /** Return the host type
  759. This function returns one of the
  760. following constants representing the
  761. type of host present.
  762. @li @ref host_type::ipv4
  763. @li @ref host_type::ipv6
  764. @li @ref host_type::ipvfuture
  765. @li @ref host_type::name
  766. @li @ref host_type::none
  767. When @ref has_authority is false, the
  768. host type is @ref host_type::none.
  769. @par Example
  770. @code
  771. assert( url_view( "https://192.168.0.1/local.htm" ).host_type() == host_type::ipv4 );
  772. @endcode
  773. @par Complexity
  774. Constant.
  775. @par Exception Safety
  776. Throws nothing.
  777. @par Specification
  778. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
  779. >3.2.2. Host (rfc3986)</a>
  780. */
  781. urls::host_type
  782. host_type() const noexcept
  783. {
  784. return pi_->host_type_;
  785. }
  786. /** Return the host
  787. This function returns the host portion
  788. of the authority as a string, or the
  789. empty string if there is no authority.
  790. Any percent-escapes in the string are
  791. decoded first.
  792. @par Example
  793. @code
  794. assert( url_view( "https://www%2droot.example.com/" ).host() == "www-root.example.com" );
  795. @endcode
  796. @par Complexity
  797. Linear in `this->host().size()`.
  798. @par Exception Safety
  799. Calls to allocate may throw.
  800. @par BNF
  801. @code
  802. host = IP-literal / IPv4address / reg-name
  803. IP-literal = "[" ( IPv6address / IPvFuture ) "]"
  804. reg-name = *( unreserved / pct-encoded / "-" / ".")
  805. @endcode
  806. @par Specification
  807. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
  808. >3.2.2. Host (rfc3986)</a>
  809. */
  810. template<BOOST_URL_STRTOK_TPARAM>
  811. BOOST_URL_STRTOK_RETURN
  812. host(
  813. BOOST_URL_STRTOK_ARG(token)) const
  814. {
  815. encoding_opts opt;
  816. opt.space_as_plus = false;
  817. return encoded_host().decode(
  818. opt, std::move(token));
  819. }
  820. /** Return the host
  821. This function returns the host portion
  822. of the authority as a string, or the
  823. empty string if there is no authority.
  824. The returned string may contain
  825. percent escapes.
  826. @par Example
  827. @code
  828. assert( url_view( "https://www%2droot.example.com/" ).encoded_host() == "www%2droot.example.com" );
  829. @endcode
  830. @par Complexity
  831. Constant.
  832. @par Exception Safety
  833. Throws nothing.
  834. @par BNF
  835. @code
  836. host = IP-literal / IPv4address / reg-name
  837. IP-literal = "[" ( IPv6address / IPvFuture ) "]"
  838. reg-name = *( unreserved / pct-encoded / "-" / ".")
  839. @endcode
  840. @par Specification
  841. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
  842. >3.2.2. Host (rfc3986)</a>
  843. */
  844. BOOST_URL_DECL
  845. pct_string_view
  846. encoded_host() const noexcept;
  847. /** Return the host
  848. The value returned by this function
  849. depends on the type of host returned
  850. from the function @ref host_type.
  851. @li If the type is @ref host_type::ipv4,
  852. then the IPv4 address string is returned.
  853. @li If the type is @ref host_type::ipv6,
  854. then the IPv6 address string is returned,
  855. without any enclosing brackets.
  856. @li If the type is @ref host_type::ipvfuture,
  857. then the IPvFuture address string is returned,
  858. without any enclosing brackets.
  859. @li If the type is @ref host_type::name,
  860. then the host name string is returned.
  861. Any percent-escapes in the string are
  862. decoded first.
  863. @li If the type is @ref host_type::none,
  864. then an empty string is returned.
  865. @par Example
  866. @code
  867. assert( url_view( "https://[1::6:c0a8:1]/" ).host_address() == "1::6:c0a8:1" );
  868. @endcode
  869. @par Complexity
  870. Linear in `this->host_address().size()`.
  871. @par Exception Safety
  872. Calls to allocate may throw.
  873. @par BNF
  874. @code
  875. host = IP-literal / IPv4address / reg-name
  876. IP-literal = "[" ( IPv6address / IPvFuture ) "]"
  877. reg-name = *( unreserved / pct-encoded / "-" / ".")
  878. @endcode
  879. @par Specification
  880. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
  881. >3.2.2. Host (rfc3986)</a>
  882. */
  883. template<BOOST_URL_STRTOK_TPARAM>
  884. BOOST_URL_STRTOK_RETURN
  885. host_address(
  886. BOOST_URL_STRTOK_ARG(token)) const
  887. {
  888. encoding_opts opt;
  889. opt.space_as_plus = false;
  890. return encoded_host_address().decode(
  891. opt, std::move(token));
  892. }
  893. /** Return the host
  894. The value returned by this function
  895. depends on the type of host returned
  896. from the function @ref host_type.
  897. @li If the type is @ref host_type::ipv4,
  898. then the IPv4 address string is returned.
  899. @li If the type is @ref host_type::ipv6,
  900. then the IPv6 address string is returned,
  901. without any enclosing brackets.
  902. @li If the type is @ref host_type::ipvfuture,
  903. then the IPvFuture address string is returned,
  904. without any enclosing brackets.
  905. @li If the type is @ref host_type::name,
  906. then the host name string is returned.
  907. Any percent-escapes in the string are
  908. decoded first.
  909. @li If the type is @ref host_type::none,
  910. then an empty string is returned.
  911. The returned string may contain
  912. percent escapes.
  913. @par Example
  914. @code
  915. assert( url_view( "https://www%2droot.example.com/" ).encoded_host_address() == "www%2droot.example.com" );
  916. @endcode
  917. @par Complexity
  918. Constant.
  919. @par Exception Safety
  920. Throws nothing.
  921. @par BNF
  922. @code
  923. host = IP-literal / IPv4address / reg-name
  924. IP-literal = "[" ( IPv6address / IPvFuture ) "]"
  925. reg-name = *( unreserved / pct-encoded / "-" / ".")
  926. @endcode
  927. @par Specification
  928. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
  929. >3.2.2. Host (rfc3986)</a>
  930. */
  931. BOOST_URL_DECL
  932. pct_string_view
  933. encoded_host_address() const noexcept;
  934. /** Return the host IPv4 address
  935. If the host type is @ref host_type::ipv4,
  936. this function returns the address as
  937. a value of type @ref ipv4_address.
  938. Otherwise, if the host type is not an IPv4
  939. address, it returns a default-constructed
  940. value which is equal to the unspecified
  941. address "0.0.0.0".
  942. @par Example
  943. @code
  944. assert( url_view( "http://127.0.0.1/index.htm?user=win95" ).host_ipv4_address() == ipv4_address( "127.0.0.1" ) );
  945. @endcode
  946. @par Complexity
  947. Constant.
  948. @par Exception Safety
  949. Throws nothing.
  950. @par BNF
  951. @code
  952. IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
  953. dec-octet = DIGIT ; 0-9
  954. / %x31-39 DIGIT ; 10-99
  955. / "1" 2DIGIT ; 100-199
  956. / "2" %x30-34 DIGIT ; 200-249
  957. / "25" %x30-35 ; 250-255
  958. @endcode
  959. @par Specification
  960. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
  961. >3.2.2. Host (rfc3986)</a>
  962. */
  963. BOOST_URL_DECL
  964. ipv4_address
  965. host_ipv4_address() const noexcept;
  966. /** Return the host IPv6 address
  967. If the host type is @ref host_type::ipv6,
  968. this function returns the address as
  969. a value of type @ref ipv6_address.
  970. Otherwise, if the host type is not an IPv6
  971. address, it returns a default-constructed
  972. value which is equal to the unspecified
  973. address "0:0:0:0:0:0:0:0".
  974. @par Example
  975. @code
  976. assert( url_view( "ftp://[::1]/" ).host_ipv6_address() == ipv6_address( "::1" ) );
  977. @endcode
  978. @par Complexity
  979. Constant.
  980. @par Exception Safety
  981. Throws nothing.
  982. @par BNF
  983. @code
  984. IPv6address = 6( h16 ":" ) ls32
  985. / "::" 5( h16 ":" ) ls32
  986. / [ h16 ] "::" 4( h16 ":" ) ls32
  987. / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
  988. / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
  989. / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
  990. / [ *4( h16 ":" ) h16 ] "::" ls32
  991. / [ *5( h16 ":" ) h16 ] "::" h16
  992. / [ *6( h16 ":" ) h16 ] "::"
  993. ls32 = ( h16 ":" h16 ) / IPv4address
  994. ; least-significant 32 bits of address
  995. h16 = 1*4HEXDIG
  996. ; 16 bits of address represented in hexadecimal
  997. @endcode
  998. @par Specification
  999. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
  1000. >3.2.2. Host (rfc3986)</a>
  1001. */
  1002. BOOST_URL_DECL
  1003. ipv6_address
  1004. host_ipv6_address() const noexcept;
  1005. /** Return the host IPvFuture address
  1006. If the host type is @ref host_type::ipvfuture,
  1007. this function returns the address as
  1008. a string.
  1009. Otherwise, if the host type is not an
  1010. IPvFuture address, it returns an
  1011. empty string.
  1012. @par Example
  1013. @code
  1014. assert( url_view( "http://[v1fe.d:9]/index.htm" ).host_ipvfuture() == "v1fe.d:9" );
  1015. @endcode
  1016. @par Complexity
  1017. Constant.
  1018. @par Exception Safety
  1019. Throws nothing.
  1020. @par BNF
  1021. @code
  1022. IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
  1023. @endcode
  1024. @par Specification
  1025. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
  1026. >3.2.2. Host (rfc3986)</a>
  1027. */
  1028. BOOST_URL_DECL
  1029. string_view
  1030. host_ipvfuture() const noexcept;
  1031. /** Return the host name
  1032. If the host type is @ref host_type::name,
  1033. this function returns the name as
  1034. a string. Otherwise an empty string is returned.
  1035. Any percent-escapes in the string are
  1036. decoded first.
  1037. @par Example
  1038. @code
  1039. assert( url_view( "https://www%2droot.example.com/" ).host_name() == "www-root.example.com" );
  1040. @endcode
  1041. @par Complexity
  1042. Linear in `this->host_name().size()`.
  1043. @par Exception Safety
  1044. Calls to allocate may throw.
  1045. @par BNF
  1046. @code
  1047. host = IP-literal / IPv4address / reg-name
  1048. IP-literal = "[" ( IPv6address / IPvFuture ) "]"
  1049. reg-name = *( unreserved / pct-encoded / "-" / ".")
  1050. @endcode
  1051. @par Specification
  1052. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
  1053. >3.2.2. Host (rfc3986)</a>
  1054. */
  1055. template<BOOST_URL_STRTOK_TPARAM>
  1056. BOOST_URL_STRTOK_RETURN
  1057. host_name(
  1058. BOOST_URL_STRTOK_ARG(token)) const
  1059. {
  1060. encoding_opts opt;
  1061. opt.space_as_plus = false;
  1062. return encoded_host_name().decode(
  1063. opt, std::move(token));
  1064. }
  1065. /** Return the host name
  1066. If the host type is @ref host_type::name,
  1067. this function returns the name as
  1068. a string.
  1069. Otherwise, if the host type is not an
  1070. name, it returns an empty string.
  1071. The returned string may contain
  1072. percent escapes.
  1073. @par Example
  1074. @code
  1075. assert( url_view( "https://www%2droot.example.com/" ).encoded_host_name() == "www%2droot.example.com" );
  1076. @endcode
  1077. @par Complexity
  1078. Constant.
  1079. @par Exception Safety
  1080. Throws nothing.
  1081. @par BNF
  1082. @code
  1083. host = IP-literal / IPv4address / reg-name
  1084. IP-literal = "[" ( IPv6address / IPvFuture ) "]"
  1085. reg-name = *( unreserved / pct-encoded / "-" / ".")
  1086. @endcode
  1087. @par Specification
  1088. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
  1089. >3.2.2. Host (rfc3986)</a>
  1090. */
  1091. BOOST_URL_DECL
  1092. pct_string_view
  1093. encoded_host_name() const noexcept;
  1094. //--------------------------------------------
  1095. //
  1096. // Port
  1097. //
  1098. //--------------------------------------------
  1099. /** Return true if a port is present
  1100. This function returns true if an
  1101. authority is present and contains a port.
  1102. @par Example
  1103. @code
  1104. assert( url_view( "wss://www.example.com:443" ).has_port() );
  1105. @endcode
  1106. @par Complexity
  1107. Constant.
  1108. @par Exception Safety
  1109. Throws nothing.
  1110. @par BNF
  1111. @code
  1112. authority = [ userinfo "@" ] host [ ":" port ]
  1113. port = *DIGIT
  1114. @endcode
  1115. @par Specification
  1116. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3"
  1117. >3.2.3. Port (rfc3986)</a>
  1118. @see
  1119. @ref encoded_host_and_port,
  1120. @ref port,
  1121. @ref port_number.
  1122. */
  1123. BOOST_URL_DECL
  1124. bool
  1125. has_port() const noexcept;
  1126. /** Return the port
  1127. If present, this function returns a
  1128. string representing the port (which
  1129. may be empty).
  1130. Otherwise it returns an empty string.
  1131. @par Example
  1132. @code
  1133. assert( url_view( "http://localhost.com:8080" ).port() == "8080" );
  1134. @endcode
  1135. @par Complexity
  1136. Constant.
  1137. @par Exception Safety
  1138. Throws nothing.
  1139. @par BNF
  1140. @code
  1141. port = *DIGIT
  1142. @endcode
  1143. @par Specification
  1144. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3"
  1145. >3.2.3. Port (rfc3986)</a>
  1146. @see
  1147. @ref encoded_host_and_port,
  1148. @ref has_port,
  1149. @ref port_number.
  1150. */
  1151. BOOST_URL_DECL
  1152. string_view
  1153. port() const noexcept;
  1154. /** Return the port
  1155. If a port is present and the numerical
  1156. value is representable, it is returned
  1157. as an unsigned integer. Otherwise, the
  1158. number zero is returned.
  1159. @par Example
  1160. @code
  1161. assert( url_view( "http://localhost.com:8080" ).port_number() == 8080 );
  1162. @endcode
  1163. @par Complexity
  1164. Constant.
  1165. @par Exception Safety
  1166. Throws nothing.
  1167. @par BNF
  1168. @code
  1169. port = *DIGIT
  1170. @endcode
  1171. @par Specification
  1172. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3"
  1173. >3.2.3. Port (rfc3986)</a>
  1174. @see
  1175. @ref encoded_host_and_port,
  1176. @ref has_port,
  1177. @ref port.
  1178. */
  1179. BOOST_URL_DECL
  1180. std::uint16_t
  1181. port_number() const noexcept;
  1182. //--------------------------------------------
  1183. //
  1184. // Path
  1185. //
  1186. //--------------------------------------------
  1187. /** Return true if the path is absolute
  1188. This function returns true if the path
  1189. begins with a forward slash ('/').
  1190. @par Example
  1191. @code
  1192. assert( url_view( "/path/to/file.txt" ).is_path_absolute() );
  1193. @endcode
  1194. @par Complexity
  1195. Constant.
  1196. @par Exception Safety
  1197. Throws nothing.
  1198. @par BNF
  1199. @code
  1200. path = path-abempty ; begins with "/" or is empty
  1201. / path-absolute ; begins with "/" but not "//"
  1202. / path-noscheme ; begins with a non-colon segment
  1203. / path-rootless ; begins with a segment
  1204. / path-empty ; zero characters
  1205. path-abempty = *( "/" segment )
  1206. path-absolute = "/" [ segment-nz *( "/" segment ) ]
  1207. path-noscheme = segment-nz-nc *( "/" segment )
  1208. path-rootless = segment-nz *( "/" segment )
  1209. path-empty = 0<pchar>
  1210. @endcode
  1211. @par Specification
  1212. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
  1213. >3.3. Path (rfc3986)</a>
  1214. @see
  1215. @ref encoded_path,
  1216. @ref encoded_segments.
  1217. @ref path,
  1218. @ref segments.
  1219. */
  1220. bool
  1221. is_path_absolute() const noexcept
  1222. {
  1223. return
  1224. pi_->len(id_path) > 0 &&
  1225. pi_->cs_[pi_->offset(id_path)] == '/';
  1226. }
  1227. /** Return the path
  1228. This function returns the path as a
  1229. string. The path may be empty.
  1230. Any percent-escapes in the string are
  1231. decoded first.
  1232. @par Example
  1233. @code
  1234. assert( url_view( "file:///Program%20Files/Games/config.ini" ).path() == "/Program Files/Games/config.ini" );
  1235. @endcode
  1236. @par Complexity
  1237. Linear in `this->path().size()`.
  1238. @par Exception Safety
  1239. Calls to allocate may throw.
  1240. @par BNF
  1241. @code
  1242. path = path-abempty ; begins with "/" or is empty
  1243. / path-absolute ; begins with "/" but not "//"
  1244. / path-noscheme ; begins with a non-colon segment
  1245. / path-rootless ; begins with a segment
  1246. / path-empty ; zero characters
  1247. path-abempty = *( "/" segment )
  1248. path-absolute = "/" [ segment-nz *( "/" segment ) ]
  1249. path-noscheme = segment-nz-nc *( "/" segment )
  1250. path-rootless = segment-nz *( "/" segment )
  1251. path-empty = 0<pchar>
  1252. @endcode
  1253. @par Specification
  1254. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
  1255. >3.3. Path (rfc3986)</a>
  1256. @see
  1257. @ref is_path_absolute,
  1258. @ref encoded_path,
  1259. @ref encoded_segments.
  1260. @ref segments.
  1261. */
  1262. template<BOOST_URL_STRTOK_TPARAM>
  1263. BOOST_URL_STRTOK_RETURN
  1264. path(
  1265. BOOST_URL_STRTOK_ARG(token)) const
  1266. {
  1267. encoding_opts opt;
  1268. opt.space_as_plus = false;
  1269. return encoded_path().decode(
  1270. opt, std::move(token));
  1271. }
  1272. /** Return the path
  1273. This function returns the path as a
  1274. string. The path may be empty.
  1275. Any percent-escapes in the string are
  1276. decoded first.
  1277. @par Example
  1278. @code
  1279. assert( url_view( "file:///Program%20Files/Games/config.ini" ).encoded_path() == "/Program%20Files/Games/config.ini" );
  1280. @endcode
  1281. @par Complexity
  1282. Constant.
  1283. @par Exception Safety
  1284. Throws nothing.
  1285. @par BNF
  1286. @code
  1287. path = path-abempty ; begins with "/" or is empty
  1288. / path-absolute ; begins with "/" but not "//"
  1289. / path-noscheme ; begins with a non-colon segment
  1290. / path-rootless ; begins with a segment
  1291. / path-empty ; zero characters
  1292. path-abempty = *( "/" segment )
  1293. path-absolute = "/" [ segment-nz *( "/" segment ) ]
  1294. path-noscheme = segment-nz-nc *( "/" segment )
  1295. path-rootless = segment-nz *( "/" segment )
  1296. path-empty = 0<pchar>
  1297. @endcode
  1298. @par Specification
  1299. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
  1300. >3.3. Path (rfc3986)</a>
  1301. @see
  1302. @ref is_path_absolute,
  1303. @ref encoded_segments.
  1304. @ref path,
  1305. @ref segments.
  1306. */
  1307. BOOST_URL_DECL
  1308. pct_string_view
  1309. encoded_path() const noexcept;
  1310. /** Return the path as a container of segments
  1311. This function returns a bidirectional
  1312. view of strings over the path.
  1313. The returned view references the same
  1314. underlying character buffer; ownership
  1315. is not transferred.
  1316. Any percent-escapes in strings returned
  1317. when iterating the view are decoded first.
  1318. @par Example
  1319. @code
  1320. segments_view sv = url_view( "/path/to/file.txt" ).segments();
  1321. @endcode
  1322. @par Complexity
  1323. Constant.
  1324. @par Exception Safety
  1325. Throws nothing.
  1326. @par BNF
  1327. @code
  1328. path = [ "/" ] segment *( "/" segment )
  1329. @endcode
  1330. @par Specification
  1331. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
  1332. >3.3. Path (rfc3986)</a>
  1333. @see
  1334. @ref is_path_absolute,
  1335. @ref encoded_path,
  1336. @ref encoded_segments.
  1337. @ref path,
  1338. @ref segments_view.
  1339. */
  1340. BOOST_URL_DECL
  1341. segments_view
  1342. segments() const noexcept;
  1343. /** Return the path as a container of segments
  1344. This function returns a bidirectional
  1345. view of strings over the path.
  1346. The returned view references the same
  1347. underlying character buffer; ownership
  1348. is not transferred.
  1349. Strings returned when iterating the
  1350. range may contain percent escapes.
  1351. @par Example
  1352. @code
  1353. segments_encoded_view sv = url_view( "/path/to/file.txt" ).encoded_segments();
  1354. @endcode
  1355. @par Complexity
  1356. Constant.
  1357. @par Exception Safety
  1358. Throws nothing.
  1359. @par BNF
  1360. @code
  1361. path = path-abempty ; begins with "/" or is empty
  1362. / path-absolute ; begins with "/" but not "//"
  1363. / path-noscheme ; begins with a non-colon segment
  1364. / path-rootless ; begins with a segment
  1365. / path-empty ; zero characters
  1366. path-abempty = *( "/" segment )
  1367. path-absolute = "/" [ segment-nz *( "/" segment ) ]
  1368. path-noscheme = segment-nz-nc *( "/" segment )
  1369. path-rootless = segment-nz *( "/" segment )
  1370. path-empty = 0<pchar>
  1371. @endcode
  1372. @par Specification
  1373. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
  1374. >3.3. Path (rfc3986)</a>
  1375. @see
  1376. @ref is_path_absolute,
  1377. @ref encoded_path,
  1378. @ref path,
  1379. @ref segments,
  1380. @ref segments_encoded_view.
  1381. */
  1382. BOOST_URL_DECL
  1383. segments_encoded_view
  1384. encoded_segments() const noexcept;
  1385. //--------------------------------------------
  1386. //
  1387. // Query
  1388. //
  1389. //--------------------------------------------
  1390. /** Return true if a query is present
  1391. This function returns true if this
  1392. contains a query. An empty query is
  1393. distinct from having no query.
  1394. @par Example
  1395. @code
  1396. assert( url_view( "/sql?id=42&col=name&page-size=20" ).has_query() );
  1397. @endcode
  1398. @par Complexity
  1399. Constant.
  1400. @par Exception Safety
  1401. Throws nothing.
  1402. @par BNF
  1403. @code
  1404. query = *( pchar / "/" / "?" )
  1405. query-param = key [ "=" value ]
  1406. query-params = [ query-param ] *( "&" query-param )
  1407. @endcode
  1408. @par Specification
  1409. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
  1410. >3.4. Query (rfc3986)</a>
  1411. @li <a href="https://en.wikipedia.org/wiki/Query_string"
  1412. >Query string (Wikipedia)</a>
  1413. @see
  1414. @ref encoded_params,
  1415. @ref encoded_query,
  1416. @ref params,
  1417. @ref query.
  1418. */
  1419. BOOST_URL_DECL
  1420. bool
  1421. has_query() const noexcept;
  1422. /** Return the query
  1423. If this contains a query, it is returned
  1424. as a string (which may be empty).
  1425. Otherwise, an empty string is returned.
  1426. Any percent-escapes in the string are
  1427. decoded first.
  1428. <br>
  1429. When plus signs appear in the query
  1430. portion of the url, they are converted
  1431. to spaces automatically upon decoding.
  1432. This behavior can be changed by setting
  1433. decode options.
  1434. @par Example
  1435. @code
  1436. assert( url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).query() == "id=42&name=jane-doe&page size=20" );
  1437. @endcode
  1438. @par Complexity
  1439. Linear in `this->query().size()`.
  1440. @par Exception Safety
  1441. Calls to allocate may throw.
  1442. @par BNF
  1443. @code
  1444. query = *( pchar / "/" / "?" )
  1445. query-param = key [ "=" value ]
  1446. query-params = [ query-param ] *( "&" query-param )
  1447. @endcode
  1448. @par Specification
  1449. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
  1450. >3.4. Query (rfc3986)</a>
  1451. @li <a href="https://en.wikipedia.org/wiki/Query_string"
  1452. >Query string (Wikipedia)</a>
  1453. @see
  1454. @ref encoded_params,
  1455. @ref encoded_query,
  1456. @ref has_query,
  1457. @ref params.
  1458. */
  1459. template<BOOST_URL_STRTOK_TPARAM>
  1460. BOOST_URL_STRTOK_RETURN
  1461. query(
  1462. BOOST_URL_STRTOK_ARG(token)) const
  1463. {
  1464. // When interacting with the query as
  1465. // an intact string, we do not treat
  1466. // the plus sign as an encoded space.
  1467. encoding_opts opt;
  1468. opt.space_as_plus = false;
  1469. return encoded_query().decode(
  1470. opt, std::move(token));
  1471. }
  1472. /** Return the query
  1473. If this contains a query, it is returned
  1474. as a string (which may be empty).
  1475. Otherwise, an empty string is returned.
  1476. The returned string may contain
  1477. percent escapes.
  1478. @par Example
  1479. @code
  1480. assert( url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_query() == "id=42&name=jane%2Ddoe&page+size=20" );
  1481. @endcode
  1482. @par Complexity
  1483. Constant.
  1484. @par Exception Safety
  1485. Throws nothing.
  1486. @par BNF
  1487. @code
  1488. query = *( pchar / "/" / "?" )
  1489. query-param = key [ "=" value ]
  1490. query-params = [ query-param ] *( "&" query-param )
  1491. @endcode
  1492. @par Specification
  1493. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
  1494. >3.4. Query (rfc3986)</a>
  1495. @li <a href="https://en.wikipedia.org/wiki/Query_string"
  1496. >Query string (Wikipedia)</a>
  1497. @see
  1498. @ref encoded_params,
  1499. @ref has_query,
  1500. @ref params,
  1501. @ref query.
  1502. */
  1503. BOOST_URL_DECL
  1504. pct_string_view
  1505. encoded_query() const noexcept;
  1506. /** Return the query as a container of parameters
  1507. This function returns a bidirectional
  1508. view of key/value pairs over the query.
  1509. The returned view references the same
  1510. underlying character buffer; ownership
  1511. is not transferred.
  1512. Any percent-escapes in strings returned
  1513. when iterating the view are decoded first.
  1514. @par Example
  1515. @code
  1516. params_view pv = url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).params();
  1517. @endcode
  1518. @par Complexity
  1519. Constant.
  1520. @par Exception Safety
  1521. Throws nothing.
  1522. @par BNF
  1523. @code
  1524. query = *( pchar / "/" / "?" )
  1525. query-param = key [ "=" value ]
  1526. query-params = [ query-param ] *( "&" query-param )
  1527. @endcode
  1528. @par Specification
  1529. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
  1530. >3.4. Query (rfc3986)</a>
  1531. @li <a href="https://en.wikipedia.org/wiki/Query_string"
  1532. >Query string (Wikipedia)</a>
  1533. @see
  1534. @ref encoded_params,
  1535. @ref encoded_query,
  1536. @ref has_query,
  1537. @ref query.
  1538. */
  1539. BOOST_URL_DECL
  1540. params_view
  1541. params() const noexcept;
  1542. BOOST_URL_DECL
  1543. params_view
  1544. params(encoding_opts opt) const noexcept;
  1545. /** Return the query as a container of parameters
  1546. This function returns a bidirectional
  1547. view of key/value pairs over the query.
  1548. The returned view references the same
  1549. underlying character buffer; ownership
  1550. is not transferred.
  1551. Strings returned when iterating the
  1552. range may contain percent escapes.
  1553. @par Example
  1554. @code
  1555. params_encoded_view pv = url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_params();
  1556. @endcode
  1557. @par Complexity
  1558. Constant.
  1559. @par Exception Safety
  1560. Throws nothing.
  1561. @par Specification
  1562. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
  1563. >3.4. Query (rfc3986)</a>
  1564. @par BNF
  1565. @code
  1566. query = *( pchar / "/" / "?" )
  1567. query-param = key [ "=" value ]
  1568. query-params = [ query-param ] *( "&" query-param )
  1569. @endcode
  1570. @par Specification
  1571. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
  1572. >3.4. Query (rfc3986)</a>
  1573. @li <a href="https://en.wikipedia.org/wiki/Query_string"
  1574. >Query string (Wikipedia)</a>
  1575. @see
  1576. @ref encoded_query,
  1577. @ref has_query,
  1578. @ref params,
  1579. @ref query.
  1580. */
  1581. BOOST_URL_DECL
  1582. params_encoded_view
  1583. encoded_params() const noexcept;
  1584. //--------------------------------------------
  1585. //
  1586. // Fragment
  1587. //
  1588. //--------------------------------------------
  1589. /** Return true if a fragment is present
  1590. This function returns true if the url
  1591. contains a fragment.
  1592. An empty fragment is distinct from
  1593. no fragment.
  1594. @par Example
  1595. @code
  1596. assert( url_view( "http://www.example.com/index.htm#anchor" ).has_fragment() );
  1597. @endcode
  1598. @par Complexity
  1599. Constant.
  1600. @par Exception Safety
  1601. Throws nothing.
  1602. @par BNF
  1603. @code
  1604. URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
  1605. relative-ref = relative-part [ "?" query ] [ "#" fragment ]
  1606. @endcode
  1607. @par Specification
  1608. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
  1609. >3.5. Fragment (rfc3986)</a>
  1610. @see
  1611. @ref encoded_fragment,
  1612. @ref fragment.
  1613. */
  1614. BOOST_URL_DECL
  1615. bool
  1616. has_fragment() const noexcept;
  1617. /** Return the fragment
  1618. This function calculates the fragment
  1619. of the url, with percent escapes decoded
  1620. and without the leading pound sign ('#')
  1621. whose presence indicates that the url
  1622. contains a fragment.
  1623. <br>
  1624. This function accepts an optional
  1625. <em>StringToken</em> parameter which
  1626. controls the return type and behavior
  1627. of the function:
  1628. @li When called with no arguments,
  1629. the return type of the function is
  1630. `std::string`. Otherwise
  1631. @li When called with a string token,
  1632. the behavior and return type of the
  1633. function depends on the type of string
  1634. token being passed.
  1635. @par Example
  1636. @code
  1637. assert( url_view( "http://www.example.com/index.htm#a%2D1" ).fragment() == "a-1" );
  1638. @endcode
  1639. @par Complexity
  1640. Linear in `this->fragment().size()`.
  1641. @par Exception Safety
  1642. Calls to allocate may throw.
  1643. String tokens may throw exceptions.
  1644. @param token An optional string token to
  1645. use. If this parameter is omitted, the
  1646. function returns a new `std::string`.
  1647. @par BNF
  1648. @code
  1649. fragment = *( pchar / "/" / "?" )
  1650. fragment-part = [ "#" fragment ]
  1651. @endcode
  1652. @par Specification
  1653. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
  1654. >3.5. Fragment (rfc3986)</a>
  1655. @see
  1656. @ref encoded_fragment,
  1657. @ref has_fragment.
  1658. */
  1659. template<BOOST_URL_STRTOK_TPARAM>
  1660. BOOST_URL_STRTOK_RETURN
  1661. fragment(
  1662. BOOST_URL_STRTOK_ARG(token)) const
  1663. {
  1664. encoding_opts opt;
  1665. opt.space_as_plus = false;
  1666. return encoded_fragment().decode(
  1667. opt, std::move(token));
  1668. }
  1669. /** Return the fragment
  1670. This function returns the fragment as a
  1671. string with percent-escapes.
  1672. Ownership is not transferred; the
  1673. string returned references the underlying
  1674. character buffer, which must remain valid
  1675. or else undefined behavior occurs.
  1676. @par Example
  1677. @code
  1678. assert( url_view( "http://www.example.com/index.htm#a%2D1" ).encoded_fragment() == "a%2D1" );
  1679. @endcode
  1680. @par Complexity
  1681. Constant.
  1682. @par Exception Safety
  1683. Throws nothing.
  1684. @par BNF
  1685. @code
  1686. fragment = *( pchar / "/" / "?" )
  1687. pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
  1688. @endcode
  1689. @par Specification
  1690. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
  1691. >3.5. Fragment (rfc3986)</a>
  1692. @see
  1693. @ref fragment,
  1694. @ref has_fragment.
  1695. */
  1696. BOOST_URL_DECL
  1697. pct_string_view
  1698. encoded_fragment() const noexcept;
  1699. //--------------------------------------------
  1700. //
  1701. // Compound Fields
  1702. //
  1703. //--------------------------------------------
  1704. /** Return the host and port
  1705. If an authority is present, this
  1706. function returns the host and optional
  1707. port as a string, which may be empty.
  1708. Otherwise it returns an empty string.
  1709. The returned string may contain
  1710. percent escapes.
  1711. @par Example
  1712. @code
  1713. assert( url_view( "http://www.example.com:8080/index.htm" ).encoded_host_and_port() == "www.example.com:8080" );
  1714. @endcode
  1715. @par Complexity
  1716. Constant.
  1717. @par Exception Safety
  1718. Throws nothing.
  1719. @par BNF
  1720. @code
  1721. authority = [ userinfo "@" ] host [ ":" port ]
  1722. @endcode
  1723. @par Specification
  1724. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
  1725. >3.2.2. Host (rfc3986)</a>
  1726. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3"
  1727. >3.2.3. Port (rfc3986)</a>
  1728. @see
  1729. @ref has_port,
  1730. @ref port,
  1731. @ref port_number.
  1732. */
  1733. BOOST_URL_DECL
  1734. pct_string_view
  1735. encoded_host_and_port() const noexcept;
  1736. /** Return the origin
  1737. If an authority is present, this
  1738. function returns the scheme and
  1739. authority portion of the url.
  1740. Otherwise, an empty string is
  1741. returned.
  1742. The returned string may contain
  1743. percent escapes.
  1744. @par Example
  1745. @code
  1746. assert( url_view( "http://www.example.com:8080/index.htm?text=none#h1" ).encoded_origin() == "http://www.example.com:8080" );
  1747. @endcode
  1748. @par Complexity
  1749. Constant.
  1750. @par Exception Safety
  1751. Throws nothing.
  1752. @see
  1753. @ref encoded_resource,
  1754. @ref encoded_target.
  1755. */
  1756. BOOST_URL_DECL
  1757. pct_string_view
  1758. encoded_origin() const noexcept;
  1759. /** Return the resource
  1760. This function returns the resource, which
  1761. is the portion of the url that includes
  1762. only the path, query, and fragment.
  1763. The returned string may contain
  1764. percent escapes.
  1765. @par Example
  1766. @code
  1767. assert( url_view( "http://www.example.com/index.html?query#frag" ).encoded_resource() == "/index.html?query#frag" );
  1768. @endcode
  1769. @par Complexity
  1770. Constant.
  1771. @par Exception Safety
  1772. Throws nothing.
  1773. @par Specification
  1774. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
  1775. >3.3. Path (rfc3986)</a>
  1776. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
  1777. >3.4. Query (rfc3986)</a>
  1778. @see
  1779. @ref encoded_origin,
  1780. @ref encoded_target.
  1781. */
  1782. BOOST_URL_DECL
  1783. pct_string_view
  1784. encoded_resource() const noexcept;
  1785. /** Return the target
  1786. This function returns the target, which
  1787. is the portion of the url that includes
  1788. only the path and query.
  1789. The returned string may contain
  1790. percent escapes.
  1791. @par Example
  1792. @code
  1793. assert( url_view( "http://www.example.com/index.html?query#frag" ).encoded_target() == "/index.html?query" );
  1794. @endcode
  1795. @par Complexity
  1796. Constant.
  1797. @par Exception Safety
  1798. Throws nothing.
  1799. @par Specification
  1800. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
  1801. >3.3. Path (rfc3986)</a>
  1802. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
  1803. >3.4. Query (rfc3986)</a>
  1804. @see
  1805. @ref encoded_origin,
  1806. @ref encoded_resource.
  1807. */
  1808. BOOST_URL_DECL
  1809. pct_string_view
  1810. encoded_target() const noexcept;
  1811. //--------------------------------------------
  1812. //
  1813. // Comparison
  1814. //
  1815. //--------------------------------------------
  1816. /** Return the result of comparing this with another url
  1817. This function compares two URLs
  1818. according to Syntax-Based comparison
  1819. algorithm.
  1820. @par Complexity
  1821. Linear in `min( u0.size(), u1.size() )`
  1822. @par Exception Safety
  1823. Throws nothing.
  1824. @par Specification
  1825. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
  1826. >6.2.2 Syntax-Based Normalization (rfc3986)</a>
  1827. @return -1 if `*this < other`, 0 if
  1828. `this == other`, and 1 if `this > other`.
  1829. */
  1830. BOOST_URL_DECL
  1831. int
  1832. compare(url_view_base const& other) const noexcept;
  1833. /** Return the result of comparing two URLs
  1834. The URLs are compared component by
  1835. component as if they were first
  1836. normalized.
  1837. @par Example
  1838. @code
  1839. url_view u0( "http://www.a.com/index.htm" );
  1840. url_view u1( "http://www.a.com/index.htm" );
  1841. assert( u0 == u1 );
  1842. @endcode
  1843. @par Effects
  1844. @code
  1845. url a(u0);
  1846. a.normalize();
  1847. url b(u1);
  1848. b.normalize();
  1849. return std::make_tuple(
  1850. a.scheme(),
  1851. a.user(),
  1852. a.password(),
  1853. a.host(),
  1854. a.port(),
  1855. a.path(),
  1856. a.query(),
  1857. a.fragment()) ==
  1858. std::make_tuple(
  1859. b.scheme(),
  1860. b.user(),
  1861. b.password(),
  1862. b.host(),
  1863. b.port(),
  1864. b.path(),
  1865. b.query(),
  1866. b.fragment());
  1867. @endcode
  1868. @par Complexity
  1869. Linear in `min( u0.size(), u1.size() )`
  1870. @par Exception Safety
  1871. Throws nothing
  1872. @return `true` if `u0 == u1`
  1873. @par Specification
  1874. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
  1875. >6.2.2 Syntax-Based Normalization (rfc3986)</a>
  1876. */
  1877. friend
  1878. bool
  1879. operator==(
  1880. url_view_base const& u0,
  1881. url_view_base const& u1) noexcept
  1882. {
  1883. return u0.compare(u1) == 0;
  1884. }
  1885. /** Return the result of comparing two URLs
  1886. The URLs are compared component by
  1887. component as if they were first
  1888. normalized.
  1889. @par Example
  1890. @code
  1891. url_view u0( "http://www.a.com/index.htm" );
  1892. url_view u1( "http://www.b.com/index.htm" );
  1893. assert( u0 != u1 );
  1894. @endcode
  1895. @par Effects
  1896. @code
  1897. url a(u0);
  1898. a.normalize();
  1899. url b(u1);
  1900. b.normalize();
  1901. return std::make_tuple(
  1902. a.scheme(),
  1903. a.user(),
  1904. a.password(),
  1905. a.host(),
  1906. a.port(),
  1907. a.path(),
  1908. a.query(),
  1909. a.fragment()) !=
  1910. std::make_tuple(
  1911. b.scheme(),
  1912. b.user(),
  1913. b.password(),
  1914. b.host(),
  1915. b.port(),
  1916. b.path(),
  1917. b.query(),
  1918. b.fragment());
  1919. @endcode
  1920. @par Complexity
  1921. Linear in `min( u0.size(), u1.size() )`
  1922. @par Exception Safety
  1923. Throws nothing
  1924. @return `true` if `u0 != u1`
  1925. @par Specification
  1926. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
  1927. >6.2.2 Syntax-Based Normalization (rfc3986)</a>
  1928. */
  1929. friend
  1930. bool
  1931. operator!=(
  1932. url_view_base const& u0,
  1933. url_view_base const& u1) noexcept
  1934. {
  1935. return ! (u0 == u1);
  1936. }
  1937. /** Return the result of comparing two URLs
  1938. The URLs are compared component by
  1939. component as if they were first
  1940. normalized.
  1941. @par Example
  1942. @code
  1943. url_view u0( "http://www.a.com/index.htm" );
  1944. url_view u1( "http://www.b.com/index.htm" );
  1945. assert( u0 < u1 );
  1946. @endcode
  1947. @par Effects
  1948. @code
  1949. url a(u0);
  1950. a.normalize();
  1951. url b(u1);
  1952. b.normalize();
  1953. return std::make_tuple(
  1954. a.scheme(),
  1955. a.user(),
  1956. a.password(),
  1957. a.host(),
  1958. a.port(),
  1959. a.path(),
  1960. a.query(),
  1961. a.fragment()) <
  1962. std::make_tuple(
  1963. b.scheme(),
  1964. b.user(),
  1965. b.password(),
  1966. b.host(),
  1967. b.port(),
  1968. b.path(),
  1969. b.query(),
  1970. b.fragment());
  1971. @endcode
  1972. @par Complexity
  1973. Linear in `min( u0.size(), u1.size() )`
  1974. @par Exception Safety
  1975. Throws nothing
  1976. @return `true` if `u0 < u1`
  1977. @par Specification
  1978. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
  1979. >6.2.2 Syntax-Based Normalization (rfc3986)</a>
  1980. */
  1981. friend
  1982. bool
  1983. operator<(
  1984. url_view_base const& u0,
  1985. url_view_base const& u1) noexcept
  1986. {
  1987. return u0.compare(u1) < 0;
  1988. }
  1989. /** Return the result of comparing two URLs
  1990. The URLs are compared component by
  1991. component as if they were first
  1992. normalized.
  1993. @par Example
  1994. @code
  1995. url_view u0( "http://www.b.com/index.htm" );
  1996. url_view u1( "http://www.b.com/index.htm" );
  1997. assert( u0 <= u1 );
  1998. @endcode
  1999. @par Effects
  2000. @code
  2001. url a(u0);
  2002. a.normalize();
  2003. url b(u1);
  2004. b.normalize();
  2005. return std::make_tuple(
  2006. a.scheme(),
  2007. a.user(),
  2008. a.password(),
  2009. a.host(),
  2010. a.port(),
  2011. a.path(),
  2012. a.query(),
  2013. a.fragment()) <=
  2014. std::make_tuple(
  2015. b.scheme(),
  2016. b.user(),
  2017. b.password(),
  2018. b.host(),
  2019. b.port(),
  2020. b.path(),
  2021. b.query(),
  2022. b.fragment());
  2023. @endcode
  2024. @par Complexity
  2025. Linear in `min( u0.size(), u1.size() )`
  2026. @par Exception Safety
  2027. Throws nothing
  2028. @return `true` if `u0 <= u1`
  2029. @par Specification
  2030. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
  2031. >6.2.2 Syntax-Based Normalization (rfc3986)</a>
  2032. */
  2033. friend
  2034. bool
  2035. operator<=(
  2036. url_view_base const& u0,
  2037. url_view_base const& u1) noexcept
  2038. {
  2039. return u0.compare(u1) <= 0;
  2040. }
  2041. /** Return the result of comparing two URLs
  2042. The URLs are compared component by
  2043. component as if they were first
  2044. normalized.
  2045. @par Example
  2046. @code
  2047. url_view u0( "http://www.b.com/index.htm" );
  2048. url_view u1( "http://www.a.com/index.htm" );
  2049. assert( u0 > u1 );
  2050. @endcode
  2051. @par Effects
  2052. @code
  2053. url a(u0);
  2054. a.normalize();
  2055. url b(u1);
  2056. b.normalize();
  2057. return std::make_tuple(
  2058. a.scheme(),
  2059. a.user(),
  2060. a.password(),
  2061. a.host(),
  2062. a.port(),
  2063. a.path(),
  2064. a.query(),
  2065. a.fragment()) >
  2066. std::make_tuple(
  2067. b.scheme(),
  2068. b.user(),
  2069. b.password(),
  2070. b.host(),
  2071. b.port(),
  2072. b.path(),
  2073. b.query(),
  2074. b.fragment());
  2075. @endcode
  2076. @par Complexity
  2077. Linear in `min( u0.size(), u1.size() )`
  2078. @par Exception Safety
  2079. Throws nothing
  2080. @return `true` if `u0 > u1`
  2081. @par Specification
  2082. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
  2083. >6.2.2 Syntax-Based Normalization (rfc3986)</a>
  2084. */
  2085. friend
  2086. bool
  2087. operator>(
  2088. url_view_base const& u0,
  2089. url_view_base const& u1) noexcept
  2090. {
  2091. return u0.compare(u1) > 0;
  2092. }
  2093. /** Return the result of comparing two URLs
  2094. The URLs are compared component by
  2095. component as if they were first
  2096. normalized.
  2097. @par Example
  2098. @code
  2099. url_view u0( "http://www.a.com/index.htm" );
  2100. url_view u1( "http://www.a.com/index.htm" );
  2101. assert( u0 >= u1 );
  2102. @endcode
  2103. @par Effects
  2104. @code
  2105. url a(u0);
  2106. a.normalize();
  2107. url b(u1);
  2108. b.normalize();
  2109. return std::make_tuple(
  2110. a.scheme(),
  2111. a.user(),
  2112. a.password(),
  2113. a.host(),
  2114. a.port(),
  2115. a.path(),
  2116. a.query(),
  2117. a.fragment()) >=
  2118. std::make_tuple(
  2119. b.scheme(),
  2120. b.user(),
  2121. b.password(),
  2122. b.host(),
  2123. b.port(),
  2124. b.path(),
  2125. b.query(),
  2126. b.fragment());
  2127. @endcode
  2128. @par Complexity
  2129. Linear in `min( u0.size(), u1.size() )`
  2130. @par Exception Safety
  2131. Throws nothing
  2132. @return `true` if `u0 >= u1`
  2133. @par Specification
  2134. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
  2135. >6.2.2 Syntax-Based Normalization (rfc3986)</a>
  2136. */
  2137. friend
  2138. bool
  2139. operator>=(
  2140. url_view_base const& u0,
  2141. url_view_base const& u1) noexcept
  2142. {
  2143. return u0.compare(u1) >= 0;
  2144. }
  2145. friend
  2146. std::ostream&
  2147. operator<<(
  2148. std::ostream& os,
  2149. url_view_base const& u)
  2150. {
  2151. return os << u.buffer();
  2152. }
  2153. private:
  2154. //--------------------------------------------
  2155. //
  2156. // implementation
  2157. //
  2158. //--------------------------------------------
  2159. BOOST_URL_DECL
  2160. static
  2161. int
  2162. segments_compare(
  2163. segments_encoded_view seg0,
  2164. segments_encoded_view seg1) noexcept;
  2165. };
  2166. //------------------------------------------------
  2167. /** Format the url to the output stream
  2168. This function serializes the url to
  2169. the specified output stream. Any
  2170. percent-escapes are emitted as-is;
  2171. no decoding is performed.
  2172. @par Example
  2173. @code
  2174. url_view u( "http://www.example.com/index.htm" );
  2175. std::stringstream ss;
  2176. ss << u;
  2177. assert( ss.str() == "http://www.example.com/index.htm" );
  2178. @endcode
  2179. @par Effects
  2180. @code
  2181. return os << u.buffer();
  2182. @endcode
  2183. @par Complexity
  2184. Linear in `u.buffer().size()`
  2185. @par Exception Safety
  2186. Basic guarantee.
  2187. @return A reference to the output stream, for chaining
  2188. @param os The output stream to write to.
  2189. @param u The url to write.
  2190. */
  2191. std::ostream&
  2192. operator<<(
  2193. std::ostream& os,
  2194. url_view_base const& u);
  2195. } // urls
  2196. } // boost
  2197. #endif