☰
cpp-httplib HTTPS 客户端实战:从 https:// URL 到证书校验与重定向追踪
2026/10/2 15:08:38 网站建设 项目流程
  • 后端
  • 网络

【免费下载链接】cpp-httplib

A C++ header-only HTTP/HTTPS server and client library

项目地址:https://gitcode.com/GitHub_Trending/cp/cpp-httplib
点击查看免费下载

cpp-httplib 的httplib::Client同时支持明文 HTTP 与加密 HTTPS 通信。本文基于官方 Tour 文档的「HTTPS Client」章节,完整讲解如何用一行https://前缀切换协议、处理 HTTPS 默认端口、控制 CA 证书校验策略,以及开启重定向自动追踪;同时结合仓库源码与测试用例,揭示这些 API 背后的实现机制,让你在真实项目中安全、正确地使用 HTTPS 客户端。

前置准备:开启 TLS 支持

在写出第一个 HTTPS 客户端之前,需要确保编译时启用了 TLS 后端。cpp-httplib 以CPPHTTPLIB_OPENSSL_SUPPORT宏开关 TLS 功能,并链接 OpenSSL 的libssl与libcrypto两个库(Linux 下典型编译命令如下):

clang++ -std=c++17 -pthread -DCPPHTTPLIB_OPENSSL_SUPPORT \ -lssl -lcrypto \ -o client client.cpp

macOS 下还需借助-I/-L指定 Homebrew 版 OpenSSL 路径,并通过-framework CoreFoundation -framework Security让 Keychain 中的系统证书可被自动读取。除 OpenSSL 外,项目还支持 Mbed TLS(CPPHTTPLIB_MBEDTLS_SUPPORT)与 wolfSSL(CPPHTTPLIB_WOLFSSL_SUPPORT),切换方式仅涉及宏定义与链接库名,客户端 API 完全一致。完整的安装与编译选项对照可参见 05-tls-setup。

从 http 到 https:只改一个 URL 前缀

在 02-basic-client 中,我们使用httplib::Client cli("http://localhost:8080")发送明文请求。切换到 HTTPS 时,只需把构造函数的 URL 前缀改为https://,其余 API(Get()、Post()、参数传递、响应读取等)全部保持不变:

#define CPPHTTPLIB_OPENSSL_SUPPORT #include "httplib.h" #include <iostream> int main() { httplib::Client cli("https://nghttp2.org"); auto res = cli.Get("/"); if (res) { std::cout << res->status << std::endl; // 200 std::cout << res->body.substr(0, 100) << std::endl; // HTML 开头部分 } else { std::cout << "Error: " << httplib::to_string(res.error()) << std::endl; } }

对应的curl命令同样只换协议前缀:

curl https://nghttp2.org/

从源码结构看,httplib::Client在解析 URL 时会根据 scheme 自动选择加密传输路径;仓库 example/client.cc 中也提供了直接使用httplib::SSLClient的另一种写法(SSLClient cli("localhost", 8080)),便于显式声明 TLS 连接。无论哪种方式,只要在#include "httplib.h"之前定义了CPPHTTPLIB_OPENSSL_SUPPORT,客户端即可完成 TLS 握手。

指定端口:HTTPS 默认端口 443

HTTPS 的默认端口是 443。当服务器监听在其他端口(例如本地开发常用的 8443)时,直接在 URL 中写明端口即可:

httplib::Client cli("https://localhost:8443");

该默认值在实现中亦有体现:在重定向跳转等场景下,当 URL 未显式携带端口时,实现代码会按next_scheme == "https" ? 443 : 80补齐端口(见 httplib.h),与 HTTP 默认端口 80 形成对应。

CA 证书验证:默认开启,自动读取系统信任库

httplib::Client建立 HTTPS 连接时,默认会对服务器证书进行验证,只信任由受信 CA(证书颁发机构)签发的证书。CA 证书的加载是自动完成的:

  • macOS:从 Keychain 读取;
  • Linux:从系统 CA 证书存储读取;
  • Windows:从 Windows 证书存储读取。

大多数情况下无需任何额外配置。源码中该行为由enable_system_ca(bool)与system_ca_mode_(SystemCAMode::Enabled/Disabled)控制(见 httplib.h);macOS 上自动读取 Keychain 依赖编译时的-framework CoreFoundation -framework Security链接选项。

手动指定 CA 证书文件

某些环境(如精简容器、嵌入式系统)可能找不到系统 CA 证书,此时可用set_ca_cert_path()显式指定证书文件路径:

httplib::Client cli("https://nghttp2.org"); cli.set_ca_cert_path("/etc/ssl/certs/ca-certificates.crt"); auto res = cli.Get("/");

对应的 curl 参数为--cacert:

curl --cacert /etc/ssl/certs/ca-certificates.crt https://nghttp2.org/

值得留意的是,set_ca_cert_path()的实现签名带有两个参数——证书文件路径与证书目录路径(见 httplib.h):

inline void ClientImpl::set_ca_cert_path(const std::string &ca_cert_file_path, const std::string &ca_cert_dir_path);

日常用法只传第一个参数即可;第二个参数可用于指定存放多个 CA 证书的目录,适合需要同时信任多个证书源的场景。仓库 example/client.cc 中的实际用法是配合随仓库提供的 example/ca-bundle.crt:

cli.set_ca_cert_path(CA_CERT_FILE); // CA_CERT_FILE = "./ca-bundle.crt" cli.enable_server_certificate_verification(true);

测试套件 test/test.cc 同样通过set_ca_cert_path(CA_CERT_FILE)+ 开启验证的组合来校验 HTTPS 客户端行为,可作为集成范例。

开发期禁用证书验证

在开发阶段连接自签名证书的服务器(如本地localhost:8443使用测试证书)时,可以临时关闭验证:

httplib::Client cli("https://localhost:8443"); cli.enable_server_certificate_verification(false); auto res = cli.Get("/");

curl 的等价写法是-k(或--insecure):

curl -k https://localhost:8443/

生产环境绝不要关闭证书验证,否则中间人攻击(MITM)可以轻松伪造服务器身份,窃取或篡改通信内容。测试代码 test/test.cc 中大量enable_server_certificate_verification(false)调用均用于本地自签名证书的测试场景,这正是它适合出现的位置——测试环境,而非线上。

重定向追踪:默认不追,开启后自动跟进

访问真实网站时常会遇到重定向:http://跳转到https://、www域名跳转到非www域名、路径迁移等。cpp-httplib 的客户端默认不自动追踪重定向,此时响应会停留在 3xx 状态码,重定向目标位于Location响应头中:

httplib::Client cli("https://nghttp2.org"); auto res = cli.Get("/httpbin/redirect/3"); if (res) { std::cout << res->status << std::endl; // 302 std::cout << res->get_header_value("Location") << std::endl; }
curl https://nghttp2.org/httpbin/redirect/3

调用set_follow_location(true)后,客户端会自动追踪重定向并返回最终响应:

httplib::Client cli("https://nghttp2.org"); cli.set_follow_location(true); auto res = cli.Get("/httpbin/redirect/3"); if (res) { std::cout << res->status << std::endl; // 200(最终响应) }
curl -L https://nghttp2.org/httpbin/redirect/3

源码层面的重定向实现

深入 httplib.h 的ClientImpl::redirect()实现,可以看到自动追踪的若干关键行为:

  • 只跟随 http/https:Location指向的 URL 若使用其他 scheme,直接放弃跳转,防止协议混淆;
  • 相对路径解析:Location为相对路径(如/redirect/3)时会基于当前请求路径解析出完整目标;
  • 同主机复用连接:目标与当前请求 scheme、host、port 一致时,复用当前客户端继续发送请求;
  • 跨主机新建客户端:跳转到其他主机/端口时,会创建新的客户端实例(HTTPS 目标创建SSLClient),并把超时、代理、套接字选项等配置复制过去;
  • 敏感头不跨主机传递:跨主机跳转时会移除Host、Proxy-Authorization、Authorization、Cookie、Cookie2等头部(见 httplib.h),避免把身份凭据泄露给第三方主机,这与 RFC 9110 对凭据转发的约束一致;
  • 跳转次数上限:请求内部维护redirect_count_计数,超限时返回Error::ExceedRedirectCount,防止无限重定向死循环。

测试套件对重定向的覆盖相当完整(见 test/test.cc):包括/absolute-redirect/3(绝对路径跳转)、/redirect/3(相对路径跳转)、/relative-redirect/3、/redirect/21(多次跳转)以及 httpbin 风格的/redirect-to,均配合set_follow_location(true)验证最终响应状态码与 body。

错误处理与排查

HTTPS 请求失败的原因比明文 HTTP 更多:连接失败、TLS 握手失败、证书验证失败等。与普通请求一样,务必先判断返回值再使用:

httplib::Client cli("https://invalid.example.com"); auto res = cli.Get("/"); if (!res) { // 连接或 TLS 层错误 std::cout << "Error: " << httplib::to_string(res.error()) << std::endl; return 1; }

res.error()返回错误枚举,httplib::to_string()可转换为可读文本。若在 OpenSSL 后端下需要进一步查看底层错误码,example/client.cc 展示了使用res.ssl_backend_error()的方式,对排查证书链不完整、协议版本不匹配等问题很有帮助。

下一步

至此你已经掌握了 HTTPS 客户端的完整用法:协议切换、端口指定、CA 证书管理与验证开关、重定向追踪,以及对应的 curl 对照命令和源码级行为依据。接下来可以尝试搭建自己的 HTTPS 服务端——从生成自签名证书开始,参见 07-https-server。

  • 后端
  • 网络

【免费下载链接】cpp-httplib

A C++ header-only HTTP/HTTPS server and client library

项目地址:https://gitcode.com/GitHub_Trending/cp/cpp-httplib
点击查看免费下载
上一篇:gorilla/websocket超时控制:读写超时的合理配置
下一篇:novideo_srgb 项目常见问题解决方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询