Что такое библиотека libcurl и как её использовать в C++?

Ответ

libcurl — это кроссплатформенная клиентская библиотека на языке C для передачи данных по URL, поддерживающая множество протоколов (HTTP, HTTPS, FTP, FTPS, SCP, SFTP, SMTP и др.). Она предоставляет простой и единообразный API для выполнения сетевых запросов. В C++ проектах она часто используется через C-интерфейс или C++-обёртки.

Ключевые возможности:

  • Поддержка SSL/TLS (через OpenSSL, Schannel, Secure Transport и др.).
  • Асинхронные (non-blocking) и синхронные вызовы.
  • Прокси, HTTP-куки, аутентификация (Basic, Digest, NTLM, Kerberos).
  • Загрузка и отправка файлов, поддержка многопоточности.
  • Минимальные зависимости, высокая производительность.

Базовый пример синхронного HTTP GET-запроса на C++:

#include <iostream>
#include <curl/curl.h>

// Callback-функция для записи полученных данных
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* userp) {
    size_t totalSize = size * nmemb;
    userp->append(static_cast<char*>(contents), totalSize);
    return totalSize;
}

int main() {
    CURL* curl;
    CURLcode res;
    std::string readBuffer;

    curl_global_init(CURL_GLOBAL_DEFAULT); // Инициализация libcurl
    curl = curl_easy_init();

    if (curl) {
        // Установка опций запроса
        curl_easy_setopt(curl, CURLOPT_URL, "https://api.example.com/data");
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
        curl_easy_setopt(curl, CURLOPT_USERAGENT, "MyCppApp/1.0");
        // Для HTTPS рекомендуется явно задать путь к CA bundle или использовать CURLOPT_CAINFO
        // curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/cacert.pem");

        // Выполнение запроса
        res = curl_easy_perform(curl);

        // Проверка результата
        if (res != CURLE_OK) {
            std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << 'n';
        } else {
            long http_code = 0;
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
            std::cout << "HTTP код ответа: " << http_code << 'n';
            std::cout << "Получено данных: " << readBuffer.size() << " байтn";
            // std::cout << "Тело ответа: " << readBuffer << 'n';
        }

        // Очистка
        curl_easy_cleanup(curl);
    }

    curl_global_cleanup();
    return 0;
}

Типичные сценарии использования в C++ проектах:

  1. Загрузка данных из REST API (JSON/XML).
  2. Отправка метрик или логов на сервер.
  3. Реализация автообновления приложения.
  4. Интеграция с облачными хранилищами (загрузка/выгрузка файлов).

Альтернативы в экосистеме C++: Для более идиоматичного C++ кода можно рассмотреть библиотеки-обёртки над libcurl (например, curlpp) или нативные C++ библиотеки, такие как Boost.Beast (для HTTP/WebSocket) или cpp-httplib. Однако libcurl остаётся отраслевым стандартом благодаря своей зрелости, стабильности и широте поддерживаемых протоколов.

Ответ 18+ 🔞

Слушай, а вот libcurl — это, блядь, такая штука, которая в мире C и C++ как батя в подъезде: все его знают, все им пользуются, но иногда он такой старый и консервативный, что просто ёперный театр. По сути, это библиотека, которая умеет таскать данные по интернету куда угодно: HTTP, HTTPS, FTP — да ей, вротберунчик, вообще похуй, какой протокол, она со всеми договорится.

Что она умеет, эта мартышлюшка:

  • Работать с шифрованием через OpenSSL или другие движки — то есть не светить твой трафик всем подряд, как голую жопу в окне.
  • Делать запросы и синхронно (ждать ответа, как дурак), и асинхронно (отправил и пошёл дальше чай пить, красава).
  • Пролезать через прокси, жрать куки, авторизовываться кучей способов. Хочешь как человек — логин-пароль, хочешь как корпоративный шпион — NTLM или Kerberos.
  • Качать и заливать файлы, работать в несколько потоков. В общем, функционала — овердохуища.

Смотри, как это выглядит в коде, самый простой случай — тупо стянуть что-то с сайта:

#include <iostream>
#include <curl/curl.h>

// Эта функция вызывается, когда libcurl получает куски данных.
// Просто складываем их в нашу строку, как в ведро.
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* userp) {
    size_t totalSize = size * nmemb;
    userp->append(static_cast<char*>(contents), totalSize);
    return totalSize;
}

int main() {
    CURL* curl;
    CURLcode res;
    std::string readBuffer; // Сюда всё скачается

    curl_global_init(CURL_GLOBAL_DEFAULT); // Без этой инициализации — нихуя не заработает
    curl = curl_easy_init(); // Рождаем наш инструмент для запросов

    if (curl) {
        // Настраиваем, куда и как будем стучаться
        curl_easy_setopt(curl, CURLOPT_URL, "https://api.example.com/data");
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
        curl_easy_setopt(curl, CURLOPT_USERAGENT, "MyCppApp/1.0"); // Притворяемся браузером, а не скриптом

        // ВОТ МОМЕНТ ИСТИНЫ, ПАДЛА! Выполняем запрос.
        res = curl_easy_perform(curl);

        // Смотрим, не обосрались ли мы
        if (res != CURLE_OK) {
            std::cerr << "Всё пропало, шеф: " << curl_easy_strerror(res) << 'n';
        } else {
            long http_code = 0;
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
            std::cout << "Сервер ответил кодом: " << http_code << 'n';
            std::cout << "Пришло данных: " << readBuffer.size() << " байтn";
            // Если хочешь посмотреть, что пришло — раскомментируй строку ниже и приготовься к сюрпризам
            // std::cout << "Тело ответа: " << readBuffer << 'n';
        }

        // Обязательно прибираем за собой, а то память потечёт
        curl_easy_cleanup(curl);
    }

    curl_global_cleanup();
    return 0;
}

Где эту хуйню применяют в реальной жизни:

  1. Вытягивание данных из API. Нужен курс доллара или погода? libcurl тебе в помощь, чувак.
  2. Отправка телеметрии. Приложение наклало что-то важное — отсылает на сервер лог, и всем хорошо.
  3. Автоапдейты. Новая версия вышла? Прога сама скачает и предложит обновиться, хитрая жопа.
  4. Работа с облаками. Залить отчёт или скачать картинку — всё через эту библиотеку.

А есть ли что-то покруче? Ну, для любителей чистого C++ есть обёртки типа curlpp или нативные библиотеки вроде Boost.Beast — это мощно, но и сложно, ёпта. А есть простенькие, как cpp-httplib. Но libcurl — это как проверенный УАЗик: вид, конечно, блядовитый, и бензина жрёт дохуя, но заведётся в любой мороз и везде проедет. Все её знают, все ей доверяют, и она уже двадцать лет никого не подводила. Так что выбор за тобой: или быстро и надёжно, или модно и с приключениями.