summaryrefslogtreecommitdiff
path: root/src/other_tools/utils/curl_url_handle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/other_tools/utils/curl_url_handle.cpp')
-rw-r--r--src/other_tools/utils/curl_url_handle.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/other_tools/utils/curl_url_handle.cpp b/src/other_tools/utils/curl_url_handle.cpp
index 90102e0b..5722a1cb 100644
--- a/src/other_tools/utils/curl_url_handle.cpp
+++ b/src/other_tools/utils/curl_url_handle.cpp
@@ -788,3 +788,49 @@ auto CurlURLHandle::NoproxyStringMatches(std::string const& no_proxy) noexcept
return std::nullopt;
}
}
+
+auto CurlURLHandle::ReplaceHostname(std::string const& url,
+ std::string const& hostname) noexcept
+ -> std::optional<std::string> {
+ try {
+ // We should not guess the scheme based on current hostname, as it may
+ // cause the URL with the new hostname to falsely fail; we set
+ // use_default_scheme instead. Additionally, we set use_no_authority to
+ // false as the given URL MUST already have a hostname to be replaced.
+ if (auto parsed_url = CreatePermissive(url,
+ false /*use_guess_scheme*/,
+ true /*use_default_scheme*/,
+ true /*use_non_support_scheme*/,
+ false /*use_no_authority*/,
+ true /*use_path_as_is*/,
+ true /*use_allow_space*/,
+ true /*ignore_fatal*/)) {
+ if (*parsed_url == nullptr) {
+ return std::nullopt;
+ }
+ auto rc = curl_url_set(parsed_url.value()->handle_.get(),
+ CURLUPART_HOST,
+ hostname.c_str(),
+ 0U);
+ if (rc != CURLUE_OK) {
+ Logger::Log(LogLevel::Debug,
+ "CurlURLHandle: setting hostname {} in URL {} "
+ "failed with:\n{}",
+ hostname,
+ url,
+ curl_url_strerror(rc));
+ return std::nullopt;
+ }
+ return parsed_url.value()->GetURL(false /*use_default_port*/,
+ true /*use_default_scheme*/,
+ false /*use_no_default_port*/,
+ true /*ignore_fatal*/);
+ }
+ } catch (std::exception const& ex) {
+ Logger::Log(LogLevel::Debug,
+ "CurlURLHandle: Replacing URL hostname failed unexpectedly "
+ "with:\n{}",
+ ex.what());
+ }
+ return std::nullopt;
+}