curl/curl
Easy interface
Active contributors: Daniel Stenberg, Stefan Eissing, Jay Satiro
Purpose
The "easy" interface is the simplest libcurl entry point: create a handle, set options, perform the transfer, get info, clean up. Internally it is a thin blocking wrapper around the multi interface (lib/easy.c); applications that only need synchronous transfers can ignore the multi/socket APIs entirely.
Public surface
| Header | Function family |
|---|---|
include/curl/easy.h |
curl_easy_init, curl_easy_cleanup, curl_easy_duphandle, curl_easy_reset |
include/curl/curl.h |
curl_easy_setopt, curl_easy_perform, curl_easy_getinfo, curl_easy_strerror, curl_easy_pause, curl_easy_recv, curl_easy_send, curl_easy_upkeep |
include/curl/header.h |
curl_easy_header, curl_easy_nextheader |
include/curl/options.h |
curl_easy_option_by_id, curl_easy_option_next |
Minimal example
#include <curl/curl.h>
int main(void) {
CURL *easy = curl_easy_init();
if(!easy) return 1;
curl_easy_setopt(easy, CURLOPT_URL, "https://example.com/");
curl_easy_setopt(easy, CURLOPT_FOLLOWLOCATION, 1L);
CURLcode rc = curl_easy_perform(easy);
if(rc != CURLE_OK)
fprintf(stderr, "%s\n", curl_easy_strerror(rc));
curl_easy_cleanup(easy);
return rc;
}docs/examples/simple.c is the in-tree variant.
Lifecycle
graph LR
A[curl_easy_init] --> B[curl_easy_setopt × N]
B --> C[curl_easy_perform]
C --> D{retry?}
D -- yes --> B
D -- no --> E[curl_easy_getinfo × N]
E --> F[curl_easy_cleanup]curl_easy_reset() returns the handle to its initial option-defaults state without freeing it — useful for handle reuse without re-allocation.
curl_easy_duphandle() produces a copy of the option state (not the live transfer state). Useful for forking parameterised transfers off a "template" handle.
Setopt categories
curl_easy_setopt takes a CURLOPT_* enum and a value. The argument type is one of:
long— feature flags, integer parametersconst char *— strings (URL, headers, cookies, …) — typically copied internally; some are owned by the callercurl_off_t— large numeric values like file sizesvoid *— application data passed back to callbacks- function pointer —
CURLOPT_*FUNCTIONcallbacks struct curl_slist *— string lists for headers, custom requests, etc.
The full table is auto-generated in lib/easyoptions.c (from lib/optiontable.pl), and dispatched in lib/setopt.c. Documentation per option is in docs/libcurl/opts/CURLOPT_*.md.
curl_easy_setopt returns CURLE_UNKNOWN_OPTION for an unrecognized option, CURLE_BAD_FUNCTION_ARGUMENT for an invalid value, CURLE_OK otherwise. Many setopt errors are deferred to perform() (e.g. malformed URLs).
Callbacks
The most common application-supplied callbacks:
| Option | Purpose |
|---|---|
CURLOPT_WRITEFUNCTION + CURLOPT_WRITEDATA |
Receive response body bytes |
CURLOPT_HEADERFUNCTION + CURLOPT_HEADERDATA |
Receive response headers |
CURLOPT_READFUNCTION + CURLOPT_READDATA |
Provide request body bytes |
CURLOPT_PROGRESSFUNCTION / CURLOPT_XFERINFOFUNCTION |
Per-tick progress |
CURLOPT_DEBUGFUNCTION + CURLOPT_DEBUGDATA |
Receive trace data when verbose is on |
CURLOPT_SSL_CTX_FUNCTION (OpenSSL only) |
Adjust the TLS context before handshake |
CURLOPT_OPENSOCKETFUNCTION |
Custom socket creation |
CURLOPT_PREREQFUNCTION |
Hook fired right before each request |
Callbacks must not call curl_easy_perform recursively. They may call curl_easy_pause to suspend the transfer.
Getinfo
curl_easy_getinfo reads transfer-level properties post-perform: CURLINFO_RESPONSE_CODE, CURLINFO_TOTAL_TIME, CURLINFO_SIZE_DOWNLOAD_T, CURLINFO_PROTOCOL, CURLINFO_CERTINFO, etc. Sources: lib/getinfo.c.
Header API
After a perform, curl_easy_header and curl_easy_nextheader (lib/headers.c) provide structured access to received HTTP headers:
struct curl_header *h;
if(curl_easy_header(easy, "Content-Type", 0, CURLH_HEADER, -1, &h) == CURLHE_OK)
printf("%s: %s\n", h->name, h->value);This avoids parsing headers from the HEADERFUNCTION stream.
Programmatic option metadata
include/curl/options.h exposes a runtime metadata table: option ID, name, type, alias status. This lets generic libraries (e.g. PHP's curl extension, the --libcurl source generator) iterate options without hard-coding them.
Threading
A single easy handle must be used by one thread at a time. Two threads can share a handle only if they serialize calls. The standard pattern is one easy handle per thread; share state explicitly via a curl_share handle.
Related pages
- Multi — concurrent transfers and the underlying state machine
- URL —
curl_url_*(works without an easy handle) - Connection management — how easy handles share connections
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.