{"id":20077196,"url":"https://github.com/boostorg/url","last_synced_at":"2025-04-12T19:42:36.747Z","repository":{"id":37833465,"uuid":"224468298","full_name":"boostorg/url","owner":"boostorg","description":"Boost.URL is a library for manipulating Uniform Resource Identifiers (URIs) and Locators (URLs).","archived":false,"fork":false,"pushed_at":"2025-04-10T21:43:12.000Z","size":7155,"stargazers_count":185,"open_issues_count":33,"forks_count":54,"subscribers_count":8,"default_branch":"develop","last_synced_at":"2025-04-10T22:31:58.334Z","etag":null,"topics":["boost","cpp","cpp11","urllib"],"latest_commit_sha":null,"homepage":"https://www.boost.org/doc/libs/master/libs/url/index.html","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/boostorg.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":null,"license":"LICENSE_1_0.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-11-27T16:06:18.000Z","updated_at":"2025-04-10T21:43:17.000Z","dependencies_parsed_at":"2023-11-18T02:01:52.825Z","dependency_job_id":"c17b60e5-5b06-46a7-ac1d-2e91c3f72d6b","html_url":"https://github.com/boostorg/url","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boostorg%2Furl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boostorg%2Furl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boostorg%2Furl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boostorg%2Furl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/boostorg","download_url":"https://codeload.github.com/boostorg/url/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248625402,"owners_count":21135512,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["boost","cpp","cpp11","urllib"],"created_at":"2024-11-13T15:06:28.881Z","updated_at":"2025-04-12T19:42:36.718Z","avatar_url":"https://github.com/boostorg.png","language":"C++","readme":"//\n// Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)\n//\n// Distributed under the Boost Software License, Version 1.0. (See accompanying\n// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//\n// Official repository: https://github.com/boostorg/url\n//\n\nhttps://www.boost.org/doc/libs/master/libs/url/doc/html/[image:https://raw.githubusercontent.com/vinniefalco/url/master/doc/images/repo-logo.png[Boost.URL]]\n\n[width=\"100%\",cols=\"7%,66%,27%\",options=\"header\",]\n|===\n|Branch |https://github.com/boostorg/url/tree/master[`master`]\n|https://github.com/boostorg/url/tree/develop[`develop`]\n\n|https://www.boost.org/doc/libs/master/libs/url/doc/html/[Docs]\n|https://www.boost.org/doc/libs/master/libs/url/doc/html/[image:https://img.shields.io/badge/docs-master-brightgreen.svg[Documentation]]\n|https://www.boost.org/doc/libs/develop/libs/url/doc/html/[image:https://img.shields.io/badge/docs-develop-brightgreen.svg[Documentation]]\n\n|https://github.com/[GitHub Actions]\n|https://github.com/boostorg/url/actions/workflows/ci.yml[image:https://github.com/boostorg/url/actions/workflows/ci.yml/badge.svg?branch=master[CI]]\n|https://github.com/boostorg/url/actions/workflows/ci.yml[image:https://github.com/boostorg/url/actions/workflows/ci.yml/badge.svg?branch=develop[CI]]\n\n|https://drone.io/[Drone]\n|https://drone.cpp.al/boostorg/url[image:https://drone.cpp.al/api/badges/boostorg/url/status.svg?ref=refs/heads/master[Build\nStatus]]\n|https://drone.cpp.al/boostorg/url[image:https://drone.cpp.al/api/badges/boostorg/url/status.svg?ref=refs/heads/develop[Build\nStatus]]\n\n|https://www.boost.org/development/tests/master/developer/summary.html[Matrix]\n|http://www.boost.org/development/tests/master/developer/url.html[image:https://img.shields.io/badge/matrix-master-brightgreen.svg[Matrix]]\n|http://www.boost.org/development/tests/develop/developer/url.html[image:https://img.shields.io/badge/matrix-develop-brightgreen.svg[Matrix]]\n\n|https://codecov.io[Codecov]\n|https://codecov.io/gh/boostorg/url/branch/master[image:https://codecov.io/gh/boostorg/url/branch/master/graph/badge.svg[codecov]]\n|https://codecov.io/gh/boostorg/url/branch/develop[image:https://codecov.io/gh/boostorg/url/branch/develop/graph/badge.svg[codecov]]\n|===\n\n== Boost.URL\n\nBoost.URL is a portable C++ library which provides containers and algorithms which model a \"URL,\" more formally described using the\nhttps://datatracker.ietf.org/doc/html/rfc3986[Uniform Resource Identifier (URI)]\nspecification (henceforth referred to as _rfc3986_).\nA URL is a compact sequence of characters that identifies an abstract or physical resource.\nFor example, this is a valid URL:\n\n[source]\n----\nhttps://www.example.com/path/to/file.txt?userid=1001\u0026pages=3\u0026results=full#page1\n----\n\nThis library understands the grammars related to URLs and provides functionality to validate, parse, examine, and modify urls, and apply normalization or resolution algorithms.\n\n=== Features\n\nWhile the library is general purpose, special care has been taken to ensure that the implementation and data representation are friendly to network programs which need to handle URLs efficiently and securely, including the case where the inputs come from untrusted sources.\nInterfaces are provided for using error codes instead of exceptions as needed, and most algorithms have the means to opt-out of dynamic memory allocation.\nAnother feature of the library is that all modifications leave the URL in a valid state.\nCode which uses this library is easy to read, flexible, and performant.\n\nNetwork programs such as those using Boost.Asio or Boost.Beast often encounter the need to process, generate, or modify URLs.\nThis library provides a very much needed modular component for handling these use-cases.\n\nBoost.URL offers these features:\n\n* C++11 as only requirement\n* Fast compilation, few templates\n* Strict compliance with _rfc3986_\n* Containers that maintain valid URLs\n* Parsing algorithms that work without exceptions\n* Control over storage and allocation for URLs\n* Support for `-fno-exceptions`, detected automatically\n* Features that work well on embedded devices\n\n[NOTE]\n====\nCurrently, the library does not handle\nhttps://www.rfc-editor.org/rfc/rfc3987.html[Internationalized Resource Identifiers (IRIs)].\nThese are different from URLs, come from Unicode strings instead of low-ASCII strings, and are covered by a separate specification.\n====\n\n=== Requirements\n\nThe library requires a compiler supporting at least C++11.\n\nAliases for standard types, such as _error_code_ or `string_view`, use their Boost equivalents.\n\nBoost.URL works great on embedded devices.\nIt can be used in a way that avoids all dynamic memory allocations.\nFurthermore, it offers alternative interfaces that work without exceptions if desired.\n\n=== Tested Compilers\n\nBoost.URL has been tested with the following compilers:\n\n* clang: 3.8, 4, 5, 6, 7, 8, 9, 10, 11, 12\n* gcc: 4.8, 4.9, 5, 6, 7, 8, 9, 10, 11\n* msvc: 14.1, 14.2, 14.3\n\nand these architectures: x86, x64, ARM64, S390x.\n\nWe do not test and support gcc 8.0.1.\n\n=== Quality Assurance\n\nThe development infrastructure for the library includes these per-commit analyses:\n\n* Coverage reports\n* Compilation and tests on Drone.io and GitHub Actions\n* Regular code audits for security\n\n=== Nomenclature\n\nVarious names have been used historically to refer to different flavors of resource identifiers, including _URI_, _URL_, _URN_, and even _IRI_.\nOver time, the distinction between URIs and URLs has disappeared when discussed in technical documents and informal works.\nIn this library we use the term _URL_ to refer to all strings which are valid according to the top-level grammar rules found in _rfc3986_.\n\n==== ABNF\n\nThis documentation uses the\nhttps://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form[Augmented Backus-Naur Form]\n(ABNF) notation of\nhttps://datatracker.ietf.org/doc/html/rfc5234[rfc5234]\nto specify particular grammars used by algorithms and containers.\nWhile a complete understanding of the notation is not a requirement for using the library, it may help for an understanding of how valid components of URLs are defined.\nIn particular, this is of interest to users who wish to compose parsing algorithms using the combinators provided by the library.\n\n=== Visual Studio Solution Generation\n\n[source,bash]\n----\ncmake -G \"Visual Studio 17 2022\" -A Win32 -B bin -D BUILD_TESTING=ON -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/msvc.cmake\ncmake -G \"Visual Studio 17 2022\" -A x64 -B bin64 -D BUILD_TESTING=ON -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/msvc.cmake\n----\n\n== Quick Look\n\n=== Integration\n\n[NOTE]\n====\nSample code and identifiers used throughout are written as if the following declarations are in effect:\n\n[source,c++]\n----\n#include \u003cboost/url.hpp\u003e\nusing namespace boost::urls;\n----\n====\n\nWe begin by including the library header file which brings all the symbols into scope.\n\n[source,c++]\n----\n#include \u003cboost/url.hpp\u003e\n----\n\nAlternatively, individual headers may be included to obtain the declarations for specific types.\n\nBoost.URL is a compiled library.\nYou need to install binaries in a location that can be found by your linker and link your program with the Boost.URL built library.\nIf you followed the [@http://www.boost.org/doc/libs/release/more/getting_started/index.html Boost Getting Started]\ninstructions, that's already been done for you.\n\nFor example, if you are using CMake, you can use the following commands to find and link the library:\n\n[source,cmake]\n----\nfind_package(Boost REQUIRED COMPONENTS url)\ntarget_link_libraries(my_program PRIVATE Boost::url)\n----\n\n=== Parsing\n\nSay you have the following URL that you want to parse:\n\n[source,c++]\n----\nboost::core::string_view s = \"https://user:pass@example.com:443/path/to/my%2dfile.txt?id=42\u0026name=John%20Doe+Jingleheimer%2DSchmidt#page%20anchor\";\n----\n\nIn this example, `string_view` is an alias to `boost::core::string_view`, a\n`string_view` implementation that is implicitly convertible from and to `std::string_view`.\n\nYou can parse the string by calling this function:\n\n[source,c++]\n----\nboost::system::result\u003curl_view\u003e r = parse_uri( s );\n----\n\nThe function _parse_uri_ returns an object of type `result\u003curl_view\u003e`\nwhich is a container resembling a variant that holds either an error or an object.\nA number of functions are available to parse different types of URL.\n\nWe can immediately call `result::value` to obtain a `url_view`.\n\n[source,c++]\n----\nurl_view u = r.value();\n----\n\nOr simply\n\n[source,c++]\n----\nurl_view u = *r;\n----\n\nfor unchecked access.\n\nWhen there are no errors, `result::value`\nreturns an instance of _url_view_, which holds the parsed result.\n\n`result::value` throws an exception on a parsing error.\nAlternatively, the functions `result::has_value` and `result::has_error` could also be used to check if the string has been parsed without errors.\n\n[NOTE]\n====\nIt is worth noting that _parse_uri_ does not allocate any memory dynamically.\nLike a `string_view`, a _url_view_ does not retain ownership of the underlying string buffer.\n\nAs long as the contents of the original string are unmodified, constructed URL views always contain a valid URL in its correctly serialized form.\n\nIf the input does not match the URL grammar, an error code is reported through _result_ rather than exceptions.\nExceptions only thrown on excessive input length.\n====\n\n=== Accessing\n\nAccessing the parts of the URL is easy:\n\n[source,c++]\n----\nurl_view u( \"https://user:pass@example.com:443/path/to/my%2dfile.txt?id=42\u0026name=John%20Doe+Jingleheimer%2DSchmidt#page%20anchor\" );\nassert(u.scheme() == \"https\");\nassert(u.authority().buffer() == \"user:pass@example.com:443\");\nassert(u.userinfo() == \"user:pass\");\nassert(u.user() == \"user\");\nassert(u.password() == \"pass\");\nassert(u.host() == \"example.com\");\nassert(u.port() == \"443\");\nassert(u.path() == \"/path/to/my-file.txt\");\nassert(u.query() == \"id=42\u0026name=John Doe Jingleheimer-Schmidt\");\nassert(u.fragment() == \"page anchor\");\n----\n\nURL paths can be further divided into path segments with the function `url_view::segments`.\n\nAlthough URL query strings are often used to represent key/value pairs, this interpretation is not defined by _rfc3986_.\nUsers can treat the query as a single entity.\n_url_view_ provides the function\n`url_view::params` to extract this view of key/value pairs.\n\n[source,c++]\n----\nfor (auto seg: u.segments())\nstd::cout \u003c\u003c seg \u003c\u003c \"\\n\";\nstd::cout \u003c\u003c \"\\n\";\n\nfor (auto param: u.params())\nstd::cout \u003c\u003c param.key \u003c\u003c \": \" \u003c\u003c param.value \u003c\u003c \"\\n\";\nstd::cout \u003c\u003c \"\\n\";\n----\n\nThe output is:\n\n[source]\n----\npath\nto\nmy-file.txt\n\nid: 42\nname: John Doe Jingleheimer-Schmidt\n\n----\n\nThese functions return views referring to substrings and sub-ranges of the underlying URL.\nBy simply referencing the relevant portion of the URL string internally, its components can represent percent-decoded strings and be converted to other types without any previous memory allocation.\n\n[source,c++]\n----\nstd::string h = u.host();\nassert(h == \"example.com\");\n----\n\nA special `string_token` type can also be used to specify how a portion of the URL should be encoded and returned.\n\n[source,c++]\n----\nstd::string h = \"host: \";\nu.host(string_token::append_to(h));\nassert(h == \"host: example.com\");\n----\n\nThese functions might also return empty strings\n\n[source,c++]\n----\nurl_view u1 = parse_uri( \"http://www.example.com\" ).value();\nassert(u1.fragment().empty());\nassert(!u1.has_fragment());\n----\n\nfor both empty and absent components\n\n[source,c++]\n----\nurl_view u2 = parse_uri( \"http://www.example.com/#\" ).value();\nassert(u2.fragment().empty());\nassert(u2.has_fragment());\n----\n\nMany components do not have corresponding functions such as\n`has_authority` to check for their existence.\nThis happens because some URL components are mandatory.\n\nWhen applicable, the encoded components can also be directly accessed through a `string_view` without any need to allocate memory:\n\n[source,c++]\n----\nstd::cout \u003c\u003c\n    \"url       : \" \u003c\u003c u                     \u003c\u003c \"\\n\"\n    \"scheme    : \" \u003c\u003c u.scheme()            \u003c\u003c \"\\n\"\n    \"authority : \" \u003c\u003c u.encoded_authority() \u003c\u003c \"\\n\"\n    \"userinfo  : \" \u003c\u003c u.encoded_userinfo()  \u003c\u003c \"\\n\"\n    \"user      : \" \u003c\u003c u.encoded_user()      \u003c\u003c \"\\n\"\n    \"password  : \" \u003c\u003c u.encoded_password()  \u003c\u003c \"\\n\"\n    \"host      : \" \u003c\u003c u.encoded_host()      \u003c\u003c \"\\n\"\n    \"port      : \" \u003c\u003c u.port()              \u003c\u003c \"\\n\"\n    \"path      : \" \u003c\u003c u.encoded_path()      \u003c\u003c \"\\n\"\n    \"query     : \" \u003c\u003c u.encoded_query()     \u003c\u003c \"\\n\"\n    \"fragment  : \" \u003c\u003c u.encoded_fragment()  \u003c\u003c \"\\n\";\n----\n\nThe output is:\n\n[source]\n----\nurl : https://user:pass@example.com:443/path/to/my%2dfile.txt?id=42\u0026name=John%20Doe+Jingleheimer%2DSchmidt#page%20anchor\nscheme : https\nauthority : user:pass@example.com:443\nuserinfo : user:pass\nuser : user\npassword : pass\nhost : example.com\nport : 443\npath : /path/to/my%2dfile.txt\nquery : id=42\u0026name=John%20Doe+Jingleheimer%2DSchmidt\nfragment : page%20anchor\n----\n\n=== Percent-Encoding\n\nAn instance of `decode_view` provides a number of functions to persist a decoded string:\n\n[source,c++]\n----\ndecode_view dv(\"id=42\u0026name=John%20Doe%20Jingleheimer%2DSchmidt\");\nstd::cout \u003c\u003c dv \u003c\u003c \"\\n\";\n----\n\nThe output is:\n\n[source]\n----\nid=42\u0026name=John Doe Jingleheimer-Schmidt\n----\n\n`decode_view` and its decoding functions are designed to perform no memory allocations unless the algorithm where its being used needs the result to be in another container.\nThe design also permits recycling objects to reuse their memory, and at least minimize the number of allocations by deferring them until the result is in fact needed by the application.\n\nIn the example above, the memory owned by `str` can be reused to store other results.\nThis is also useful when manipulating URLs:\n\n[source,c++]\n----\nu1.set_host(u2.host());\n----\n\nIf `u2.host()` returned a value type, then two memory allocations would be necessary for this operation.\nAnother common use case is converting URL path segments into filesystem paths:\n\n[source,c++]\n----\nboost::filesystem::path p;\nfor (auto seg: u.segments())\np.append(seg.begin(), seg.end());\nstd::cout \u003c\u003c \"path: \" \u003c\u003c p \u003c\u003c \"\\n\";\n----\n\nThe output is:\n\n[source]\n----\npath: \"path/to/my-file.txt\"\n----\n\nIn this example, only the internal allocations of `filesystem::path` need to happen.\nIn many common use cases, no allocations are necessary at all, such as finding the appropriate route for a URL in a web server:\n\n[source,c++]\n----\nauto match = [](\nstd::vector\u003cstd::string\u003e const\u0026 route,\nurl_view u)\n{\nauto segs = u.segments();\nif (route.size() != segs.size())\nreturn false;\nreturn std::equal(\nroute.begin(),\nroute.end(),\nsegs.begin());\n};\n----\n\nThis allows us to easily match files in the document root directory of a web server:\n\n[source,c++]\n----\nstd::vector\u003cstd::string\u003e route =\n{\"community\", \"reviews.html\"};\nif (match(route, u))\n{\nhandle_route(route, u);\n}\n----\n\n=== Compound elements\n\nThe path and query parts of the URL are treated specially by the library.\nWhile they can be accessed as individual encoded strings, they can also be accessed through special view types.\n\nThis code calls `encoded_segments` to obtain the path segments as a container that returns encoded strings:\n\n[source,c++]\n----\nsegments_view segs = u.encoded_segments();\nfor( auto v : segs )\n{\nstd::cout \u003c\u003c v \u003c\u003c \"\\n\";\n}\n----\n\nThe output is:\n\n[source]\n----\npath to my-file.txt\n----\n\nAs with other `url_view` functions which return encoded strings, the encoded segments container does not allocate memory.\nInstead, it returns views to the corresponding portions of the underlying encoded buffer referenced by the URL.\n\nAs with other library functions, `decode_view` permits accessing elements of composed elements while avoiding memory allocations entirely:\n\n[source,c++]\n----\nsegments_view segs = u.encoded_segments();\nfor( pct_string_view v : segs )\n{\ndecode_view dv = *v;\nstd::cout \u003c\u003c dv \u003c\u003c \"\\n\";\n}\n----\n\nThe output is:\n\n[source]\n----\npath to my-file.txt\n----\n\nOr with the encoded query parameters:\n\n[source,c++]\n----\nparams_encoded_view params_ref = u.encoded_params();\n\nfor( auto v : params_ref )\n{\n    decode_view dk(v.key);\n    decode_view dv(v.value);\n    std::cout \u003c\u003c\n        \"key = \" \u003c\u003c dk \u003c\u003c\n        \", value = \" \u003c\u003c dv \u003c\u003c \"\\n\";\n}\n----\n\nThe output is:\n\n[source]\n----\nkey = id, value = 42\nkey = name, value = John Doe\n----\n\n=== Modifying\n\nThe library provides the containers `url` and `static_url` which supporting modification of the URL contents.\nA `url` or `static_url` must be constructed from an existing `url_view`.\n\nUnlike the `url_view`, which does not gain ownership of the underlying character buffer, the `url` container uses the default allocator to control a resizable character buffer which it owns.\n\n[source,c++]\n----\nurl u = parse_uri( s ).value();\n----\n\nOn the other hand, a `static_url` has fixed-capacity storage and does not require dynamic memory allocations.\n\n[source,c++]\n----\nstatic_url\u003c1024\u003e su = parse_uri( s ).value();\n----\n\nObjects of type `url` are https://en.cppreference.com/w/cpp/concepts/regular[std::regular].\nSimilarly to built-in types, such as `int`, a `url` is copyable, movable, assignable, default constructible, and equality comparable.\nThey support all the inspection functions of `url_view`, and also provide functions to modify all components of the URL.\n\nChanging the scheme is easy:\n\n[source,c++]\n----\nu.set_scheme( \"https\" );\n----\n\nOr we can use a predefined constant:\n\n[source,c++]\n----\nu.set_scheme_id( scheme::https ); // equivalent to u.set_scheme( \"https\" );\n----\n\nThe scheme must be valid, however, or an exception is thrown.\nAll modifying functions perform validation on their input.\n\n* Attempting to set the URL scheme or port to an invalid string results in an exception.\n* Attempting to set other URL components to invalid strings will get the original input properly percent-encoded for that component.\n\nIt is not possible for a `url` to hold syntactically illegal text.\n\nModification functions return a reference to the object, so chaining is possible:\n\n[source,c++]\n----\nu.set_host_ipv4( ipv4_address( \"192.168.0.1\" ) )\n    .set_port_number( 8080 )\n    .remove_userinfo();\nstd::cout \u003c\u003c u \u003c\u003c \"\\n\";\n----\n\nThe output is:\n\n[source]\n----\nhttps://192.168.0.1:8080/path/to/my%2dfile.txt?id=42\u0026name=John%20Doe#page%20anchor\n----\n\nAll non-const operations offer the strong exception safety guarantee.\n\nThe path segment and query parameter containers returned by a `url` offer modifiable range functionality, using member functions of the container:\n\n[source,c++]\n----\nparams_ref p = u.params();\np.replace(p.find(\"name\"), {\"name\", \"John Doe\"});\nstd::cout \u003c\u003c u \u003c\u003c \"\\n\";\n----\n\nThe output is:\n\n[source]\n----\nhttps://192.168.0.1:8080/path/to/my%2dfile.txt?id=42\u0026name=Vinnie%20Falco#page%20anchor\n----\n\n=== Formatting\n\nAlgorithms to format URLs construct a mutable URL by parsing and applying arguments to a URL template.\nThe following example uses the `format`\nfunction to construct an absolute URL:\n\n[source,c++]\n----\nurl u = format(\"{}://{}:{}/rfc/{}\", \"https\", \"www.ietf.org\", 80, \"rfc2396.txt\");\nassert(u.buffer() == \"https://www.ietf.org:80/rfc/rfc2396.txt\");\n----\n\nThe rules for a format URL string are the same as for a `std::format_string`, where replacement fields are delimited by curly braces.\nThe URL type is inferred from the format string.\n\nThe URL components to which replacement fields belong are identified before replacement is applied and any invalid characters for that formatted argument are percent-escaped:\n\n[source,c++]\n----\nurl u = format(\"https://{}/{}\", \"www.boost.org\", \"Hello world!\");\nassert(u.buffer() == \"https://www.boost.org/Hello%20world!\");\n----\n\nDelimiters in the URL template, such as `\":\"`, `\"//\"`, `\"?\"`, and `\"#\"`, unambiguously associate each replacement field to a URL component.\nAll other characters are normalized to ensure the URL is valid:\n\n[source,c++]\n----\nurl u = format(\"{}:{}\", \"mailto\", \"someone@example.com\");\nassert(u.buffer() == \"mailto:someone@example.com\");\nassert(u.scheme() == \"mailto\");\nassert(u.path() == \"someone@example.com\");\n----\n\n[source,c++]\n----\nurl u = format(\"{}{}\", \"mailto:\", \"someone@example.com\");\nassert(u.buffer() == \"mailto%3Asomeone@example.com\");\nassert(!u.has_scheme());\nassert(u.path() == \"mailto:someone@example.com\");\nassert(u.encoded_path() == \"mailto%3Asomeone@example.com\");\n----\n\nThe function `format_to` can be used to format URLs into any modifiable URL container.\n\n[source,c++]\n----\nstatic_url\u003c50\u003e u;\nformat_to(u, \"{}://{}:{}/rfc/{}\", \"https\", \"www.ietf.org\", 80, \"rfc2396.txt\");\nassert(u.buffer() == \"https://www.ietf.org:80/rfc/rfc2396.txt\");\n----\n\nAs with `std::format`, positional and named arguments are supported.\n\n[source,c++]\n----\nurl u = format(\"{0}://{2}:{1}/{3}{4}{3}\", \"https\", 80, \"www.ietf.org\", \"abra\", \"cad\");\nassert(u.buffer() == \"https://www.ietf.org:80/abracadabra\");\n----\n\nThe `arg` function can be used to associate names with arguments:\n\n[source,c++]\n----\nurl u = format(\"https://example.com/~{username}\", arg(\"username\", \"mark\"));\nassert(u.buffer() == \"https://example.com/~mark\");\n----\n\nA second overload based on `std::initializer_list`\nis provided for both `format` and `format_to`.\n\nThese overloads can help with lists of named arguments:\n\n[source,c++]\n----\nboost::core::string_view fmt = \"{scheme}://{host}:{port}/{dir}/{file}\";\nurl u = format(fmt, {{\"scheme\", \"https\"}, {\"port\", 80}, {\"host\", \"example.com\"}, {\"dir\", \"path/to\"}, {\"file\", \"file.txt\"}});\nassert(u.buffer() == \"https://example.com:80/path/to/file.txt\");\n----\n\n== Documentation\n\nThe complete library documentation is available online at https://www.boost.org/doc/libs/master/libs/url/doc/html/index.html[boost.org].\n\n== Acknowledgments\n\nThis library wouldn't be where it is today without the help of\nhttps://github.com/pdimov[Peter Dimov], for design advice and general assistance.\n\n== License\n\nDistributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at\nhttps://www.boost.org/LICENSE_1_0.txt)\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboostorg%2Furl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fboostorg%2Furl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboostorg%2Furl/lists"}