c++ 如何使用libcurl从github release下载.zip/rar存档?

e5nszbig  于 11个月前  发布在  Git
关注(0)|答案(2)|浏览(106)

我有一个问题,我如何从github版本下载归档文件**(.zip/.rar)**。使用简单的.html页面可以正常工作,但使用github版本则不行。奇怪的是,libcurl从curl_easy_perform返回CURL_OK状态,但甚至不尝试写入任何数据块。
下面是我的代码:

typedef size_t(*CurlWriteDataFn)(void* ptr, size_t size, size_t nmemb, FILE* stream);

// My write function (simply used from examples)
static size_t CurtWriteData(void* ptr, size_t size, size_t nmemb, FILE* stream) {
    size_t written = fwrite(ptr, size, nmemb, stream);
    return written;
}

// Donwload function
static void DownloadFile(const std::string& url, const std::string outFilePath, CurlWriteDataFn writeFn) {

    // Check url and outFilePath.
    if (url.empty()) {
        // Curl: URL is not set.
        return;
    }
    if (outFilePath.empty()) {
        // Curl: Output file path is not set.
        return;
    }

    CURL* curl;
    FILE* fp;
    CURLcode res;

    curl = curl_easy_init();
    if (!curl) {
        // Curl: Failed to initialize library.
        return;
    }

    // Copying url and outFilepath. (so char* can be always avaliable)
    String _url         = url;
    String _outFilePath = outFilePath;

    fp = fopen(_outFilePath.c_str(), "wb");
    if (!fp) {
        // Curl: Failed to fopen file
        curl_easy_cleanup(curl);
        return;
    }

    // Set options for library.
    curl_easy_setopt(curl, CURLOPT_URL, _url.c_str());
    curl_easy_setopt(curl, CURLOPT_USERAGENT, "Dark Secret Ninja/1.0");
    
    // NOTE: Also i try different UserAgents like this: 
    // "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"); 
    // but still not work
    
    if (writeFn)
       curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFn);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);

    // Process donwloading.
    res = curl_easy_perform(curl);
    if (res != CURLcode::CURLE_OK) {
        // Curl: Failed to download file.
    }

    curl_easy_cleanup(curl);
    fclose(fp);
}

int main() {
   // -- OK
   // DownloadFile("https://curl.se/mail/lib-2010-11/0182.html", "C:\\MyDownloads\\some.json", CurtWriteData); 
   
   // -- Failed (without any error code)
   DownloadFile("https://github.com/KennyProgrammer/TestRepo/archive/refs/tags/v0.0.1.zip", "C:\\MyDownloads\\SomeRelease-v0.0.1.zip", CurtWriteData);
   
   return 0;
}

字符串

注意:我也尝试使用urlhttp不是https,并尝试验证peerhost name,但仍然不起作用。

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); // verify ssl peer
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1L); // verify ssl hostname


如果有任何建议,如何解决这个问题?我将非常感谢。

qlvxas9a

qlvxas9a1#

您可以在命令行中使用-v标志在详细模式下调用curl,以查看发生了什么

curl -v https://github.com/KennyProgrammer/TestRepo/archive/refs/tags/v0.0.1.zip -o 1.zip

字符串
它显示服务器响应重定向响应:

< HTTP/1.1 302 Found
...
< Location: https://codeload.github.com/KennyProgrammer/TestRepo/zip/refs/tags/v0.0.1


你需要处理它来查询实际的位置url,例如使用CURLOPT_FOLLOWLOCATION选项:

curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);

hk8txs48

hk8txs482#

Github会对下载进行重定向,所以你还需要设置CURLOPT_FOLLOWLOCATION

curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);

字符串
当测试OP代码时,我无法成功下载,因为curl_easy_perform总是返回CURLE_PEER_FAILED_VERIFICATION错误的结果代码。
出于某种原因,我的测试还要求我设置以下内容:

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);

**免责声明:**然而,正如@273K所评论的那样,不建议这样做,因为根据Curl文档WARNING: disabling verification of the certificate allows bad guys to man-in-the-middle WARNING: disabling verification of the certificate allows bad guys to man-in-the-middle

相关问题