一个 C++ 标题唯一的 HTTP/ HTTPS 服务器和客户端库
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;
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] Mbed TLS / wolfSSL limitation:
get_ca_certs()andget_ca_names()only reflect CA certificates loaded viaload_ca_cert_store(). Certificates loaded throughset_ca_cert_path()or system certificates (load_system_certs) are not enumerable.
[!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. Two known behavioral differences vs OpenSSL: (1) BoringSSL's public headers require C++14 or later, so consumers must compile accordingly; (2) hostname verification is SAN-only per RFC 6125 §6.4.4 (no CN fallback).
…
When SSL operations fail, cpp-httplib provides detailed error information through ssl_error() and ssl_backend_error():
ssl_error() - Returns the TLS-level error code (e.g., SSL_ERROR_SSL for OpenSSL)ssl_backend_error() - Returns the backend-specific error code (e.g., ERR_get_error() for OpenSSL/wolfSSL, return value for Mbed TLS)…
You can set a custom verification callback using tls::VerifyCallback:
…
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::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 (link CoreFoundation and Security with -framework). Requires Apple Clang; GCC is not supported for this feature. |
CPPHTTPLIB_DISABLE_MACOSX_AUTOMATIC_ROOT_CERTIFICATES |
| Windows | Verifies certs via CryptoAPI (CertGetCertificateChain / CertVerifyCertificateChainPolicy) with revocation checking |
CPPHTTPLIB_DISABLE_WINDOWS_AUTOMATIC_ROOT_CERTIFICATES_UPDATE |
On Windows, verification can also be disabled at runtime:
cli.enable_windows_certificate_verification(false);
[!NOTE] When using SSL, it seems impossible to avoid SIGPIPE in all cases, since on some operating systems, SIGPIPE can only be suppressed on a per-message basis, but there is no way to make the OpenSSL library do so for its internal communications. If your program needs to avoid being terminated on SIGPIPE, the only fully general way might be to set up a signal handler for SIGPIPE to handle or ignore it yourself.
…
Post, Put, Patch, Delete and Options methods are also supported.
Methods outside the built-in set are rejected with 400 Bad Request unless a handler is registered for them with CustomRoute. This covers the WebDAV methods of RFC 4918, SUBSCRIBE and friends from UPnP, and any other extension method.
…
Patterns work exactly as they do for Get and the other methods, so regular expressions and path parameters are both available.
Note the following:
listen() is called.GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH and PRI cannot be registered this way. Use the dedicated methods above instead.is_valid() return false, and listen() then fails rather than starting a server with a route that would never fire.GET/HEAD only.Allow and the WebDAV DAV: header are not generated automatically. Register an Options handler if clients need them.int port = svr.bind_to_any_port("0.0.0.0");
svr.listen_after_bind();
// Mount / to ./www directory
auto ret = svr.set_mount_point("/", "./www");
if (!ret) {
// The specified base directory doesn't exist...
}
// Mount /public to ./www directory
ret = svr.set_mount_point("/public", "./www");
// Mount /public to ./www1 and ./www2 directories
ret = svr.set_mount_point("/public", "./www1"); // 1st order to search
ret = svr.set_mount_point("/public", "./www2"); // 2nd order to search
// Remove mount /
ret = svr.remove_mount_point("/");
// Remove mount /public
ret = svr.remove_mount_point("/public");
// User defined file extension and MIME type mappings
svr.set_file_extension_and_mimetype_mapping("cc", "text/x-c");
svr.set_file_extension_and_mimetype_mapping("cpp", "text/x-c");
svr.set_file_extension_and_mimetype_mapping("hh", "text/x-h");
The following are built-in mappings:
| Extension | MIME Type | Extension | MIME Type |
|---|---|---|---|
| css | text/css | mpga | audio/mpeg |
| csv | text/csv | weba | audio/webm |
| txt | text/plain | wav | audio/wave |
| vtt | text/vtt | otf | font/otf |
| html, htm | text/html | ttf | font/ttf |
| apng | image/apng | woff | font/woff |
| avif | image/avif | woff2 | font/woff2 |
| bmp | image/bmp | 7z | application/x-7z-compressed |
| gif | image/gif | atom | application/atom+xml |
| png | image/png | application/pdf | |
| svg | image/svg+xml | mjs, js | text/javascript |
| webp | image/webp | json | application/json |
| ico | image/x-icon | rss | application/rss+xml |
| tif | image/tiff | tar | application/x-tar |
| tiff | image/tiff | xhtml, xht | application/xhtml+xml |
| jpeg, jpg | image/jpeg | xslt | application/xslt+xml |
| mp4 | video/mp4 | xml | application/xml |
| mpeg | video/mpeg | gz | application/gzip |
| webm | video/webm | zip | application/zip |
| mp3 | audio/mp3 | wasm | application/wasm |
[!WARNING] These static file server methods are not thread-safe.
[!NOTE] On POSIX systems, the static file server rejects requests that resolve (via symlinks) to a path outside the mounted base directory. Ensure that the served directory has appropriate permissions, as managing access to the served directory is the application developer's responsibility.
// The handler is called right before the response is sent to a client
svr.set_file_request_handler([](const Request &req, Response &res) {
...
});
cpp-httplib provides separate logging capabilities for access logs and error logs, similar to web servers like Nginx and Apache.
Access loggers capture successful HTTP requests and responses:
svr.set_logger([](const httplib::Request& req, const httplib::Response& res) {
std::cout << req.method << " " << req.path << " -> " << res.status << std::endl;
});
You can also set a pre-compression logger to capture request/response data before compression is applied:
svr.set_pre_compression_logger([](const httplib::Request& req, const httplib::Response& res) {
// Log before compression - res.body contains uncompressed content
// Content-Encoding header is not yet set
your_pre_compression_logger(req, res);
});
The pre-compression logger is only called when compression would be applied. For responses without compression, only the access logger is called.
For a static file response (
暂无开放 Issues,或尚未同步最近议题。