diff options
Diffstat (limited to 'src/other_tools/utils/content.hpp')
-rw-r--r-- | src/other_tools/utils/content.hpp | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/src/other_tools/utils/content.hpp b/src/other_tools/utils/content.hpp index 907af852..19877263 100644 --- a/src/other_tools/utils/content.hpp +++ b/src/other_tools/utils/content.hpp @@ -21,12 +21,14 @@ #include "src/buildtool/common/user_structs.hpp" #include "src/buildtool/crypto/hasher.hpp" #include "src/buildtool/logging/log_level.hpp" +#include "src/other_tools/just_mr/mirrors.hpp" #include "src/other_tools/utils/curl_easy_handle.hpp" +#include "src/other_tools/utils/curl_url_handle.hpp" // Utilities related to the content of an archive /// \brief Fetches a file from the internet and stores its content in memory. -/// Returns the content. +/// \returns the content. [[nodiscard]] static auto NetworkFetch(std::string const& fetch_url, CAInfoPtr const& ca_info) noexcept -> std::optional<std::string> { @@ -38,6 +40,66 @@ return curl_handle->DownloadToString(fetch_url); } +/// \brief Fetches a file from the internet and stores its content in memory. +/// Tries not only a given remote, but also all associated remote locations. +/// \returns the content. +[[nodiscard]] static auto NetworkFetchWithMirrors( + std::string const& fetch_url, + std::vector<std::string> const& mirrors, + CAInfoPtr const& ca_info, + MirrorsPtr const& additional_mirrors) noexcept + -> std::optional<std::string> { + // first, try the local mirrors + std::optional<std::string> data{std::nullopt}; + auto local_mirrors = + MirrorsUtils::GetLocalMirrors(additional_mirrors, fetch_url); + for (auto const& mirror : local_mirrors) { + if (data = NetworkFetch(mirror, ca_info); data) { + break; + } + } + if (not data) { + // get preferred hostnames list + auto preferred_hostnames = + MirrorsUtils::GetPreferredHostnames(additional_mirrors); + // try the main fetch URL, but with each of the preferred hostnames + for (auto const& hostname : preferred_hostnames) { + if (auto preferred_url = + CurlURLHandle::ReplaceHostname(fetch_url, hostname)) { + if (data = NetworkFetch(*preferred_url, ca_info); data) { + break; + } + } + } + if (not data) { + // now try the main fetch URL + if (data = NetworkFetch(fetch_url, ca_info); not data) { + // try the mirrors, in order, if given + for (auto const& mirror : mirrors) { + // first use with preferred hostnames... + for (auto const& hostname : preferred_hostnames) { + if (auto preferred_mirror = + CurlURLHandle::ReplaceHostname(mirror, + hostname)) { + if (data = NetworkFetch(*preferred_mirror, ca_info); + data) { + break; + } + } + } + // ...then the original mirror + if (not data) { + if (data = NetworkFetch(mirror, ca_info); data) { + break; + } + } + } + } + } + } + return data; +} + template <Hasher::HashType type> [[nodiscard]] static auto GetContentHash(std::string const& data) noexcept -> std::string { |