cpp-httplb库使用手册
文章目录
- cpphttplib
- 核心类 Server 与 Client
- 补充说明:
- 核心参数 Request 类与 Response 类
- 补充说明:
- ContentType映射表
- 补充说明:
- 使用案例
- 案例 1:基础 HTTP 服务器(支持 GET/POST)
- 案例 2:HTTPS 服务器(基于 OpenSSL)
- 案例 3:HTTP 客户端(发送 GET/POST 请求)
- 案例 4:客户端发送 HTTPS 请求
- 核心知识点总结
cpphttplib
核心类 Server 与 Client
cpphttplib 是一个轻量级的 C++ HTTP 库,其核心功能围绕 Server
和 Client
两个核心类展开。以下是这两个类的核心函数、参数、返回值、函数作用及注意事项的整理:
Server 类
函数原型 | 函数作用 | 参数说明 | 返回值类型 | 注意事项 |
---|---|---|---|---|
bool listen(const char* host, int port, int socket_flags = 0) | 启动服务器并监听指定主机和端口的连接 | - host : 监听的主机地址(如 “0.0.0.0”)- port : 端口号 - socket_flags : socket 选项 | bool | - 成功返回 true ,失败返回 false - 阻塞式调用,需在单独线程运行 |
void Get(const char* pattern, Handler handler) | 注册处理 GET 请求的回调函数,用于响应特定路径的 GET 请求 | - pattern : URL 路径模式(如 “/hello”)- handler : 回调函数 (Request, Response) | void | - 支持路径参数(如 “/user/{id}”)- 回调需设置 Response 的状态码和内容 |
void Post(const char* pattern, Handler handler) | 注册处理 POST 请求的回调函数,用于响应特定路径的 POST 请求 | 同 Get ,处理 POST 请求 | void | - 需通过 Request::body 获取请求体 |
void set_mount_point(const char* uri, const char* dir) | 设置静态文件服务的挂载点,将虚拟路径映射到本地目录 | - uri : 挂载的虚拟路径 - dir : 本地目录路径 | void | - 用于静态文件服务 - 需启用 CPPHTTPLIB_USE_FILESYSTEM 宏 |
void set_keep_alive_max_count(size_t count) | 设置长连接的最大保持次数,控制连接复用的上限 | count : 最大保持连接次数 | void | - 默认值为 100- 设为 0 禁用长连接 |
void stop() | 停止服务器运行,终止监听状态 | 无 | void | - 非线程安全,需在调用 listen 的线程中执行 |
Client 类
函数原型 | 函数作用 | 参数说明 | 返回值类型 | 注意事项 |
---|---|---|---|---|
Result Get(const char* path, const Headers& headers = {}) | 向服务器发送 GET 请求,获取指定路径的资源 | - path : 请求路径 - headers : 请求头 | Result | - Result 是 std::shared_ptr<Response> 或错误信息 - 需检查 result->status 判断成功与否 |
Result Post(const char* path, const std::string& body, const char* content_type = "text/plain") | 向服务器发送 POST 请求,提交数据并获取响应 | - path : 请求路径 - body : 请求体 - content_type : 内容类型 | Result | - 常用 content_type 如 “application/json” |
Result Post(const char* path, const MultipartFormDataItems& items) | 向服务器发送包含多部分表单数据的 POST 请求,常用于文件上传 | - items : 多部分表单数据(含文件名、内容等) | Result | - 用于文件上传 |
void set_timeout(long sec, long usec) | 设置请求的超时时间,避免请求无限期阻塞 | - sec : 秒 - usec : 微秒 | void | - 设置请求超时时间 |
void set_keep_alive(bool enable) | 启用或禁用长连接功能,控制是否复用连接 | enable : 是否启用长连接 | void | - 默认启用,需服务器支持 |
补充说明:
- Handler 类型:
Server
的回调函数类型为std::function<void(const Request&, Response&)>
,需在回调中设置Response
的状态码(如res.status = 200
)和内容(如res.set_content("Hello", "text/plain")
)。 - Result 处理:
Client
的请求返回Result
,可通过if (result)
判断是否成功,再通过(*result)
获取Response
对象。 - 编译选项:使用静态文件服务或 SSL 功能时,需定义相应宏(如
CPPHTTPLIB_USE_FILESYSTEM
、CPPHTTPLIB_OPENSSL_SUPPORT
)并链接对应库。 - 线程安全:
Server
的回调函数可能被多线程调用,需自行保证线程安全;Client
非线程安全,多线程需创建独立实例。
核心参数 Request 类与 Response 类
Request 类
成员 / 函数原型 | 函数作用 | 说明 | 注意事项 |
---|---|---|---|
std::string method | 存储请求使用的 HTTP 方法 | 请求方法(如 “GET”、“POST”) | 大写字符串,可直接比较 |
std::string path | 存储请求的 URL 路径部分 | 请求路径(如 “/api/user”) | 不包含查询参数 |
std::string query | 存储请求 URL 中的查询字符串部分 | 查询字符串(如 “id=1&name=test”) | 需自行解析,可配合 httplib::split_query 函数 |
Headers headers | 存储请求的所有头部信息 | 请求头集合(std::unordered_map<std::string, std::string> ) | 键名不区分大小写,内部统一转为小写 |
std::string body | 存储请求的消息体内容 | 请求体内容 | POST/PUT 等方法常用,需根据 Content-Type 解析 |
std::string get_header_value(const char* key, const char* def = "") const | 获取指定请求头字段的值,若不存在则返回默认值 | - key : 头字段名 - def : 默认值 | 键名不区分大小写 |
std::string get_param_value(const char* key, const char* def = "") const | 获取 URL 路径中指定参数的值,若不存在则返回默认值 | - key : 路径参数名(如 “/user/{id}” 中的 “id”)- def : 默认值 | 仅对带路径参数的路由有效(如 Get("/user/{id}", ...) ) |
MultipartFormDataItems& get_multipart_form_data() | 获取多部分表单数据集合,用于处理文件上传等包含复杂数据的请求 | 无 | 需在 POST 多表单请求中使用,需先检查 Content-Type 是否为 multipart/form-data |
Response 类
成员 / 函数原型 | 函数作用 | 说明 | 返回值类型 | 注意事项 |
---|---|---|---|---|
int status | 存储响应的 HTTP 状态码 | 响应状态码(如 200、404、500) | - | 默认为 200(OK) |
Headers headers | 存储响应的所有头部信息 | 响应头集合(同 Request) | - | 常用 Content-Type 、Content-Length 等 |
std::string body | 存储响应的消息体内容 | 响应体内容 | - | 需与 Content-Type 匹配 |
void set_content(const std::string& content, const char* content_type) | 设置响应体内容及对应的内容类型,并自动设置 Content-Length 头 | - content : 响应内容 - content_type : 内容类型(如 “text/plain”) | void | 会自动设置 Content-Length 头 |
void set_header(const char* key, const std::string& value) | 设置响应头中的指定字段及其值 | - key : 头字段名 - value : 头字段值 | void | 键名会被转为小写 |
void set_redirect(const char* uri, int status = 302) | 设置重定向响应,指定重定向的目标 URI 和状态码 | - uri : 重定向目标地址 - status : 重定向状态码(默认 302) | void | 会自动设置 Location 头 |
void set_error(int status, const char* message) | 设置错误响应,指定错误状态码和错误信息 | - status : 错误状态码 - message : 错误信息 | void | 简化错误响应设置,如 set_error(404, "Not Found") |
补充说明:
- Headers 类型:
Headers
本质是键值对映射,操作时无需关心大小写(内部统一处理),例如req.headers["Content-Type"]
与req.headers["content-type"]
等效。 - 路径参数解析:对于
Server::Get("/user/{id}", ...)
这类路由,Request::get_param_value("id")
可直接获取路径中的id
值,无需手动解析 URL。 - 多表单数据:
MultipartFormDataItems
是多部分表单数据的集合,每个元素包含name
(字段名)、content
(内容)、filename
(文件名)、content_type
(内容类型)等信息,适合处理文件上传。 - 响应体设置:推荐使用
set_content()
而非直接赋值body
,因为前者会自动处理Content-Length
头,避免手动计算长度的错误。 - 状态码规范:设置状态码时应遵循 HTTP 标准(如 2xx 表示成功,4xx 表示客户端错误,5xx 表示服务器错误),避免自定义非标准码。
ContentType映射表
以下是常见的 Content-Type
(MIME 类型)与对应的文件扩展名 / 使用场景的映射表,在使用 cpphttplib 处理请求和响应时非常实用:
Content-Type | 常见文件扩展名 | 适用场景说明 |
---|---|---|
text/plain | .txt | 纯文本内容(默认文本类型) |
text/html | .html , .htm | HTML 文档(网页内容) |
text/css | .css | CSS 样式表文件 |
text/javascript | .js | JavaScript 脚本文件(HTML5 标准推荐,替代 application/javascript ) |
application/javascript | .js | JavaScript 脚本(传统类型,建议优先使用 text/javascript ) |
application/json | .json | JSON 数据(API 接口常用) |
application/xml | .xml | XML 数据 |
text/xml | .xml | XML 数据(与 application/xml 类似,更强调文本特性) |
application/x-www-form-urlencoded | - | HTTP 表单提交默认类型(数据以 key=value&key2=value2 格式编码) |
multipart/form-data | - | 表单包含文件上传时使用(需配合边界标识 boundary ) |
image/jpeg | .jpg , .jpeg | JPEG 图片文件 |
image/png | .png | PNG 图片文件(支持透明通道) |
image/gif | .gif | GIF 图片文件(支持动画) |
image/svg+xml | .svg | SVG 矢量图像文件 |
image/webp | .webp | WebP 图片文件(高效压缩格式) |
application/pdf | .pdf | PDF 文档 |
application/zip | .zip | ZIP 压缩文件 |
application/gzip | .gz | GZIP 压缩文件 |
audio/mpeg | .mp3 | MP3 音频文件 |
video/mp4 | .mp4 | MP4 视频文件 |
application/octet-stream | - | 二进制流数据(默认未知类型,常用于文件下载) |
补充说明:
-
在 cpphttplib 中设置响应时,需根据内容类型正确指定
Content-Type
,例如返回 JSON 时:res.set_content("{\"name\":\"test\"}", "application/json");
-
处理文件上传时,
Request::get_multipart_form_data()
返回的每个项包含content_type
字段,可用于判断文件类型。 -
静态文件服务中,cpphttplib 会根据文件扩展名自动设置
Content-Type
(需启用CPPHTTPLIB_USE_FILESYSTEM
宏)。 -
对于自定义文件类型,需手动指定对应的
Content-Type
,避免使用默认的application/octet-stream
导致客户端无法正确解析。 -
multipart/form-data
类型必须在请求头中包含boundary
参数,格式如:Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryxxxx
。
使用案例
案例 1:基础 HTTP 服务器(支持 GET/POST)
#include <iostream>
#include <cpp-httplib/httplib.h>int main() {// 创建 HTTP 服务器实例,监听本地 8080 端口httplib::Server svr;// 注册 GET 请求处理器:处理根路径 "/" 的请求// 参数说明:// - req: 客户端请求对象(包含请求头、参数等)// - res: 服务器响应对象(用于设置响应内容、状态码等)svr.Get("/", [](const httplib::Request& req, httplib::Response& res) {// 设置响应内容(HTML 格式)res.set_content("<h1>Hello, cpp-httplib!</h1>", "text/html");// 响应状态码默认是 200 OK,可手动设置其他状态码(如 404)});// 注册 GET 请求处理器:处理带参数的路径(如 /user?name=xxx&age=xxx)svr.Get("/user", [](const httplib::Request& req, httplib::Response& res) {// 从请求参数中获取 "name" 和 "age"(GET 参数通过 req.get_param 获取)std::string name = req.get_param_value("name"); // 若无此参数,返回空字符串std::string age = req.get_param_value("age");// 构造响应内容(JSON 格式)std::string json = R"({"status": "success", "data": {"name": ")" + name + R"(", "age": ")" + age + R"("}})";res.set_content(json, "application/json"); // 设置 Content-Type 为 JSON});// 注册 POST 请求处理器:处理表单数据提交svr.Post("/login", [](const httplib::Request& req, httplib::Response& res) {// POST 表单数据通过 req.has_param / req.get_param_value 获取if (req.has_param("username") && req.has_param("password")) {std::string user = req.get_param_value("username");std::string pwd = req.get_param_value("password");// 简单验证(实际场景需对接数据库)if (user == "admin" && pwd == "123456") {res.set_content(R"({"status": "login success"})", "application/json");} else {res.status = 401; // 设置状态码为 401 Unauthorizedres.set_content(R"({"status": "invalid credentials"})", "application/json");}} else {res.status = 400; // 400 Bad Request(参数缺失)res.set_content(R"({"status": "missing parameters"})", "application/json");}});// 注册静态文件服务:将 "/static" 路径映射到本地 "www" 目录// 客户端访问 /static/xxx.txt 会对应到本地 www/xxx.txtsvr.set_mount_point("/static", "./www");// 启动服务器,监听 0.0.0.0:8080(允许外部访问)std::cout << "Server running on http://0.0.0.0:8080" << std::endl;if (svr.listen("0.0.0.0", 8080)) {std::cerr << "Server failed to start!" << std::endl;return 1;}return 0;
}
案例 2:HTTPS 服务器(基于 OpenSSL)
#include <iostream>
#include <cpp-httplib/httplib.h>int main() {// 创建 HTTPS 服务器(需链接 OpenSSL 库,编译时加 -lcrypto -lssl)// 参数:证书文件路径、私钥文件路径httplib::SSLServer svr("./cert.pem", "./key.pem");// 处理 HTTPS 的 GET 请求svr.Get("/secure", [](const httplib::Request& req, httplib::Response& res) {res.set_content("<h1>Secure HTTPS Page</h1>", "text/html");});// 启动 HTTPS 服务器,监听 443 端口(默认 HTTPS 端口)std::cout << "HTTPS Server running on https://0.0.0.0:443" << std::endl;svr.listen("0.0.0.0", 443);return 0;
}
说明:
- 需提前生成 SSL 证书(如用
openssl
生成cert.pem
和key.pem
)。 - 编译命令需包含 OpenSSL 链接:
g++ -o https_server https_server.cpp -lcpp-httplib -lcrypto -lssl
。
案例 3:HTTP 客户端(发送 GET/POST 请求)
#include <iostream>
#include <cpp-httplib/httplib.h>int main() {// 创建客户端实例,连接到本地服务器(也可连接远程服务器,如 "www.example.com")httplib::Client cli("localhost", 8080);// 1. 发送 GET 请求(无参数)auto res = cli.Get("/"); // 调用服务器的根路径if (res && res->status == 200) { // 检查响应是否有效且状态码为 200std::cout << "GET / response:\n" << res->body << std::endl;} else {std::cout << "GET / failed! Status: " << (res ? res->status : -1) << std::endl;}// 2. 发送带参数的 GET 请求httplib::Params params; // 用于存储 GET 参数params.emplace("name", "Alice");params.emplace("age", "30");res = cli.Get("/user", params); // 等价于访问 /user?name=Alice&age=30if (res && res->status == 200) {std::cout << "GET /user response:\n" << res->body << std::endl;}// 3. 发送 POST 请求(表单数据)httplib::Params post_data;post_data.emplace("username", "admin");post_data.emplace("password", "123456");res = cli.Post("/login", post_data); // 发送表单数据(Content-Type: application/x-www-form-urlencoded)if (res && res->status == 200) {std::cout << "POST /login success:\n" << res->body << std::endl;} else {std::cout << "POST /login failed! Status: " << (res ? res->status : -1) << std::endl;}// 4. 发送 POST 请求(JSON 数据)std::string json_data = R"({"name": "Bob", "email": "bob@example.com"})";// 设置请求头为 JSON 格式httplib::Headers headers = {{"Content-Type", "application/json"}};res = cli.Post("/api/user", headers, json_data, "application/json");if (res) {std::cout << "POST /api/user response:\n" << res->body << std::endl;}return 0;
}
案例 4:客户端发送 HTTPS 请求
#include <iostream>
#include <cpp-httplib/httplib.h>int main() {// 创建 HTTPS 客户端(访问远程 HTTPS 服务器,如 https://www.example.com)httplib::SSLClient cli("www.example.com", 443);// 忽略 SSL 证书验证(仅测试用,生产环境不建议)cli.enable_server_certificate_verification(false);// 发送 GET 请求auto res = cli.Get("/");if (res && res->status == 200) {std::cout << "HTTPS GET response:\n" << res->body << std::endl;} else {std::cout << "HTTPS GET failed! Status: " << (res ? res->status : -1) << std::endl;}return 0;
}
核心知识点总结
- 服务器:
- 用
httplib::Server
创建 HTTP 服务器,httplib::SSLServer
创建 HTTPS 服务器。 - 通过
Get()
/Post()
/Put()
/Delete()
注册对应方法的处理器。 set_mount_point()
可映射静态文件目录。
- 用
- 客户端:
- 用
httplib::Client
或httplib::SSLClient
发送请求。 Get()
/Post()
等方法返回std::shared_ptr<Response>
,需检查有效性和状态码。- 可通过
Params
传递表单参数,或直接发送 JSON 字符串。
- 用
- 编译说明:
- HTTP 程序:
g++ -o main main.cpp -lcpp-httplib
。 - HTTPS 程序(需 OpenSSL):
g++ -o main main.cpp -lcpp-httplib -lcrypto -lssl
。
- HTTP 程序: