url_base.hpp 81 KB

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