url_view_base.hpp 73 KB

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