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.
#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);
#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;
}
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()andget_ca_names()only reflect CA certificates loaded viaload_ca_cert_store()orset_ca_cert_store(). Certificates loaded throughset_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_SUPPORTand 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()orenable_system_ca()after that has no effect, so make the settings before the first request, or use a new client.set_ca_cert_store()andload_ca_cert_store()take effect at once.WebSocketClientworks the same way. OnClientandSSLClient, a setter that changes a TLS setting also closes a connection kept alive under the old one, so the next request connects again.
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 matchssl_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 hereA 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;
}
}
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.
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.
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;
});
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 |
| 日期 | 榜单 | 排名 | 周期新增 | 总 STAR |
|---|