Reputation: 4592
I'm using libcurl to send HTTP post requests and subsequently process the responses. Upon a response being received the library calls back to my program using the function given to the CURLOPT_WRITEFUNCTION
property via 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);
It's unclear from the documentation wither you can leave data on the buffer (by returning 0 from the callback) or wither you have to copy the data to a local buffer and then continue appending to this on each subsequent callback until you have received the entire message.
My questions are:
Content-Length
header via CURLOPT_WRITEHEADER
?Upvotes: 2
Views: 2912
Reputation: 16121
As far as the CURLOPT_WRITEFUNCTION
option is concerned the documentation explicitly states that this function must:
[r]eturn the number of bytes actually taken care of. If that amount differs from the amount passed to your function, it'll signal an error to the library. This will abort the transfer and return CURLE_WRITE_ERROR.
So unless you want to explicitly abort the transfer you should always return the real size, i.e. size * nmemb
. Also if you choose to work with a local buffer, then yes, you have to take care to copy the incoming data into it (and take care of reallocation) as illustrated by the docs/examples/getinmemory.c
sample code.
Please note that if you do not want to use an in-memory buffer you can also use a file via the CURLOPT_WRITEDATA
option, as illustrated e.g. by docs/examples/url2file.c
or docs/examples/fopen.c
examples.
Otherwise:
I would say that to check a priori what's the size of the resource you're willing to fetch, then you should perform a HEAD
request (via CURLOPT_NOBODY
set to 1 and CURLOPT_HEADER
set to 1 too) asking for the HTTP headers to be written via CURLOPT_WRITEHEADER
and CURLOPT_WRITEFUNCTION
and at last parse the Content-Length
value. But: this is definitely not the way to go with a POST
request as it is not idempotent!
Here again if you are not comfortable with working with a growing in-memory buffer (e.g. maybe because you expect very large responses), then you should use the ability to work with files with CURLOPT_WRITEDATA
so that the response is progressively written on-disk. Once done, then use your file - that contains the entire message, the way you want.
Upvotes: 1