Knowing libcurl explains curl's behaviour and lets you move a working command into application code.
The curl tool is a thin front-end over libcurl, a portable C library used in cars, TVs, game consoles, PHP's curl extension, Python's pycurl, git's HTTP transport and countless apps. Everything a command-line option does maps to a library option.
The easy interface handles one transfer synchronously:
curl_easy_init()creates a handle,curl_easy_setopt(h, CURLOPT_URL, ...)and otherCURLOPT_*options configure it,curl_easy_perform(h)runs the transfer and returns aCURLcode(the same numbers as the tool's exit codes),curl_easy_cleanup(h)frees it. Reusing a handle for further requests keeps its connection cache.
The multi interface drives many easy handles concurrently in one thread (event-loop style with curl_multi_perform and curl_multi_poll); that is how curl -Z works.
The fastest way to start: build the command you want with the tool, then add --libcurl code.c. curl writes a C program that sets the equivalent options, which is also a great way to learn which CURLOPT matches a flag.
Library defaults differ from the tool in places (for example libcurl does not follow redirects or read .curlrc), and callbacks such as CURLOPT_WRITEFUNCTION receive data in arbitrary-sized chunks, so never assume one callback equals one response.
Example
#include <curl/curl.h>
#include <stdio.h>
int main(void) {
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *h = curl_easy_init();
curl_easy_setopt(h, CURLOPT_URL, "https://example.com/");
curl_easy_setopt(h, CURLOPT_FOLLOWLOCATION, 1L); /* like -L */
curl_easy_setopt(h, CURLOPT_TIMEOUT, 20L); /* like --max-time 20 */
CURLcode rc = curl_easy_perform(h); /* body -> stdout */
long code = 0;
curl_easy_getinfo(h, CURLINFO_RESPONSE_CODE, &code);
fprintf(stderr, "rc=%d http=%ld\n", (int)rc, code); /* rc=0 http=200 */
curl_easy_cleanup(h);
curl_global_cleanup();
return rc != CURLE_OK;
}
/* build: cc get.c -lcurl | generate similar code: curl -L --libcurl get.c URL */Remember
- easy interface: init, setopt, perform, cleanup
- multi interface runs many transfers concurrently in one thread
- --libcurl file.c turns a working command into C code
Watch out for
- Assuming the write callback receives the whole response at once; it is called with chunks.