#if LIBCURL_VERSION_NUM >= 0x073d00
/* In libcurl 7.61.0, support was added for extracting the time in plain
microseconds. Older libcurl versions are stuck in using 'double' for this
information so we complicate this example a bit by supporting either
approach. */
#define TIME_IN_US 1
#define TIMETYPE curl_off_t
#define TIMEOPT CURLINFO_TOTAL_TIME_T
#define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL 3000000
#else
#define TIMETYPE double
#define TIMEOPT CURLINFO_TOTAL_TIME
#define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL 3
#endif
#define STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES 6000
typedef struct myprogress {
TIMETYPE lastruntime; /* type depends on version, see above */
CURL *curl;
int* pContinue;
__int64* ulnow;
__int64* ultotal;
double* speed;
}myprogress;
/* this is how the CURLOPT_XFERINFOFUNCTION callback works */
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);
curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, myp->speed);
*(myp->ulnow) = ulnow;
*(myp->ultotal) = ultotal;
if(dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES)
return 1;
if (*(myp->pContinue) == 0)
return 1;
return 0;
}
// 上传函数
CURLcode CHttpClient::UploadEx(const wchar_t* file_path_name, const wchar_t* remote_url, std::wstring& output, int* pContinue, __int64* pnow, __int64* ptotal, double* pSpeed)
{
CURLcode code = CURLE_FAILED_INIT;
CURL* curl = curl_easy_init();
if(curl)
{
std::vector<char> buffer;
struct curl_httppost * post = NULL;
struct curl_httppost * last = NULL;
struct myprogress prog;
prog.lastruntime = 0;
prog.curl = curl;
prog.pContinue = pContinue;
prog.ulnow = pnow;
prog.ultotal = ptotal;
prog.speed = pSpeed;
// 添加上传的本地文件
curl_formadd(&post, &last,
CURLFORM_COPYNAME, "filename",
CURLFORM_FILE, common::wstring_to_string(file_path_name).c_str(),
CURLFORM_CONTENTTYPE, "application/octet-stream",
CURLFORM_END);
// 设置上传的其他参数
std::map<std::string, std::string>::const_iterator it;
for (it = m_mapPostFields.begin(); it != m_mapPostFields.end();it++)
{
curl_formadd(&post, &last,
CURLFORM_COPYNAME, it->first.c_str(),
CURLFORM_COPYCONTENTS, it->second.c_str(),
CURLFORM_END);
}
//curl_easy_setopt(curl, CURLOPT_POSTFIELDS, StringfyFields(m_mapPostFields).c_str());
// 输出调试信息
curl_easy_setopt(curl, CURLOPT_VERBOSE, VERBOSE_FLAG);
// 设置上传的URL
std::string url = common::encodeURI(common::wstring_to_utf8(remote_url));
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
// 设置超时时间
curl_easy_setopt(curl, CURLOPT_TIMEOUT, m_nTimeout);
// 设置连接时间为30秒
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30);
// 设置允许追踪重定向
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
// 设置为执行POST请求
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
// 设置回调函数
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteDataCallback);
// 设置获取到的数据的指针
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
// 设置是否关闭传输进度
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, false);
// 设置进度回调函数
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo);
// 设置进度函数使用指针
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &prog);
code = curl_easy_perform(curl);
if (code != CURLE_OK)
{
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(code));
}
curl_easy_cleanup(curl);
curl_formfree(post);
std::string strBuffer(buffer.begin(), buffer.end());
output = common::utf8_to_wstring(strBuffer.c_str());
}
return code;
}
在外部修改pContinue所指向的值为0即可中断。