url_base.hpp 85 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088
  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_BASE_HPP
  11. #define BOOST_URL_URL_BASE_HPP
  12. #include <boost/url/detail/config.hpp>
  13. #include <boost/url/ipv4_address.hpp>
  14. #include <boost/url/ipv6_address.hpp>
  15. #include <boost/url/params_encoded_ref.hpp>
  16. #include <boost/url/params_ref.hpp>
  17. #include <boost/url/pct_string_view.hpp>
  18. #include <boost/url/scheme.hpp>
  19. #include <boost/url/segments_encoded_ref.hpp>
  20. #include <boost/url/segments_ref.hpp>
  21. #include <boost/url/url_view_base.hpp>
  22. #include <cstdint>
  23. #include <initializer_list>
  24. #include <memory>
  25. #include <string>
  26. #include <utility>
  27. namespace boost {
  28. namespace urls {
  29. namespace detail {
  30. struct any_params_iter;
  31. struct any_segments_iter;
  32. struct params_iter_impl;
  33. struct segments_iter_impl;
  34. struct pattern;
  35. }
  36. /** Common functionality for containers
  37. This base class is used by the library
  38. to provide common member functions for
  39. containers. This cannot be instantiated
  40. directly; Instead, use one of the
  41. containers or functions:
  42. @par Containers
  43. @li @ref url
  44. @li @ref url_view
  45. @li @ref static_url
  46. @par Functions
  47. @li @ref parse_absolute_uri
  48. @li @ref parse_origin_form
  49. @li @ref parse_relative_ref
  50. @li @ref parse_uri
  51. @li @ref parse_uri_reference
  52. */
  53. class BOOST_URL_DECL
  54. url_base
  55. : public url_view_base
  56. {
  57. char* s_ = nullptr;
  58. std::size_t cap_ = 0;
  59. friend class url;
  60. friend class static_url_base;
  61. friend class params_ref;
  62. friend class segments_ref;
  63. friend class segments_encoded_ref;
  64. friend class params_encoded_ref;
  65. friend struct detail::pattern;
  66. struct op_t
  67. {
  68. ~op_t();
  69. op_t(url_base&,
  70. core::string_view* = nullptr,
  71. core::string_view* = nullptr) noexcept;
  72. void move(char*, char const*,
  73. std::size_t) noexcept;
  74. url_base& u;
  75. core::string_view* s0 = nullptr;
  76. core::string_view* s1 = nullptr;
  77. char* old = nullptr;
  78. };
  79. virtual ~url_base() noexcept = default;
  80. url_base() noexcept = default;
  81. url_base(detail::url_impl const&) noexcept;
  82. explicit url_base(core::string_view);
  83. void reserve_impl(std::size_t n);
  84. void copy(url_view_base const&);
  85. virtual void clear_impl() noexcept = 0;
  86. virtual void reserve_impl(
  87. std::size_t, op_t&) = 0;
  88. virtual void cleanup(op_t&) = 0;
  89. public:
  90. //--------------------------------------------
  91. //
  92. // Observers
  93. //
  94. //--------------------------------------------
  95. /** Return the url as a null-terminated string
  96. This function returns a pointer to a null
  97. terminated string representing the url,
  98. which may contain percent escapes.
  99. @return A pointer to a null-terminated string containing the URL.
  100. @par Example
  101. @code
  102. assert( std::strlen( url( "http://www.example.com" ).c_str() ) == 22 );
  103. @endcode
  104. @par Complexity
  105. Constant.
  106. @par Exception Safety
  107. Throws nothing.
  108. */
  109. char const*
  110. c_str() const noexcept
  111. {
  112. return pi_->cs_;
  113. }
  114. /** Return the number of characters that can be stored without reallocating
  115. This does not include the null terminator,
  116. which is always present.
  117. @return `*this`
  118. @par Complexity
  119. Constant.
  120. @par Exception Safety
  121. Throws nothing.
  122. */
  123. std::size_t
  124. capacity() const noexcept
  125. {
  126. return cap_;
  127. }
  128. /** Clear the contents while preserving the capacity
  129. @par Postconditions
  130. @code
  131. this->empty() == true
  132. @endcode
  133. @par Complexity
  134. Constant.
  135. @par Exception Safety
  136. No-throw guarantee.
  137. */
  138. void
  139. clear() noexcept
  140. {
  141. this->clear_impl();
  142. }
  143. /** Adjust the capacity without changing the size
  144. This function adjusts the capacity
  145. of the container in characters, without
  146. affecting the current contents. Has
  147. no effect if `n <= this->capacity()`.
  148. @par Exception Safety
  149. Strong guarantee.
  150. Calls to allocate may throw.
  151. @throw bad_alloc Allocation failure
  152. @param n The capacity in characters,
  153. excluding any null terminator.
  154. */
  155. void
  156. reserve(std::size_t n)
  157. {
  158. reserve_impl(n);
  159. }
  160. //--------------------------------------------
  161. //
  162. // Fluent API
  163. //
  164. //--------------------------------------------
  165. //
  166. // Scheme
  167. //
  168. //--------------------------------------------
  169. /** Set the scheme
  170. The scheme is set to the specified
  171. string, which must contain a valid
  172. scheme without any trailing colon
  173. (':').
  174. Note that schemes are case-insensitive,
  175. and the canonical form is lowercased.
  176. @par Example
  177. @code
  178. assert( url( "http://www.example.com" ).set_scheme( "https" ).scheme_id() == scheme::https );
  179. @endcode
  180. @par Complexity
  181. Linear in `this->size() + s.size()`.
  182. @par Exception Safety
  183. Strong guarantee.
  184. Calls to allocate may throw.
  185. Exceptions thrown on invalid input.
  186. @throw system_error
  187. `s` contains an invalid scheme.
  188. @param s The scheme to set.
  189. @return `*this`
  190. @par BNF
  191. @code
  192. scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
  193. @endcode
  194. @par Specification
  195. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">
  196. 3.1. Scheme (rfc3986)</a>
  197. @see
  198. @ref remove_scheme.
  199. */
  200. url_base&
  201. set_scheme(core::string_view s);
  202. /** Set the scheme
  203. This function sets the scheme to the specified
  204. known @ref urls::scheme id, which may not be
  205. @ref scheme::unknown or else an exception is
  206. thrown. If the id is @ref scheme::none, this
  207. function behaves as if @ref remove_scheme
  208. were called.
  209. @par Example
  210. @code
  211. assert( url( "http://example.com/echo.cgi" ).set_scheme_id( scheme::wss ).buffer() == "wss://example.com/echo.cgi" );
  212. @endcode
  213. @par Complexity
  214. Linear in `this->size()`.
  215. @par Exception Safety
  216. Strong guarantee.
  217. Calls to allocate may throw.
  218. Exceptions thrown on invalid input.
  219. @throw system_error
  220. The scheme is invalid.
  221. @param id The scheme to set.
  222. @return `*this`
  223. @par Specification
  224. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">
  225. 3.1. Scheme (rfc3986)</a>
  226. */
  227. url_base&
  228. set_scheme_id(urls::scheme id);
  229. /** Remove the scheme
  230. This function removes the scheme if it
  231. is present.
  232. @par Example
  233. @code
  234. assert( url("http://www.example.com/index.htm" ).remove_scheme().buffer() == "//www.example.com/index.htm" );
  235. @endcode
  236. @par Postconditions
  237. @code
  238. this->has_scheme() == false && this->scheme_id() == scheme::none
  239. @endcode
  240. @par Complexity
  241. Linear in `this->size()`.
  242. @par Exception Safety
  243. Throws nothing.
  244. @return `*this`
  245. @par BNF
  246. @code
  247. URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
  248. @endcode
  249. @par Specification
  250. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">
  251. 3.1. Scheme (rfc3986)</a>
  252. @see
  253. @ref set_scheme.
  254. */
  255. url_base&
  256. remove_scheme();
  257. //--------------------------------------------
  258. //
  259. // Authority
  260. //
  261. //--------------------------------------------
  262. /** Set the authority
  263. This function sets the authority
  264. to the specified string.
  265. The string may contain percent-escapes.
  266. @par Example
  267. @code
  268. assert( url().set_encoded_authority( "My%20Computer" ).has_authority() );
  269. @endcode
  270. @par Exception Safety
  271. Strong guarantee.
  272. Calls to allocate may throw.
  273. Exceptions thrown on invalid input.
  274. @throw system_eror
  275. The string contains an invalid percent-encoding.
  276. @param s The authority string to set.
  277. @return `*this`
  278. @par BNF
  279. @code
  280. authority = [ userinfo "@" ] host [ ":" port ]
  281. userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
  282. host = IP-literal / IPv4address / reg-name
  283. port = *DIGIT
  284. @endcode
  285. @par Specification
  286. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">
  287. 3.2. Authority (rfc3986)</a>
  288. @see
  289. @ref remove_authority.
  290. */
  291. url_base&
  292. set_encoded_authority(
  293. pct_string_view s);
  294. /** Remove the authority
  295. This function removes the authority,
  296. which includes the userinfo, host, and
  297. a port if present.
  298. @par Example
  299. @code
  300. assert( url( "http://example.com/echo.cgi" ).remove_authority().buffer() == "http:/echo.cgi" );
  301. @endcode
  302. @par Postconditions
  303. @code
  304. this->has_authority() == false && this->has_userinfo() == false && this->has_port() == false
  305. @endcode
  306. @par Complexity
  307. Linear in `this->size()`.
  308. @par Exception Safety
  309. Throws nothing.
  310. @return `*this`
  311. @par BNF
  312. @code
  313. authority = [ userinfo "@" ] host [ ":" port ]
  314. userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
  315. host = IP-literal / IPv4address / reg-name
  316. port = *DIGIT
  317. @endcode
  318. @par Specification
  319. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">
  320. 3.2. Authority (rfc3986)</a>
  321. @see
  322. @ref set_encoded_authority.
  323. */
  324. url_base&
  325. remove_authority();
  326. //--------------------------------------------
  327. //
  328. // Userinfo
  329. //
  330. //--------------------------------------------
  331. /** Set the userinfo
  332. The userinfo is set to the given string,
  333. which may contain percent-escapes.
  334. Any special or reserved characters in the
  335. string are automatically percent-encoded.
  336. The effects on the user and password
  337. depend on the presence of a colon (':')
  338. in the string:
  339. @li If an unescaped colon exists, the
  340. characters up to the colon become
  341. the user and the rest of the characters
  342. after the colon become the password.
  343. In this case @ref has_password returns
  344. true. Otherwise,
  345. @li If there is no colon, the user is
  346. set to the string. The function
  347. @ref has_password returns false.
  348. @note
  349. The interpretation of the userinfo as
  350. individual user and password components
  351. is scheme-dependent. Transmitting
  352. passwords in URLs is deprecated.
  353. @par Example
  354. @code
  355. assert( url( "http://example.com" ).set_userinfo( "user:pass" ).encoded_user() == "user" );
  356. @endcode
  357. @par Complexity
  358. Linear in `this->size() + s.size()`.
  359. @par Exception Safety
  360. Strong guarantee.
  361. Calls to allocate may throw.
  362. @param s The string to set.
  363. @return `*this`
  364. @par BNF
  365. @code
  366. userinfo = [ [ user ] [ ':' password ] ]
  367. user = *( unreserved / pct-encoded / sub-delims )
  368. password = *( unreserved / pct-encoded / sub-delims / ":" )
  369. @endcode
  370. @par Specification
  371. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
  372. 3.2.1. User Information (rfc3986)</a>
  373. @see
  374. @ref remove_userinfo,
  375. @ref set_encoded_userinfo.
  376. */
  377. url_base&
  378. set_userinfo(
  379. core::string_view s);
  380. /** Set the userinfo.
  381. The userinfo is set to the given string,
  382. which may contain percent-escapes.
  383. Escapes in the string are preserved,
  384. and reserved characters in the string
  385. are percent-escaped in the result.
  386. The effects on the user and password
  387. depend on the presence of a colon (':')
  388. in the string:
  389. @li If an unescaped colon exists, the
  390. characters up to the colon become
  391. the user and the rest of the characters
  392. after the colon become the password.
  393. In this case @ref has_password returns
  394. true. Otherwise,
  395. @li If there is no colon, the user is
  396. set to the string. The function
  397. @ref has_password returns false.
  398. @note
  399. The interpretation of the userinfo as
  400. individual user and password components
  401. is scheme-dependent. Transmitting
  402. passwords in URLs is deprecated.
  403. @par Example
  404. @code
  405. assert( url( "http://example.com" ).set_encoded_userinfo( "john%20doe" ).user() == "john doe" );
  406. @endcode
  407. @par Complexity
  408. Linear in `this->size() + s.size()`.
  409. @par Exception Safety
  410. Strong guarantee.
  411. Calls to allocate may throw.
  412. Exceptions thrown on invalid input.
  413. @throw system_error
  414. `s` contains an invalid percent-encoding.
  415. @param s The string to set.
  416. @return `*this`
  417. @par BNF
  418. @code
  419. userinfo = [ [ user ] [ ':' password ] ]
  420. user = *( unreserved / pct-encoded / sub-delims )
  421. password = *( unreserved / pct-encoded / sub-delims / ":" )
  422. @endcode
  423. @par Specification
  424. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
  425. 3.2.1. User Information (rfc3986)</a>
  426. @see
  427. @ref remove_userinfo,
  428. @ref set_userinfo.
  429. */
  430. url_base&
  431. set_encoded_userinfo(
  432. pct_string_view s);
  433. /** Remove the userinfo
  434. This function removes the userinfo if
  435. present, without removing any authority.
  436. @par Example
  437. @code
  438. assert( url( "http://user@example.com" ).remove_userinfo().has_userinfo() == false );
  439. @endcode
  440. @par Postconditions
  441. @code
  442. this->has_userinfo() == false && this->encoded_userinfo().empty == true
  443. @endcode
  444. @par Complexity
  445. Linear in `this->size()`.
  446. @par Exception Safety
  447. Throws nothing.
  448. @return `*this`
  449. @par BNF
  450. @code
  451. userinfo = [ [ user ] [ ':' password ] ]
  452. user = *( unreserved / pct-encoded / sub-delims )
  453. password = *( unreserved / pct-encoded / sub-delims / ":" )
  454. @endcode
  455. @par Specification
  456. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
  457. 3.2.1. User Information (rfc3986)</a>
  458. @see
  459. @ref set_encoded_userinfo,
  460. @ref set_userinfo.
  461. */
  462. url_base&
  463. remove_userinfo() noexcept;
  464. //--------------------------------------------
  465. /** Set the user
  466. This function sets the user part of the
  467. userinfo to the string.
  468. Any special or reserved characters in the
  469. string are automatically percent-encoded.
  470. @par Example
  471. @code
  472. assert( url().set_user("john doe").encoded_userinfo() == "john%20doe" );
  473. @endcode
  474. @par Postconditions
  475. @code
  476. this->has_authority() == true && this->has_userinfo() == true
  477. @endcode
  478. @par Complexity
  479. Linear in `this->size() + s.size()`.
  480. @par Exception Safety
  481. Strong guarantee.
  482. Calls to allocate may throw.
  483. @param s The string to set.
  484. @return `*this`
  485. @par BNF
  486. @code
  487. userinfo = [ [ user ] [ ':' password ] ]
  488. user = *( unreserved / pct-encoded / sub-delims )
  489. password = *( unreserved / pct-encoded / sub-delims / ":" )
  490. @endcode
  491. @par Specification
  492. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
  493. 3.2.1. User Information (rfc3986)</a>
  494. @see
  495. @ref remove_password,
  496. @ref set_encoded_password,
  497. @ref set_encoded_user,
  498. @ref set_password.
  499. */
  500. url_base&
  501. set_user(
  502. core::string_view s);
  503. /** Set the user
  504. This function sets the user part of the
  505. userinfo the the string, which may
  506. contain percent-escapes.
  507. Escapes in the string are preserved,
  508. and reserved characters in the string
  509. are percent-escaped in the result.
  510. @par Example
  511. @code
  512. assert( url().set_encoded_user("john%20doe").userinfo() == "john doe" );
  513. @endcode
  514. @par Postconditions
  515. @code
  516. this->has_authority() == true && this->has_userinfo() == true
  517. @endcode
  518. @par Complexity
  519. Linear in `this->size() + s.size()`.
  520. @par Exception Safety
  521. Strong guarantee.
  522. Calls to allocate may throw.
  523. @throw system_error
  524. `s` contains an invalid percent-encoding.
  525. @param s The string to set.
  526. @return `*this`
  527. @return `*this`
  528. @par BNF
  529. @code
  530. userinfo = [ [ user ] [ ':' password ] ]
  531. user = *( unreserved / pct-encoded / sub-delims )
  532. password = *( unreserved / pct-encoded / sub-delims / ":" )
  533. @endcode
  534. @par Specification
  535. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
  536. 3.2.1. User Information (rfc3986)</a>
  537. @see
  538. @ref remove_password,
  539. @ref set_encoded_password,
  540. @ref set_password,
  541. @ref set_user.
  542. */
  543. url_base&
  544. set_encoded_user(
  545. pct_string_view s);
  546. /** Set the password.
  547. This function sets the password in
  548. the userinfo to the string.
  549. Reserved characters in the string are
  550. percent-escaped in the result.
  551. @note
  552. The interpretation of the userinfo as
  553. individual user and password components
  554. is scheme-dependent. Transmitting
  555. passwords in URLs is deprecated.
  556. @par Example
  557. @code
  558. assert( url("http://user@example.com").set_password( "pass" ).encoded_userinfo() == "user:pass" );
  559. @endcode
  560. @par Postconditions
  561. @code
  562. this->has_password() == true && this->password() == s
  563. @endcode
  564. @par Exception Safety
  565. Strong guarantee.
  566. Calls to allocate may throw.
  567. @param s The string to set. This string may
  568. contain any characters, including nulls.
  569. @return `*this`
  570. @par BNF
  571. @code
  572. userinfo = [ [ user ] [ ':' password ] ]
  573. user = *( unreserved / pct-encoded / sub-delims )
  574. password = *( unreserved / pct-encoded / sub-delims / ":" )
  575. @endcode
  576. @par Specification
  577. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
  578. 3.2.1. User Information (rfc3986)</a>
  579. @see
  580. @ref remove_password,
  581. @ref set_encoded_password,
  582. @ref set_encoded_user,
  583. @ref set_user.
  584. */
  585. url_base&
  586. set_password(
  587. core::string_view s);
  588. /** Set the password.
  589. This function sets the password in
  590. the userinfo to the string, which
  591. may contain percent-escapes.
  592. Escapes in the string are preserved,
  593. and reserved characters in the string
  594. are percent-escaped in the result.
  595. @note
  596. The interpretation of the userinfo as
  597. individual user and password components
  598. is scheme-dependent. Transmitting
  599. passwords in URLs is deprecated.
  600. @par Example
  601. @code
  602. assert( url("http://user@example.com").set_encoded_password( "pass" ).encoded_userinfo() == "user:pass" );
  603. @endcode
  604. @par Postconditions
  605. @code
  606. this->has_password() == true
  607. @endcode
  608. @par Exception Safety
  609. Strong guarantee.
  610. Calls to allocate may throw.
  611. @throw system_error
  612. `s` contains an invalid percent-encoding.
  613. @param s The string to set. This string may
  614. contain any characters, including nulls.
  615. @return `*this`
  616. @par BNF
  617. @code
  618. userinfo = [ [ user ] [ ':' password ] ]
  619. user = *( unreserved / pct-encoded / sub-delims )
  620. password = *( unreserved / pct-encoded / sub-delims / ":" )
  621. @endcode
  622. @par Specification
  623. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
  624. 3.2.1. User Information (rfc3986)</a>
  625. @see
  626. @ref remove_password,
  627. @ref set_encoded_password,
  628. @ref set_encoded_user,
  629. @ref set_user.
  630. */
  631. url_base&
  632. set_encoded_password(
  633. pct_string_view s);
  634. /** Remove the password
  635. This function removes the password from
  636. the userinfo if a password exists. If
  637. there is no userinfo or no authority,
  638. the call has no effect.
  639. @note
  640. The interpretation of the userinfo as
  641. individual user and password components
  642. is scheme-dependent. Transmitting
  643. passwords in URLs is deprecated.
  644. @par Example
  645. @code
  646. assert( url( "http://user:pass@example.com" ).remove_password().authority().buffer() == "user@example.com" );
  647. @endcode
  648. @par Postconditions
  649. @code
  650. this->has_password() == false && this->encoded_password().empty() == true
  651. @endcode
  652. @par Complexity
  653. Linear in `this->size()`.
  654. @par Exception Safety
  655. Throws nothing.
  656. @par BNF
  657. @code
  658. userinfo = [ [ user ] [ ':' password ] ]
  659. user = *( unreserved / pct-encoded / sub-delims )
  660. password = *( unreserved / pct-encoded / sub-delims / ":" )
  661. @endcode
  662. @return `*this`
  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 set_encoded_password,
  668. @ref set_encoded_user,
  669. @ref set_password,
  670. @ref set_user.
  671. */
  672. url_base&
  673. remove_password() noexcept;
  674. //--------------------------------------------
  675. //
  676. // Host
  677. //
  678. //--------------------------------------------
  679. /** Set the host
  680. Depending on the contents of the passed
  681. string, this function sets the host:
  682. @li If the string is a valid IPv4 address,
  683. then the host is set to the address.
  684. The host type is @ref host_type::ipv4.
  685. @li If the string is a valid IPv6 address
  686. enclosed in square brackets, then the
  687. host is set to that address.
  688. The host type is @ref host_type::ipv6.
  689. @li If the string is a valid IPvFuture
  690. address enclosed in square brackets, then
  691. the host is set to that address.
  692. The host type is @ref host_type::ipvfuture.
  693. @li Otherwise, the host name is set to
  694. the string, which may be empty.
  695. Reserved characters in the string are
  696. percent-escaped in the result.
  697. The host type is @ref host_type::name.
  698. In all cases, when this function returns,
  699. the URL contains an authority.
  700. @par Example
  701. @code
  702. assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
  703. @endcode
  704. @par Postconditions
  705. @code
  706. this->has_authority() == true
  707. @endcode
  708. @par Complexity
  709. Linear in `this->size() + s.size()`.
  710. @par Exception Safety
  711. Strong guarantee.
  712. Calls to allocate may throw.
  713. @par BNF
  714. @code
  715. host = IP-literal / IPv4address / reg-name
  716. IP-literal = "[" ( IPv6address / IPvFuture ) "]"
  717. reg-name = *( unreserved / pct-encoded / "-" / ".")
  718. @endcode
  719. @param s The string to set.
  720. @return `*this`
  721. @par Specification
  722. @li <a href="https://en.wikipedia.org/wiki/IPv4"
  723. >IPv4 (Wikipedia)</a>
  724. @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
  725. >IP Version 6 Addressing Architecture (rfc4291)</a>
  726. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
  727. 3.2.2. Host (rfc3986)</a>
  728. @see
  729. @ref set_encoded_host,
  730. @ref set_encoded_host_address,
  731. @ref set_encoded_host_name,
  732. @ref set_host_address,
  733. @ref set_host_ipv4,
  734. @ref set_host_ipv6,
  735. @ref set_host_ipvfuture,
  736. @ref set_host_name.
  737. */
  738. url_base&
  739. set_host(
  740. core::string_view s);
  741. /** Set the host
  742. Depending on the contents of the passed
  743. string, this function sets the host:
  744. @li If the string is a valid IPv4 address,
  745. then the host is set to the address.
  746. The host type is @ref host_type::ipv4.
  747. @li If the string is a valid IPv6 address
  748. enclosed in square brackets, then the
  749. host is set to that address.
  750. The host type is @ref host_type::ipv6.
  751. @li If the string is a valid IPvFuture
  752. address enclosed in square brackets, then
  753. the host is set to that address.
  754. The host type is @ref host_type::ipvfuture.
  755. @li Otherwise, the host name is set to
  756. the string. This string can contain percent
  757. escapes, or can be empty.
  758. Escapes in the string are preserved,
  759. and reserved characters in the string
  760. are percent-escaped in the result.
  761. The host type is @ref host_type::name.
  762. In all cases, when this function returns,
  763. the URL contains an authority.
  764. @par Example
  765. @code
  766. assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
  767. @endcode
  768. @par Postconditions
  769. @code
  770. this->has_authority() == true
  771. @endcode
  772. @par Complexity
  773. Linear in `this->size() + s.size()`.
  774. @par Exception Safety
  775. Strong guarantee.
  776. Calls to allocate may throw.
  777. Exceptions thrown on invalid input.
  778. @throw system_error
  779. `s` contains an invalid percent-encoding.
  780. @param s The string to set.
  781. @return `*this`
  782. @par BNF
  783. @code
  784. host = IP-literal / IPv4address / reg-name
  785. IP-literal = "[" ( IPv6address / IPvFuture ) "]"
  786. reg-name = *( unreserved / pct-encoded / "-" / ".")
  787. @endcode
  788. @par Specification
  789. @li <a href="https://en.wikipedia.org/wiki/IPv4"
  790. >IPv4 (Wikipedia)</a>
  791. @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
  792. >IP Version 6 Addressing Architecture (rfc4291)</a>
  793. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
  794. 3.2.2. Host (rfc3986)</a>
  795. @see
  796. @ref set_encoded_host_address,
  797. @ref set_encoded_host_name,
  798. @ref set_host,
  799. @ref set_host_address,
  800. @ref set_host_ipv4,
  801. @ref set_host_ipv6,
  802. @ref set_host_ipvfuture,
  803. @ref set_host_name.
  804. */
  805. url_base&
  806. set_encoded_host(pct_string_view s);
  807. /** Set the host to an address
  808. Depending on the contents of the passed
  809. string, this function sets the host:
  810. @li If the string is a valid IPv4 address,
  811. then the host is set to the address.
  812. The host type is @ref host_type::ipv4.
  813. @li If the string is a valid IPv6 address,
  814. then the host is set to that address.
  815. The host type is @ref host_type::ipv6.
  816. @li If the string is a valid IPvFuture,
  817. then the host is set to that address.
  818. The host type is @ref host_type::ipvfuture.
  819. @li Otherwise, the host name is set to
  820. the string, which may be empty.
  821. Reserved characters in the string are
  822. percent-escaped in the result.
  823. The host type is @ref host_type::name.
  824. In all cases, when this function returns,
  825. the URL contains an authority.
  826. @par Example
  827. @code
  828. assert( url( "http://www.example.com" ).set_host_address( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
  829. @endcode
  830. @par Postconditions
  831. @code
  832. this->has_authority() == true
  833. @endcode
  834. @par Complexity
  835. Linear in `s.size()`.
  836. @par Exception Safety
  837. Strong guarantee.
  838. Calls to allocate may throw.
  839. @par BNF
  840. @code
  841. IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
  842. dec-octet = DIGIT ; 0-9
  843. / %x31-39 DIGIT ; 10-99
  844. / "1" 2DIGIT ; 100-199
  845. / "2" %x30-34 DIGIT ; 200-249
  846. / "25" %x30-35 ; 250-255
  847. IPv6address = 6( h16 ":" ) ls32
  848. / "::" 5( h16 ":" ) ls32
  849. / [ h16 ] "::" 4( h16 ":" ) ls32
  850. / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
  851. / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
  852. / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
  853. / [ *4( h16 ":" ) h16 ] "::" ls32
  854. / [ *5( h16 ":" ) h16 ] "::" h16
  855. / [ *6( h16 ":" ) h16 ] "::"
  856. ls32 = ( h16 ":" h16 ) / IPv4address
  857. ; least-significant 32 bits of address
  858. h16 = 1*4HEXDIG
  859. ; 16 bits of address represented in hexadecimal
  860. IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
  861. reg-name = *( unreserved / pct-encoded / "-" / ".")
  862. @endcode
  863. @param s The string to set.
  864. @return `*this`
  865. @par Specification
  866. @li <a href="https://en.wikipedia.org/wiki/IPv4"
  867. >IPv4 (Wikipedia)</a>
  868. @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
  869. >IP Version 6 Addressing Architecture (rfc4291)</a>
  870. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
  871. 3.2.2. Host (rfc3986)</a>
  872. @see
  873. @ref set_encoded_host,
  874. @ref set_encoded_host_address,
  875. @ref set_encoded_host_name,
  876. @ref set_host,
  877. @ref set_host_address,
  878. @ref set_host_ipv4,
  879. @ref set_host_ipv6,
  880. @ref set_host_ipvfuture,
  881. @ref set_host_name.
  882. */
  883. url_base&
  884. set_host_address(core::string_view s);
  885. /** Set the host to an address
  886. Depending on the contents of the passed
  887. string, this function sets the host:
  888. @li If the string is a valid IPv4 address,
  889. then the host is set to the address.
  890. The host type is @ref host_type::ipv4.
  891. @li If the string is a valid IPv6 address,
  892. then the host is set to that address.
  893. The host type is @ref host_type::ipv6.
  894. @li If the string is a valid IPvFuture,
  895. then the host is set to that address.
  896. The host type is @ref host_type::ipvfuture.
  897. @li Otherwise, the host name is set to
  898. the string. This string can contain percent
  899. escapes, or can be empty.
  900. Escapes in the string are preserved,
  901. and reserved characters in the string
  902. are percent-escaped in the result.
  903. The host type is @ref host_type::name.
  904. In all cases, when this function returns,
  905. the URL contains an authority.
  906. @par Example
  907. @code
  908. assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
  909. @endcode
  910. @par Postconditions
  911. @code
  912. this->has_authority() == true
  913. @endcode
  914. @par Complexity
  915. Linear in `this->size() + s.size()`.
  916. @par Exception Safety
  917. Strong guarantee.
  918. Calls to allocate may throw.
  919. Exceptions thrown on invalid input.
  920. @throw system_error
  921. `s` contains an invalid percent-encoding.
  922. @par BNF
  923. @code
  924. IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
  925. dec-octet = DIGIT ; 0-9
  926. / %x31-39 DIGIT ; 10-99
  927. / "1" 2DIGIT ; 100-199
  928. / "2" %x30-34 DIGIT ; 200-249
  929. / "25" %x30-35 ; 250-255
  930. IPv6address = 6( h16 ":" ) ls32
  931. / "::" 5( h16 ":" ) ls32
  932. / [ h16 ] "::" 4( h16 ":" ) ls32
  933. / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
  934. / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
  935. / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
  936. / [ *4( h16 ":" ) h16 ] "::" ls32
  937. / [ *5( h16 ":" ) h16 ] "::" h16
  938. / [ *6( h16 ":" ) h16 ] "::"
  939. ls32 = ( h16 ":" h16 ) / IPv4address
  940. ; least-significant 32 bits of address
  941. h16 = 1*4HEXDIG
  942. ; 16 bits of address represented in hexadecimal
  943. IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
  944. reg-name = *( unreserved / pct-encoded / "-" / ".")
  945. @endcode
  946. @param s The string to set.
  947. @return `*this`
  948. @par Specification
  949. @li <a href="https://en.wikipedia.org/wiki/IPv4"
  950. >IPv4 (Wikipedia)</a>
  951. @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
  952. >IP Version 6 Addressing Architecture (rfc4291)</a>
  953. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
  954. 3.2.2. Host (rfc3986)</a>
  955. @see
  956. @ref set_encoded_host,
  957. @ref set_encoded_host_name,
  958. @ref set_host,
  959. @ref set_host_address,
  960. @ref set_host_ipv4,
  961. @ref set_host_ipv6,
  962. @ref set_host_ipvfuture,
  963. @ref set_host_name.
  964. */
  965. url_base&
  966. set_encoded_host_address(
  967. pct_string_view s);
  968. /** Set the host to an address
  969. The host is set to the specified IPv4
  970. address.
  971. The host type is @ref host_type::ipv4.
  972. @par Example
  973. @code
  974. assert( url("http://www.example.com").set_host_ipv4( ipv4_address( "127.0.0.1" ) ).buffer() == "http://127.0.0.1" );
  975. @endcode
  976. @par Complexity
  977. Linear in `this->size()`.
  978. @par Postconditions
  979. @code
  980. this->has_authority() == true && this->host_ipv4_address() == addr && this->host_type() == host_type::ipv4
  981. @endcode
  982. @par Exception Safety
  983. Strong guarantee.
  984. Calls to allocate may throw.
  985. @param addr The address to set.
  986. @return `*this`
  987. @par BNF
  988. @code
  989. IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
  990. dec-octet = DIGIT ; 0-9
  991. / %x31-39 DIGIT ; 10-99
  992. / "1" 2DIGIT ; 100-199
  993. / "2" %x30-34 DIGIT ; 200-249
  994. / "25" %x30-35 ; 250-255
  995. @endcode
  996. @par Specification
  997. @li <a href="https://en.wikipedia.org/wiki/IPv4"
  998. >IPv4 (Wikipedia)</a>
  999. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
  1000. 3.2.2. Host (rfc3986)</a>
  1001. @see
  1002. @ref set_encoded_host,
  1003. @ref set_encoded_host_address,
  1004. @ref set_encoded_host_name,
  1005. @ref set_host,
  1006. @ref set_host_address,
  1007. @ref set_host_ipv6,
  1008. @ref set_host_ipvfuture,
  1009. @ref set_host_name.
  1010. */
  1011. url_base&
  1012. set_host_ipv4(
  1013. ipv4_address const& addr);
  1014. /** Set the host to an address
  1015. The host is set to the specified IPv6
  1016. address.
  1017. The host type is @ref host_type::ipv6.
  1018. @par Example
  1019. @code
  1020. assert( url().set_host_ipv6( ipv6_address( "1::6:c0a8:1" ) ).authority().buffer() == "[1::6:c0a8:1]" );
  1021. @endcode
  1022. @par Postconditions
  1023. @code
  1024. this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::ipv6
  1025. @endcode
  1026. @par Complexity
  1027. Linear in `this->size()`.
  1028. @par Exception Safety
  1029. Strong guarantee.
  1030. Calls to allocate may throw.
  1031. @param addr The address to set.
  1032. @return `*this`
  1033. @par BNF
  1034. @code
  1035. IPv6address = 6( h16 ":" ) ls32
  1036. / "::" 5( h16 ":" ) ls32
  1037. / [ h16 ] "::" 4( h16 ":" ) ls32
  1038. / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
  1039. / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
  1040. / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
  1041. / [ *4( h16 ":" ) h16 ] "::" ls32
  1042. / [ *5( h16 ":" ) h16 ] "::" h16
  1043. / [ *6( h16 ":" ) h16 ] "::"
  1044. ls32 = ( h16 ":" h16 ) / IPv4address
  1045. ; least-significant 32 bits of address
  1046. h16 = 1*4HEXDIG
  1047. ; 16 bits of address represented in hexadecimal
  1048. @endcode
  1049. @par Specification
  1050. @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
  1051. >IP Version 6 Addressing Architecture (rfc4291)</a>
  1052. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
  1053. 3.2.2. Host (rfc3986)</a>
  1054. @see
  1055. @ref set_encoded_host,
  1056. @ref set_encoded_host_address,
  1057. @ref set_encoded_host_name,
  1058. @ref set_host,
  1059. @ref set_host_address,
  1060. @ref set_host_ipv4,
  1061. @ref set_host_ipvfuture,
  1062. @ref set_host_name.
  1063. */
  1064. url_base&
  1065. set_host_ipv6(
  1066. ipv6_address const& addr);
  1067. /** Set the zone ID for an IPv6 address.
  1068. This function sets the zone ID for the host if the host is an IPv6 address.
  1069. Reserved characters in the string are percent-escaped in the result.
  1070. @par Example
  1071. @code
  1072. assert( u.set_host_ipv6( ipv6_address( "fe80::1" ) ).set_zone_id( "eth0" ).buffer() == "https://[fe80::1%25eth0]" );
  1073. @endcode
  1074. @par Complexity
  1075. Linear in `this->size()`.
  1076. @par Exception Safety
  1077. Strong guarantee. Calls to allocate may throw.
  1078. @param s The zone ID to set.
  1079. @return `*this`
  1080. @par Specification
  1081. @li <a href="https://datatracker.ietf.org/doc/html/rfc6874">RFC 6874</a>
  1082. */
  1083. url_base&
  1084. set_zone_id(core::string_view s);
  1085. /** Set the zone ID for an IPv6 address (percent-encoded).
  1086. This function sets the zone ID for the host if the host is an IPv6 address.
  1087. Escapes in the string are preserved, and reserved characters in the string
  1088. are percent-escaped in the result.
  1089. @par Example
  1090. @code
  1091. assert( u.set_host_ipv6( ipv6_address( "fe80::1" ) ).set_encoded_zone_id( "eth0" ).buffer() == "https://[fe80::1%25eth0]" );
  1092. @endcode
  1093. @par Complexity
  1094. Linear in `this->size()`.
  1095. @par Exception Safety
  1096. Strong guarantee. Calls to allocate may throw.
  1097. Exceptions thrown on invalid input.
  1098. @throw system_error
  1099. `s` contains an invalid percent-encoding.
  1100. @param s The zone ID to set.
  1101. @return `*this`
  1102. @par Specification
  1103. @li <a href="https://datatracker.ietf.org/doc/html/rfc6874">RFC 6874</a>
  1104. */
  1105. url_base&
  1106. set_encoded_zone_id(pct_string_view s);
  1107. /** Set the host to an address
  1108. The host is set to the specified IPvFuture
  1109. string.
  1110. The host type is @ref host_type::ipvfuture.
  1111. @par Example
  1112. @code
  1113. assert( url().set_host_ipvfuture( "v42.bis" ).buffer() == "//[v42.bis]" );
  1114. @endcode
  1115. @par Complexity
  1116. Linear in `this->size() + s.size()`.
  1117. @par Postconditions
  1118. @code
  1119. this->has_authority() == true && this->host_ipvfuture) == s && this->host_type() == host_type::ipvfuture
  1120. @endcode
  1121. @par Exception Safety
  1122. Strong guarantee.
  1123. Calls to allocate may throw.
  1124. Exceptions thrown on invalid input.
  1125. @throw system_error
  1126. `s` contains an invalid percent-encoding.
  1127. @param s The string to set.
  1128. @return `*this`
  1129. @par BNF
  1130. @code
  1131. IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
  1132. @endcode
  1133. @par Specification
  1134. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
  1135. 3.2.2. Host (rfc3986)</a>
  1136. @see
  1137. @ref set_encoded_host,
  1138. @ref set_encoded_host_address,
  1139. @ref set_encoded_host_name,
  1140. @ref set_host,
  1141. @ref set_host_address,
  1142. @ref set_host_ipv4,
  1143. @ref set_host_ipv6,
  1144. @ref set_host_name.
  1145. */
  1146. url_base&
  1147. set_host_ipvfuture(
  1148. core::string_view s);
  1149. /** Set the host to a name
  1150. The host is set to the specified string,
  1151. which may be empty.
  1152. Reserved characters in the string are
  1153. percent-escaped in the result.
  1154. The host type is @ref host_type::name.
  1155. @par Example
  1156. @code
  1157. assert( url( "http://www.example.com/index.htm").set_host_name( "localhost" ).host_address() == "localhost" );
  1158. @endcode
  1159. @par Postconditions
  1160. @code
  1161. this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::name
  1162. @endcode
  1163. @par Exception Safety
  1164. Strong guarantee.
  1165. Calls to allocate may throw.
  1166. @param s The string to set.
  1167. @return `*this`
  1168. @par BNF
  1169. @code
  1170. reg-name = *( unreserved / pct-encoded / "-" / ".")
  1171. @endcode
  1172. @par Specification
  1173. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
  1174. 3.2.2. Host (rfc3986)</a>
  1175. @see
  1176. @ref set_encoded_host,
  1177. @ref set_encoded_host_address,
  1178. @ref set_encoded_host_name,
  1179. @ref set_host,
  1180. @ref set_host_address,
  1181. @ref set_host_ipv4,
  1182. @ref set_host_ipv6,
  1183. @ref set_host_ipvfuture.
  1184. */
  1185. url_base&
  1186. set_host_name(
  1187. core::string_view s);
  1188. /** Set the host to a name
  1189. The host is set to the specified string,
  1190. which may contain percent-escapes and
  1191. can be empty.
  1192. Escapes in the string are preserved,
  1193. and reserved characters in the string
  1194. are percent-escaped in the result.
  1195. The host type is @ref host_type::name.
  1196. @par Example
  1197. @code
  1198. assert( url( "http://www.example.com/index.htm").set_encoded_host_name( "localhost" ).host_address() == "localhost" );
  1199. @endcode
  1200. @par Postconditions
  1201. @code
  1202. this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::name
  1203. @endcode
  1204. @par Exception Safety
  1205. Strong guarantee.
  1206. Calls to allocate may throw.
  1207. Exceptions thrown on invalid input.
  1208. @throw system_error
  1209. `s` contains an invalid percent-encoding.
  1210. @param s The string to set.
  1211. @return `*this`
  1212. @par BNF
  1213. @code
  1214. reg-name = *( unreserved / pct-encoded / "-" / ".")
  1215. @endcode
  1216. @par Specification
  1217. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
  1218. 3.2.2. Host (rfc3986)</a>
  1219. @see
  1220. @ref set_encoded_host,
  1221. @ref set_encoded_host_address,
  1222. @ref set_host,
  1223. @ref set_host_address,
  1224. @ref set_host_ipv4,
  1225. @ref set_host_ipv6,
  1226. @ref set_host_ipvfuture,
  1227. @ref set_host_name.
  1228. */
  1229. url_base&
  1230. set_encoded_host_name(
  1231. pct_string_view s);
  1232. //--------------------------------------------
  1233. /** Set the port
  1234. The port is set to the specified integer.
  1235. @par Example
  1236. @code
  1237. assert( url( "http://www.example.com" ).set_port_number( 8080 ).authority().buffer() == "www.example.com:8080" );
  1238. @endcode
  1239. @par Postconditions
  1240. @code
  1241. this->has_authority() == true && this->has_port() == true && this->port_number() == n
  1242. @endcode
  1243. @par Complexity
  1244. Linear in `this->size()`.
  1245. @par Exception Safety
  1246. Strong guarantee.
  1247. Calls to allocate may throw.
  1248. @param n The port number to set.
  1249. @return `*this`
  1250. @par BNF
  1251. @code
  1252. authority = [ userinfo "@" ] host [ ":" port ]
  1253. port = *DIGIT
  1254. @endcode
  1255. @par Specification
  1256. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">
  1257. 3.2.3. Port (rfc3986)</a>
  1258. @see
  1259. @ref remove_port,
  1260. @ref set_port.
  1261. */
  1262. url_base&
  1263. set_port_number(std::uint16_t n);
  1264. /** Set the port
  1265. This port is set to the string, which
  1266. must contain only digits or be empty.
  1267. An empty port string is distinct from
  1268. having no port.
  1269. @par Example
  1270. @code
  1271. assert( url( "http://www.example.com" ).set_port( "8080" ).authority().buffer() == "www.example.com:8080" );
  1272. @endcode
  1273. @par Postconditions
  1274. @code
  1275. this->has_port() == true && this->port_number() == n && this->port() == std::to_string(n)
  1276. @endcode
  1277. @par Exception Safety
  1278. Strong guarantee.
  1279. Calls to allocate may throw.
  1280. Exceptions thrown on invalid input.
  1281. @throw system_error
  1282. `s` does not contain a valid port.
  1283. @param s The port string to set.
  1284. @return `*this`
  1285. @par BNF
  1286. @code
  1287. port = *DIGIT
  1288. @endcode
  1289. @par Specification
  1290. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">
  1291. 3.2.3. Port (rfc3986)</a>
  1292. @see
  1293. @ref remove_port,
  1294. @ref set_port.
  1295. */
  1296. url_base&
  1297. set_port(core::string_view s);
  1298. /** Remove the port
  1299. If a port exists, it is removed. The rest
  1300. of the authority is unchanged.
  1301. @return `*this`
  1302. @par Example
  1303. @code
  1304. assert( url( "http://www.example.com:80" ).remove_port().authority().buffer() == "www.example.com" );
  1305. @endcode
  1306. @par Postconditions
  1307. @code
  1308. this->has_port() == false && this->port_number() == 0 && this->port() == ""
  1309. @endcode
  1310. @par Complexity
  1311. Linear in `this->size()`.
  1312. @par Exception Safety
  1313. Throws nothing.
  1314. @par BNF
  1315. @code
  1316. authority = [ userinfo "@" ] host [ ":" port ]
  1317. port = *DIGIT
  1318. @endcode
  1319. @par Specification
  1320. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">
  1321. 3.2.3. Port (rfc3986)</a>
  1322. @see
  1323. @ref set_port.
  1324. */
  1325. url_base&
  1326. remove_port() noexcept;
  1327. //--------------------------------------------
  1328. //
  1329. // Path
  1330. //
  1331. //--------------------------------------------
  1332. /** Set if the path is absolute
  1333. This function adjusts the path to make
  1334. it absolute or not, depending on the
  1335. parameter.
  1336. @note
  1337. If an authority is present, the path
  1338. is always absolute. In this case, the
  1339. function has no effect.
  1340. @par Example
  1341. @code
  1342. url u( "path/to/file.txt" );
  1343. assert( u.set_path_absolute( true ) );
  1344. assert( u.buffer() == "/path/to/file.txt" );
  1345. @endcode
  1346. @par Postconditions
  1347. @code
  1348. this->is_path_absolute() == true && this->encoded_path().front() == '/'
  1349. @endcode
  1350. @param absolute If `true`, the path is made absolute.
  1351. @return true on success.
  1352. @par Complexity
  1353. Linear in `this->size()`.
  1354. @par BNF
  1355. @code
  1356. path = path-abempty ; begins with "/" or is empty
  1357. / path-absolute ; begins with "/" but not "//"
  1358. / path-noscheme ; begins with a non-colon segment
  1359. / path-rootless ; begins with a segment
  1360. / path-empty ; zero characters
  1361. path-abempty = *( "/" segment )
  1362. path-absolute = "/" [ segment-nz *( "/" segment ) ]
  1363. path-noscheme = segment-nz-nc *( "/" segment )
  1364. path-rootless = segment-nz *( "/" segment )
  1365. path-empty = 0<pchar>
  1366. @endcode
  1367. @par Specification
  1368. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
  1369. >3.3. Path (rfc3986)</a>
  1370. @see
  1371. @ref encoded_segments,
  1372. @ref segments,
  1373. @ref set_encoded_path,
  1374. @ref set_path.
  1375. */
  1376. bool
  1377. set_path_absolute(bool absolute);
  1378. /** Set the path.
  1379. This function sets the path to the
  1380. string, which may be empty.
  1381. Reserved characters in the string are
  1382. percent-escaped in the result.
  1383. @note
  1384. The library may adjust the final result
  1385. to ensure that no other parts of the URL
  1386. are semantically affected.
  1387. @note
  1388. This function does not encode '/' chars, which
  1389. are unreserved for paths but reserved for
  1390. path segments. If a path segment should include
  1391. encoded '/'s to differentiate it from path separators,
  1392. the functions @ref set_encoded_path or @ref segments
  1393. should be used instead.
  1394. @par Example
  1395. @code
  1396. url u( "http://www.example.com" );
  1397. u.set_path( "path/to/file.txt" );
  1398. assert( u.path() == "/path/to/file.txt" );
  1399. @endcode
  1400. @par Complexity
  1401. Linear in `this->size() + s.size()`.
  1402. @par Exception Safety
  1403. Strong guarantee.
  1404. Calls to allocate may throw.
  1405. @param s The string to set.
  1406. @return `*this`
  1407. @par BNF
  1408. @code
  1409. path = path-abempty ; begins with "/" or is empty
  1410. / path-absolute ; begins with "/" but not "//"
  1411. / path-noscheme ; begins with a non-colon segment
  1412. / path-rootless ; begins with a segment
  1413. / path-empty ; zero characters
  1414. path-abempty = *( "/" segment )
  1415. path-absolute = "/" [ segment-nz *( "/" segment ) ]
  1416. path-noscheme = segment-nz-nc *( "/" segment )
  1417. path-rootless = segment-nz *( "/" segment )
  1418. path-empty = 0<pchar>
  1419. @endcode
  1420. @par Specification
  1421. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
  1422. >3.3. Path (rfc3986)</a>
  1423. @see
  1424. @ref encoded_segments,
  1425. @ref segments,
  1426. @ref set_encoded_path,
  1427. @ref set_path_absolute.
  1428. */
  1429. url_base&
  1430. set_path(
  1431. core::string_view s);
  1432. /** Set the path.
  1433. This function sets the path to the
  1434. string, which may contain percent-escapes
  1435. and can be empty.
  1436. Escapes in the string are preserved,
  1437. and reserved characters in the string
  1438. are percent-escaped in the result.
  1439. @note
  1440. The library may adjust the final result
  1441. to ensure that no other parts of the url
  1442. is semantically affected.
  1443. @par Example
  1444. @code
  1445. url u( "http://www.example.com" );
  1446. u.set_encoded_path( "path/to/file.txt" );
  1447. assert( u.encoded_path() == "/path/to/file.txt" );
  1448. @endcode
  1449. @par Complexity
  1450. Linear in `this->size() + s.size()`.
  1451. @par Exception Safety
  1452. Strong guarantee.
  1453. Calls to allocate may throw.
  1454. Exceptions thrown on invalid input.
  1455. @throw system_error
  1456. `s` contains an invalid percent-encoding.
  1457. @param s The string to set.
  1458. @return `*this`
  1459. @par BNF
  1460. @code
  1461. path = path-abempty ; begins with "/" or is empty
  1462. / path-absolute ; begins with "/" but not "//"
  1463. / path-noscheme ; begins with a non-colon segment
  1464. / path-rootless ; begins with a segment
  1465. / path-empty ; zero characters
  1466. path-abempty = *( "/" segment )
  1467. path-absolute = "/" [ segment-nz *( "/" segment ) ]
  1468. path-noscheme = segment-nz-nc *( "/" segment )
  1469. path-rootless = segment-nz *( "/" segment )
  1470. path-empty = 0<pchar>
  1471. @endcode
  1472. @par Specification
  1473. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
  1474. >3.3. Path (rfc3986)</a>
  1475. @see
  1476. @ref encoded_segments,
  1477. @ref segments,
  1478. @ref set_path,
  1479. @ref set_path_absolute.
  1480. */
  1481. url_base&
  1482. set_encoded_path(
  1483. pct_string_view s);
  1484. /** Return the path as a container of segments
  1485. This function returns a bidirectional
  1486. view of segments over the path.
  1487. The returned view references the same
  1488. underlying character buffer; ownership
  1489. is not transferred.
  1490. Any percent-escapes in strings returned
  1491. when iterating the view are decoded first.
  1492. The container is modifiable; changes
  1493. to the container are reflected in the
  1494. underlying URL.
  1495. @return `*this`
  1496. @par Example
  1497. @code
  1498. url u( "http://example.com/path/to/file.txt" );
  1499. segments sv = u.segments();
  1500. @endcode
  1501. @par Complexity
  1502. Constant.
  1503. @par Exception Safety
  1504. Throws nothing.
  1505. @par BNF
  1506. @code
  1507. path = path-abempty ; begins with "/" or is empty
  1508. / path-absolute ; begins with "/" but not "//"
  1509. / path-noscheme ; begins with a non-colon segment
  1510. / path-rootless ; begins with a segment
  1511. / path-empty ; zero characters
  1512. path-abempty = *( "/" segment )
  1513. path-absolute = "/" [ segment-nz *( "/" segment ) ]
  1514. path-noscheme = segment-nz-nc *( "/" segment )
  1515. path-rootless = segment-nz *( "/" segment )
  1516. path-empty = 0<pchar>
  1517. @endcode
  1518. @par Specification
  1519. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
  1520. >3.3. Path (rfc3986)</a>
  1521. @see
  1522. @ref encoded_segments,
  1523. @ref set_encoded_path,
  1524. @ref set_path,
  1525. @ref set_path_absolute.
  1526. */
  1527. urls::segments_ref
  1528. segments() noexcept;
  1529. /// @copydoc url_view_base::segments
  1530. segments_view
  1531. segments() const noexcept
  1532. {
  1533. return url_view_base::segments();
  1534. }
  1535. /** Return the path as a container of segments
  1536. This function returns a bidirectional
  1537. view of segments over the path.
  1538. The returned view references the same
  1539. underlying character buffer; ownership
  1540. is not transferred.
  1541. Strings returned when iterating the
  1542. range may contain percent escapes.
  1543. The container is modifiable; changes
  1544. to the container are reflected in the
  1545. underlying URL.
  1546. @return `*this`
  1547. @par Example
  1548. @code
  1549. url u( "http://example.com/path/to/file.txt" );
  1550. segments_encoded_ref sv = u.encoded_segments();
  1551. @endcode
  1552. @par Complexity
  1553. Constant.
  1554. @par Exception Safety
  1555. Throws nothing.
  1556. @par BNF
  1557. @code
  1558. path = path-abempty ; begins with "/" or is empty
  1559. / path-absolute ; begins with "/" but not "//"
  1560. / path-noscheme ; begins with a non-colon segment
  1561. / path-rootless ; begins with a segment
  1562. / path-empty ; zero characters
  1563. path-abempty = *( "/" segment )
  1564. path-absolute = "/" [ segment-nz *( "/" segment ) ]
  1565. path-noscheme = segment-nz-nc *( "/" segment )
  1566. path-rootless = segment-nz *( "/" segment )
  1567. path-empty = 0<pchar>
  1568. @endcode
  1569. @par Specification
  1570. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
  1571. >3.3. Path (rfc3986)</a>
  1572. @see
  1573. @ref encoded_segments,
  1574. @ref set_encoded_path,
  1575. @ref set_path,
  1576. @ref set_path_absolute.
  1577. */
  1578. segments_encoded_ref
  1579. encoded_segments() noexcept;
  1580. /// @copydoc url_view_base::encoded_segments
  1581. segments_encoded_view
  1582. encoded_segments() const noexcept
  1583. {
  1584. return url_view_base::encoded_segments();
  1585. }
  1586. //--------------------------------------------
  1587. //
  1588. // Query
  1589. //
  1590. //--------------------------------------------
  1591. /** Set the query
  1592. This sets the query to the string, which
  1593. can be empty.
  1594. An empty query is distinct from having
  1595. no query.
  1596. Reserved characters in the string are
  1597. percent-escaped in the result.
  1598. @par Example
  1599. @code
  1600. assert( url( "http://example.com" ).set_query( "id=42" ).query() == "id=42" );
  1601. @endcode
  1602. @par Postconditions
  1603. @code
  1604. this->has_query() == true && this->query() == s
  1605. @endcode
  1606. @par Exception Safety
  1607. Strong guarantee.
  1608. Calls to allocate may throw.
  1609. @param s The string to set.
  1610. @return `*this`
  1611. @par BNF
  1612. @code
  1613. query = *( pchar / "/" / "?" )
  1614. query-param = key [ "=" value ]
  1615. query-params = [ query-param ] *( "&" query-param )
  1616. @endcode
  1617. @par Specification
  1618. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
  1619. >3.4. Query (rfc3986)</a>
  1620. @li <a href="https://en.wikipedia.org/wiki/Query_string"
  1621. >Query string (Wikipedia)</a>
  1622. @see
  1623. @ref encoded_params,
  1624. @ref params,
  1625. @ref remove_query,
  1626. @ref set_encoded_query.
  1627. */
  1628. url_base&
  1629. set_query(
  1630. core::string_view s);
  1631. /** Set the query
  1632. This sets the query to the string, which
  1633. may contain percent-escapes and can be
  1634. empty.
  1635. An empty query is distinct from having
  1636. no query.
  1637. Escapes in the string are preserved,
  1638. and reserved characters in the string
  1639. are percent-escaped in the result.
  1640. @par Example
  1641. @code
  1642. assert( url( "http://example.com" ).set_encoded_query( "id=42" ).encoded_query() == "id=42" );
  1643. @endcode
  1644. @par Postconditions
  1645. @code
  1646. this->has_query() == true && this->query() == decode_view( s );
  1647. @endcode
  1648. @par Exception Safety
  1649. Strong guarantee.
  1650. Calls to allocate may throw.
  1651. Exceptions thrown on invalid input.
  1652. @param s The string to set.
  1653. @return `*this`
  1654. @throws system_error
  1655. `s` contains an invalid percent-encoding.
  1656. @par BNF
  1657. @code
  1658. query = *( pchar / "/" / "?" )
  1659. query-param = key [ "=" value ]
  1660. query-params = [ query-param ] *( "&" query-param )
  1661. @endcode
  1662. @par Specification
  1663. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
  1664. >3.4. Query (rfc3986)</a>
  1665. @li <a href="https://en.wikipedia.org/wiki/Query_string"
  1666. >Query string (Wikipedia)</a>
  1667. @see
  1668. @ref encoded_params,
  1669. @ref params,
  1670. @ref remove_query,
  1671. @ref set_query.
  1672. */
  1673. url_base&
  1674. set_encoded_query(
  1675. pct_string_view s);
  1676. /** Return the query as a container of parameters
  1677. This function returns a bidirectional
  1678. view of key/value pairs over the query.
  1679. The returned view references the same
  1680. underlying character buffer; ownership
  1681. is not transferred.
  1682. Any percent-escapes in strings returned
  1683. when iterating the view are decoded first.
  1684. The container is modifiable; changes
  1685. to the container are reflected in the
  1686. underlying URL.
  1687. @return `*this`
  1688. @par Example
  1689. @code
  1690. params_ref pv = url( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).params();
  1691. @endcode
  1692. @par Complexity
  1693. Constant.
  1694. @par Exception Safety
  1695. Throws nothing.
  1696. @par BNF
  1697. @code
  1698. query = *( pchar / "/" / "?" )
  1699. query-param = key [ "=" value ]
  1700. query-params = [ query-param ] *( "&" query-param )
  1701. @endcode
  1702. @par Specification
  1703. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
  1704. >3.4. Query (rfc3986)</a>
  1705. @li <a href="https://en.wikipedia.org/wiki/Query_string"
  1706. >Query string (Wikipedia)</a>
  1707. @see
  1708. @ref encoded_params,
  1709. @ref remove_query,
  1710. @ref set_encoded_query,
  1711. @ref set_query.
  1712. */
  1713. params_ref
  1714. params() noexcept;
  1715. /// @copydoc url_view_base::params
  1716. params_view
  1717. params() const noexcept
  1718. {
  1719. return url_view_base::params();
  1720. }
  1721. /** Return the query as a container of parameters
  1722. This function returns a bidirectional
  1723. view of key/value pairs over the query.
  1724. The returned view references the same
  1725. underlying character buffer; ownership
  1726. is not transferred.
  1727. Any percent-escapes in strings returned
  1728. when iterating the view are decoded first.
  1729. The container is modifiable; changes
  1730. to the container are reflected in the
  1731. underlying URL.
  1732. @par Example
  1733. @code
  1734. encoding_opts opt;
  1735. opt.space_as_plus = true;
  1736. params_ref pv = url( "/sql?id=42&name=jane+doe&page+size=20" ).params(opt);
  1737. @endcode
  1738. @par Complexity
  1739. Constant.
  1740. @par Exception Safety
  1741. Throws nothing.
  1742. @param opt The options for decoding. If
  1743. this parameter is omitted, the `space_as_plus`
  1744. is used.
  1745. @return A range of references to the parameters.
  1746. @par BNF
  1747. @code
  1748. query = *( pchar / "/" / "?" )
  1749. query-param = key [ "=" value ]
  1750. query-params = [ query-param ] *( "&" query-param )
  1751. @endcode
  1752. @par Specification
  1753. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
  1754. >3.4. Query (rfc3986)</a>
  1755. @li <a href="https://en.wikipedia.org/wiki/Query_string"
  1756. >Query string (Wikipedia)</a>
  1757. @see
  1758. @ref encoded_params,
  1759. @ref remove_query,
  1760. @ref set_encoded_query,
  1761. @ref set_query.
  1762. */
  1763. params_ref
  1764. params(encoding_opts opt) noexcept;
  1765. /// @copydoc url_view_base::encoded_params
  1766. params_encoded_view
  1767. encoded_params() const noexcept
  1768. {
  1769. return url_view_base::encoded_params();
  1770. }
  1771. /** Return the query as a container of parameters
  1772. This function returns a bidirectional
  1773. view of key/value pairs over the query.
  1774. The returned view references the same
  1775. underlying character buffer; ownership
  1776. is not transferred.
  1777. Strings returned when iterating the
  1778. range may contain percent escapes.
  1779. The container is modifiable; changes
  1780. to the container are reflected in the
  1781. underlying URL.
  1782. @return `*this`
  1783. @par Example
  1784. @code
  1785. params_encoded_ref pv = url( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_params();
  1786. @endcode
  1787. @par Complexity
  1788. Constant.
  1789. @par Exception Safety
  1790. Throws nothing.
  1791. @par BNF
  1792. @code
  1793. query = *( pchar / "/" / "?" )
  1794. query-param = key [ "=" value ]
  1795. query-params = [ query-param ] *( "&" query-param )
  1796. @endcode
  1797. @par Specification
  1798. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
  1799. >3.4. Query (rfc3986)</a>
  1800. @li <a href="https://en.wikipedia.org/wiki/Query_string"
  1801. >Query string (Wikipedia)</a>
  1802. @see
  1803. @ref params,
  1804. @ref remove_query,
  1805. @ref set_encoded_query,
  1806. @ref set_query.
  1807. */
  1808. params_encoded_ref
  1809. encoded_params() noexcept;
  1810. /** Set the query params
  1811. This sets the query params to the list
  1812. of param_view, which can be empty.
  1813. An empty list of params is distinct from
  1814. having no params.
  1815. Reserved characters in the string are
  1816. percent-escaped in the result.
  1817. @par Example
  1818. @code
  1819. assert( url( "http://example.com" ).set_params( {"id", "42"} ).query() == "id=42" );
  1820. @endcode
  1821. @par Postconditions
  1822. @code
  1823. this->has_query() == true
  1824. @endcode
  1825. @par Exception Safety
  1826. Strong guarantee.
  1827. Calls to allocate may throw.
  1828. @par Complexity
  1829. Linear.
  1830. @param ps The params to set.
  1831. @param opts The options for encoding.
  1832. @return `*this`
  1833. @par BNF
  1834. @code
  1835. query = *( pchar / "/" / "?" )
  1836. query-param = key [ "=" value ]
  1837. query-params = [ query-param ] *( "&" query-param )
  1838. @endcode
  1839. @par Specification
  1840. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
  1841. >3.4. Query (rfc3986)</a>
  1842. @li <a href="https://en.wikipedia.org/wiki/Query_string"
  1843. >Query string (Wikipedia)</a>
  1844. @see
  1845. @ref encoded_params,
  1846. @ref remove_query,
  1847. @ref set_encoded_query,
  1848. @ref set_query.
  1849. */
  1850. url_base&
  1851. set_params(
  1852. std::initializer_list<param_view> ps,
  1853. encoding_opts opts = {}) noexcept;
  1854. /** Set the query params
  1855. This sets the query params to the elements
  1856. in the list, which may contain
  1857. percent-escapes and can be empty.
  1858. An empty list of params is distinct from
  1859. having no query.
  1860. Escapes in the string are preserved,
  1861. and reserved characters in the string
  1862. are percent-escaped in the result.
  1863. @par Example
  1864. @code
  1865. assert( url( "http://example.com" ).set_encoded_params( {"id", "42"} ).encoded_query() == "id=42" );
  1866. @endcode
  1867. @par Postconditions
  1868. @code
  1869. this->has_query() == true
  1870. @endcode
  1871. @par Complexity
  1872. Linear.
  1873. @par Exception Safety
  1874. Strong guarantee.
  1875. Calls to allocate may throw.
  1876. Exceptions thrown on invalid input.
  1877. @param ps The params to set.
  1878. @return `*this`
  1879. @throws system_error
  1880. some element in `ps` contains an invalid percent-encoding.
  1881. @par BNF
  1882. @code
  1883. query = *( pchar / "/" / "?" )
  1884. query-param = key [ "=" value ]
  1885. query-params = [ query-param ] *( "&" query-param )
  1886. @endcode
  1887. @par Specification
  1888. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
  1889. >3.4. Query (rfc3986)</a>
  1890. @li <a href="https://en.wikipedia.org/wiki/Query_string"
  1891. >Query string (Wikipedia)</a>
  1892. @see
  1893. @ref set_params,
  1894. @ref params,
  1895. @ref remove_query,
  1896. @ref set_encoded_query,
  1897. @ref set_query.
  1898. */
  1899. url_base&
  1900. set_encoded_params( std::initializer_list< param_pct_view > ps ) noexcept;
  1901. /** Remove the query
  1902. If a query is present, it is removed.
  1903. An empty query is distinct from having
  1904. no query.
  1905. @return `*this`
  1906. @par Example
  1907. @code
  1908. assert( url( "http://www.example.com?id=42" ).remove_query().buffer() == "http://www.example.com" );
  1909. @endcode
  1910. @par Postconditions
  1911. @code
  1912. this->has_query() == false && this->params().empty()
  1913. @endcode
  1914. @par Exception Safety
  1915. Throws nothing.
  1916. @par BNF
  1917. @code
  1918. query = *( pchar / "/" / "?" )
  1919. query-param = key [ "=" value ]
  1920. query-params = [ query-param ] *( "&" query-param )
  1921. @endcode
  1922. @par Specification
  1923. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
  1924. >3.4. Query (rfc3986)</a>
  1925. @li <a href="https://en.wikipedia.org/wiki/Query_string"
  1926. >Query string (Wikipedia)</a>
  1927. @see
  1928. @ref encoded_params,
  1929. @ref params,
  1930. @ref set_encoded_query,
  1931. @ref set_query.
  1932. */
  1933. url_base&
  1934. remove_query() noexcept;
  1935. //--------------------------------------------
  1936. //
  1937. // Fragment
  1938. //
  1939. //--------------------------------------------
  1940. /** Remove the fragment
  1941. This function removes the fragment.
  1942. An empty fragment is distinct from
  1943. having no fragment.
  1944. @return `*this`
  1945. @par Example
  1946. @code
  1947. assert( url( "?first=john&last=doe#anchor" ).remove_fragment().buffer() == "?first=john&last=doe" );
  1948. @endcode
  1949. @par Postconditions
  1950. @code
  1951. this->has_fragment() == false && this->encoded_fragment() == ""
  1952. @endcode
  1953. @par Complexity
  1954. Constant.
  1955. @par Exception Safety
  1956. Throws nothing.
  1957. @par BNF
  1958. @code
  1959. fragment = *( pchar / "/" / "?" )
  1960. @endcode
  1961. @par Specification
  1962. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
  1963. >3.5. Fragment</a>
  1964. @see
  1965. @ref remove_fragment,
  1966. @ref set_encoded_fragment,
  1967. @ref set_fragment.
  1968. */
  1969. url_base&
  1970. remove_fragment() noexcept;
  1971. /** Set the fragment.
  1972. This function sets the fragment to the
  1973. specified string, which may be empty.
  1974. An empty fragment is distinct from
  1975. having no fragment.
  1976. Reserved characters in the string are
  1977. percent-escaped in the result.
  1978. @par Example
  1979. @code
  1980. assert( url("?first=john&last=doe" ).set_encoded_fragment( "john doe" ).encoded_fragment() == "john%20doe" );
  1981. @endcode
  1982. @par Postconditions
  1983. @code
  1984. this->has_fragment() == true && this->fragment() == s
  1985. @endcode
  1986. @par Complexity
  1987. Linear in `this->size() + s.size()`.
  1988. @par Exception Safety
  1989. Strong guarantee.
  1990. Calls to allocate may throw.
  1991. @param s The string to set.
  1992. @return `*this`
  1993. @par BNF
  1994. @code
  1995. fragment = *( pchar / "/" / "?" )
  1996. @endcode
  1997. @par Specification
  1998. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
  1999. >3.5. Fragment</a>
  2000. @see
  2001. @ref remove_fragment,
  2002. @ref set_encoded_fragment.
  2003. */
  2004. url_base&
  2005. set_fragment(
  2006. core::string_view s);
  2007. /** Set the fragment.
  2008. This function sets the fragment to the
  2009. specified string, which may contain
  2010. percent-escapes and which may be empty.
  2011. An empty fragment is distinct from
  2012. having no fragment.
  2013. Escapes in the string are preserved,
  2014. and reserved characters in the string
  2015. are percent-escaped in the result.
  2016. @return `*this`
  2017. @par Example
  2018. @code
  2019. assert( url("?first=john&last=doe" ).set_encoded_fragment( "john%2Ddoe" ).fragment() == "john-doe" );
  2020. @endcode
  2021. @par Postconditions
  2022. @code
  2023. this->has_fragment() == true && this->fragment() == decode_view( s )
  2024. @endcode
  2025. @par Complexity
  2026. Linear in `this->size() + s.size()`.
  2027. @par Exception Safety
  2028. Strong guarantee.
  2029. Calls to allocate may throw.
  2030. Exceptions thrown on invalid input.
  2031. @throw system_error
  2032. `s` contains an invalid percent-encoding.
  2033. @param s The string to set.
  2034. @return `*this`
  2035. @par BNF
  2036. @code
  2037. fragment = *( pchar / "/" / "?" )
  2038. @endcode
  2039. @par Specification
  2040. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
  2041. >3.5. Fragment</a>
  2042. @see
  2043. @ref remove_fragment,
  2044. @ref set_fragment.
  2045. */
  2046. url_base&
  2047. set_encoded_fragment(
  2048. pct_string_view s);
  2049. //--------------------------------------------
  2050. //
  2051. // Compound Fields
  2052. //
  2053. //--------------------------------------------
  2054. /** Remove the origin component
  2055. This function removes the origin, which
  2056. consists of the scheme and authority.
  2057. @return `*this`
  2058. @par Example
  2059. @code
  2060. assert( url( "http://www.example.com/index.htm" ).remove_origin().buffer() == "/index.htm" );
  2061. @endcode
  2062. @par Postconditions
  2063. @code
  2064. this->scheme_id() == scheme::none && this->has_authority() == false
  2065. @endcode
  2066. @par Complexity
  2067. Linear in `this->size()`.
  2068. @par Exception Safety
  2069. Throws nothing.
  2070. */
  2071. url_base&
  2072. remove_origin();
  2073. //--------------------------------------------
  2074. //
  2075. // Normalization
  2076. //
  2077. //--------------------------------------------
  2078. /** Normalize the URL components
  2079. Applies Syntax-based normalization to
  2080. all components of the URL.
  2081. @return `*this`
  2082. @par Exception Safety
  2083. Strong guarantee.
  2084. Calls to allocate may throw.
  2085. @par Specification
  2086. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
  2087. >6.2.2 Syntax-Based Normalization (rfc3986)</a>
  2088. */
  2089. url_base&
  2090. normalize();
  2091. /** Normalize the URL scheme
  2092. Applies Syntax-based normalization to the
  2093. URL scheme.
  2094. The scheme is normalized to lowercase.
  2095. @return `*this`
  2096. @par Exception Safety
  2097. Strong guarantee.
  2098. Calls to allocate may throw.
  2099. @par Specification
  2100. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
  2101. >6.2.2 Syntax-Based Normalization (rfc3986)</a>
  2102. */
  2103. url_base&
  2104. normalize_scheme();
  2105. /** Normalize the URL authority
  2106. Applies Syntax-based normalization to the
  2107. URL authority.
  2108. Percent-encoding triplets are normalized
  2109. to uppercase letters. Percent-encoded
  2110. octets that correspond to unreserved
  2111. characters are decoded.
  2112. @return `*this`
  2113. @par Exception Safety
  2114. Strong guarantee.
  2115. Calls to allocate may throw.
  2116. @par Specification
  2117. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
  2118. >6.2.2 Syntax-Based Normalization (rfc3986)</a>
  2119. */
  2120. url_base&
  2121. normalize_authority();
  2122. /** Normalize the URL path
  2123. Applies Syntax-based normalization to the
  2124. URL path.
  2125. Percent-encoding triplets are normalized
  2126. to uppercase letters. Percent-encoded
  2127. octets that correspond to unreserved
  2128. characters are decoded. Redundant
  2129. path-segments are removed.
  2130. @return `*this`
  2131. @par Exception Safety
  2132. Strong guarantee.
  2133. Calls to allocate may throw.
  2134. @par Specification
  2135. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
  2136. >6.2.2 Syntax-Based Normalization (rfc3986)</a>
  2137. */
  2138. url_base&
  2139. normalize_path();
  2140. /** Normalize the URL query
  2141. Applies Syntax-based normalization to the
  2142. URL query.
  2143. Percent-encoding triplets are normalized
  2144. to uppercase letters. Percent-encoded
  2145. octets that correspond to unreserved
  2146. characters are decoded.
  2147. @return `*this`
  2148. @par Exception Safety
  2149. Strong guarantee.
  2150. Calls to allocate may throw.
  2151. @par Specification
  2152. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
  2153. >6.2.2 Syntax-Based Normalization (rfc3986)</a>
  2154. */
  2155. url_base&
  2156. normalize_query();
  2157. /** Normalize the URL fragment
  2158. Applies Syntax-based normalization to the
  2159. URL fragment.
  2160. Percent-encoding triplets are normalized
  2161. to uppercase letters. Percent-encoded
  2162. octets that correspond to unreserved
  2163. characters are decoded.
  2164. @return `*this`
  2165. @par Exception Safety
  2166. Strong guarantee.
  2167. Calls to allocate may throw.
  2168. @par Specification
  2169. @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
  2170. >6.2.2 Syntax-Based Normalization (rfc3986)</a>
  2171. */
  2172. url_base&
  2173. normalize_fragment();
  2174. //
  2175. // (end of fluent API)
  2176. //
  2177. //--------------------------------------------
  2178. //--------------------------------------------
  2179. //
  2180. // Resolution
  2181. //
  2182. //--------------------------------------------
  2183. /** Resolve a URL reference against this base URL
  2184. This function attempts to resolve a URL
  2185. reference `ref` against this base URL
  2186. in a manner similar to that of a web browser
  2187. resolving an anchor tag.
  2188. This URL must satisfy the <em>URI</em>
  2189. grammar. In other words, it must contain
  2190. a scheme.
  2191. Relative references are only usable when
  2192. in the context of a base absolute URI.
  2193. This process of resolving a relative
  2194. <em>reference</em> within the context of
  2195. a <em>base</em> URI is defined in detail
  2196. in rfc3986 (see below).
  2197. The resolution process works as if the
  2198. relative reference is appended to the base
  2199. URI and the result is normalized.
  2200. Given the input base URL, this function
  2201. resolves the relative reference
  2202. as if performing the following steps:
  2203. @li Ensure the base URI has at least a scheme
  2204. @li Normalizing the reference path
  2205. @li Merge base and reference paths
  2206. @li Normalize the merged path
  2207. This function places the result of the
  2208. resolution into this URL in place.
  2209. If an error occurs, the contents of
  2210. this URL are unspecified and a `boost::system::result`
  2211. with an `system::error_code` is returned.
  2212. @note Abnormal hrefs where the number of ".."
  2213. segments exceeds the number of segments in
  2214. the base path are handled by including the
  2215. unmatched ".." segments in the result, as described
  2216. in <a href="https://www.rfc-editor.org/errata/eid4547"
  2217. >Errata 4547</a>.
  2218. @par Example
  2219. @code
  2220. url base1( "/one/two/three" );
  2221. base1.resolve("four");
  2222. assert( base1.buffer() == "/one/two/four" );
  2223. url base2( "http://example.com/" )
  2224. base2.resolve("/one");
  2225. assert( base2.buffer() == "http://example.com/one" );
  2226. url base3( "http://example.com/one" );
  2227. base3.resolve("/two");
  2228. assert( base3.buffer() == "http://example.com/two" );
  2229. url base4( "http://a/b/c/d;p?q" );
  2230. base4.resolve("g#s");
  2231. assert( base4.buffer() == "http://a/b/c/g#s" );
  2232. @endcode
  2233. @par BNF
  2234. @code
  2235. absolute-URI = scheme ":" hier-part [ "?" query ]
  2236. @endcode
  2237. @par Exception Safety
  2238. Basic guarantee.
  2239. Calls to allocate may throw.
  2240. @return An empty `boost::system::result` upon success,
  2241. otherwise an error code if `!base.has_scheme()`.
  2242. @param ref The URL reference to resolve.
  2243. @par Specification
  2244. <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-5"
  2245. >5. Reference Resolution (rfc3986)</a>
  2246. @see
  2247. @ref url,
  2248. @ref url_view.
  2249. */
  2250. system::result<void>
  2251. resolve(
  2252. url_view_base const& ref);
  2253. friend
  2254. system::result<void>
  2255. resolve(
  2256. url_view_base const& base,
  2257. url_view_base const& ref,
  2258. url_base& dest);
  2259. private:
  2260. //--------------------------------------------
  2261. //
  2262. // implementation
  2263. //
  2264. //--------------------------------------------
  2265. void check_invariants() const noexcept;
  2266. char* resize_impl(int, std::size_t, op_t&);
  2267. char* resize_impl(int, int, std::size_t, op_t&);
  2268. char* shrink_impl(int, std::size_t, op_t&);
  2269. char* shrink_impl(int, int, std::size_t, op_t&);
  2270. void set_scheme_impl(core::string_view, urls::scheme);
  2271. char* set_user_impl(std::size_t n, op_t& op);
  2272. char* set_password_impl(std::size_t n, op_t& op);
  2273. char* set_userinfo_impl(std::size_t n, op_t& op);
  2274. char* set_host_impl(std::size_t n, op_t& op);
  2275. char* set_port_impl(std::size_t n, op_t& op);
  2276. char* set_path_impl(std::size_t n, op_t& op);
  2277. void
  2278. set_host_ipv6_and_zone_id(
  2279. ipv6_address const& addr,
  2280. core::string_view zone_id);
  2281. void
  2282. set_host_ipv6_and_encoded_zone_id(
  2283. ipv6_address const& addr,
  2284. pct_string_view zone_id);
  2285. core::string_view
  2286. first_segment() const noexcept;
  2287. detail::segments_iter_impl
  2288. edit_segments(
  2289. detail::segments_iter_impl const&,
  2290. detail::segments_iter_impl const&,
  2291. detail::any_segments_iter&& it0,
  2292. int absolute = -1);
  2293. auto
  2294. edit_params(
  2295. detail::params_iter_impl const&,
  2296. detail::params_iter_impl const&,
  2297. detail::any_params_iter&&) ->
  2298. detail::params_iter_impl;
  2299. // Decode any unnecessary percent-escapes
  2300. // and ensures hexadecimals are uppercase.
  2301. // The encoding of ignored characters is
  2302. // preserved.
  2303. template
  2304. <class AllowedCharSet,
  2305. class IgnoredCharSet>
  2306. void
  2307. normalize_octets_impl(
  2308. int,
  2309. AllowedCharSet const& allowed,
  2310. IgnoredCharSet const& ignored,
  2311. op_t&) noexcept;
  2312. template<class CharSet>
  2313. void
  2314. normalize_octets_impl(
  2315. int,
  2316. CharSet const& allowed,
  2317. op_t&) noexcept;
  2318. void decoded_to_lower_impl(int id) noexcept;
  2319. void to_lower_impl(int id) noexcept;
  2320. };
  2321. //------------------------------------------------
  2322. /** Resolve a URL reference against a base URL
  2323. This function attempts to resolve a URL
  2324. reference `ref` against the base URL `base`
  2325. in a manner similar to that of a web browser
  2326. resolving an anchor tag.
  2327. The base URL must satisfy the <em>URI</em>
  2328. grammar. In other words, it must contain
  2329. a scheme.
  2330. Relative references are only usable when
  2331. in the context of a base absolute URI.
  2332. This process of resolving a relative
  2333. <em>reference</em> within the context of
  2334. a <em>base</em> URI is defined in detail
  2335. in rfc3986 (see below).
  2336. The resolution process works as if the
  2337. relative reference is appended to the base
  2338. URI and the result is normalized.
  2339. Given the input base URL, this function
  2340. resolves the relative reference
  2341. as if performing the following steps:
  2342. @li Ensure the base URI has at least a scheme
  2343. @li Normalizing the reference path
  2344. @li Merge base and reference paths
  2345. @li Normalize the merged path
  2346. This function places the result of the
  2347. resolution into `dest`, which can be
  2348. any of the url containers that inherit
  2349. from @ref url_base.
  2350. If an error occurs, the contents of
  2351. `dest` is unspecified and `ec` is set.
  2352. @note Abnormal hrefs where the number of ".."
  2353. segments exceeds the number of segments in
  2354. the base path are handled by including the
  2355. unmatched ".." segments in the result, as described
  2356. in <a href="https://www.rfc-editor.org/errata/eid4547"
  2357. >Errata 4547</a>.
  2358. @par Example
  2359. @code
  2360. url dest;
  2361. system::error_code ec;
  2362. resolve("/one/two/three", "four", dest, ec);
  2363. assert( dest.str() == "/one/two/four" );
  2364. resolve("http://example.com/", "/one", dest, ec);
  2365. assert( dest.str() == "http://example.com/one" );
  2366. resolve("http://example.com/one", "/two", dest, ec);
  2367. assert( dest.str() == "http://example.com/two" );
  2368. resolve("http://a/b/c/d;p?q", "g#s", dest, ec);
  2369. assert( dest.str() == "http://a/b/c/g#s" );
  2370. @endcode
  2371. @par BNF
  2372. @code
  2373. absolute-URI = scheme ":" hier-part [ "?" query ]
  2374. @endcode
  2375. @par Exception Safety
  2376. Basic guarantee.
  2377. Calls to allocate may throw.
  2378. @return An empty `boost::system::result` upon success,
  2379. otherwise an error code if `!base.has_scheme()`.
  2380. @param base The base URL to resolve against.
  2381. @param ref The URL reference to resolve.
  2382. @param dest The container where the result
  2383. is written, upon success.
  2384. @par Specification
  2385. <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-5"
  2386. >5. Reference Resolution (rfc3986)</a>
  2387. @see
  2388. @ref url,
  2389. @ref url_view.
  2390. */
  2391. inline
  2392. system::result<void>
  2393. resolve(
  2394. url_view_base const& base,
  2395. url_view_base const& ref,
  2396. url_base& dest)
  2397. {
  2398. if (&dest != &base)
  2399. dest.copy(base);
  2400. return dest.resolve(ref);
  2401. }
  2402. } // urls
  2403. } // boost
  2404. // These are here because of circular references
  2405. #include <boost/url/impl/params_ref.hpp>
  2406. #include <boost/url/impl/params_encoded_ref.hpp>
  2407. #include <boost/url/impl/segments_ref.hpp>
  2408. #include <boost/url/impl/segments_encoded_ref.hpp>
  2409. #endif