问题
I have the following libcurl program. When I run the program I get the following error.
Operation was aborted by an application callback
Process finished with exit code 42
My complete program
#include <stdio.h>
#include <curl/curl.h>
#include <cstdint>
#include <malloc.h>
#include <cstring>
#define TIMETYPE double
#define TIMEOPT CURLINFO_TOTAL_TIME
#define STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES 6000
struct myprogress {
TIMETYPE lastruntime;
CURL *curl;
};
struct memoryStruct {
uint8_t* memory;
size_t size;
};
size_t handleData(void* contents, size_t size, size_t nmemb, void* stream) {
size_t realSize = size * nmemb;
struct memoryStruct* mem = static_cast<struct memoryStruct*>(stream);
mem->memory = static_cast<uint8_t*>(realloc(mem->memory, (mem->size + realSize + 1)));
if (mem->memory == nullptr) {
return 0;
}
memcpy(&(mem->memory[mem->size]), contents, realSize);
mem->size += realSize;
mem->memory[mem->size] = 0;
return realSize;
}
static int xferinfo(void *p,
curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow)
{
struct myprogress *myp = (struct myprogress *)p;
CURL *curl = myp->curl;
TIMETYPE curtime = 0;
curl_easy_getinfo(curl, TIMEOPT, &curtime);
myp->lastruntime = curtime;
fprintf(stderr, "TOTAL TIME: %f \r\n", curtime);
fprintf(stderr," DOWN: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
"\r\n", dlnow, dltotal);
if(dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES)
return 1;
return 0;
}
int main(void)
{
CURL *curl;
CURLcode res = CURLE_OK;
struct myprogress prog;
struct memoryStruct m_chunk;
curl = curl_easy_init();
if(curl) {
prog.lastruntime = 0;
prog.curl = curl;
m_chunk.memory = static_cast<uint8_t*>(malloc(1));
if (nullptr == m_chunk.memory) {
return 1;
}
m_chunk.size = 0;
curl_easy_setopt(curl, CURLOPT_URL, "http://172.16.132.84:5000/download/file.out");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, handleData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*) &m_chunk);
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo);
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &prog);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
res = curl_easy_perform(curl);
if(res != CURLE_OK) {
fprintf(stderr, "%s\n", curl_easy_strerror(res));
}
curl_easy_cleanup(curl);
}
return (int)res;
}
回答1:
Your file is larger then 6000 bytes:
STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES 6000
In this case you return 1 in your xferinfo function, which aborts the download.
Documentation
If your callback function returns CURL_PROGRESSFUNC_CONTINUE it will cause libcurl to continue executing the default progress function.
Returning any other non-zero value from this callback will cause libcurl to abort the transfer and return CURLE_ABORTED_BY_CALLBACK.
see https://curl.haxx.se/libcurl/c/CURLOPT_XFERINFOFUNCTION.html
Test
If I download a file with your code with 4431 bytes I get in the debug console:
...
TOTAL TIME: 0.088631
DOWN: 4431 of 4431
Process finished with exit code 0
If I change STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES to 2000 then I get:
...
Operation was aborted by an application callback
Process finished with exit code 42
来源:https://stackoverflow.com/questions/60556895/operation-was-aborted-by-an-application-callback-libcurl