Oj设计细节 之 【cpp-httplib】

目录

1.cpp-httplib简介

2.安装与使用注意事项

[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上搜索下载

核心特点包括:

  1. 单文件设计:整个库仅 httplib.h 一个头文件,无需编译、无需链接,直接 #include 即可使用
  2. 同步阻塞 I/O + 多线程:采用 select/poll 多路复用和线程池模型处理请求,但每个请求的处理是同步阻塞的,适合中小并发
  3. 完整协议支持:HTTP/1.1、HTTPS(需 OpenSSL/mbedTLS)、WebSocket
  4. 跨平台:Windows、Linux、macOS 全兼容
  5. 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_QUICKACKTCP_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 支持的宏 适用于嵌入式场景
相关推荐
zl_dfq9 小时前
OJ设计细节 之 【进程资源限制】(getrlimit、setrlimit、prlimit)
oj设计