我正在实施一个C程序,它需要从Content-Length
标题中读取远程文件的大小(在响应标头中发送Content-Length
时)。
我查看了libcurl的文档,到目前为止我能够提出的最好的是CURLOPT_HEADERFUNCTION
设置的回调函数。我已经整理了一个回调的玩具实现,它应该将标题打印到STDOUT
:
size_t hdf(char* b, size_t size, size_t nitems, void *userdata) {
printf("%s", b);
return 0;
}
虽然我希望能够打印Content-Length
标题(或者至少打印所有标题),但我只能使用此函数来打印响应代码:
$ ./curltest "some_url_which_sends_back_Content_Length"
HTTP/1.1 200 OK
如果我在我的main
中注释掉了将回调设置为上面定义的hdf
函数的行,则默认行为是将所有标题打印到STDOUT
。
供参考,以下是我使用的main
函数,基于libcurl邮件列表中的一个帖子:
int main(int argc, char *argv[])
{
CURLcode ret;
CURL *hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_URL, argv[1]);
curl_easy_setopt(hnd, CURLOPT_HEADER, 1);
curl_easy_setopt(hnd, CURLOPT_NOBODY, 1);
curl_easy_setopt(hnd, CURLOPT_HEADERFUNCTION, hdf);
ret = curl_easy_perform(hnd);
curl_easy_cleanup(hnd);
}
如何编写CURLOPT_HEADERFUNCTION
选项的回调函数,该选项可以将特定的标题加载到内存中或以其他方式操作它 - 或者至少将所有标题加载到内存中?
答案 0 :(得分:8)
我只能使用此功能打印响应代码:
答案就在CURLOPT_HEADERFUNCTION
文档中:
一旦收到头数据,libcurl就会调用此函数。每个标头将调用一次标头回调,只有完整的标题行传递给回调。解析头很容易使用它。 缓冲区指向的数据大小是大小乘以nmemb。不要假设标题行是零终止!名为userdata的指针是您使用CURLOPT_HEADERDATA选项设置的指针。 此回调函数必须返回实际处理的字节数。如果该金额与传入您的函数的金额不同,它将向库发出错误信号。这将导致传输中止,正在进行的libcurl函数将返回CURLE_WRITE_ERROR 。
您的size_t hdf(char* b, size_t size, size_t nitems, void *userdata) {
size_t numbytes = size * nitems;
printf("%.*s\n", numbytes, b);
return numbytes;
}
调用假定为空终止,并且您的回调返回的字节数少于提供的字节数,因此您将在收到第一个响应行后中止响应。
试试这个。
b
如何为CURLOPT_HEADERFUNCTION选项编写一个回调函数,该选项可以将特定的头文件加载到内存中或以其他方式操作它 - 或者至少将所有头文件加载到内存中?
修复错误后,您应该能够看到所有标题。然后,您可以解析Content-Length
查找userdata
标头,并在找到时将其数据保存到您通过CURLOPT_HEADERDATA
传递到HEAD
的缓冲区。
现在,有了这个说法,有一种更简单的方法来检索Content-Length值。使用curl_easy_perform()
(CURLOPT_NOBODY
)执行curl_easy_getinfo()
请求,如果成功,请使用{{1}}检索CURLINFO_CONTENT_LENGTH_DOWNLOAD
值:
CURLINFO_CONTENT_LENGTH_DOWNLOAD
内容长度来自Content-Length标题。