libcurl

Language: C

Web / Networking

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.

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.

Installation

linux: sudo apt install libcurl4-openssl-dev
mac: brew install curl
windows: Download pre-built binaries from https://curl.se/windows/

Usage

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.

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.

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.

Error Handling

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.