mamba/include/fetch.hpp

127 lines
3.0 KiB
C++

// Copyright (c) 2019, QuantStack and Mamba Contributors
//
// Distributed under the terms of the BSD 3-Clause License.
//
// The full license is in the file LICENSE, distributed with this software.
#ifndef MAMBA_FETCH_HPP
#define MAMBA_FETCH_HPP
#include "nlohmann/json.hpp"
#include "output.hpp"
#include "validate.hpp"
extern "C"
{
#include <curl/curl.h>
#include <archive.h>
}
namespace mamba
{
class DownloadTarget
{
public:
DownloadTarget() = default;
DownloadTarget(const std::string& name, const std::string& url, const std::string& filename);
~DownloadTarget();
static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *self);
static size_t header_callback(char *buffer, size_t size, size_t nitems, void *self);
int progress_callback(void*, curl_off_t total_to_download, curl_off_t now_downloaded, curl_off_t, curl_off_t);
void set_mod_etag_headers(const nlohmann::json& mod_etag);
void set_progress_bar(ProgressProxy progress_proxy);
void set_expected_size(std::size_t size);
const std::string& name() const;
void init_curl_target(const std::string& url);
bool perform();
CURL* handle();
curl_off_t get_speed();
template <class C>
inline void set_finalize_callback(bool (C::*cb)(), C* data)
{
m_finalize_callback = std::bind(cb, data);
}
inline void set_ignore_failure(bool yes)
{
m_ignore_failure = yes;
}
inline bool ignore_failure() const
{
return m_ignore_failure;
}
void set_result(CURLcode r);
bool finalize();
bool can_retry();
CURL* retry();
CURLcode result;
bool failed = false;
int http_status = 10000;
curl_off_t downloaded_size = 0;
curl_off_t avg_speed = 0;
std::string final_url;
std::string etag, mod, cache_control;
private:
std::function<bool()> m_finalize_callback;
std::string m_name, m_filename, m_url;
// validation
std::size_t m_expected_size = 0;
std::chrono::steady_clock::time_point m_progress_throttle_time;
// retry & backoff
std::chrono::steady_clock::time_point m_next_retry;
std::size_t m_retry_wait_seconds = Context::instance().retry_timeout;
std::size_t m_retries = 0;
CURL* m_handle;
curl_slist* m_headers;
bool m_has_progress_bar = false;
bool m_ignore_failure = false;
ProgressProxy m_progress_bar;
std::ofstream m_file;
};
class MultiDownloadTarget
{
public:
MultiDownloadTarget();
~MultiDownloadTarget();
void add(DownloadTarget* target);
bool check_msgs(bool failfast);
bool download(bool failfast);
private:
std::vector<DownloadTarget*> m_targets;
std::vector<DownloadTarget*> m_retry_targets;
CURLM* m_handle;
};
}
#endif // MAMBA_FETCH_HPP