【C++】cpp-httplib基础使用 目录一、什么是 cpp-httplib核心特性二、如何安装和引入1. 获取源码2. 引入项目三、核心类与接口详解3.1 命名空间与基础类型3.2 Request 结构体获取请求信息3.3 Response 结构体构建响应3.4 Server 类搭建 HTTP 服务3.5 Client 类发起 HTTP 请求3.6 Result 类处理响应结果四、示例4.1 搭建基础 HTTP 服务器4.2 HTTP 客户端示例五、原理图六、实践与注意事项6.1 线程安全6.2 错误处理6.3 性能优化6.4 HTTPS 支持一、什么是 cpp-httplibcpp-httplib是一个轻量级、单头文件的 C HTTP 客户端/服务器库。只需包含一个头文件即可快速搭建 HTTP 服务或发起 HTTP 请求无需依赖复杂的第三方库。核心特性特性说明单头文件仅需#include httplib.h零依赖除 SSL 外跨平台支持 Windows、Linux、macOSHTTP/1.1完整支持持久连接、管道化SSL/TLS可选 OpenSSL 或 mbedTLS 支持 HTTPS文件上传原生支持multipart/form-data正则路由支持正则表达式匹配 URL 路径二、如何安装和引入1. 获取源码git clone https://github.com/yhirose/cpp-httplib.git2. 引入项目cpp-httplib 是header-only库只需将httplib.h复制到你的项目目录#include httplib.h // 或者 #include httplib.h如果放在系统路径编译时记得链接线程库Linuxg -stdc17 server.cpp -o server -pthread三、核心类与接口详解3.1 命名空间与基础类型namespace httplib { // 范围请求用于断点续传 using Range std::pairssize_t, ssize_t; using Ranges std::vectorRange; // 表单数据文件上传用 struct MultipartFormData { std::string name; // 表单字段名 std::string content; // 文件内容 std::string filename; // 文件名 std::string content_type;// MIME 类型 }; // 常用容器别名 using MultipartFormDataItems std::vectorMultipartFormData; using Params std::multimapstd::string, std::string; // 查询参数 using Headers std::multimapstd::string, std::string;// HTTP 头部 } // namespace httplib3.2 Request 结构体获取请求信息当客户端发起请求时cpp-httplib 会将所有信息封装在Request对象中struct Request { std::string method; // HTTP 方法GET/POST/PUT/DELETE 等 std::string path; // 请求路径如 /hi Headers headers; // 请求头 std::string body; // 请求体POST 数据等 Params params; // URL 查询参数?namezhangsanage18 MultipartFormDataMap files; // 上传的文件 Ranges ranges; // 范围请求断点续传 Match matches; // 正则路由捕获组 };常用字段详解字段用途示例method判断请求类型req.method POSTpath获取请求路径/api/user/123params获取 URL 参数?namezhangsan→req.params[name]headers获取请求头req.headers[Content-Type]body获取原始请求体JSON 字符串或表单数据matches正则匹配结果捕获 URL 中的动态部分3.3 Response 结构体构建响应struct Response { std::string version; // HTTP 版本 int status -1; // 状态码200, 404, 500 等 std::string reason; // 状态描述 Headers headers; // 响应头 std::string body; // 响应体 // 便捷方法 void set_content(const std::string s, const std::string content_type); void set_header(const std::string key, const std::string val); };关键方法说明set_content(body, type)设置响应内容和 MIME 类型text/html- HTML 页面application/json- JSON 数据text/plain- 纯文本set_header(key, val)添加自定义响应头如 CORS 支持3.4 Server 类搭建 HTTP 服务class Server { public: // 路由注册支持 GET/POST/PUT/DELETE/PATCH/OPTIONS Server Get(const std::string pattern, Handler handler); Server Post(const std::string pattern, Handler handler); Server Put(const std::string pattern, Handler handler); Server Delete(const std::string pattern, Handler handler); // 静态文件服务 bool set_mount_point(const std::string mount_point, const std::string dir, Headers headers Headers()); // 启动服务器 bool listen(const std::string host, int port); private: using Handler std::functionvoid(const Request , Response ); };路由匹配规则精确匹配/hi匹配http://localhost:9000/hi正则匹配R(/numbers/(\d))匹配/numbers/123并捕获数字3.5 Client 类发起 HTTP 请求class Client { public: explicit Client(const std::string host, int port); // GET 请求 Result Get(const std::string path, const Headers headers); Result Get(const std::string path, const Params params, const Headers headers, Progress progress nullptr); // POST 请求多种重载 Result Post(const std::string path, const std::string body, const std::string content_type); Result Post(const std::string path, const Params params); Result Post(const std::string path, const Headers headers, const Params params); Result Post(const std::string path, const MultipartFormDataItems items); // 文件上传 // PUT/DELETE Result Put(const std::string path, ...); Result Delete(const std::string path, ...); };3.6 Result 类处理响应结果class Result { public: operator bool() const; // 是否请求成功 const Response value() const; // 获取响应可能抛出异常 const Response operator*() const; // 解引用访问 const Response* operator-() const; // 箭头访问 // 使用示例 // auto res client.Get(/api); // if (res res-status 200) { ... } };四、示例4.1 搭建基础 HTTP 服务器#include httplib.h #include iostream // 处理函数打印请求详情并返回 HTML void HelloWorld(const httplib::Request req, httplib::Response rsp) { // 打印请求方法 std::cout Method: req.method std::endl; // 打印请求路径 std::cout Path: req.path std::endl; // 打印请求体 std::cout Body: req.body std::endl; // 遍历并打印所有请求头 std::cout Headers: std::endl; for (auto [key, val] : req.headers) { std::cout key val std::endl; } // 遍历并打印 URL 查询参数 std::cout Params: std::endl; for (auto [key, val] : req.params) { std::cout key val std::endl; } // 设置响应内容 std::string html_body htmlbodyh1Hello World/h1/body/html; rsp.set_content(html_body, text/html); rsp.status 200; // HTTP OK } int main() { httplib::Server svr; // 注册路由GET /hi svr.Get(/hi, HelloWorld); // 正则路由匹配 /numbers/123 这样的路径 // R() 是原始字符串字面量避免转义 svr.Get(R(/numbers/(\d)), [](const httplib::Request req, httplib::Response rsp) { std::cout Matched path: req.path std::endl; // req.matches[0] 是整个匹配的字符串如 /numbers/123 // req.matches[1] 是第一个捕获组如 123 std::cout Full match: req.matches[0] std::endl; std::cout Captured number: req.matches[1] std::endl; rsp.set_content(Number received: req.matches[1].str(), text/plain); rsp.status 200; }); std::cout Server starting at http://0.0.0.0:9000 std::endl; // 启动服务器阻塞调用 svr.listen(0.0.0.0, 9000); return 0; }测试命令# 基础请求 curl http://localhost:9000/hi?namezhangsanage18 # 正则路由 curl http://localhost:9000/numbers/1234564.2 HTTP 客户端示例#include httplib.h #include iostream int main() { // 创建客户端指定服务器地址和端口 httplib::Client client(192.168.65.128, 9000); // 设置请求头 httplib::Headers headers { {Connection, closed}, // 短连接 {User-Agent, cpp-httplib-client} }; // 设置查询参数 httplib::Params params { {name, lisi}, {age, 18} }; // 发起 GET 请求 auto rsp client.Get(/hi, params, headers); // 检查响应 if (rsp) { // 请求成功网络层 std::cout Status: rsp-status std::endl; if (rsp-status 200) { // HTTP 成功 std::cout Response body: std::endl; std::cout rsp-body std::endl; } else { std::cerr HTTP Error: rsp-reason std::endl; } } else { std::cerr Request failed (network error) std::endl; } // POST 请求示例表单数据 httplib::Params form_data { {username, admin}, {password, 123456} }; auto post_res client.Post(/login, form_data); // POST JSON 示例 std::string json R({user:admin,pass:secret}); auto json_res client.Post(/api/login, json, application/json); return 0; }五、原理图┌─────────┐ GET /hi?namezhangsan HTTP/1.1 │ Client │ ───────────────────────────────────────► └─────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ Class Server │ │ ┌─────────────────┐ ┌─────────────────────────────────┐ │ │ │ get_handlers_ │ │ 路由表 │ │ │ │ post_handlers_│───►├─────────────┬───────────────────┤ │ │ │ listen(port) │ │ 路径 │ 回调函数 │ │ │ └─────────────────┘ │ /hi │ HelloWorld │ │ │ │ │ /numbers/(\d)│ lambda │ │ │ │ └─────────────┴───────────────────┘ │ │ │ │ │ │ └──────────────────────────┘ │ │ 匹配成功调用回调 │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ void HelloWorld(const Request req, │ │ Response rsp) { │ │ // 访问 req.method, req.path │ │ // 访问 req.params[name] │ │ // 设置 rsp.set_content(...) │ │ // 设置 rsp.status 200 │ │ } │ └─────────────────────────────────────┘六、实践与注意事项6.1 线程安全Server是多线程的每个请求在独立线程中处理不要在处理函数中使用非线程安全的全局变量如果一定要用则加锁保护6.2 错误处理// 始终检查 Result 对象 auto res client.Get(/api); if (!res) { // 网络错误连接失败、超时等 std::cerr Network error std::endl; return; } if (res-status ! 200) { // HTTP 错误404, 500 等 std::cerr HTTP res-status : res-reason std::endl; return; }6.3 性能优化// 启用 Keep-Alive默认已启用 httplib::Client client(api.example.com, 80); client.set_keep_alive(true); // 设置超时 client.set_connection_timeout(5); // 连接超时 5 秒 client.set_read_timeout(10); // 读取超时 10 秒6.4 HTTPS 支持编译时链接 OpenSSLgg -stdc17 server.cpp -o server -pthread -lssl -lcrypto如果是用CmakeLists则需要#添加CPPHTTPLIB_OPENSSL_SUPPORT target_compile_definitions(testLLM PRIVATE CPPHTTPLIB_OPENSSL_SUPPORT) #链接库 target_link_libraries(OpenSSL::SSL OpenSSL::Crypto)代码中使用httplib::SSLServer svr(./cert.pem, ./key.pem); // HTTPS 服务器 httplib::SSLClient client(https://example.com); // HTTPS 客户端感谢阅读本文如有错漏之处烦请斧正。