如何使用CURLOPT_HEADERFUNCTION读取单个响应头字段?

时间:2016-05-30 02:11:57

标签: c libcurl

我正在实施一个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选项的回调函数,该选项可以将特定的标题加载到内存中或以其他方式操作它 - 或者至少将所有标题加载到内存中?

1 个答案:

答案 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标题。