当前位置: 首页 > news >正文

HTTP Client/Server 实践:cpp-httplib使用


目录

  • 1.概述
  • 2.快速使用cpp-httplib
    • 1)安装
    • 2)快速使用
      • (1)创建simple_server.cpp
      • (2)编译应用
      • (3)运行和测试
  • 3.使用CMake构建
    • 1)构建步骤
    • 2)自定义构建选项示例
    • 3)CMake项目中使用cpp-httplib
      • (1)查找包方法
      • (2)find_package()后的可用变量
    • 4)使用预编译头文件
    • 5)高级配置
      • (1)使用静态库依赖项
      • (2)构建测试
      • (3)将httplib.h拆分为.h和.cc文件
  • 4.HTTP基本用法
    • 1)HTTP服务器
      • (1)最小HTTP服务器示例:
      • (2)理解路由和处理器
      • (3)处理请求和响应
      • (4)常见操作
      • (5)完整服务器示例
    • 2)HTTP客户端
      • (1)创建客户端
      • (2)发起 HTTP 请求
      • (3)添加请求头
      • (4)处理响应数据
      • (5)错误处理
      • (6)高级客户端功能
      • (7)完整示例


.

1.概述

cpp-httplib 是一个基于 C++11 的单头文件 HTTP/HTTPS 库,设计简洁,易于使用。只需包含一个头文件,即可快速实现 Web 服务器或 HTTP 客户端,支持现代 C++ 应用的服务器端与客户端通信。

主要功能

1)HTTP/HTTPS 服务器

  • 简单路由 API:使用直观的语法定义端点处理程序

  • 支持所有标准 HTTP 方法:GET、POST、PUT、DELETE、OPTIONS、PATCH

  • 路径参数和正则匹配:直接从 URL 路径中提取值

  • 静态文件服务:轻松从目录中提供文件

  • 默认多线程:高效处理并发连接

  • SSL/TLS 支持:使用 HTTPS 保护服务器

2)HTTP/HTTPS 客户端

  • 简单请求 API:用最少的代码发起 HTTP 请求

  • 所有标准 HTTP 方法:完整的 HTTP 动词支持

  • 认证:内置支持 Basic、Digest 和 Bearer token 认证

  • 代理支持:通过代理服务器连接

  • 重定向跟随:自动跟随 HTTP 重定向

  • 内容处理:流式处理大请求/响应

.


.

2.快速使用cpp-httplib

1)安装

由于cpp-httplib是一个头文件库,安装只需将httplib.h文件复制到您的项目中:

  • 从仓库下载最新的httplib.h文件

  • 将其包含到您的项目中

# 1.下载httplib.h:(https://github.com/yhirose/cpp-httplib)
wget https://github.com/yhirose/cpp-httplib/raw/refs/heads/master/httplib.h# 如果需要使用json,可以下载以下头文件,并引入# 下载nlohman_json.hpp:(https://github.com/nlohmann/json)wget https://github.com/nlohmann/json/releases/download/v3.12.0/json.hpp -O nlohman_json.hpp# 2.代码中引入httplib.h
#include "path/to/httplib.h"

.

2)快速使用

(1)创建simple_server.cpp

创建一个名为simple_server.cpp的文件,内容如下:

#include <httplib.h>
#include <iostream>int main() {std::cout << "正在启动8080端口的服务器..." << std::endl;httplib::Server svr;svr.Get("/", [](const httplib::Request& /*req*/, httplib::Response& res) {res.set_content("<h1>欢迎使用cpp-httplib!</h1>", "text/html");});svr.Get("/json", [](const httplib::Request& /*req*/, httplib::Response& res) {res.set_content("{\"message\":\"Hello, JSON!\"}", "application/json");});svr.listen("0.0.0.0", 8080);
}

(2)编译应用

g++ -std=c++11 -o simple_server simple_server.cpp -pthread

注意:在许多系统上,使用-pthread确保正确的多线程支持。

(3)运行和测试

  1. 运行您的服务器:
./simple_server
  1. 打开您的浏览器并访问:
  • http://localhost:8080/ - 您应该看到欢迎消息

  • http://localhost:8080/json - 您应该看到JSON响应

.


.

3.使用CMake构建

cpp-httplib主要设计为头文件库,只需在代码中包含httplib.h即可轻松使用。然而,CMake集成提供了多项优势:

  • 系统化的依赖管理(OpenSSL、ZLIB、Brotli、ZSTD)

  • 可选编译为共享或静态库

  • 正确安装到系统中

  • 易于与其他基于CMake的项目集成

基本构建选项:

在构建之前,了解关键配置选项很有帮助:

选项默认值描述
HTTPLIB_COMPILEOFF作为编译库而不是头文件库进行构建
BUILD_SHARED_LIBSOFF构建为共享库(仅当HTTPLIB_COMPILE为ON时)
HTTPLIB_USE_OPENSSL_IF_AVAILABLEON如果可用,使用OpenSSL
HTTPLIB_REQUIRE_OPENSSLOFF如果未找到OpenSSL,构建失败
HTTPLIB_USE_ZLIB_IF_AVAILABLEON如果可用,使用ZLIB
HTTPLIB_REQUIRE_ZLIBOFF如果未找到ZLIB,构建失败
HTTPLIB_USE_BROTLI_IF_AVAILABLEON如果可用,使用Brotli
HTTPLIB_REQUIRE_BROTLIOFF如果未找到Brotli,构建失败
HTTPLIB_USE_ZSTD_IF_AVAILABLEON如果可用,使用ZSTD
HTTPLIB_REQUIRE_ZSTDOFF如果未找到ZSTD,构建失败
HTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAINON启用从macOS Keychain加载证书
HTTPLIB_INSTALLON启用安装目标
HTTPLIB_TESTOFF构建并运行测试

这些选项允许你根据需要自定义cpp-httplib,启用或要求特定的压缩算法和SSL支持。

.

1)构建步骤

Linux/macOS

mkdir -p build
cd build# 配置项目
cmake -DCMAKE_BUILD_TYPE=Release ..# 构建库
cmake --build .# 可选安装(可能需要sudo)
sudo cmake --build . --target install

Windows

# 创建构建目录
mkdir build
cd build# 配置项目
cmake ..# 构建库
cmake --build . --config Release# 可选以管理员身份安装
runas /user:Administrator "cmake --build . --config Release --target install"

.

2)自定义构建选项示例

要使用特定功能进行构建:

mkdir -p build
cd build# 以编译库形式构建并要求OpenSSL
cmake -DHTTPLIB_COMPILE=ON -DHTTPLIB_REQUIRE_OPENSSL=ON ..# 以共享库形式构建并支持ZLIB
cmake -DHTTPLIB_COMPILE=ON -DBUILD_SHARED_LIBS=ON -DHTTPLIB_REQUIRE_ZLIB=ON ..# 使用所有压缩库进行构建
cmake -DHTTPLIB_REQUIRE_OPENSSL=ON -DHTTPLIB_REQUIRE_ZLIB=ON -DHTTPLIB_REQUIRE_BROTLI=ON -DHTTPLIB_REQUIRE_ZSTD=ON ..cmake --build .

.

3)CMake项目中使用cpp-httplib

安装cpp-httplib后,你可以在自己的CMake项目中使用它:

(1)查找包方法

cmake_minimum_required(VERSION 3.14)
project(MyProject)# 查找httplib及其可选组件
find_package(httplib COMPONENTS OpenSSL ZLIB Brotli zstd REQUIRED)# 创建你的可执行文件
add_executable(my_app main.cpp)# 链接到httplib
target_link_libraries(my_app PRIVATE httplib::httplib)

find_package()中列出的组件告诉CMake你需要的可选功能,但即使不是所有组件都可用,库仍然会被找到。

(2)find_package()后的可用变量

调用find_package(httplib)后,以下变量可用:

变量描述
HTTPLIB_HEADER_PATHhttplib.h头文件的完整路径
HTTPLIB_IS_USING_OPENSSL布尔值,指示是否启用OpenSSL支持
HTTPLIB_IS_USING_ZLIB布尔值,指示是否启用ZLIB支持
HTTPLIB_IS_USING_BROTLI布尔值,指示是否启用Brotli支持
HTTPLIB_IS_USING_ZSTD布尔值,指示是否启用ZSTD支持
HTTPLIB_IS_COMPILED布尔值,指示库是编译的还是头文件库
HTTPLIB_INCLUDE_DIRhttplib头文件的根路径
HTTPLIB_LIBRARY如果已编译,库的完整路径
httplib_VERSION项目的版本字符串

你可以在CMake配置中使用这些变量,根据可用功能调整构建。

.

4)使用预编译头文件

如果你想要使用预编译头文件(CMake自v3.16起支持的功能):

find_package(httplib REQUIRED)
target_precompile_headers(your_target INTERFACE "${HTTPLIB_HEADER_PATH}")

这在大型项目中可以显著提高构建速度。
.

5)高级配置

(1)使用静态库依赖项

要使用OpenSSL或Brotli的静态版本:

cmake -DOPENSSL_USE_STATIC_LIBS=ON -DBROTLI_USE_STATIC_LIBS=ON ..

这些选项告诉CMake查找依赖项的静态版本而不是共享库。

(2)构建测试

要构建并运行测试:

mkdir -p build
cd build
cmake -DHTTPLIB_TEST=ON ..
cmake --build .
ctest

这将编译并运行cpp-httplib的测试套件。

(3)将httplib.h拆分为.h和.cc文件

如果你更喜欢使用单独的头文件和实现文件,而不是单个头文件,cpp-httplib提供了一个Python脚本来拆分文件:

# 从仓库根目录
./split.py
# 这将创建out/httplib.h和out/httplib.cc

这在大型项目中通过将声明与实现分离,有助于减少编译时间。

在使用cpp-httplib的CMake构建系统时,请记住默认为头文件模式。

如果想将其作为编译库使用,必须设置-DHTTPLIB_COMPILE=ON

.


.

4.HTTP基本用法

1)HTTP服务器

可视化一个典型的cpp-httplib服务器的工作原理:
在这里插入图片描述

.

(1)最小HTTP服务器示例:

#include <httplib.h>int main() {// 创建服务器实例httplib::Server svr;// 定义GET /hi的路由处理器svr.Get("/hi", [](const httplib::Request& req, httplib::Response& res) {res.set_content("Hello World!", "text/plain");});// 启动服务器svr.listen("0.0.0.0", 8080);
}

这个简单的示例:

  1. 创建一个服务器实例

  2. 定义一个处理GET请求到"/hi"的路由处理器,返回纯文本响应

  3. 在所有接口(0.0.0.0)的8080端口上启动服务器

.

(2)理解路由和处理器

a.什么是路由(Routing)?

  • 路由就是:当用户访问某个网址(URL)时,服务器决定“该调用哪个函数来处理这个请求”。

  • 换句话说,路由 = URL 路径 + 对应的处理函数。

路由定义了你的API或Web服务器的端点。每个路由都与一个处理函数相关联,该函数处理请求并生成响应。

b.路由处理器基本结构

svr.METHOD("/path", [](const httplib::Request& req, httplib::Response& res) {  // 你的处理器代码});

其中:

  • METHOD是以下之一:Get, Post, Put, Delete, Options等

  • /path是要匹配的URL路径

  • lambda函数接收请求和响应对象

c.路由中的模式匹配

cpp-httplib支持多种定义路由的方式:

  • 简单静态路由
svr.Get("/hi", [](const httplib::Request& req, httplib::Response& res) {res.set_content("Hello World!", "text/plain");
});
  • 正则表达式模式
// 这将匹配类似"/numbers/42"的路径,并将"42"在matches向量中提供。svr.Get(R"(/numbers/(\d+))", [&](const httplib::Request& req, httplib::Response& res) {auto numbers = req.matches[1]; // 捕获的值res.set_content(numbers, "text/plain");
});
  • 命名路径参数
// 这将匹配类似"/users/123"的路径,并将"123"作为req.path_params["id"]提供。svr.Get("/users/:id", [&](const httplib::Request& req, httplib::Response& res) {auto user_id = req.path_params.at("id");res.set_content(user_id, "text/plain");
});

.

(3)处理请求和响应

请求对象(Request),提供了对以下内容的访问:

  • HTTP方法(req.method

  • URL路径(req.path

  • 查询参数(req.params

  • 头部(req.headers

  • 正文(req.body

  • 表单数据(req.form

**响应对象(Response)**对象允许你:

  • 设置响应状态(res.status

  • 设置头部(res.set_header()

  • 设置内容(res.set_content()

  • 实现重定向(res.set_redirect()

常见响应类型

// HTML响应:
res.set_content("<h1>Hello World!</h1>", "text/html");// JSON响应:
res.set_content("{\"message\":\"Hello World!\"}", "application/json");// 重定向:
res.set_redirect("/new-location");

.

(4)常见操作

a.提供静态文件

  • cpp-httplib可以轻松地从目录中提供文件:
// 将/public路由挂载到./assets目录
auto ret = svr.set_mount_point("/public", "./assets");
if (!ret) {// 指定的目录不存在
}
  • 你可以将多个目录挂载到同一路由。服务器将按顺序搜索它们:
// 首先在./primary中查找,然后在./fallback中查找
svr.set_mount_point("/public", "./primary");
svr.set_mount_point("/public", "./fallback");

b.错误处理:

  • 为所有错误响应实现自定义错误处理:
svr.set_error_handler([](const httplib::Request& /*req*/, httplib::Response& res) {const char* fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>";char buf[BUFSIZ];snprintf(buf, sizeof(buf), fmt, res.status);res.set_content(buf, "text/html");
});

c.请求日志:

  • 添加日志以跟踪请求和响应:
svr.set_logger([](const httplib::Request& req, const httplib::Response& res) {printf("%s %s - %d\n", req.method.c_str(), req.path.c_str(), res.status);
});

d.连接设置

// 设置保持连接设置
svr.set_keep_alive_max_count(100); // 每个连接的最大保持连接请求数
svr.set_keep_alive_timeout(5);     // 超时时间(秒)// 设置读写超时
svr.set_read_timeout(5, 0);        // 5秒
svr.set_write_timeout(5, 0);       // 5秒// 设置最大有效负载大小
svr.set_payload_max_length(1024 * 1024 * 50); // 50MB

e.控制服务器

  • 启动服务器:
svr.listen("localhost", 8080);
  • 停止服务器(从另一个线程或处理程序中):
svr.stop();

.

(5)完整服务器示例

下面是一个结合了各种功能的更全面的示例

#include <httplib.h>
#include <iostream>int main() {// 创建服务器实例httplib::Server svr;// 路由处理器svr.Get("/", [](const httplib::Request& /*req*/, httplib::Response& res) {res.set_redirect("/hello");});svr.Get("/hello", [](const httplib::Request& /*req*/, httplib::Response& res) {res.set_content("<h1>Hello, cpp-httplib!</h1>", "text/html");});// 带路径参数的路由svr.Get("/users/:id", [](const httplib::Request& req, httplib::Response& res) {auto user_id = req.path_params.at("id");res.set_content("User ID: " + user_id, "text/plain");});// POST处理器svr.Post("/submit", [](const httplib::Request& req, httplib::Response& res) {if (req.has_param("name")) {auto name = req.get_param_value("name");res.set_content("Hello, " + name + "!", "text/plain");} else {res.status = 400;res.set_content("Missing 'name' parameter", "text/plain");}});// 提供静态文件if (!svr.set_mount_point("/assets", "./public")) {std::cerr << "Failed to set mount point: directory doesn't exist\n";return 1;}// 自定义错误处理器svr.set_error_handler([](const httplib::Request& /*req*/, httplib::Response& res) {res.set_content("<h1>Error " + std::to_string(res.status) + "</h1>", "text/html");});// 日志记录器svr.set_logger([](const httplib::Request& req, const httplib::Response& res) {std::cout << req.method << " " << req.path << " - " << res.status << std::endl;});// 启动服务器std::cout << "Server starting on http://localhost:8080" << std::endl;svr.listen("localhost", 8080);return 0;
}

.


.

2)HTTP客户端

(1)创建客户端

要发起 HTTP 请求,需先创建一个客户端对象:

// 用于 HTTP 连接
httplib::Client cli("example.com", 80);  // 主机和端口// 用于 HTTPS 连接(需在启用 SSL 支持的情况下构建)
httplib::SSLClient ssl_cli("example.com", 443);

也可用 scheme-host-port 格式创建客户端:

// 根据 scheme 自动选择 HTTP 或 HTTPS
httplib::Client cli("http://example.com:8080");

.

(2)发起 HTTP 请求

GET 请求:

  • GET 请求默认会自动跳转到重定向目标地址,并自动保存和携带服务器设置的 Cookie(一小段数据)。
auto res = cli.Get("/path");
if (res) {// 请求成功 - 使用 resstd::cout << res->status << std::endl;      // 状态码(例如 200)std::cout << res->body << std::endl;        // 响应体
} else {// 请求失败 - 检查错误std::cout << "Error: " << res.error() << std::endl;
}

POST 请求

// 使用字符串数据POST
auto res = cli.Post("/resource", "Hello World", "text/plain");// 使用表单数据POST
httplib::Params params;
params.emplace("key1", "value1");
params.emplace("key2", "value2");
auto res = cli.Post("/form-endpoint", params);// 使用多部分表单数据POST(用于文件上传)
httplib::MultipartFormDataItems items = {{"text1", "plain text", "", ""},{"file1", "file content", "file.txt", "text/plain"},
};
auto res = cli.Post("/upload", items);

其他 HTTP 方法

// PUT请求
auto res = cli.Put("/resource", "Updated content", "text/plain");// DELETE请求
auto res = cli.Delete("/resource");// HEAD请求(仅获取头部,无正文)
auto res = cli.Head("/resource");// OPTIONS请求
auto res = cli.Options("*");// PATCH请求
auto res = cli.Patch("/resource", "Patch data", "text/plain");

.

(3)添加请求头

// 方法1:使用headers参数
httplib::Headers headers = {{"Authorization", "Bearer token12345"},{"User-Agent", "cpp-httplib/0.1"}
};
auto res = cli.Get("/api/resource", headers);// 方法2:为所有请求设置默认头部
cli.set_default_headers({{"Authorization", "Bearer token12345"},{"User-Agent", "cpp-httplib/0.1"}
});
auto res = cli.Get("/api/resource");  // 使用默认头部

.

(4)处理响应数据

当请求成功时,您可以操作响应对象:

auto res = cli.Get("/api/data");
if (res) {// 状态码int status = res->status;// 获取特定头部std::string content_type = res->get_header_value("Content-Type");// 响应体(字符串形式)std::string body = res->body;// 检查响应是否包含特定头部if (res->has_header("X-Custom-Header")) {// ...}// 遍历所有头部for (const auto& header : res->headers) {std::cout << header.first << ": " << header.second << std::endl;}
}

.

(5)错误处理

库使用类似结果的模式进行错误处理:

auto res = cli.Get("/api/data");
if (res) {// 请求成功// 使用 res->status、res->body 等
} else {// 请求失败auto err = res.error();switch (err) {case httplib::Error::Connection:std::cout << "Connection failed" << std::endl;break;case httplib::Error::TimeOut:std::cout << "Request timed out" << std::endl;break;// 处理其他错误情况...default:std::cout << "Error: " << httplib::to_string(err) << std::endl;break;}// SSL 验证错误(如果使用 SSLClient)if (res.error() == httplib::Error::SSLVerification) {auto result = cli.get_openssl_verify_result();if (result) {std::cout << "SSL verification error: " << X509_verify_cert_error_string(result) << std::endl;}}
}

.

(6)高级客户端功能

设置超时

// 设置连接超时
cli.set_connection_timeout(5, 0);  // 5 秒,0 微秒
// 设置读取超时
cli.set_read_timeout(30, 0);       // 30 秒,0 微秒
// 设置写入超时
cli.set_write_timeout(5, 0);       // 5 秒,0 微秒// 使用 chrono(C++11 及以后)
cli.set_connection_timeout(std::chrono::seconds(5));
cli.set_read_timeout(std::chrono::seconds(30));
cli.set_write_timeout(std::chrono::seconds(5));

处理重定向

// 禁用自动跟随重定向(默认启用)
cli.follow_location(false);
// 设置最大重定向次数
cli.set_follow_location(true);
cli.set_follow_location_max_count(5);  // 最多跟随 5 次重定向

SSL/TLS 配置:对于HTTPS连接,可配置SSL选项

httplib::SSLClient cli("example.com");
// 设置 CA 证书用于服务器验证
cli.set_ca_cert_path("./ca-bundle.crt");
// 启用服务器证书验证
cli.enable_server_certificate_verification(true);
// 客户端证书(用于双向 TLS)
cli.set_client_cert_path("client.crt", "client.key");

压缩

// 启用压缩(需在启用 ZLIB 支持的情况下构建)
cli.set_compress(true);
// 或者仅解压响应
cli.set_decompress(true);

保持连接:重用连接以提高性能

// 启用保持连接
cli.set_keep_alive(true);
// 禁用保持连接
cli.set_keep_alive(false);

一次性请求(静态方法):对于简单的一次性请求,无需创建客户端实例

// 静态 GET
auto res = httplib::Client("http://example.com").Get("/");
// 静态 POST
auto res = httplib::Client("http://example.com").Post("/api", "data", "text/plain");

.

(7)完整示例

以下是一个完整的示例,展示如何发起 GET 请求并处理响应:

#include <httplib.h>
#include <iostream>int main() {// 创建HTTP客户端httplib::Client cli("http://example.com");// 设置一些选项cli.set_connection_timeout(5, 0);  // 5秒超时cli.set_follow_location(true);     // 跟随重定向// 添加自定义头部httplib::Headers headers = {{"User-Agent", "MyClient/1.0"}};// 发出GET请求auto res = cli.Get("/api/data", headers);// 处理响应if (res) {// 成功std::cout << "状态: " << res->status << std::endl;std::cout << "内容类型: " << res->get_header_value("Content-Type") << std::endl;std::cout << "正文: " << res->body << std::endl;return 0;} else {// 错误std::cout << "HTTP错误: " << httplib::to_string(res.error()) << std::endl;return 1;}
}

以上内容涵盖了使用 cpp-httplib 作为客户端的基本要点。借助这些工具,您可以在 C++ 应用程序中向任意 Web 服务或 API 发起 HTTP 请求并处理响应。

.


声明:资源可能存在第三方来源,若有侵权请联系删除!

http://www.dtcms.com/a/503320.html

相关文章:

  • 项目招商网站大全河北智慧团建网站
  • 量化交易的开源框架
  • 【Linux系统编程】4. Linux权限
  • 个人主页网站制作免费融资平台哪家好
  • week6
  • ZigBee中的many-to-one和link status(3)
  • 大型网站多少钱佳源房地产最新消息
  • Linux Bash(一)
  • 【Redis】哨兵与对脑裂的情况分析
  • 49.词向量:把文字变成数字
  • 【pulldown-cmark】创建自定义分支
  • python 网站开发流程图网站首页被k还有救吗
  • TsingtaoAI受邀参加HICOOL2025全球创业者峰会项目对接会
  • windows10激活解决办法
  • 学习建网站玩网站建设学习包装设计需要哪些信息
  • 【图像处理】rgb和srgb
  • 如何撰写网站建设方案海口网站开发制作
  • 查找成绩(向量实现)
  • STL中容器string -- 讲解超详细
  • Python lambda 表达式详解
  • 【JavaScript】原生函数
  • 渗透测试中爆破与撞库的区别
  • 门户网站如何做谷歌seo儿童网站建设
  • AI智能体的“瑞士军刀”:工具调用功能详解与实践
  • GYCTF2020
  • 2025-10-19 hetao1733837刷题记录
  • 批量字符替换工具,支持多种格式
  • 50.情感分析:AI读懂你的心情
  • 嵌入式Linux开发环境学习(二)
  • 分析静态代码分析工具