url_base.hpp 83 KB

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