diff options
Diffstat (limited to 'src/other_tools/utils/curl_url_handle.cpp')
-rw-r--r-- | src/other_tools/utils/curl_url_handle.cpp | 46 |
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; +} |