libcurl中GET请求调用curl_easy_getinfo获总耗时报CURLE_UNKNOWN_OPTION错误
问题:curl_easy_getinfo在GET请求的xferinfo回调中返回CURLE_UNKNOWN_OPTION错误码48
在xferinfo回调函数中调用curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &curtime)返回错误码48,对应CURLE_UNKNOWN_OPTION(用户指定了未知选项),输出信息如下:
ret 48
TOTAL TIME: 0.000000
DOWN: 41992 of 45998104
该调用在POST请求中可正常运行,但在GET请求中出现异常。相关代码如下:
#include "curl.h" #include "json.h" #include <fcntl.h> typedef struct myprogress { curl_off_t lastruntime; /* type depends on version, see above */ CURL *curl; }myprogress; static size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) { size_t written = fwrite(ptr, size, nmemb, stream); return written; } 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; double curtime = 0; int ret = curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &curtime); // <<< HERE printf("ret %d\n", ret); // <<< HERE 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; } CURLcode curl_get(const char* Path, const char* URL) { CURL *curl; FILE *fp; CURLcode res = 0; struct myprogress prog; fp = fopen(Path, "wb"); if(!fp) { LOGE("post text file fail\n"); /* cannot continue */ return FAILURE; } curl = curl_easy_init(); if (curl) { //prog.lastruntime = 0; //prog.curl = curl; curl_easy_setopt(curl, CURLOPT_URL, URL); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE); /* Install the callback function */ curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo); /* pass the struct pointer into the xferinfo function */ curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &prog); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); res = curl_easy_perform(curl); if(res != CURLE_OK) { fprintf(stderr, "curl_easy_perform() %d failed: %s\n", __LINE__, curl_easy_strerror(res)); res = FAILURE; } /* always cleanup */ curl_easy_cleanup(curl); } else { res = CURLE_FAILED_INIT; fprintf(stderr, "curl_easy_perform() %d failed: %s\n", __LINE__, curl_easy_strerror(res)); res = FAILURE; } fclose(fp); return res; }
问题分析与修复
- 核心问题:
curl_get函数中注释掉了prog.curl = curl;,导致传递给xferinfo回调的myprogress结构体里的curl指针是未初始化的野指针。用无效指针调用curl_easy_getinfo时,curl无法识别该句柄,因此返回CURLE_UNKNOWN_OPTION错误码48。 - POST请求正常的原因:推测POST请求的代码中正确初始化了
prog.curl成员,而GET请求遗漏了这一步,两者的代码差异导致了不同的运行结果。
修复步骤:
取消curl_get函数中以下两行代码的注释:
prog.lastruntime = 0; prog.curl = curl;
这样xferinfo回调就能拿到有效的curl句柄,调用curl_easy_getinfo即可正常获取CURLINFO_TOTAL_TIME信息。
内容的提问来源于stack exchange,提问作者jjaeh
相关产品推荐
相关产品推荐

