Skip to content

cpp-httplib — 轻量 HTTP 库

cpp-httplib 是单头文件的 C++ HTTP/HTTPS 客户端和服务端库,零依赖(可选 OpenSSL),5 分钟上手,适合快速原型和工具开发。

安装

bash
# 单头文件,直接下载
# https://github.com/yhirose/cpp-httplib/releases
# 将 httplib.h 放入项目

# vcpkg
vcpkg install cpp-httplib

# CMake
find_package(httplib REQUIRED)
target_link_libraries(myapp PRIVATE httplib::httplib)

HTTP 服务端

cpp
#include "httplib.h"

int main() {
    httplib::Server svr;

    // GET 路由
    svr.Get("/", [](const httplib::Request& req, httplib::Response& res) {
        res.set_content("Hello, World!", "text/plain");
    });

    // 路径参数
    svr.Get("/users/:id", [](const httplib::Request& req, httplib::Response& res) {
        auto id = req.path_params.at("id");
        res.set_content("{\"id\": " + id + "}", "application/json");
    });

    // POST + JSON
    svr.Post("/api/users", [](const httplib::Request& req, httplib::Response& res) {
        // 读取请求体
        auto body = req.body;
        // 解析 JSON(配合 nlohmann/json)
        auto json = nlohmann::json::parse(body);
        std::string name = json["name"];

        nlohmann::json resp;
        resp["id"] = 1;
        resp["name"] = name;
        resp["created"] = true;

        res.status = 201;
        res.set_content(resp.dump(), "application/json");
    });

    // 查询参数
    svr.Get("/search", [](const httplib::Request& req, httplib::Response& res) {
        auto q = req.get_param_value("q");
        auto page = req.get_param_value("page");
        res.set_content("query=" + q + "&page=" + page, "text/plain");
    });

    // 请求头
    svr.Get("/protected", [](const httplib::Request& req, httplib::Response& res) {
        auto auth = req.get_header_value("Authorization");
        if (auth.empty()) {
            res.status = 401;
            res.set_content("Unauthorized", "text/plain");
            return;
        }
        res.set_content("OK", "text/plain");
    });

    // 静态文件
    svr.set_mount_point("/static", "./public");

    // 错误处理
    svr.set_error_handler([](const httplib::Request&, httplib::Response& res) {
        res.set_content("Error " + std::to_string(res.status), "text/plain");
    });

    // 日志
    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);
    });

    printf("服务器启动: http://localhost:8080\n");
    svr.listen("0.0.0.0", 8080);
}

HTTPS 服务端

cpp
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "httplib.h"

httplib::SSLServer svr("server.crt", "server.key");

svr.Get("/", [](const httplib::Request&, httplib::Response& res) {
    res.set_content("HTTPS Hello!", "text/plain");
});

svr.listen("0.0.0.0", 8443);

HTTP 客户端

cpp
#include "httplib.h"

// GET 请求
httplib::Client cli("http://httpbin.org");
cli.set_connection_timeout(5);  // 5 秒连接超时
cli.set_read_timeout(10);       // 10 秒读取超时

auto res = cli.Get("/get");
if (res && res->status == 200) {
    std::cout << res->body << "\n";
} else if (!res) {
    auto err = res.error();
    std::cout << "错误: " << httplib::to_string(err) << "\n";
}

// POST JSON
nlohmann::json body = {{"name", "Alice"}, {"age", 30}};
auto res2 = cli.Post("/post",
    body.dump(),
    "application/json");

// 带请求头
httplib::Headers headers = {
    {"Authorization", "Bearer token123"},
    {"X-Custom-Header", "value"}
};
auto res3 = cli.Get("/protected", headers);

// 文件上传(multipart)
httplib::MultipartFormDataItems items = {
    {"file", read_file("photo.jpg"), "photo.jpg", "image/jpeg"},
    {"description", "My photo", "", "text/plain"}
};
auto res4 = cli.Post("/upload", items);

// HTTPS 客户端
#define CPPHTTPLIB_OPENSSL_SUPPORT
httplib::Client https_cli("https://api.example.com");
https_cli.set_ca_cert_path("ca.crt");
auto res5 = https_cli.Get("/api/data");

中间件模式

cpp
httplib::Server svr;

// 全局前置处理器
svr.set_pre_routing_handler(
    [](const httplib::Request& req, httplib::Response& res) {
        // 日志、限流等
        printf("[%s] %s\n", req.method.c_str(), req.path.c_str());
        return httplib::Server::HandlerResponse::Unhandled;  // 继续处理
    });

// 全局后置处理器
svr.set_post_routing_handler(
    [](const httplib::Request& req, httplib::Response& res) {
        res.set_header("X-Powered-By", "cpp-httplib");
    });

与 Drogon/Asio 的对比

cpp-httplib:
  优点:单头文件,零配置,同步 API,极易上手
  缺点:同步阻塞,每连接一线程,高并发性能有限
  适合:工具、原型、内部服务、低并发场景

Drogon:
  优点:全异步,高性能,功能完整(ORM、模板等)
  缺点:依赖多,学习曲线较陡
  适合:生产级 Web 服务、高并发 API

Boost.Asio + Beast:
  优点:最灵活,可定制性强
  缺点:代码量大,需要手写很多样板
  适合:需要精细控制的网络应用

关键认知

cpp-httplib 是快速原型和工具开发的最佳选择,5 分钟就能跑起来一个 HTTP 服务。生产环境高并发场景用 Drogon 或 Asio。HTTPS 支持需要在包含头文件前定义 CPPHTTPLIB_OPENSSL_SUPPORT

系统学习 C++ 生态,深入底层架构