CURLOPT_HEADERFUNCTION принимает функцию, которая видит каждую строку.">
Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗cpSpHtRsH 652 of 696 menu
◀ ▶

Заголовки ответа в C++

Заголовки ответа приходят отдельно от тела и построчно попадают в колбэк libcurl.

Опция CURLOPT_HEADERFUNCTION принимает функцию, которая видит каждую строку, включая "Content-Type". Имена в HTTP не чувствительны к регистру, но в коде удобно искать вариант в нижнем регистре. Выведем тип содержимого для example.com:

#include <iostream> #include <string> #include <cctype> #include <curl/curl.h> size_t writeBody( char* ptr, size_t size, size_t nmemb, void* userdata ) { auto* body = static_cast<std::string*>(userdata); body->append(ptr, size * nmemb); return size * nmemb; } size_t captureHeader( char* buffer, size_t size, size_t nitems, void* userdata ) { auto* type = static_cast<std::string*>(userdata); size_t total = size * nitems; std::string line(buffer, total); const std::string key = "content-type:"; if (line.size() >= key.size()) { std::string lower; lower.reserve(line.size()); for (char ch : line) { lower.push_back( static_cast<char>(std::tolower(ch)) ); } if (lower.rfind(key, 0) == 0) { *type = line.substr(key.size()); while ( !type->empty() && (type->front() == ' ' || type->front() == '\t') ) { type->erase(type->begin()); } while ( !type->empty() && (type->back() == '\r' || type->back() == '\n') ) { type->pop_back(); } } } return total; } int main() { curl_global_init(CURL_GLOBAL_DEFAULT); CURL* curl = curl_easy_init(); std::string body; std::string contentType; curl_easy_setopt( curl, CURLOPT_URL, "https://example.com/" ); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeBody); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &body); curl_easy_setopt( curl, CURLOPT_HEADERFUNCTION, captureHeader ); curl_easy_setopt( curl, CURLOPT_HEADERDATA, &contentType ); CURLcode res = curl_easy_perform(curl); if (res == CURLE_OK) { std::cout << contentType << "\n"; } curl_easy_cleanup(curl); curl_global_cleanup(); return res == CURLE_OK ? 0 : 1; }

Число строк заголовков можно посчитать в том же колбэке, пропуская пустые строки и стартовую "HTTP/...":

#include <iostream> #include <string> #include <cctype> #include <curl/curl.h> size_t writeBody( char* ptr, size_t size, size_t nmemb, void* userdata ) { auto* body = static_cast<std::string*>(userdata); body->append(ptr, size * nmemb); return size * nmemb; } size_t countHeader( char* buffer, size_t size, size_t nitems, void* userdata ) { auto* count = static_cast<int*>(userdata); size_t total = size * nitems; std::string line(buffer, total); bool blank = true; for (char ch : line) { if (ch != '\r' && ch != '\n' && ch != ' ') { blank = false; break; } } if (blank) { return total; } if (line.rfind("HTTP/", 0) == 0) { return total; } ++(*count); return total; } int main() { curl_global_init(CURL_GLOBAL_DEFAULT); CURL* curl = curl_easy_init(); std::string body; int headerCount = 0; curl_easy_setopt( curl, CURLOPT_URL, "https://example.com/" ); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeBody); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &body); curl_easy_setopt( curl, CURLOPT_HEADERFUNCTION, countHeader ); curl_easy_setopt( curl, CURLOPT_HEADERDATA, &headerCount ); CURLcode res = curl_easy_perform(curl); if (res == CURLE_OK) { std::cout << headerCount << "\n"; } curl_easy_cleanup(curl); curl_global_cleanup(); return res == CURLE_OK ? 0 : 1; }

Выведите значение поля "content-type" для ответа "https://example.com/".

Отправьте чтение на "https://example.com/" и напечатайте первое значение заголовка "date", если он пришел, иначе строку "none".

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить