[英]Using Libcurl library for file download
我正在嘗試通過從 Dropbox 或谷歌驅動器中的共享鏈接下載更新文件來實現自動更新。 一開始,我使用windows API函數URLDownloadToFile()從網上下載公共文件。 它工作正常,但是當我將它用於雲文件時,它沒有下載文件。 而是獲取一個 HTML 文件,當使用瀏覽器打開時,我可以使用瀏覽器下載該文件。
因此,我轉而使用 Libcurl 庫並按照他們的教程進行操作。 我總是收到錯誤
(60) : CURL_PEER_FAILED_VERIFICATION。
我按照https://curl.haxx.se/libcurl/c/url2file.html 中的示例進行操作。 並嘗試獲取相同的公共文件,我已經下載了 Windows API,但仍然收到相同的錯誤。 所以我知道它與服務器身份驗證或類似問題無關。
這是我使用 windows api 和 Libcurl 的下載功能:
static size_t write_data (void *ptr,size_t size,size_t nmemb,void* stream)
{
size_t written = fwrite (ptr,size,nmemb,(FILE *) stream) ;
return written ;
} /* write_data */
int DownloadFile ()
{
static const char FileURL[] = "https://www.pexels.com/photo/618608/download/?search_query=park&tracking_id=6qgsqm6nzau" :
static char TargetURL[] = "D:\\Download\\DownloadURL\\Test.jpg" ;
static char TargetCURL[] = "D:\\Download\\DownloadCURL\\Test.jpg" ;
// Download the file using windows function into DownloadURL folder
URLDownloadToFile (nullptr,FileURL[2],TargetURL,0,nullptr) ; // OK
// Download the file using curl library into DownloadCURL folder
if (auto curl = curl_easy_init ()) {
auto fp = fopen (TargetCURL,"wb") ;
curl_easy_setopt (curl,CURLOPT_URL,FileURL[1]) ;
curl_easy_setopt (curl,CURLOPT_FAILONERROR,1) ;
curl_easy_setopt (curl,CURLOPT_WRITEDATA,fp) ;
/* Perform the request, res will get the return code */
auto res = curl_easy_perform (curl) ; // Always Fail
fclose (fp) ;
curl_easy_cleanup (curl) ;
} /* if (auto curl = curl_easy_init ()) */
return true ;
} /* Download */
我的系統運行的是 Windows 10 x64。 我使用帶有 openSSL 的 Visual Studio 2017,Libcurl 修訂版 7.67。
誰能幫我弄清楚缺少什么?
您使用的 URL 重定向到此 URL: https://images.pexels.com/photos/618608/pexels-photo-618608.jpeg?cs=srgb&dl=worm-s-eyeview-of-tall-tree-under-a-gray-sky-618608.jpg&fm=jpg
: https://images.pexels.com/photos/618608/pexels-photo-618608.jpeg?cs=srgb&dl=worm-s-eyeview-of-tall-tree-under-a-gray-sky-618608.jpg&fm=jpg
所以你需要在 curl 中啟用以下重定向:
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // follow redirects
您還需要提供write_data
函數:
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
和curl_easy_setopt (curl,CURLOPT_URL,FileURL[1]) ;
應該curl_easy_setopt (curl,CURLOPT_URL,FileURL);
如果您在 http 代理后面,您可能還需要curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L);
#include "curl/curl.h"
#include <cstdio>
static size_t write_data(void* ptr, size_t size, size_t nmemb, void* stream) {
size_t written = fwrite(ptr, size, nmemb, static_cast<FILE*>(stream));
return written;
} /* write_data */
bool DownloadFile() {
bool retval = false;
static const char FileURL[] =
"https://www.pexels.com/photo/618608/download/"
"?search_query=park&tracking_id=6qgsqm6nzau";
static char TargetCURL[] = "D:\\Download\\DownloadCURL\\Test.jpg";
// Download the file using curl library into DownloadCURL folder
if(CURL* curl = curl_easy_init()) {
if(FILE* fp = fopen(TargetCURL, "wb")) {
curl_easy_setopt(curl, CURLOPT_URL, FileURL);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // follow redirects
curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L); // corp. proxies etc.
/* Perform the request, res will get the return code */
CURLcode res = curl_easy_perform(curl);
if(!res) retval = true;
fclose(fp);
}
curl_easy_cleanup(curl);
} /* if (auto curl = curl_easy_init ()) */
return retval;
} /* Download */
int main() {
CURLcode res = curl_global_init(CURL_GLOBAL_ALL);
if(res) return 1;
DownloadFile();
curl_global_cleanup();
}
該錯誤與 TLS 證書頒發者驗證有關。 您缺少服務器的 CA 證書。 在 Windows 上,默認情況下 OpenSSL 帶有一個空的證書存儲。 在 Windows 上最好使用 schannel 支持而不是 OpenSSL 編譯 libcurl,然后它將使用 Windows 內置證書存儲。
您需要設置這些選項:
curl_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0);
也許你可以試試teemo庫,它基於 libcurl,並且支持多線程下載
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.