Cliente HTTP em C++: fazendo requisições corretamente do A ao Z
\n\nNo mundo moderno do desenvolvimento de software, a capacidade de interagir com servidores remotos via HTTP é uma habilidade básica. Seja para baixar dados de uma API, enviar formulários ou trabalhar com serviços web, o C++ oferece várias ferramentas poderosas para criar clientes HTTP. Neste artigo, vamos analisar como fazer requisições HTTP corretamente em C++, explorar bibliotecas populares e escrever exemplos de código funcionais.
\n\nPor que C++ para requisições HTTP?
\n\nO C++ não possui suporte nativo a HTTP na biblioteca padrão, ao contrário de Python ou JavaScript. No entanto, isso não é um problema: existem bibliotecas testadas pelo tempo que permitem enviar requisições de forma fácil e eficiente. As principais opções são:
\n\n- \n
- libcurl (cURL) — a biblioteca multiplataforma mais popular. \n
- Boost.Beast — uma biblioteca moderna baseada em Boost.Asio. \n
- WinHTTP — solução nativa para Windows. \n
- Qt Network — para projetos em Qt. \n
Neste artigo, vamos focar nas duas primeiras, pois são as mais versáteis e adequadas para a maioria das tarefas.
\n\n1. Cliente HTTP usando libcurl
\n\nlibcurl é uma biblioteca testada ao longo dos anos que suporta HTTP, HTTPS, FTP e muitos outros protocolos. É fácil de usar e bem documentada.
\n\nInstalação do libcurl
\n\nPara Linux (Ubuntu/Debian):
\nsudo apt-get install libcurl4-openssl-dev\n\nPara Windows, você pode baixar os binários pré-compilados do site oficial curl.se ou usar o vcpkg:
\nvcpkg install curl\n\nRequisição GET simples
\n\nVamos escrever um exemplo básico de obtenção de dados de um servidor:
\n\n#include <iostream>\n#include <string>\n#include <curl/curl.h>\n\n// Função de callback para escrever dados\nstatic size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* output) {\n size_t totalSize = size * nmemb;\n output->append((char*)contents, totalSize);\n return totalSize;\n}\n\nint main() {\n CURL* curl = curl_easy_init();\n if (!curl) {\n std::cerr << "Erro de inicialização do CURL" << std::endl;\n return 1;\n }\n\n std::string response;\n curl_easy_setopt(curl, CURLOPT_URL, "https://jsonplaceholder.typicode.com/posts/1");\n curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);\n curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);\n curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); // Desativa verificação SSL para teste\n\n CURLcode res = curl_easy_perform(curl);\n if (res != CURLE_OK) {\n std::cerr << "Erro na requisição: " << curl_easy_strerror(res) << std::endl;\n } else {\n std::cout << "Resposta do servidor:\\n" << response << std::endl;\n }\n\n curl_easy_cleanup(curl);\n return 0;\n}\n\nCompile com a flag -lcurl:
g++ -o http_client http_client.cpp -lcurl\n\nRequisição POST com envio de JSON
\n\nAgora vamos adicionar o envio de dados:
\n\n#include <iostream>\n#include <string>\n#include <curl/curl.h>\n\nint main() {\n CURL* curl = curl_easy_init();\n if (!curl) return 1;\n\n std::string response;\n std::string jsonData = R"({"title": "foo", "body": "bar", "userId": 1})";\n\n struct curl_slist* headers = nullptr;\n headers = curl_slist_append(headers, "Content-Type: application/json");\n\n curl_easy_setopt(curl, CURLOPT_URL, "https://jsonplaceholder.typicode.com/posts");\n curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonData.c_str());\n curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);\n curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCal