Taywee /
args
A header-only C++ argument parser library. Supposed to be flexible and powerful, and attempts to be compatible with the functionality of the Python standard argparse library (though not necessarily the API).
91/100 healthLoading repository data…
yhirose / repository
A C++ header-only HTTP/HTTPS server and client library
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
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).
// 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:1234"); // host
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);
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)#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 true to accept, false to reject
return ctx.preverify_ok;
});
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.
#include <httplib.h>
int main(void)
{
using namespace httplib;
Server svr;
svr.Get("/hi", [](const Request& req, Response& res) {
res.set_content("Hello World!", "text/plain");
});
// Match the request path against a regular expression
// and extract its captures
svr.Get(R"(/numbers/(\d+))", [&](const Request& req, Response& res) {
auto numbers = req.matches[1];
res.set_content(numbers, "text/plain");
});
// Capture the second segment of the request path as "id" path param
svr.Get("/users/:id", [&](const Request& req, Response& res) {
auto user_id = req.path_params.at("id");
res.set_content(user_id, "text/plain");
});
// Extract values from HTTP headers and URL query params
svr.Get("/body-header-param", [](const Request& req, Response& res) {
if (req.has_header("Content-Length")) {
auto val = req.get_header_value("Content-Length");
}
if (req.has_param("key")) {
auto val = req.get_param_value("key");
}
// Get all values for a given key (e.g., ?tag=a&tag=b)
auto values = req.get_param_values("tag");
res.set_content(req.body, "text/plain");
});
// If the handler takes time to finish, you can also poll the connection state
svr.Get("/task", [&](const Request& req, Response& res) {
const char * result = nullptr;
process.run(); // for example, starting an external process
while (result == nullptr) {
sleep(1);
if (req.is_connection_closed()) {
process.kill(); // kill the process
return;
}
result = process.stdout(); // != nullptr if the process finishes
}
res.set_content(result, "text/plain");
});
svr.Get("/stop", [&](const Request& req, Response& res) {
svr.stop();
});
svr.listen("localhost", 1234);
}
Post, Put, Patch, Delete and Options methods are also supported.
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 |
Selected from shared topics, language and repository description—not editorial ratings.
Taywee /
A header-only C++ argument parser library. Supposed to be flexible and powerful, and attempts to be compatible with the functionality of the Python standard argparse library (though not necessarily the API).
91/100 healthagauniyal /
A Minimal, Header only Modern c++ library for terminal goodies 💄✨
87/100 healthrigtorp /
A bounded multi-producer multi-consumer concurrent queue written in C++11
rigtorp /
A bounded single-producer single-consumer wait-free and lock-free queue written in C++11
88/100 healthbfgroup /
A simple to use, composable, command line parser for C++ 11 and beyond
85/100 healthkthohr /
A C++ header-only library of statistical distribution functions.
85/100 health