📦yhirose / cpp-httplib
← 返回首页
A C++ header-only HTTP/HTTPS server and client library
⚖️ MIT#cpp#cpp11#http#https#header-only🌐 yhirose.github.io📅 创建于 2012-09-22🔄 更新于 2026-10-28

📄 仓库 README

在 GitHub 查看 ↗
来自 GitHub 仓库自述文件 · 版权归原作者所有

cpp-httplib

A C++11 single-file header-only cross platform HTTP/HTTPS library.
It's extremely easy to set up. Just include the httplib.h file in your code!

Learn more in the official documentation (built with docs-gen).

[!IMPORTANT] This library uses 'blocking' socket I/O. If you are looking for a library with 'non-blocking' socket I/O, this is not the one that you want. Only HTTP/1.1 is supported — HTTP/2 and HTTP/3 are not implemented.

[!WARNING] 32-bit platforms are NOT supported. Use at your own risk. The library may compile on 32-bit targets, but no security review has been conducted for 32-bit environments. Integer truncation and other 32-bit-specific issues may exist. Security reports that only affect 32-bit platforms will be closed without action. The maintainer does not have access to 32-bit environments for testing or fixing issues. CI includes basic compile checks only, not functional or security testing.

Main Features

Simple examples

Server

#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "path/to/httplib.h"

// HTTP
httplib::Server svr;

// HTTPS
httplib::SSLServer svr("./cert.pem", "./key.pem");

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

svr.listen("0.0.0.0", 8080);

Client

#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "path/to/httplib.h"

// HTTP
httplib::Client cli("http://yhirose.github.io");

// HTTPS
httplib::Client cli("https://yhirose.github.io");

if (auto res = cli.Get("/hi")) {
  res->status;
  res->body;
}

SSL/TLS Support

cpp-httplib supports multiple TLS backends through an abstraction layer:

Backend Define Libraries Notes
OpenSSL CPPHTTPLIB_OPENSSL_SUPPORT libssl, libcrypto 3.0 or later required
Mbed TLS CPPHTTPLIB_MBEDTLS_SUPPORT libmbedtls, libmbedx509, libmbedcrypto 2.x, 3.x, and 4.x supported (auto-detected); 4.x renames libmbedcrypto to libtfpsacrypto
wolfSSL CPPHTTPLIB_WOLFSSL_SUPPORT libwolfssl 5.x supported; must build with --enable-opensslall

[!NOTE] wolfSSL limitation: get_ca_certs() and get_ca_names() only reflect CA certificates loaded via load_ca_cert_store() or set_ca_cert_store(). Certificates loaded through set_ca_cert_path() or system certificates (load_system_certs) are not enumerable.

A wolfSSL server that verifies client certificates does not resume TLS sessions: wolfSSL shares its session cache between contexts, so a resumed session could carry a certificate checked against another server's client CA.

[!NOTE] BoringSSL (best-effort): BoringSSL builds under CPPHTTPLIB_OPENSSL_SUPPORT and is exercised by CI against current upstream. Because BoringSSL does not guarantee API stability, support is best-effort — breakage may occasionally land. One known difference vs OpenSSL: BoringSSL's public headers require C++14 or later, so consumers must compile accordingly.

[!NOTE] Hostname verification is SAN-only on every backend (RFC 9525). A host is matched against the certificate's subjectAltName entries, never its Common Name, so a certificate that names its host only in the CN is rejected. Reissue it with a subjectAltName.

// Use either OpenSSL, Mbed TLS, or wolfSSL
#define CPPHTTPLIB_OPENSSL_SUPPORT   // or CPPHTTPLIB_MBEDTLS_SUPPORT or CPPHTTPLIB_WOLFSSL_SUPPORT
#include "path/to/httplib.h"

// Server
httplib::SSLServer svr("./cert.pem", "./key.pem");

// Client
httplib::Client cli("https://localhost:1234"); // scheme + host
httplib::SSLClient cli("localhost"); // host (port 443)
httplib::SSLClient cli("localhost", 1234); // host, port

// Use your CA bundle
cli.set_ca_cert_path("./ca-bundle.crt");

// Disable cert verification
cli.enable_server_certificate_verification(false);

// Disable host verification
cli.enable_server_hostname_verification(false);

[!NOTE] The CA certificates are loaded when the client makes its first connection. Changing set_ca_cert_path() or enable_system_ca() after that has no effect, so make the settings before the first request, or use a new client. set_ca_cert_store() and load_ca_cert_store() take effect at once. WebSocketClient works the same way. On Client and SSLClient, a setter that changes a TLS setting also closes a connection kept alive under the old one, so the next request connects again.

SSL Error Handling

When SSL operations fail, cpp-httplib provides detailed error information through ssl_error() and ssl_backend_error():

  • ssl_error() - Returns the TLS-level error as a backend-independent httplib::tls::ErrorCode value (e.g., Fatal, CertVerifyFailed), cast to int. A server certificate that the built-in verification rejects reports CertVerifyFailed, or HostnameMismatch when only its name does not match
  • ssl_backend_error() - Returns the backend-specific error code (e.g., ERR_get_error() for OpenSSL/wolfSSL, return value for Mbed TLS). With OpenSSL, a certificate verification failure reports the verify result (X509_V_ERR_*) here instead. On Windows, when CryptoAPI verifies the chain, a failure there reports the CryptoAPI error code here

A request that fails after the handshake with Error::Read or Error::Write also carries the TLS error behind it in both values, such as a TLS 1.3 "certificate required" alert from the server. Both values are reset for each request.

#define CPPHTTPLIB_OPENSSL_SUPPORT  // or CPPHTTPLIB_MBEDTLS_SUPPORT or CPPHTTPLIB_WOLFSSL_SUPPORT
#include "path/to/httplib.h"

httplib::Client cli("https://example.com");

auto res = cli.Get("/");
if (!res) {
  // Check the error type
  const auto err = res.error();

  switch (err) {
    case httplib::Error::SSLConnection:
      std::cout << "SSL connection failed, SSL error: "
                << res.ssl_error() << std::endl;
      break;

    case httplib::Error::SSLLoadingCerts:
      std::cout << "SSL cert loading failed, backend error: "
                << std::hex << res.ssl_backend_error() << std::endl;
      break;

    case httplib::Error::SSLServerVerification:
      std::cout << "SSL verification failed, verify error: "
                << res.ssl_backend_error() << std::endl;
      break;

    case httplib::Error::SSLServerHostnameVerification:
      std::cout << "SSL hostname verification failed, verify error: "
                << res.ssl_backend_error() << std::endl;
      break;

    default:
      std::cout << "HTTP error: " << httplib::to_string(err) << std::endl;
  }
}

Custom Certificate Verification

You can set a custom verification callback using tls::VerifyCallback:

httplib::Client cli("https://example.com");

cli.set_server_certificate_verifier(
    [](const httplib::tls::VerifyContext &ctx) -> bool {
      std::cout << "Subject CN: " << ctx.subject_cn() << std::endl;
      std::cout << "Issuer: " << ctx.issuer_name() << std::endl;
      std::cout << "Depth: " << ctx.depth << std::endl;
      std::cout << "Pre-verified: " << ctx.preverify_ok << std::endl;

      // Inspect SANs (Subject Alternative Names)
      for (const auto &san : ctx.sans()) {
        std::cout << "SAN: " << san.value << std::endl;
      }

      // Return false to reject
      return ctx.preverify_ok;
    });

Returning false, or throwing, rejects the certificate. The callback runs alongside the built-in verification, so to accept a certificate that verification rejects, such as a self-signed one, also call enable_server_certificate_verification(false); the callback is then the only check.

Mutual TLS (mTLS)

Regular TLS only verifies the server certificate. With mTLS, the client also presents a certificate that the server verifies.

// Server: pass a CA to verify client certificates against
httplib::SSLServer svr("./cert.pem", "./key.pem", "./client-ca-cert.pem");

// Client: present a certificate
httplib::SSLClient cli("api.example.com", 443,
                       "./client-cert.pem", "./client-key.pem");

Both SSLServer and SSLClient also accept an in-memory PemMemory struct instead of file paths — handy when certs come from an environment variable or a secrets manager:

httplib::SSLServer::PemMemory server_pem{};
server_pem.cert_pem = server_cert.data();
server_pem.cert_pem_len = server_cert.size();
server_pem.key_pem = server_key.data();
server_pem.key_pem_len = server_key.size();
server_pem.client_ca_pem = client_ca.data();
server_pem.client_ca_pem_len = client_ca.size();
httplib::SSLServer svr(server_pem);

httplib::SSLClient::PemMemory client_pem{};
client_pem.cert_pem = client_cert.data();
client_pem.cert_pem_len = client_cert.size();
client_pem.key_pem = client_key.data();
client_pem.key_pem_len = client_key.size();
httplib::SSLClient cli("api.example.com", 443, client_pem);

A length of 0 means the field is a NUL-terminated string.

httplib::ws::WebSocketClient has the same PemMemory constructor for wss:// connections. See README-websocket.md for details.

Peer Certificate Inspection

On the server side, you can inspect the client's peer certificate from a request handler:

httplib::SSLServer svr("./cert.pem", "./key.pem",
                       "./client-ca-cert.pem");

svr.Get("/", [](const httplib::Request &req, httplib::Response &res) {
  auto cert = req.peer_cert();
  if (cert) {
    std::cout << "Client CN: " << cert.subject_cn() << std::endl;
    std::cout << "Serial: " << cert.serial() << std::endl;
  }

  auto sni = req.sni();
  std::cout << "SNI: " << sni << std::endl;
});

Platform-specific Certificate Handling

cpp-httplib automatically integrates with the OS certificate store on macOS and Windows. This works with all TLS backends.

Platform Behavior Disable (compile time)
macOS Loads system certs from Keychain, honouring their Trust Settings: a certificate set to "Never Trust", or trusted only for another policy such as S/MIME, is not loaded (link CoreFoundation and Security with -framework). Requires Apple Clang; GC

📈 近 7 天 Star 趋势

每日新增 Star(柱)与累计 Star(线)· 数据来自 GitHub

🏆 排名变化趋势

在各榜单中的排名历史(数字越小越靠前)

📋 历史上榜记录

每次快照的详细数据
日期 榜单 排名 周期新增 总 STAR