11#include " RepoManager.h"
2+ #include < atomic>
23#include " util/Logger.h"
34
45#include < curl/curl.h>
@@ -21,7 +22,12 @@ bool RepoManager::validateUrl(const std::string& url) {
2122 return true ;
2223}
2324
24- static std::string fetchUrl (const std::string& url, std::string& error) {
25+ struct FetchCancelCtx { std::atomic<bool >* flag; };
26+ static int fetchProgress (void * ud, curl_off_t , curl_off_t , curl_off_t , curl_off_t ) {
27+ auto * ctx = static_cast <FetchCancelCtx*>(ud);
28+ return (ctx && ctx->flag && ctx->flag ->load ()) ? 1 : 0 ;
29+ }
30+ static std::string fetchUrl (const std::string& url, std::string& error, std::atomic<bool >* cancelFlag = nullptr ) {
2531 LOG_INFO (" fetchUrl: %s" , url.c_str ());
2632 std::string body;
2733 CURL * curl = curl_easy_init ();
@@ -30,12 +36,16 @@ static std::string fetchUrl(const std::string& url, std::string& error) {
3036 curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION , writeString);
3137 curl_easy_setopt (curl, CURLOPT_WRITEDATA , &body);
3238 curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION , 1L );
33- curl_easy_setopt (curl, CURLOPT_TIMEOUT , 30L );
34- curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT , 10L );
39+ curl_easy_setopt (curl, CURLOPT_TIMEOUT , 5L );
40+ curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT , 3L );
3541 curl_easy_setopt (curl, CURLOPT_NOSIGNAL , 1L );
3642 curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER , 0L );
3743 curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST , 0L );
3844 curl_easy_setopt (curl, CURLOPT_USERAGENT , " WiiUModStore/0.1" );
45+ FetchCancelCtx ctx{ cancelFlag };
46+ curl_easy_setopt (curl, CURLOPT_XFERINFOFUNCTION , fetchProgress);
47+ curl_easy_setopt (curl, CURLOPT_XFERINFODATA , &ctx);
48+ curl_easy_setopt (curl, CURLOPT_NOPROGRESS , 0L );
3949 LOG_INFO (" calling curl_easy_perform..." );
4050 CURLcode res = curl_easy_perform (curl);
4151 LOG_INFO (" curl returned: %d" , res);
@@ -56,7 +66,7 @@ static std::string resolveUrl(const std::string& base, const std::string& path)
5666 return base.substr (0 , slash + 1 ) + path;
5767}
5868
59- void RepoManager::fetch (const std::string& url) {
69+ void RepoManager::fetch (const std::string& url, std::atomic< bool >* cancelFlag ) {
6070 m_lastError.clear ();
6171 m_repo = {};
6272
@@ -67,7 +77,7 @@ void RepoManager::fetch(const std::string& url) {
6777 }
6878
6979 std::string err;
70- std::string body = fetchUrl (url, err);
80+ std::string body = fetchUrl (url, err, cancelFlag );
7181 if (body.empty ()) {
7282 m_lastError = " Network error: " + err;
7383 LOG_ERROR (" RepoManager: %s" , m_lastError.c_str ());
@@ -101,7 +111,7 @@ void RepoManager::fetch(const std::string& url) {
101111 std::string gameUrl = resolveUrl (url, gamePath);
102112 LOG_INFO (" RepoManager: fetching game from %s" , gameUrl.c_str ());
103113
104- std::string gameBody = fetchUrl (gameUrl, err);
114+ std::string gameBody = fetchUrl (gameUrl, err, cancelFlag );
105115 if (gameBody.empty ()) {
106116 LOG_WARN (" RepoManager: failed to fetch %s: %s" , gameUrl.c_str (), err.c_str ());
107117 continue ;
0 commit comments