Skip to content

libcurl

The HTTP client behind an enormous share of software — every protocol, every platform.

Web & HTTPWeb / NetworkingCC++

What it is

libcurl is a free and easy-to-use client-side URL transfer library, supporting a wide range of protocols including HTTP, HTTPS, FTP, and more. It allows sending and receiving data via URL requests with robust support for authentication, cookies, headers, and SSL.

libcurl provides easy-to-use functions to perform network operations like GET, POST, file upload, and download. It supports synchronous and asynchronous operations, SSL/TLS, cookies, authentication, and proxy support.

Licence
MIT-like (curl licence)
Watch for
Always set CURLOPT_TIMEOUT and verify TLS certificates

When to use it

The question documentation cannot answer for you — because it cannot recommend something else.

Reach for it when

  • Any C or C++ program that needs to make network requests
  • You need protocol coverage beyond HTTP — FTP, SMTP, SFTP and more

Look elsewhere when

  • A C++ project happy to take a modern C++ wrapper instead of a C API

Installation

sudo apt install libcurl4-openssl-dev

Getting started

The smallest useful thing you can do with it, and what each part means.

Simple GET request
#include <curl/curl.h>
#include <stdio.h>

int main() {
    CURL *curl = curl_easy_init();
    if(curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/get");
        CURLcode res = curl_easy_perform(curl);
        if(res != CURLE_OK)
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        curl_easy_cleanup(curl);
    }
    return 0;
}
Initializes libcurl, sets the URL for a GET request, performs the request, and cleans up.
POST request with data
#include <curl/curl.h>

int main() {
    CURL *curl = curl_easy_init();
    if(curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/post");
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=John&age=30");
        curl_easy_perform(curl);
        curl_easy_cleanup(curl);
    }
    return 0;
}
Sends a POST request with URL-encoded form data using libcurl.

Advanced usage

Where the library earns its place over a simpler alternative.

Handling response in memory
#include <curl/curl.h>
#include <stdlib.h>
#include <string.h>

size_t write_callback(void *ptr, size_t size, size_t nmemb, void *userdata) {
    size_t total = size * nmemb;
    strncat((char*)userdata, (char*)ptr, total);
    return total;
}

int main() {
    CURL *curl = curl_easy_init();
    char response[10000] = {0};
    curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/get");
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, response);
    curl_easy_perform(curl);
    printf("Response: %s\n", response);
    curl_easy_cleanup(curl);
    return 0;
}
Processes the response data in memory using a custom write callback.
HTTPS request with SSL verification
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/cacert.pem");
Ensures HTTPS requests verify the SSL certificate using a trusted CA.
Setting custom headers
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Authorization: Bearer TOKEN");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
Adds custom HTTP headers for requests, e.g., for API authentication.
File download
FILE *fp = fopen("file.txt", "wb");
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/file.txt");
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_perform(curl);
fclose(fp);
Downloads a remote file and saves it locally.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

CURLE_COULDNT_CONNECT
Check network connectivity and server availability.
CURLE_OPERATION_TIMEDOUT
Set proper timeout using `curl_easy_setopt(curl, CURLOPT_TIMEOUT, seconds)`.
CURLE_SSL_CONNECT_ERROR
Verify SSL certificates and use `CURLOPT_CAINFO` with a valid CA bundle.

Best practices

  • Always check the return code of `curl_easy_perform` for error handling.
  • Clean up CURL handles with `curl_easy_cleanup` to prevent memory leaks.
  • Use `curl_global_init` and `curl_global_cleanup` at the start and end of your program if using libcurl in multi-threaded applications.
  • Use timeouts and retries for robust network operations.
  • Separate headers and POST data to improve readability and maintainability.

Alternatives

Comparable options, and the reason you would pick one over the other.

  • cpp-httplib

    Header-only C++ HTTP client and server; far simpler API, HTTP only

Background

Why it exists, and what it was reacting to.

libcurl was created by Daniel Stenberg in 1997 to provide a portable and flexible library for network communication in C. It became widely adopted in both open-source and commercial applications due to its stability, performance, and support for multiple protocols.