2

我正在使用 libcurl 发送 HTTP 发布请求并随后处理响应。收到响应后,库使用CURLOPT_WRITEFUNCTION通过curl_easy_setopt.

// callback function
std::size_t on_data(const char* buffer, const std::size_t size, const std::size_t nmemb, void* context);

从文档中不清楚你可以将数据留在缓冲区中(通过从回调返回 0)或者你必须将数据复制到本地缓冲区,然后在每个后续回调中继续附加到这个缓冲区,直到你收到整个消息.

我的问题是:

  1. 获取整个消息长度的最佳方法是什么?是来自Content-Length标题CURLOPT_WRITEHEADER吗?
  2. 有没有办法避免复制部分响应,而是等待收到最终消息,然后将其全部处理?
4

1 回答 1

1

CURLOPT_WRITEFUNCTION选项而言,文档明确指出此功能必须:

[r]返回实际处理的字节数。如果该数量与传递给您的函数的数量不同,它将向库发出错误信号。这将中止传输并返回 CURLE_WRITE_ERROR。

因此,除非您想明确中止传输,否则您应该始终返回实际大小,即size * nmemb. 此外,如果您选择使用本地缓冲区,那么是的,您必须注意将传入的数据复制到其中(并注意重新分配),如docs/examples/getinmemory.c示例代码所示。

请注意,如果您不想使用内存缓冲区,您也可以通过选项使用文件,CURLOPT_WRITEDATA如示例中所示。docs/examples/url2file.cdocs/examples/fopen.c

除此以外:

  1. 我想说,要先验地检查您愿意获取的资源的大小,那么您应该执行一个HEAD请求(通过CURLOPT_NOBODY设置为 1 并设置为 1),要求通过and和 atCURLOPT_HEADER写入 HTTP 标头最后解析值。但是:这绝对不是请求的方式,因为它不是幂等的!CURLOPT_WRITEHEADERCURLOPT_WRITEFUNCTIONContent-LengthPOST

  2. 同样,如果您对使用不断增长的内存缓冲区感到不满意(例如,可能因为您期望响应非常大),那么您应该使用处理文件的能力,CURLOPT_WRITEDATA以便将响应逐步写入磁盘。一旦完成,然后使用您的文件 - 包含整个消息,您想要的方式。

于 2012-10-16T08:18:39.320 回答