我正在尝试通过从Dropbox或Google驱动器中的共享链接下载更新文件来实现自动更新。首先,我使用Windows API函数URLDownloadToFile()从Web下载公共文件。它工作正常,但是当我将其用于云文件时,它没有下载文件。而是获得一个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
,因此您需要在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();
}
错误与SSL证书颁发者验证有关。您缺少服务器的CA证书。在Windows上,默认情况下,OpenSSL带有空的证书存储。在Windows上,最好使用schannel支持而不是OpenSSL来编译libcurl,然后使用Windows内置的证书存储。