Issue
When I run curl --header <url here>
from the command line, I am able to see quite a bit of information, including the desired field Content-Length.
But when I write a C script based on libcurl, including the line
curl_easy_getinfo(c, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &ContentLength);
ContentLength ends up with a value of -1 and the header I receive is merely "HTTP/2 200".
I seem to be able to get the Content-Length field from the command line curl but not using C's libcurl. What gives?
#include <stdlib.h>
#include <stdio.h>
#include <curl/curl.h>
int hcb(void *contents, size_t size, size_t nmemb, void *data) {
// this prints "HTTP/2 200"
printf("%.*s\n", (int)(size*nmemb), ((char *) contents));
return 0;
}
int wcb(void *contents, size_t size, size_t nmemb, void *data) {
printf("not implemented\n");
return 0;
}
ssize_t myfunc(){
char url[] = "http://thisisafakeurl.com/test.txt";
CURL *c = curl_easy_init();
if(c) {
CURLcode res;
curl_easy_setopt(c, CURLOPT_URL, url);
curl_easy_setopt(c, CURLOPT_HEADERFUNCTION, hcb);
curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, wcb);
res = curl_easy_perform(c);
int ContentLength;
curl_easy_getinfo(c, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &ContentLength);
// this line prints 23.
printf("content length: %i\n", ContentLength);
curl_easy_cleanup(c);
}
return 0;
}
int main() {
myfunc();
return 0;
}
Solution
The documentation for CURLOPT_HEADERFUNCTION
states the following:
This callback function must return the number of bytes actually taken care of. If that amount differs from the amount passed in to your function, it will signal an error to the library. This will cause the transfer to get aborted and the libcurl function in progress will return
CURLE_WRITE_ERROR
.
The documentation for CURLOPT_WRITEFUNCTION
states something very similar:
Your callback should return the number of bytes actually taken care of. If that amount differs from the amount passed to your callback function, it will signal an error condition to the library. This will cause the transfer to get aborted and the libcurl function used will return
CURLE_WRITE_ERROR
.
Since your callback functions are always returning a value that indicates an error, according to the quoted documentation, this will cause the transfer to be aborted. That is probably why the line
curl_easy_getinfo(c, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &ContentLength);
is failing.
In order to fix this, you should change your callback functions to always indicate success, by changing the line
return 0;
to
return nmemb;
in both functions.
Answered By - Andreas Wenzel Answer Checked By - Marie Seifert (WPSolving Admin)