libcurl для C++: полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Что такое libcurl и зачем она нужна

libcurl — это мощная и широко используемая кроссплатформенная библиотека для передачи данных по различным сетевым протоколам. Написанная на C, она предоставляет C++ интерфейс (часто называемый curlpp или просто обёрткой libcurl) для выполнения HTTP-запросов, загрузки файлов, работы с FTP, SMTP и многими другими протоколами. В контексте C++ libcurl является де-факто стандартом для создания HTTP-клиентов.

Зачем нужна libcurl в C++?

  • Работа с REST API: Отправка GET, POST, PUT, DELETE запросов к веб-сервисам.
  • Загрузка файлов: Скачивание изображений, документов, архивов из интернета.
  • Отправка данных: Загрузка файлов на сервер, отправка форм.
  • Парсинг веб-страниц: Получение HTML-кода для дальнейшего анализа.
  • Аутентификация: Поддержка Basic, Digest, OAuth, NTLM и других схем.
  • Работа с cookies: Управление сессиями и состоянием.
  • SSL/TLS: Безопасное соединение через HTTPS.

Библиотека отличается высокой производительностью, стабильностью и поддержкой практически всех современных сетевых протоколов. Она используется в таких проектах, как cURL (командная строка), PHP (расширение cURL), и многих других.

Установка libcurl для C++

В отличие от Python или JavaScript, в C++ нет единого менеджера пакетов, поэтому установка зависит от вашей операционной системы и компилятора.

Установка на Linux (Ubuntu/Debian)

sudo apt update
sudo apt install libcurl4-openssl-dev

Для других дистрибутивов (Fedora, CentOS, Arch) используйте соответствующие пакетные менеджеры (dnf, yum, pacman).

Установка на macOS

brew install curl

Установка на Windows

Самый простой способ — использовать vcpkg:

git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
.\bootstrap-vcpkg.bat
.\vcpkg integrate install
.\vcpkg install curl

Или скачайте предварительно собранные бинарники с официального сайта curl.

Подключение в проекте CMake

find_package(CURL REQUIRED)
target_link_libraries(your_project PRIVATE CURL::libcurl)

Быстрый старт: простой HTTP GET запрос

Давайте напишем простейшую программу, которая выполняет GET-запрос к сайту и выводит полученные данные.

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

// Функция обратного вызова для записи данных в строку
size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* output) {
    size_t totalSize = size * nmemb;
    output->append(static_cast<char*>(contents), totalSize);
    return totalSize;
}

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

    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();

    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "https://api.github.com");
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
        
        // Выполняем запрос
        res = curl_easy_perform(curl);
        
        if (res != CURLE_OK) {
            std::cerr << "Ошибка: " << curl_easy_strerror(res) << std::endl;
        } else {
            std::cout << "Ответ сервера:" << std::endl;
            std::cout << response << std::endl;
        }
        
        curl_easy_cleanup(curl);
    }

    curl_global_cleanup();
    return 0;
}

Компиляция:

g++ -o http_client http_client.cpp -lcurl

Основные методы/функции libcurl

1. curl_easy_init()

Что делает: Инициализирует сессию CURL и возвращает указатель на неё. Это первый шаг перед любыми операциями.

Параметры: Нет.

Возвращает: Указатель CURL* или NULL в случае ошибки.

Пример:

CURL* curl = curl_easy_init();
if (!curl) {
    std::cerr << "Не удалось инициализировать CURL" << std::endl;
    return -1;
}

2. curl_easy_setopt()

Что делает: Устанавливает опции для текущей сессии. Это самый важный метод — через него настраивается URL, заголовки, тело запроса, таймауты и многое другое.

Параметры:

  • CURL* curl — указатель на сессию
  • CURLoption option — опция, которую нужно установить (например, CURLOPT_URL)
  • ... (vararg) — значение опции (строка, число, указатель на функцию)

Пример:

curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // Следовать редиректам

3. curl_easy_perform()

Что делает: Выполняет запрос с настроенными параметрами. Блокирует выполнение до получения ответа или ошибки.

Параметры: CURL* curl

Возвращает: CURLcode — код результата (CURLE_OK при успехе).

Пример:

CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
    std::cerr << "Ошибка выполнения: " << curl_easy_strerror(res) << std::endl;
}

4. curl_easy_cleanup()

Что делает: Освобождает ресурсы, выделенные для сессии. Должен вызываться после завершения работы с сессией.

Параметры: CURL* curl

Пример:

curl_easy_cleanup(curl);

5. curl_global_init() / curl_global_cleanup()

Что делает: Глобальная инициализация/деинициализация библиотеки. Должна вызываться один раз в программе (обычно в main).

Параметры: long flags (CURL_GLOBAL_DEFAULT, CURL_GLOBAL_SSL, CURL_GLOBAL_WIN32 и др.)

Пример:

curl_global_init(CURL_GLOBAL_DEFAULT);
// ... работа с curl ...
curl_global_cleanup();

6. curl_easy_strerror()

Что делает: Преобразует код ошибки CURLcode в человекочитаемое строковое описание.

Параметры: CURLcode error

Возвращает: const char*

Пример:

CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
    std::cerr << curl_easy_strerror(res) << std::endl;
}

7. curl_easy_getinfo()

Что делает: Получает информацию о выполненном запросе: HTTP-код ответа, размер данных, время выполнения и т.д.

Параметры:

  • CURL* curl
  • CURLINFO info — тип запрашиваемой информации
  • void* ptr — указатель на переменную для результата

Пример:

long http_code;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
std::cout << "HTTP код: " << http_code << std::endl;

double total_time;
curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time);
std::cout << "Время запроса: " << total_time << " сек" << std::endl;

8. curl_slist_append() / curl_slist_free_all()

Что делает: Управление списком строк (например, для HTTP-заголовков). curl_slist_append добавляет строку в список, curl_slist_free_all освобождает память.

Параметры:

  • struct curl_slist* list — указатель на список (или NULL для первого элемента)
  • const char* string — добавляемая строка

Пример:

struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, "Authorization: Bearer token123");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
// ... выполнение запроса ...
curl_slist_free_all(headers);

9. curl_easy_escape() / curl_easy_unescape()

Что делает: URL-кодирование/декодирование строк. Полезно для передачи специальных символов в URL.

Параметры:

  • CURL* curl
  • const char* string — строка для кодирования
  • int length — длина строки (0 для автоопределения)

Пример:

char* encoded = curl_easy_escape(curl, "Hello World! Привет!", 0);
std::cout << "Закодировано: " << encoded << std::endl;
curl_free(encoded);

10. curl_version()

Что делает: Возвращает строку с версией библиотеки libcurl и поддерживаемыми протоколами.

Параметры: Нет.

Пример:

std::cout << "Версия libcurl: " << curl_version() << std::endl;

Реальный практический пример: загрузка файла с прогрессом

Создадим программу, которая скачивает файл, показывает прогресс и обрабатывает ошибки.

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

// Функция для записи в файл
size_t WriteFileCallback(void* ptr, size_t size, size_t nmemb, std::ofstream* file) {
    file->write(static_cast<char*>(ptr), size * nmemb);
    return size * nmemb;
}

// Функция отображения прогресса
int ProgressCallback(void* clientp, double dltotal, double dlnow, double ultotal, double ulnow) {
    if (dltotal > 0) {
        int percent = static_cast<int>((dlnow / dltotal) * 100);
        std::cout << "\rЗагрузка: " << percent << "% (" 
                  << dlnow << " из " << dltotal << " байт)" << std::flush;
    }
    return 0; // 0 = продолжать, 1 = отменить
}

int main() {
    std::string url = "https://speed.hetzner                    

Рекомендаций