Prepare for boost::url upgrade

The new boost URL now interops properly with std::string_view, which is
great, and cleans up a bunch of mediocre code to convert one to another.
It has also been pulled into boost-proper, so we no longer need a
boost-url dependency that's separate.

Unfortunately, boost url makes these improvements by changing
boost::string_view for boost::urls::const_string, which causes us to
have some compile errors on the missing type.

The bulk of these changes fall into a couple categories, and have to be
executed in one commit.
string() is replaced with buffer() on the url and url_view types
boost::string_view is replaced by std::string_view for many times, in
many cases removing a temporary that we had in the code previously.

Tested: Code compiles with boost 1.81.0 beta.
Redfish service validator passes.
Pretty good unit test coverage for URL-specific use cases.

Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I8d3dc89b53d1cc390887fe53605d4867f75f76fd
diff --git a/.clang-tidy b/.clang-tidy
index 8af0822..7d9979f 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -9,7 +9,6 @@
 bugprone-copy-constructor-init,
 bugprone-dangling-handle,
 bugprone-dynamic-static-initializers,
-bugprone-exception-escape,
 bugprone-fold-init-type,
 bugprone-forward-declaration-namespace,
 bugprone-forwarding-reference-overload,
diff --git a/http/http_request.hpp b/http/http_request.hpp
index deaba31..d203077 100644
--- a/http/http_request.hpp
+++ b/http/http_request.hpp
@@ -116,16 +116,14 @@
   private:
     bool setUrlInfo()
     {
-        auto result = boost::urls::parse_relative_ref(
-            boost::urls::string_view(target().data(), target().size()));
+        auto result = boost::urls::parse_relative_ref(target());
 
         if (!result)
         {
             return false;
         }
         urlView = *result;
-        url = std::string_view(urlView.encoded_path().data(),
-                               urlView.encoded_path().size());
+        url = urlView.encoded_path();
         return true;
     }
 };
diff --git a/http/utility.hpp b/http/utility.hpp
index b1b38da..4f5cea7 100644
--- a/http/utility.hpp
+++ b/http/utility.hpp
@@ -4,7 +4,9 @@
 #include <openssl/crypto.h>
 
 #include <boost/callable_traits.hpp>
+#include <boost/url/parse.hpp>
 #include <boost/url/url.hpp>
+#include <boost/url/url_view.hpp>
 #include <nlohmann/json.hpp>
 
 #include <array>
@@ -616,13 +618,13 @@
   public:
     UrlParseResult operator()(std::string& output)
     {
-        output = std::string_view(segment.data(), segment.size());
+        output = segment;
         return UrlParseResult::Continue;
     }
 
     UrlParseResult operator()(std::string_view expected)
     {
-        if (std::string_view(segment.data(), segment.size()) == expected)
+        if (segment == expected)
         {
             return UrlParseResult::Continue;
         }
@@ -634,13 +636,12 @@
         return UrlParseResult::Done;
     }
 
-    explicit UrlSegmentMatcherVisitor(
-        const boost::urls::string_value& segmentIn) :
+    explicit UrlSegmentMatcherVisitor(std::string_view segmentIn) :
         segment(segmentIn)
     {}
 
   private:
-    const boost::urls::string_value& segment;
+    std::string_view segment;
 };
 
 inline bool readUrlSegments(const boost::urls::url_view& urlView,
@@ -766,9 +767,8 @@
                                 std::string& host, uint16_t& port,
                                 std::string& path)
 {
-    boost::string_view urlBoost(destUrl.data(), destUrl.size());
     boost::urls::result<boost::urls::url_view> url =
-        boost::urls::parse_uri(urlBoost);
+        boost::urls::parse_uri(destUrl);
     if (!url)
     {
         return false;
@@ -781,11 +781,9 @@
 
     port = setPortDefaults(url.value());
 
-    host = std::string_view(url->encoded_host().data(),
-                            url->encoded_host().size());
+    host = url->encoded_host();
 
-    path = std::string_view(url->encoded_path().data(),
-                            url->encoded_path().size());
+    path = url->encoded_path();
     if (path.empty())
     {
         path = "/";
@@ -793,15 +791,13 @@
     if (url->has_fragment())
     {
         path += '#';
-        path += std::string_view(url->encoded_fragment().data(),
-                                 url->encoded_fragment().size());
+        path += url->encoded_fragment();
     }
 
     if (url->has_query())
     {
         path += '?';
-        path += std::string_view(url->encoded_query().data(),
-                                 url->encoded_query().size());
+        path += url->encoded_query();
     }
 
     return true;
@@ -819,7 +815,7 @@
     // NOLINTNEXTLINE(readability-identifier-naming)
     static void to_json(json& j, const boost::urls::url& url)
     {
-        j = url.string();
+        j = url.buffer();
     }
 };
 
@@ -829,7 +825,7 @@
     // NOLINTNEXTLINE(readability-identifier-naming)
     static void to_json(json& j, const boost::urls::url_view& url)
     {
-        j = url.string();
+        j = url.buffer();
     }
 };
 } // namespace nlohmann
diff --git a/http/websocket.hpp b/http/websocket.hpp
index ecaa1d2..3e4ef0c 100644
--- a/http/websocket.hpp
+++ b/http/websocket.hpp
@@ -218,8 +218,8 @@
                 }
                 if (closeHandler)
                 {
-                    std::string_view reason = ws.reason().reason;
-                    closeHandler(*this, std::string(reason));
+                    std::string reason{ws.reason().reason.c_str()};
+                    closeHandler(*this, reason);
                 }
                 return;
             }
diff --git a/meson.build b/meson.build
index 4c03ef9..967b309 100644
--- a/meson.build
+++ b/meson.build
@@ -168,8 +168,8 @@
      '-Wduplicated-cond',
      '-Wduplicated-branches',
      '-Wlogical-op',
-     '-Wunused-parameter',
      '-Wnull-dereference',
+     '-Wunused-parameter',
      '-Wdouble-promotion',
      '-Wshadow',
      '-Wno-psabi',
@@ -241,7 +241,6 @@
   '-DBOOST_ASIO_NO_DEPRECATED',
   '-DBOOST_ASIO_SEPARATE_COMPILATION',
   '-DBOOST_BEAST_SEPARATE_COMPILATION',
-  '-DBOOST_BEAST_USE_STD_STRING_VIEW',
   '-DBOOST_EXCEPTION_DISABLE',
   '-DBOOST_URL_NO_SOURCE_LOCATION',
   '-DJSON_NOEXCEPTION',
@@ -285,21 +284,13 @@
 endif
 bmcweb_dependencies += nlohmann_json
 
-boost = dependency('boost',version : '>=1.80.0', required : false, include_type: 'system')
+boost = dependency('boost',version : '>=1.81.0', required : false, include_type: 'system')
 if not boost.found()
   boost = subproject('boost', required: true).get_variable('boost_dep')
   boost = boost.as_system('system')
 endif
 bmcweb_dependencies += boost
 
-if cxx.has_header('boost/url/url_view.hpp')
-  boost_url = declare_dependency()
-else
-  boost_url = subproject('boost-url', required: true).get_variable('boost_url_dep')
-  boost_url = boost_url.as_system('system')
-endif
-bmcweb_dependencies += boost_url
-
 if get_option('tests').enabled()
   gtest = dependency('gtest', main: true,disabler: true, required : false)
   gmock = dependency('gmock', required : false)
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
index 7f3b43a..6f1e91b 100644
--- a/redfish-core/include/event_service_manager.hpp
+++ b/redfish-core/include/event_service_manager.hpp
@@ -519,7 +519,7 @@
         {
             if (std::find(metricReportDefinitions.begin(),
                           metricReportDefinitions.end(),
-                          mrdUri.string()) == metricReportDefinitions.end())
+                          mrdUri.buffer()) == metricReportDefinitions.end())
             {
                 return;
             }
diff --git a/redfish-core/include/redfish_aggregator.hpp b/redfish-core/include/redfish_aggregator.hpp
index 99da8ee..8170b64 100644
--- a/redfish-core/include/redfish_aggregator.hpp
+++ b/redfish-core/include/redfish_aggregator.hpp
@@ -312,7 +312,7 @@
                     BMCWEB_LOG_ERROR << "Port value out of range";
                     return;
                 }
-                url.set_port(static_cast<uint16_t>(*propVal));
+                url.set_port(std::to_string(static_cast<uint16_t>(*propVal)));
             }
 
             else if (prop.first == "AuthType")
@@ -435,8 +435,7 @@
         }
 
         // We didn't recognize the prefix and need to return a 404
-        boost::urls::string_value name = req.urlView.segments().back();
-        std::string_view nameStr(name.data(), name.size());
+        std::string_view nameStr = req.urlView.segments().back();
         messages::resourceNotFound(asyncResp->res, "", nameStr);
     }
 
@@ -461,9 +460,7 @@
             // don't need to write an error code
             if (isCollection == AggregationType::Resource)
             {
-                boost::urls::string_value name =
-                    sharedReq->urlView.segments().back();
-                std::string_view nameStr(name.data(), name.size());
+                std::string_view nameStr = sharedReq->urlView.segments().back();
                 messages::resourceNotFound(asyncResp->res, "", nameStr);
             }
             return;
diff --git a/redfish-core/include/utils/collection.hpp b/redfish-core/include/utils/collection.hpp
index 97f622d..f117302 100644
--- a/redfish-core/include/utils/collection.hpp
+++ b/redfish-core/include/utils/collection.hpp
@@ -29,7 +29,7 @@
                          const char* subtree = "/xyz/openbmc_project/inventory")
 {
     BMCWEB_LOG_DEBUG << "Get collection members for: "
-                     << collectionPath.string();
+                     << collectionPath.buffer();
     crow::connections::systemBus->async_method_call(
         [collectionPath, aResp{std::move(aResp)}](
             const boost::system::error_code ec,
diff --git a/redfish-core/include/utils/query_param.hpp b/redfish-core/include/utils/query_param.hpp
index fec5384..bfe1001 100644
--- a/redfish-core/include/utils/query_param.hpp
+++ b/redfish-core/include/utils/query_param.hpp
@@ -16,7 +16,6 @@
 #include <boost/beast/http/status.hpp>
 #include <boost/beast/http/verb.hpp>
 #include <boost/url/params_view.hpp>
-#include <boost/url/string.hpp>
 #include <nlohmann/json.hpp>
 
 #include <algorithm>
@@ -374,80 +373,78 @@
     return true;
 }
 
-inline std::optional<Query>
-    parseParameters(const boost::urls::params_view& urlParams,
-                    crow::Response& res)
+inline std::optional<Query> parseParameters(boost::urls::params_view urlParams,
+                                            crow::Response& res)
 {
     Query ret;
     for (const boost::urls::params_view::value_type& it : urlParams)
     {
-        std::string_view key(it.key.data(), it.key.size());
-        std::string_view value(it.value.data(), it.value.size());
-        if (key == "only")
+        if (it.key == "only")
         {
             if (!it.value.empty())
             {
-                messages::queryParameterValueFormatError(res, value, key);
+                messages::queryParameterValueFormatError(res, it.value, it.key);
                 return std::nullopt;
             }
             ret.isOnly = true;
         }
-        else if (key == "$expand" && bmcwebInsecureEnableQueryParams)
+        else if (it.key == "$expand" && bmcwebInsecureEnableQueryParams)
         {
-            if (!getExpandType(value, ret))
+            if (!getExpandType(it.value, ret))
             {
-                messages::queryParameterValueFormatError(res, value, key);
+                messages::queryParameterValueFormatError(res, it.value, it.key);
                 return std::nullopt;
             }
         }
-        else if (key == "$top")
+        else if (it.key == "$top")
         {
-            QueryError topRet = getTopParam(value, ret);
+            QueryError topRet = getTopParam(it.value, ret);
             if (topRet == QueryError::ValueFormat)
             {
-                messages::queryParameterValueFormatError(res, value, key);
+                messages::queryParameterValueFormatError(res, it.value, it.key);
                 return std::nullopt;
             }
             if (topRet == QueryError::OutOfRange)
             {
                 messages::queryParameterOutOfRange(
-                    res, value, "$top", "0-" + std::to_string(Query::maxTop));
+                    res, it.value, "$top",
+                    "0-" + std::to_string(Query::maxTop));
                 return std::nullopt;
             }
         }
-        else if (key == "$skip")
+        else if (it.key == "$skip")
         {
-            QueryError topRet = getSkipParam(value, ret);
+            QueryError topRet = getSkipParam(it.value, ret);
             if (topRet == QueryError::ValueFormat)
             {
-                messages::queryParameterValueFormatError(res, value, key);
+                messages::queryParameterValueFormatError(res, it.value, it.key);
                 return std::nullopt;
             }
             if (topRet == QueryError::OutOfRange)
             {
                 messages::queryParameterOutOfRange(
-                    res, value, key,
+                    res, it.value, it.key,
                     "0-" + std::to_string(std::numeric_limits<size_t>::max()));
                 return std::nullopt;
             }
         }
-        else if (key == "$select")
+        else if (it.key == "$select")
         {
-            if (!getSelectParam(value, ret))
+            if (!getSelectParam(it.value, ret))
             {
-                messages::queryParameterValueFormatError(res, value, key);
+                messages::queryParameterValueFormatError(res, it.value, it.key);
                 return std::nullopt;
             }
         }
         else
         {
             // Intentionally ignore other errors Redfish spec, 7.3.1
-            if (key.starts_with("$"))
+            if (it.key.starts_with("$"))
             {
                 // Services shall return... The HTTP 501 Not Implemented
                 // status code for any unsupported query parameters that
                 // start with $ .
-                messages::queryParameterValueFormatError(res, value, key);
+                messages::queryParameterValueFormatError(res, it.value, it.key);
                 res.result(boost::beast::http::status::not_implemented);
                 return std::nullopt;
             }
diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp
index 33c8c9c..0fb3a68 100644
--- a/redfish-core/lib/metric_report.hpp
+++ b/redfish-core/lib/metric_report.hpp
@@ -42,16 +42,12 @@
                        const TimestampReadings& timestampReadings)
 {
     json["@odata.type"] = "#MetricReport.v1_3_0.MetricReport";
-    json["@odata.id"] =
-        crow::utility::urlFromPieces("redfish", "v1", "TelemetryService",
-                                     "MetricReports", id)
-            .string();
+    json["@odata.id"] = crow::utility::urlFromPieces(
+        "redfish", "v1", "TelemetryService", "MetricReports", id);
     json["Id"] = id;
     json["Name"] = id;
-    json["MetricReportDefinition"]["@odata.id"] =
-        crow::utility::urlFromPieces("redfish", "v1", "TelemetryService",
-                                     "MetricReportDefinitions", id)
-            .string();
+    json["MetricReportDefinition"]["@odata.id"] = crow::utility::urlFromPieces(
+        "redfish", "v1", "TelemetryService", "MetricReportDefinitions", id);
 
     const auto& [timestamp, readings] = timestampReadings;
     json["Timestamp"] = redfish::time_utils::getDateTimeUintMs(timestamp);
diff --git a/redfish-core/lib/metric_report_definition.hpp b/redfish-core/lib/metric_report_definition.hpp
index bc1b894..e6308eb 100644
--- a/redfish-core/lib/metric_report_definition.hpp
+++ b/redfish-core/lib/metric_report_definition.hpp
@@ -34,16 +34,13 @@
 {
     asyncResp->res.jsonValue["@odata.type"] =
         "#MetricReportDefinition.v1_3_0.MetricReportDefinition";
-    asyncResp->res.jsonValue["@odata.id"] =
-        crow::utility::urlFromPieces("redfish", "v1", "TelemetryService",
-                                     "MetricReportDefinitions", id)
-            .string();
+    asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
+        "redfish", "v1", "TelemetryService", "MetricReportDefinitions", id);
     asyncResp->res.jsonValue["Id"] = id;
     asyncResp->res.jsonValue["Name"] = id;
     asyncResp->res.jsonValue["MetricReport"]["@odata.id"] =
         crow::utility::urlFromPieces("redfish", "v1", "TelemetryService",
-                                     "MetricReports", id)
-            .string();
+                                     "MetricReports", id);
     asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
     asyncResp->res.jsonValue["ReportUpdates"] = "Overwrite";
 
diff --git a/redfish-core/lib/redfish_v1.hpp b/redfish-core/lib/redfish_v1.hpp
index fa3ca36..95db449 100644
--- a/redfish-core/lib/redfish_v1.hpp
+++ b/redfish-core/lib/redfish_v1.hpp
@@ -38,12 +38,11 @@
 
     BMCWEB_LOG_ERROR << "404 on path " << path;
 
-    boost::urls::string_value name = req.urlView.segments().back();
-    std::string_view nameStr(name.data(), name.size());
+    std::string name = req.urlView.segments().back();
     // Note, if we hit the wildcard route, we don't know the "type" the user was
     // actually requesting, but giving them a return with an empty string is
     // still better than nothing.
-    messages::resourceNotFound(asyncResp->res, "", nameStr);
+    messages::resourceNotFound(asyncResp->res, "", name);
 }
 
 inline void redfish405(App& app, const crow::Request& req,
diff --git a/redfish-core/lib/virtual_media.hpp b/redfish-core/lib/virtual_media.hpp
index af38163..402cbbd 100644
--- a/redfish-core/lib/virtual_media.hpp
+++ b/redfish-core/lib/virtual_media.hpp
@@ -32,12 +32,12 @@
 inline std::string getTransferProtocolTypeFromUri(const std::string& imageUri)
 {
     boost::urls::result<boost::urls::url_view> url =
-        boost::urls::parse_uri(boost::string_view(imageUri));
+        boost::urls::parse_uri(imageUri);
     if (!url)
     {
         return "None";
     }
-    boost::string_view scheme = url->scheme();
+    std::string_view scheme = url->scheme();
     if (scheme == "smb")
     {
         return "CIFS";
@@ -294,7 +294,7 @@
 inline std::optional<TransferProtocol>
     getTransferProtocolFromUri(const boost::urls::url_view& imageUri)
 {
-    boost::string_view scheme = imageUri.scheme();
+    std::string_view scheme = imageUri.scheme();
     if (scheme == "smb")
     {
         return TransferProtocol::smb;
@@ -401,7 +401,7 @@
         return false;
     }
     boost::urls::result<boost::urls::url_view> url =
-        boost::urls::parse_uri(boost::string_view(imageUrl));
+        boost::urls::parse_uri(imageUrl);
     if (!url)
     {
         messages::actionParameterValueFormatError(res, imageUrl, "Image",
diff --git a/redfish-core/src/error_messages.cpp b/redfish-core/src/error_messages.cpp
index 5f055bf..bee3140 100644
--- a/redfish-core/src/error_messages.cpp
+++ b/redfish-core/src/error_messages.cpp
@@ -206,8 +206,7 @@
  */
 nlohmann::json resourceMissingAtURI(const boost::urls::url_view& arg1)
 {
-    std::array<std::string_view, 1> args{
-        std::string_view{arg1.data(), arg1.size()}};
+    std::array<std::string_view, 1> args{arg1.buffer()};
     return getLog(redfish::registries::base::Index::resourceMissingAtURI, args);
 }
 
@@ -293,9 +292,8 @@
 nlohmann::json resourceAtUriUnauthorized(const boost::urls::url_view& arg1,
                                          std::string_view arg2)
 {
-    return getLog(
-        redfish::registries::base::Index::resourceAtUriUnauthorized,
-        std::to_array({std::string_view{arg1.data(), arg1.size()}, arg2}));
+    return getLog(redfish::registries::base::Index::resourceAtUriUnauthorized,
+                  std::to_array<std::string_view>({arg1.buffer(), arg2}));
 }
 
 void resourceAtUriUnauthorized(crow::Response& res,
@@ -524,10 +522,9 @@
  */
 nlohmann::json resourceAtUriInUnknownFormat(const boost::urls::url_view& arg1)
 {
-    std::string_view arg1str{arg1.data(), arg1.size()};
     return getLog(
         redfish::registries::base::Index::resourceAtUriInUnknownFormat,
-        std::to_array({arg1str}));
+        std::to_array<std::string_view>({arg1.buffer()}));
 }
 
 void resourceAtUriInUnknownFormat(crow::Response& res,
@@ -701,9 +698,8 @@
 nlohmann::json resetRequired(const boost::urls::url_view& arg1,
                              std::string_view arg2)
 {
-    std::string_view arg1str(arg1.data(), arg1.size());
     return getLog(redfish::registries::base::Index::resetRequired,
-                  std::to_array({arg1str, arg2}));
+                  std::to_array<std::string_view>({arg1.buffer(), arg2}));
 }
 
 void resetRequired(crow::Response& res, const boost::urls::url_view& arg1,
@@ -786,8 +782,7 @@
 {
     return getLog(
         redfish::registries::base::Index::propertyValueResourceConflict,
-        std::to_array(
-            {arg1, arg2, std::string_view{arg3.data(), arg3.size()}}));
+        std::to_array<std::string_view>({arg1, arg2, arg3.buffer()}));
 }
 
 void propertyValueResourceConflict(crow::Response& res, std::string_view arg1,
@@ -852,9 +847,8 @@
  */
 nlohmann::json resourceCreationConflict(const boost::urls::url_view& arg1)
 {
-    std::string_view arg1str(arg1.data(), arg1.size());
     return getLog(redfish::registries::base::Index::resourceCreationConflict,
-                  std::to_array({arg1str}));
+                  std::to_array<std::string_view>({arg1.buffer()}));
 }
 
 void resourceCreationConflict(crow::Response& res,
@@ -1005,9 +999,8 @@
  */
 nlohmann::json couldNotEstablishConnection(const boost::urls::url_view& arg1)
 {
-    std::string_view arg1str(arg1.data(), arg1.size());
     return getLog(redfish::registries::base::Index::couldNotEstablishConnection,
-                  std::to_array({arg1str}));
+                  std::to_array<std::string_view>({arg1.buffer()}));
 }
 
 void couldNotEstablishConnection(crow::Response& res,
@@ -1131,10 +1124,9 @@
 nlohmann::json sourceDoesNotSupportProtocol(const boost::urls::url_view& arg1,
                                             std::string_view arg2)
 {
-    std::string_view arg1str(arg1.data(), arg1.size());
     return getLog(
         redfish::registries::base::Index::sourceDoesNotSupportProtocol,
-        std::to_array({arg1str, arg2}));
+        std::to_array<std::string_view>({arg1.buffer(), arg2}));
 }
 
 void sourceDoesNotSupportProtocol(crow::Response& res,
@@ -1192,9 +1184,8 @@
  */
 nlohmann::json accessDenied(const boost::urls::url_view& arg1)
 {
-    std::string_view arg1str(arg1.data(), arg1.size());
     return getLog(redfish::registries::base::Index::accessDenied,
-                  std::to_array({arg1str}));
+                  std::to_array<std::string_view>({arg1.buffer()}));
 }
 
 void accessDenied(crow::Response& res, const boost::urls::url_view& arg1)
@@ -1360,9 +1351,8 @@
  */
 nlohmann::json invalidObject(const boost::urls::url_view& arg1)
 {
-    std::string_view arg1str(arg1.data(), arg1.size());
     return getLog(redfish::registries::base::Index::invalidObject,
-                  std::to_array({arg1str}));
+                  std::to_array<std::string_view>({arg1.buffer()}));
 }
 
 void invalidObject(crow::Response& res, const boost::urls::url_view& arg1)
@@ -1707,9 +1697,8 @@
 
 nlohmann::json passwordChangeRequired(const boost::urls::url_view& arg1)
 {
-    std::string_view arg1str(arg1.data(), arg1.size());
     return getLog(redfish::registries::base::Index::passwordChangeRequired,
-                  std::to_array({arg1str}));
+                  std::to_array<std::string_view>({arg1.buffer()}));
 }
 
 /**
diff --git a/subprojects/boost-url.wrap b/subprojects/boost-url.wrap
deleted file mode 100644
index d19baba..0000000
--- a/subprojects/boost-url.wrap
+++ /dev/null
@@ -1,6 +0,0 @@
-[wrap-git]
-directory = boost-url-git
-
-revision = d740a92d38e3a8f4d5b2153f53b82f1c98e312ab
-url = https://github.com/CPPAlliance/url.git
-patch_directory = boost-url
diff --git a/subprojects/boost.wrap b/subprojects/boost.wrap
index 75735f4..1e44ebf 100644
--- a/subprojects/boost.wrap
+++ b/subprojects/boost.wrap
@@ -1,9 +1,9 @@
 [wrap-file]
-directory = boost_1_80_0
+directory = boost_1_81_0
 
-source_url = https://downloads.yoctoproject.org/mirror/sources/boost_1_80_0.tar.bz2
-source_hash = 1e19565d82e43bc59209a168f5ac899d3ba471d55c7610c677d4ccf2c9c500c0
-source_filename = 1_80_0.tar.bz2
+source_url = https://boostorg.jfrog.io/artifactory/main/release/1.81.0/source/boost_1_81_0.tar.bz2
+source_hash = 941c568e7ac79aa448ac28c98a5ec391fd1317170953c487bcf977c6ee6061ce
+source_filename = 1_81_0.tar.bz2
 
 patch_directory = boost
 
diff --git a/test/http/utility_test.cpp b/test/http/utility_test.cpp
index 58a2865..2e0c82e 100644
--- a/test/http/utility_test.cpp
+++ b/test/http/utility_test.cpp
@@ -84,16 +84,16 @@
 TEST(Utility, UrlFromPieces)
 {
     boost::urls::url url = urlFromPieces("redfish", "v1", "foo");
-    EXPECT_EQ(std::string_view(url.data(), url.size()), "/redfish/v1/foo");
+    EXPECT_EQ(url.buffer(), "/redfish/v1/foo");
 
     url = urlFromPieces("/", "badString");
-    EXPECT_EQ(std::string_view(url.data(), url.size()), "/%2f/badString");
+    EXPECT_EQ(url.buffer(), "/%2F/badString");
 
     url = urlFromPieces("bad?tring");
-    EXPECT_EQ(std::string_view(url.data(), url.size()), "/bad%3ftring");
+    EXPECT_EQ(url.buffer(), "/bad%3Ftring");
 
     url = urlFromPieces("/", "bad&tring");
-    EXPECT_EQ(std::string_view(url.data(), url.size()), "/%2f/bad&tring");
+    EXPECT_EQ(url.buffer(), "/%2F/bad&tring");
 }
 
 TEST(Utility, readUrlSegments)
@@ -232,7 +232,7 @@
 
     appendUrlPieces(url, "/", "bad&tring");
     EXPECT_EQ(std::string_view(url.data(), url.size()),
-              "/redfish/v1/foo/bar/%2f/bad&tring");
+              "/redfish/v1/foo/bar/%2F/bad&tring");
 }
 
 } // namespace