在项目中,需要做一个下载中间件,查看资料发现libcurl很适合,因此选用libcurl来实现HTTP下载功能。
用libcurl实现下载功能很方便,只要调用libcurl库的
curl_easy_init()
curl_easy_setopt()
curl_easy_perform()
curl_easy_getinfo()
就可以完成http下载,并且libcurl教程很多,网上资料也很多。
对于libcurl获取文件长度,网上比较多的做法如下:
long downloadFileLenth = 0;
CURL *handle = curl_easy_init();
curl_easy_setopt(handle, CURLOPT_URL, url);
curl_easy_setopt(handle, CURLOPT_HEADER, 1); //只要求header头
curl_easy_setopt(handle, CURLOPT_NOBODY, 1); //不需求body
if (curl_easy_perform(handle) == CURLE_OK)
{
curl_easy_getinfo(handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &downloadFileLenth);
}
else {
downloadFileLenth = -1;
}
curl_easy_cleanup(handle);
但是这种做法,默认是通过HTTP的HEAD方式来获取的,但是并不是所有HTTP的服务器都是支持HEAD方式来获取,比如说本人项目中,
有个HTTP server就不支持HEAD方式,而只能使用GET方式来获取文件长度,所以这种方式不可行, 本希望能够使用如下代码段来实现:
long downloadFileLenth = 0;
CURL *handle = curl_easy_init();
curl_easy_setopt(handle, CURLOPT_URL, url);
curl_easy_setopt(handle, CURLOPT_HTTPGET, 1); //使用HTTPGET
curl_easy_setopt(handle, CURLOPT_NOBODY, 1); //不需求body
if (curl_easy_perform(handle) == CURLE_OK)
{
curl_easy_getinfo(handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &downloadFileLenth);
}
else {
downloadFileLenth = -1;
}
curl_easy_cleanup(handle);
但是发现还是用的HEAD方式获取,查看libcurl源代码发现,当设置CURLOPT_NOBODY,libcurl会默认设置获取方式为HEAD方式,如果把
set nobody的option去掉,又会下载文件内容!所以上面代码无法满足。
没办法只能看libcurl源代码,终于发现如下解决方案:
long downloadFileLenth = 0;
CURL *handle = curl_easy_init();
curl_easy_setopt(handle, CURLOPT_URL, url);
curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, “GET”); //使用CURLOPT_CUSTOMREQUEST
curl_easy_setopt(handle, CURLOPT_NOBODY, 1); //不需求body
if (curl_easy_perform(handle) == CURLE_OK)
{
curl_easy_getinfo(handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &downloadFileLenth);
}
else {
downloadFileLenth = -1;
}
curl_easy_cleanup(handle);
可以完美解决用GET获取文件长度,而不下载文件内容。