使用Libcurl库下载文件

问题描述 投票:1回答:2

我正在尝试通过从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。

任何人都可以帮助我找出丢失的内容吗?

c++ winapi libcurl
2个回答
0
投票

您使用的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();
}

0
投票

错误与SSL证书颁发者验证有关。您缺少服务器的CA证书。在Windows上,默认情况下,OpenSSL带有空的证书存储。在Windows上,最好使用schannel支持而不是OpenSSL来编译libcurl,然后使用Windows内置的证书存储。

© www.soinside.com 2019 - 2024. All rights reserved.