Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое libcurl?
libcurl — это мощная открытая библиотека для создания HTTP/HTTPS запросов в C и C++ приложениях. Я имею глубокий опыт работы с ней в production системах.
Что такое libcurl
libcurl (URL Transfer Library) — это кросс-платформенная библиотека для:
- Загрузки и отправки данных по различным протоколам
- Работы с HTTP, HTTPS, FTP, SFTP и другими
- Управления кукиз, авторизацией, редиректами
- Асинхронной обработки сетевых запросов
Поддерживает: Linux, Windows, macOS, Android, iOS и другие ОС.
Протоколы
libcurl поддерживает:
- HTTP/0.9, HTTP/1.0, HTTP/1.1, HTTP/2, HTTP/3 — веб
- HTTPS — защищённый веб
- FTP/FTPS — файловые сервера
- SFTP — SSH file transfer
- SCP — Secure copy
- TELNET — удалённый терминал
- LDAP/LDAPS — directory services
- Многое другое
Установка
На Linux:
# Ubuntu/Debian
sudo apt-get install libcurl4-openssl-dev
# RHEL/CentOS
sudo yum install curl-devel
# Arch
sudo pacman -S curl
На macOS:
brew install curl
Базовый пример
#include <iostream>
#include <curl/curl.h>
#include <string>
// Callback для обработки ответа
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* s)
{
size_t newLength = size * nmemb;
s->append((char*)contents, newLength);
return newLength;
}
int main()
{
CURL* curl = curl_easy_init();
if (curl) {
std::string readBuffer;
// Устанавливаем URL
curl_easy_setopt(curl, CURLOPT_URL, "https://api.example.com/users");
// Устанавливаем callback для получения данных
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
// Таймаут
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
// Выполняем запрос
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
std::cerr << "Ошибка: " << curl_easy_strerror(res) << std::endl;
} else {
std::cout << "Ответ: " << readBuffer << std::endl;
}
// Очищаем
curl_easy_cleanup(curl);
}
return 0;
}
Компиляция:
g++ -o example example.cpp -lcurl
./example
POST запрос с JSON
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* s)
{
s->append((char*)contents, size * nmemb);
return size * nmemb;
}
int main()
{
CURL* curl = curl_easy_init();
if (curl) {
std::string readBuffer;
std::string postData = R"({"name": "John", "email": "john@example.com"})";
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_URL, "https://api.example.com/users");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
std::cerr << "Ошибка: " << curl_easy_strerror(res) << std::endl;
} else {
long response_code;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
std::cout << "HTTP Code: " << response_code << std::endl;
std::cout << "Response: " << readBuffer << std::endl;
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
return 0;
}
Основные опции (curl_easy_setopt)
URL и Метод:
curl_easy_setopt(curl, CURLOPT_URL, "https://api.example.com");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
Заголовки:
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Authorization: Bearer token123");
headers = curl_slist_append(headers, "X-Custom-Header: value");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
Авторизация:
// Basic auth
curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password");
// Bearer token
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BEARER);
curl_easy_setopt(curl, CURLOPT_XOAUTH2_BEARER, "token");
SSL/TLS:
// Отключить проверку сертификата (только для разработки!)
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
// Использовать конкретный сертификат
curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/ca-bundle.crt");
Таймауты:
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); // 30 сек
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L); // 10 сек на подключение
Редирект:
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // Следить редиректам
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5L); // Максимум 5 редиректов
Кукиз:
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "cookies.txt");
curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookies.txt");
Proxy:
curl_easy_setopt(curl, CURLOPT_PROXY, "proxy.example.com:8080");
curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, "user:password");
Вывод информации о запросе
long response_code;
char* effective_url = nullptr;
struct curl_slist* cookies = nullptr;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effective_url);
curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies);
std::cout << "Response code: " << response_code << std::endl;
std::cout << "Final URL: " << effective_url << std::endl;
Загрузка файла
FILE* file = fopen("image.jpg", "rb");
curl_easy_setopt(curl, CURLOPT_URL, "https://upload.example.com");
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(curl, CURLOPT_READDATA, file);
CURLcode res = curl_easy_perform(curl);
fclose(file);
Асинхронные запросы с curl_multi
CURLM* multi_handle = curl_multi_init();
// Добавляем несколько запросов
CURL* curl1 = curl_easy_init();
CURL* curl2 = curl_easy_init();
CURL* curl3 = curl_easy_init();
curl_easy_setopt(curl1, CURLOPT_URL, "https://api.example.com/1");
curl_easy_setopt(curl2, CURLOPT_URL, "https://api.example.com/2");
curl_easy_setopt(curl3, CURLOPT_URL, "https://api.example.com/3");
curl_multi_add_handle(multi_handle, curl1);
curl_multi_add_handle(multi_handle, curl2);
curl_multi_add_handle(multi_handle, curl3);
int still_running = 1;
while (still_running) {
curl_multi_perform(multi_handle, &still_running);
// Можем делать что-то ещё пока запросы обрабатываются
}
curl_multi_remove_handle(multi_handle, curl1);
curl_multi_remove_handle(multi_handle, curl2);
curl_multi_remove_handle(multi_handle, curl3);
curl_multi_cleanup(multi_handle);
Best Practices
- Всегда проверяй return код — curl_easy_perform может упасть
- Используй таймауты — не жди бесконечно
- Обработка ошибок — curl_easy_strerror для читаемых сообщений
- Очистка памяти — curl_easy_cleanup, curl_slist_free_all
- SSL сертификаты — проверяй в production, не отключай
- Переиспользуй handles — создание CURL handle дорого
- Логирование — используй CURLOPT_VERBOSE для отладки
Практическое применение в Backend
Я использовал libcurl для:
- Интеграции с внешними API (платёжные системы, облачные сервисы)
- Вебхуков и callback уведомлений
- Кэширования данных из третьих источников
- Микросервис коммуникации
- Здоровья проверки (health checks) внешних сервисов
libcurl — это стандартный инструмент в C/C++ backend разработке, незаменим при работе с HTTP.