2424#include  < cstdarg> 
2525#include  < filesystem> 
2626#include  < fstream> 
27+ #include  < future> 
2728#include  < list> 
2829#include  < regex> 
2930#include  < set> 
3637#if  defined(LLAMA_USE_CURL)
3738#include  < curl/curl.h> 
3839#include  < curl/easy.h> 
39- #include  < future> 
4040#endif 
4141
42+ #ifdef  __linux__
43+ #include  < linux/limits.h> 
44+ #elif  defined(_WIN32)
45+ #   if  !defined(PATH_MAX)
46+ #   define  PATH_MAX  MAX_PATH
47+ #   endif 
48+ #elif  defined(_AIX)
49+ #include  < sys/limits.h> 
50+ #else 
51+ #include  < sys/syslimits.h> 
52+ #endif 
53+ #define  LLAMA_MAX_URL_LENGTH  2084  //  Maximum URL Length in Chrome: 2083
54+ 
4255using  json = nlohmann::ordered_json;
4356
4457std::initializer_list<enum  llama_example> mmproj_examples = {
@@ -208,19 +221,6 @@ bool common_has_curl() {
208221    return  true ;
209222}
210223
211- #ifdef  __linux__
212- #include  < linux/limits.h> 
213- #elif  defined(_WIN32)
214- #   if  !defined(PATH_MAX)
215- #   define  PATH_MAX  MAX_PATH
216- #   endif 
217- #elif  defined(_AIX)
218- #include  < sys/limits.h> 
219- #else 
220- #include  < sys/syslimits.h> 
221- #endif 
222- #define  LLAMA_CURL_MAX_URL_LENGTH  2084  //  Maximum URL Length in Chrome: 2083
223- 
224224// 
225225//  CURL utils
226226// 
@@ -368,10 +368,9 @@ static bool common_download_head(CURL *              curl,
368368}
369369
370370//  download one single file from remote URL to local path
371- static  bool  common_download_file_single (const  std::string & url,
372-                                         const  std::string & path,
373-                                         const  std::string & bearer_token,
374-                                         bool                 offline) {
371+ static  bool  common_download_file_single_online (const  std::string & url,
372+                                                const  std::string & path,
373+                                                const  std::string & bearer_token) {
375374    //  If the file exists, check its JSON metadata companion file.
376375    std::string metadata_path = path + " .json"  ;
377376    static  const  int  max_attempts        = 3 ;
@@ -384,10 +383,6 @@ static bool common_download_file_single(const std::string & url,
384383        //  Check if the file already exists locally
385384        const  auto  file_exists = std::filesystem::exists (path);
386385        if  (file_exists) {
387-             if  (offline) {
388-                 LOG_INF (" %s: using cached file (offline mode): %s\n "  , __func__, path.c_str ());
389-                 return  true ;  //  skip verification/downloading
390-             }
391386            //  Try and read the JSON metadata file (note: stream autoclosed upon exiting this block).
392387            std::ifstream metadata_in (metadata_path);
393388            if  (metadata_in.good ()) {
@@ -407,10 +402,6 @@ static bool common_download_file_single(const std::string & url,
407402            }
408403            //  if we cannot open the metadata file, we assume that the downloaded file is not valid (etag and last-modified are left empty, so we will download it again)
409404        } else  {
410-             if  (offline) {
411-                 LOG_ERR (" %s: required file is not available in cache (offline mode): %s\n "  , __func__, path.c_str ());
412-                 return  false ;
413-             }
414405            LOG_INF (" %s: no previous model file found %s\n "  , __func__, path.c_str ());
415406        }
416407
@@ -530,6 +521,89 @@ static bool common_download_file_single(const std::string & url,
530521    return  true ;
531522}
532523
524+ std::pair<long , std::vector<char >> common_remote_get_content (const  std::string & url, const  common_remote_params & params) {
525+     curl_ptr       curl (curl_easy_init (), &curl_easy_cleanup);
526+     curl_slist_ptr http_headers;
527+     std::vector<char > res_buffer;
528+ 
529+     curl_easy_setopt (curl.get (), CURLOPT_URL, url.c_str ());
530+     curl_easy_setopt (curl.get (), CURLOPT_NOPROGRESS, 1L );
531+     curl_easy_setopt (curl.get (), CURLOPT_FOLLOWLOCATION, 1L );
532+     curl_easy_setopt (curl.get (), CURLOPT_VERBOSE, 1L );
533+     typedef  size_t (*CURLOPT_WRITEFUNCTION_PTR)(void  * ptr, size_t  size, size_t  nmemb, void  * data);
534+     auto  write_callback = [](void  * ptr, size_t  size, size_t  nmemb, void  * data) -> size_t  {
535+         auto  data_vec = static_cast <std::vector<char > *>(data);
536+         data_vec->insert (data_vec->end (), (char  *)ptr, (char  *)ptr + size * nmemb);
537+         return  size * nmemb;
538+     };
539+     curl_easy_setopt (curl.get (), CURLOPT_WRITEFUNCTION, static_cast <CURLOPT_WRITEFUNCTION_PTR>(write_callback));
540+     curl_easy_setopt (curl.get (), CURLOPT_WRITEDATA, &res_buffer);
541+ #if  defined(_WIN32)
542+     curl_easy_setopt (curl.get (), CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA);
543+ #endif 
544+     if  (params.timeout  > 0 ) {
545+         curl_easy_setopt (curl.get (), CURLOPT_TIMEOUT, params.timeout );
546+     }
547+     if  (params.max_size  > 0 ) {
548+         curl_easy_setopt (curl.get (), CURLOPT_MAXFILESIZE, params.max_size );
549+     }
550+     http_headers.ptr  = curl_slist_append (http_headers.ptr , " User-Agent: llama-cpp"  );
551+     for  (const  auto  & header : params.headers ) {
552+         http_headers.ptr  = curl_slist_append (http_headers.ptr , header.c_str ());
553+     }
554+     curl_easy_setopt (curl.get (), CURLOPT_HTTPHEADER, http_headers.ptr );
555+ 
556+     CURLcode res = curl_easy_perform (curl.get ());
557+ 
558+     if  (res != CURLE_OK) {
559+         std::string error_msg = curl_easy_strerror (res);
560+         throw  std::runtime_error (" error: cannot make GET request: "   + error_msg);
561+     }
562+ 
563+     long  res_code;
564+     curl_easy_getinfo (curl.get (), CURLINFO_RESPONSE_CODE, &res_code);
565+ 
566+     return  { res_code, std::move (res_buffer) };
567+ }
568+ 
569+ #else 
570+ 
571+ bool  common_has_curl () {
572+     return  false ;
573+ }
574+ 
575+ static  bool  common_download_file_single_online (const  std::string &, const  std::string &, const  std::string &) {
576+     LOG_ERR (" error: built without CURL, cannot download model from internet\n "  );
577+     return  false ;
578+ }
579+ 
580+ std::pair<long , std::vector<char >> common_remote_get_content (const  std::string & url, const  common_remote_params &) {
581+     if  (!url.empty ()) {
582+         throw  std::runtime_error (" error: built without CURL, cannot download model from the internet"  );
583+     }
584+ 
585+     return  {};
586+ }
587+ 
588+ #endif  //  LLAMA_USE_CURL
589+ 
590+ static  bool  common_download_file_single (const  std::string & url,
591+                                         const  std::string & path,
592+                                         const  std::string & bearer_token,
593+                                         bool                 offline) {
594+     if  (!offline) {
595+         return  common_download_file_single_online (url, path, bearer_token);
596+     }
597+ 
598+     if  (!std::filesystem::exists (path)) {
599+         LOG_ERR (" %s: required file is not available in cache (offline mode): %s\n "  , __func__, path.c_str ());
600+         return  false ;
601+     }
602+ 
603+     LOG_INF (" %s: using cached file (offline mode): %s\n "  , __func__, path.c_str ());
604+     return  true ;
605+ }
606+ 
533607//  download multiple files from remote URLs to local paths
534608//  the input is a vector of pairs <url, path>
535609static  bool  common_download_file_multiple (const  std::vector<std::pair<std::string, std::string>> & urls, const  std::string & bearer_token, bool  offline) {
@@ -588,7 +662,7 @@ static bool common_download_model(
588662
589663    if  (n_split > 1 ) {
590664        char  split_prefix[PATH_MAX] = {0 };
591-         char  split_url_prefix[LLAMA_CURL_MAX_URL_LENGTH ] = {0 };
665+         char  split_url_prefix[LLAMA_MAX_URL_LENGTH ] = {0 };
592666
593667        //  Verify the first split file format
594668        //  and extract split URL and PATH prefixes
@@ -609,7 +683,7 @@ static bool common_download_model(
609683            char  split_path[PATH_MAX] = {0 };
610684            llama_split_path (split_path, sizeof (split_path), split_prefix, idx, n_split);
611685
612-             char  split_url[LLAMA_CURL_MAX_URL_LENGTH ] = {0 };
686+             char  split_url[LLAMA_MAX_URL_LENGTH ] = {0 };
613687            llama_split_path (split_url, sizeof (split_url), split_url_prefix, idx, n_split);
614688
615689            if  (std::string (split_path) == model.path ) {
@@ -626,50 +700,6 @@ static bool common_download_model(
626700    return  true ;
627701}
628702
629- std::pair<long , std::vector<char >> common_remote_get_content (const  std::string & url, const  common_remote_params & params) {
630-     curl_ptr       curl (curl_easy_init (), &curl_easy_cleanup);
631-     curl_slist_ptr http_headers;
632-     std::vector<char > res_buffer;
633- 
634-     curl_easy_setopt (curl.get (), CURLOPT_URL, url.c_str ());
635-     curl_easy_setopt (curl.get (), CURLOPT_NOPROGRESS, 1L );
636-     curl_easy_setopt (curl.get (), CURLOPT_FOLLOWLOCATION, 1L );
637-     typedef  size_t (*CURLOPT_WRITEFUNCTION_PTR)(void  * ptr, size_t  size, size_t  nmemb, void  * data);
638-     auto  write_callback = [](void  * ptr, size_t  size, size_t  nmemb, void  * data) -> size_t  {
639-         auto  data_vec = static_cast <std::vector<char > *>(data);
640-         data_vec->insert (data_vec->end (), (char  *)ptr, (char  *)ptr + size * nmemb);
641-         return  size * nmemb;
642-     };
643-     curl_easy_setopt (curl.get (), CURLOPT_WRITEFUNCTION, static_cast <CURLOPT_WRITEFUNCTION_PTR>(write_callback));
644-     curl_easy_setopt (curl.get (), CURLOPT_WRITEDATA, &res_buffer);
645- #if  defined(_WIN32)
646-     curl_easy_setopt (curl.get (), CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA);
647- #endif 
648-     if  (params.timeout  > 0 ) {
649-         curl_easy_setopt (curl.get (), CURLOPT_TIMEOUT, params.timeout );
650-     }
651-     if  (params.max_size  > 0 ) {
652-         curl_easy_setopt (curl.get (), CURLOPT_MAXFILESIZE, params.max_size );
653-     }
654-     http_headers.ptr  = curl_slist_append (http_headers.ptr , " User-Agent: llama-cpp"  );
655-     for  (const  auto  & header : params.headers ) {
656-         http_headers.ptr  = curl_slist_append (http_headers.ptr , header.c_str ());
657-     }
658-     curl_easy_setopt (curl.get (), CURLOPT_HTTPHEADER, http_headers.ptr );
659- 
660-     CURLcode res = curl_easy_perform (curl.get ());
661- 
662-     if  (res != CURLE_OK) {
663-         std::string error_msg = curl_easy_strerror (res);
664-         throw  std::runtime_error (" error: cannot make GET request: "   + error_msg);
665-     }
666- 
667-     long  res_code;
668-     curl_easy_getinfo (curl.get (), CURLINFO_RESPONSE_CODE, &res_code);
669- 
670-     return  { res_code, std::move (res_buffer) };
671- }
672- 
673703/* *
674704 * Allow getting the HF file from the HF repo with tag (like ollama), for example: 
675705 * - bartowski/Llama-3.2-3B-Instruct-GGUF:q4 
@@ -766,45 +796,6 @@ static struct common_hf_file_res common_get_hf_file(const std::string & hf_repo_
766796    return  { hf_repo, ggufFile, mmprojFile };
767797}
768798
769- #else 
770- 
771- bool  common_has_curl () {
772-     return  false ;
773- }
774- 
775- static  bool  common_download_file_single (const  std::string &, const  std::string &, const  std::string &, bool ) {
776-     LOG_ERR (" error: built without CURL, cannot download model from internet\n "  );
777-     return  false ;
778- }
779- 
780- static  bool  common_download_file_multiple (const  std::vector<std::pair<std::string, std::string>> &, const  std::string &, bool ) {
781-     LOG_ERR (" error: built without CURL, cannot download model from the internet\n "  );
782-     return  false ;
783- }
784- 
785- static  bool  common_download_model (
786-         const  common_params_model &,
787-         const  std::string &,
788-         bool ) {
789-     LOG_ERR (" error: built without CURL, cannot download model from the internet\n "  );
790-     return  false ;
791- }
792- 
793- static  struct  common_hf_file_res  common_get_hf_file (const  std::string &, const  std::string &, bool ) {
794-     LOG_ERR (" error: built without CURL, cannot download model from the internet\n "  );
795-     return  {};
796- }
797- 
798- std::pair<long , std::vector<char >> common_remote_get_content (const  std::string & url, const  common_remote_params &) {
799-     if  (!url.empty ()) {
800-         throw  std::runtime_error (" error: built without CURL, cannot download model from the internet"  );
801-     }
802- 
803-     return  {};
804- }
805- 
806- #endif  //  LLAMA_USE_CURL
807- 
808799// 
809800//  Docker registry functions
810801// 
0 commit comments