目录
[4.1.Request 核心字段](#4.1.Request 核心字段)
[4.2.Response 核心方法](#4.2.Response 核心方法)
[6.Server 类核心接口](#6.Server 类核心接口)
[7Client 类核心接口](#7Client 类核心接口)
[8.SSL/TLS 支持(HTTPS)](#8.SSL/TLS 支持(HTTPS))
1.cpp-httplib简介
cpp-httplib由 yhirose 开发
是一个Header-Only、零依赖(无需任何第三方库)的 C++11 HTTP库
HTTPS 模式下依赖 OpenSSL 或 mbedTLS
可在github、gitee、gitcode上搜索下载
核心特点包括:
- 单文件设计:整个库仅 httplib.h 一个头文件,无需编译、无需链接,直接 #include 即可使用
- 同步阻塞 I/O + 多线程:采用 select/poll 多路复用和线程池模型处理请求,但每个请求的处理是同步阻塞的,适合中小并发
- 完整协议支持:HTTP/1.1、HTTPS(需 OpenSSL/mbedTLS)、WebSocket
- 跨平台:Windows、Linux、macOS 全兼容
- cpp-httplib 要求 GCC 6.0 及以上版本才能稳定运行,原因是旧版本中的 <regex> 实现存在严重 bug
2.安装与使用注意事项
-
只需将 httplib.h 拷贝到项目目录即可使用,无需安装或编译
#include "httplib.h"
-
使用 HTTPS 时需要链接 OpenSSL(-lssl -lcrypto)和线程库(-lpthread),否则链接会报错,并且#define CPPHTTPLIB_OPENSSL_SUPPORT 必须写在 #include "httplib.h" 之前,否则 HTTPS 功能无法启用
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "httplib.h"g++ -std=c++11 main.cpp -lssl -lcrypto -lpthread
-
仅用 HTTP 时无需定义宏和链接 OpenSSL,命令可简化为 g++ -std=c++11 xxx -lpthread
3.核心概念与类结构
完整用法可参考 Gitee 仓库 https://gitee.com/YeLee_CN/cpp-httplib/blob/master/README.md#
cpp-httplib 围绕以下四个核心结构展开(均存在于 httplib 命令空间中):
| 类/结构 | 职责 | 说明 |
|---|---|---|
Server |
服务器端核心类 | 注册路由、监听端口、控制服务运行 |
Client / SSLClient |
客户端核心类 | 发起 HTTP/HTTPS 请求,支持各种 HTTP 方法 |
Request |
请求数据结构 | 封装客户端发来的 HTTP 请求(方法、路径、头部、正文等) |
Response |
响应数据结构 | 封装服务器要返回的 HTTP 响应(状态码、内容、头部等) |
4.Request 与 Response 对象核心成员
Request 侧重「数据字段」,Response 侧重「操作方法」
4.1.Request 核心字段
| 成员 | 类型 | 说明 |
| method | std::string | HTTP 方法(GET、POST、PUT 等) |
| path | std::string | 请求路径(如 /users/123) |
| version | std::string | HTTP 版本(如 HTTP/1.1) |
| body | std::string | 请求体内容 |
| headers | Headers | 请求头键值对 |
| params | Params | URL 查询参数(?key=value) |
| path_params | Params | 路径参数(:id 匹配的值) |
| matches | std::smatch | 正则表达式匹配结果 |
| remote_addr | std::string | 客户端 IP 地址 |
| remote_port | int | 客户端端口号 |
| has_header() | 方法 | 检查是否存在某个请求头 |
| get_header_value() | 方法 | 获取请求头值 |
| has_param() | 方法 | 检查是否存在某个查询参数 |
get_param_value() |
方法 | 获取查询参数值 |
|---|
4.2.Response 核心方法
| 字段 | 类型 | 作用 |
|---|---|---|
status |
int |
HTTP 状态码(200、404、500) |
body |
std::string |
响应体内容 |
headers |
Headers |
响应头集合 |
version |
std::string |
HTTP 版本 |
| 方法 | 作用 | 示例 |
|---|---|---|
set_content(content, type) |
设置响应体 + MIME 类型 | res.set_content("Hello", "text/plain") |
set_header(key, val) |
设置响应头 | res.set_header("X-Custom", "value") |
set_redirect(url, status) |
重定向(默认 302) | res.set_redirect("/login") |
set_file_content(path) |
读取文件作为响应体 | res.set_file_content("./index.html") |
set_content_provider(...) |
流式返回(固定长度) | 大文件传输 |
set_chunked_content_provider(...) |
分块流式返回(未知长度) | 动态生成内容 |
6.Server 类核心接口
- HTTP 方法路由注册
| 函数原型 | 参数说明 | 核心作用 | 注意事项 |
|---|---|---|---|
void Get(const char* pattern, Handler handler) |
pattern: URL路径模式 handler: 回调函数(const Request&, Response&) → void |
注册处理 GET 请求的路由 | 支持路径参数,如 "/user/{id}" |
void Post(const char* pattern, Handler handler) |
同 Get |
注册处理 POST 请求的路由 | 通过 Request::body 获取请求体 |
void Put(const char* pattern, Handler handler) |
同 Get |
注册处理 PUT 请求的路由 | --- |
void Delete(const char* pattern, Handler handler) |
同 Get |
注册处理 DELETE 请求的路由 | --- |
void Patch(const char* pattern, Handler handler) |
同 Get |
注册处理 PATCH 请求的路由 | --- |
void Options(const char* pattern, Handler handler) |
同 Get |
注册处理 OPTIONS 请求的路由 | 常用于 CORS 预检 |
- 服务器运行控制
| 函数原型 | 参数说明 | 核心作用 | 注意事项 |
|---|---|---|---|
bool listen(const char* host, int port, int socket_flags = 0) |
host: 监听地址(如 "0.0.0.0") port: 端口号 socket_flags: socket选项 |
启动服务器,开始监听端口 | 阻塞调用,需要在单独线程运行 |
void stop() |
无 | 停止服务器运行 | 非线程安全,必须在调用 listen 的同一线程中执行 |
bool is_running() const |
无 | 检查服务器是否正在运行 | --- |
- 常见 Socket 选项
| 选项 | 作用 |
|---|---|
TCP_NODELAY |
禁用 Nagle 算法,立即发送数据(不等待缓冲),降低延迟 |
SO_REUSEADDR |
允许重用本地地址和端口,服务器重启时避免 Address already in use 错误 |
SO_KEEPALIVE |
启用 TCP 保活机制,检测死连接 |
SO_RCVBUF / SO_SNDBUF |
设置接收/发送缓冲区大小 |
IPPROTO_TCP 级别选项 |
如 TCP_QUICKACK、TCP_DEFER_ACCEPT 等 |
- 服务器配置
| 函数原型 | 参数说明 | 核心作用 | 注意事项 |
|---|---|---|---|
void set_threads(size_t num_threads) |
num_threads: 线程池线程数 |
设置工作线程池大小 | 默认值为 CPU 核心数 |
void set_keep_alive_max_count(size_t count) |
count: 最大保持次数 |
设置长连接复用上限 | 默认值为 100,设为 0 禁用长连接 |
void set_mount_point(const char* uri, const char* dir) |
uri: 虚拟路径 dir: 本地目录 |
设置静态文件服务挂载点 | 一行代码即可实现静态文件服务器 |
void set_logger(Logger logger) |
logger: 日志回调函数 |
设置自定义日志处理器 | 参数类型为 void(*)(const Request&, const Response&) |
void set_error_handler(Handler handler) |
handler: 错误处理回调 |
设置全局错误处理 | 处理未匹配路由等场景 |
| 函数原型 | 作用 | 注意事项 |
|---|---|---|
bool set_base_dir(const std::string& dir, const std::string& mount_point = "") |
设置静态文件服务根目录,默认挂载到 / |
是 set_mount_point 的简化版本 |
bool set_mount_point(const std::string& mount_point, const std::string& dir, Headers headers = Headers()) |
设置静态文件挂载点,支持自定义响应头 | 更灵活,可指定自定义头部 |
- 超时控制
| 函数原型 | 参数说明 | 核心作用 | 注意事项 |
|---|---|---|---|
void set_read_timeout(time_t sec, time_t usec = 0) |
sec: 秒数 usec: 微秒数 |
设置读取请求的超时时间 | 防止慢客户端攻击 |
void set_write_timeout(time_t sec, time_t usec = 0) |
同 set_read_timeout |
设置发送响应的超时时间 | --- |
服务端示例
httplib::Server svr;
// GET /hello 响应
svr.Get("/hello", [](const httplib::Request& req, httplib::Response& res) {
res.set_content("Hello World", "text/plain");
});
// POST /login 处理 JSON 请求
svr.Post("/login", [](const httplib::Request& req, httplib::Response& res) {
auto body = req.body; // 原始请求体
// 解析 JSON/表单,处理业务逻辑...
res.set_content("{\"status\":\"ok\"}", "application/json");
});
svr.listen("0.0.0.0", 8080);
7Client 类核心接口
- 构造与配置
| 函数原型 | 参数说明 | 核心作用 | 注意事项 |
|---|---|---|---|
Client(const std::string& host, int port = 80) |
host: 目标服务器地址 port: 端口号(默认80) |
创建 HTTP 客户端 | 默认端口为 80 |
void set_keep_alive(bool enable) |
enable: 是否启用长连接 |
启用/禁用长连接 | 默认启用,可复用连接 |
void set_default_headers(Headers headers) |
headers: 默认请求头 |
设置所有请求的默认头部 | --- |
- HTTP 请求方法
| 函数原型 | 参数说明 | 核心作用 | 注意事项 |
|---|---|---|---|
Result Get(const std::string& path, const Headers& headers = {}) |
path: 请求路径 headers: 自定义请求头 |
发送 GET 请求,获取资源 | 返回类型为 std::shared_ptr<Response> 或错误信息 |
Result Post(const std::string& path, const std::string& body, const char* content_type = "text/plain") |
path: 请求路径 body: 请求体 content_type: 内容类型 |
发送 POST 请求,提交数据 | 常用 content_type 为 "application/json" |
Result Post(const std::string& path, const MultipartFormDataItems& items) |
path: 请求路径 items: 多部分表单数据 |
发送包含表单数据的 POST 请求 | 常用于文件上传 |
Result Put(const std::string& path, const std::string& body, const std::string& content_type) |
同 Post |
发送 PUT 请求,更新资源 | --- |
Result Delete(const std::string& path, const std::string& body = "", const std::string& content_type = "text/plain") |
同 Post |
发送 DELETE 请求 | --- |
Result 本质上是一个 std::unique_ptr<Response>,指向 Response 对象
using Result = std::unique_ptr<Response, detail::response_deleter>;
| 情况 | Result 状态 | 说明 |
|---|---|---|
| 请求成功 | result 非空,result->status 为 200 等 |
正常收到 HTTP 响应 |
| 请求失败 | result 非空,但 result.error() 返回错误码 |
网络错误、SSL 错误、超时等 |
| 致命错误 | result 为空(极少见) |
内存分配失败等极端情况 |
注意:即使请求失败(如连接拒绝),Result 通常也非空,需要通过 result.error() 判断具体错误
- 请求与错误处理
| 函数原型 | 参数说明 | 核心作用 | 注意事项 |
|---|---|---|---|
Error error() const |
无 | 获取上次请求的错误码 | 错误类型包括超时、连接失败等 |
bool is_socket_open() const |
无 | 检查 socket 是否仍处于打开状态 | 用于检查长连接是否有效 |
Error 是 httplib::Error 枚举类型,包含 30+ 种错误码,Success=0 表示成功,可用 httplib::to_string() 转为字符串输出
客户端示例
httplib::Client client("api.example.com");
client.set_timeout(5, 0); // 5秒超时
client.set_default_headers({{"User-Agent", "MyApp/1.0"}});
if (auto res = client.Get("/users")) {
if (res->status == 200) {
std::cout << "Response: " << res->body << std::endl;
} else {
std::cerr << "HTTP Error: " << res->status << std::endl;
}
} else {
auto err = res.error();
std::cerr << "Request Error: " << httplib::to_string(err) << std::endl;
}
8.SSL/TLS 支持(HTTPS)
| 类/宏 | 说明 | 示例 |
|---|---|---|
SSLServer |
HTTPS 服务器类,构造时需提供证书和私钥路径 | httplib::SSLServer svr("cert.pem", "key.pem") |
SSLClient |
HTTPS 客户端类,端口默认为 443 | httplib::SSLClient client("api.example.com") |
CPPHTTPLIB_OPENSSL_SUPPORT |
启用 OpenSSL 支持的宏 | #define CPPHTTPLIB_OPENSSL_SUPPORT |
CPPHTTPLIB_MBEDTLS_SUPPORT |
启用 mbedTLS 支持的宏 | 适用于嵌入式场景 |