cpp-httplib: A Minimalist HTTP/HTTPS Server and Client Library in C++

cpp-httplib: A Minimalist HTTP/HTTPS Server and Client Library in C++

cpp-httplib is a header-only C++ library developed by yhirose for quickly creating HTTP/HTTPS servers and clients. It is popular in the C++ community due to its simple API, zero dependencies (only requires the SSL library provided by the operating system), and ease of integration.

1. Core Features

  • Header-only: Just include httplib.h to use it, no compilation required.
  • No external dependencies: For HTTP, only the standard library is needed; for HTTPS, OpenSSL or Mbed TLS must be installed on the system.
  • Cross-platform: Supports major platforms such as Windows (MSVC), Linux, and macOS.
  • Comprehensive functionality:
    • Supports HTTP/1.1 and partial HTTP/2 (via Mbed TLS).
    • Supports common methods such as GET, POST, PUT, DELETE, HEAD, OPTIONS.
    • Supports file uploads, downloads, form data, and JSON data transmission.
    • Includes a simple routing mechanism.
    • Supports server-side rendering (returning HTML) and static file serving.
    • Client supports connection pooling, timeout settings, etc.
  • Modern C++: API design is intuitive, and the code is clean and easy to read.

2. Quick Start Example

Example 1: Create a Simple HTTP Server

// server.cpp
#include <httplib.h>
using namespace httplib;

int main() {
    Server svr;

    // Handle GET request for root path
    svr.Get("/", [](const Request& req, Response& res) {
        res.set_content("<h1>Hello from cpp-httplib!</h1>", "text/html");
    });

    // Handle /json path, return JSON data
    svr.Get("/json", [](const Request& req, Response& res) {
        res.set_content(R"({"message": "Hello, World!", "status": "ok"})", "application/json");
    });

    // Handle POST request
    svr.Post("/submit", [](const Request& req, Response& res) {
        std::string name = req.get_param_value("name"); // Get form parameter
        res.set_content("Hello, " + name + "!", "text/plain");
    });

    // Start server, listening on port 8080
    svr.listen("localhost", 8080);

    return 0;
}

Compile and Run:

g++ -std=c++14 server.cpp -o server
./server

Access http://localhost:8080 to see “Hello from cpp-httplib!”.

Example 2: Create an HTTP Client

// client.cpp
#include <httplib.h>
#include <iostream>
using namespace httplib;

int main() {
    Client cli("http://localhost:8080");

    // Send GET request
    auto res = cli.Get("/");
    if (res && res->status == 200) {
        std::cout << "GET Response:\n" << res->body << std::endl;
    }

    // Send POST request
    std::string body = "name=Bob";
    Headers headers = {{"Content-Type", "application/x-www-form-urlencoded"}};
    auto post_res = cli.Post("/submit", headers, body);
    if (post_res && post_res->status == 200) {
        std::cout << "POST Response:\n" << post_res->body << std::endl;
    }

    // Request JSON interface
    auto json_res = cli.Get("/json");
    if (json_res && json_res->status == 200) {
        std::cout << "JSON Data:\n" << json_res->body << std::endl;
    }

    return 0;
}

Example 3: Provide Static File Service

svr.Get("/index.html", [&](const Request& req, Response& res) {
    res.set_file_content("./public/index.html", "text/html");
});

// Recommended way: mount the entire directory
svr.set_base_dir("./public"); // Set ./public directory as root
// After this, accessing /style.css will automatically return ./public/style.css

Example 4: Handle File Upload

svr.Post("/upload", [](const Request& req, Response& res) {
    const auto& file = req.get_file_value("file"); // Assume form field name is "file"

    if (!file.content.empty()) {
        // Write uploaded file content to local
        std::ofstream out("uploads/" + file.filename, std::ios::binary);
        out << file.content;
        res.set_content("Upload successful!", "text/plain");
    } else {
        res.status = 400;
        res.set_content("No file uploaded.", "text/plain");
    }
});

3. How to Use in Your Project?

Method 1: Directly Download the Header File

curl -O https://raw.githubusercontent.com/yhirose/cpp-httplib/master/httplib.h

Place the httplib.h file in your project directory, then include it in your code with #include "httplib.h".

Method 2: Use CMake (Recommended)

In CMakeLists.txt:

include(FetchContent)
FetchContent_Declare(
  cpp-httplib
  GIT_REPOSITORY https://github.com/yhirose/cpp-httplib.git
  GIT_TAG        v0.14.0  # Use stable version
)
FetchContent_MakeAvailable(cpp-httplib)

target_link_libraries(your_target PRIVATE httplib::httplib)

4. Enable HTTPS Support

To use HTTPS, you need to link the OpenSSL library and define CPPHTTPLIB_OPENSSL_SUPPORT during compilation.

Server-side Example:

#define CPPHTTPLIB_OPENSSL_SUPPORT
#include <httplib.h>

int main() {
    SSLServer svr("./cert.pem", "./key.pem"); // Certificate and private key files

    svr.Get("/secure", [](const Request& req, Response& res) {
        res.set_content("This is secure!", "text/plain");
    });

    svr.listen("localhost", 8443);
    return 0;
}

Compile Command (requires linking OpenSSL):

g++ -std=c++14 server.cpp -o server -lssl -lcrypto

5. Use Cases

  • Rapid Prototyping: Set up a web service for testing with just a few lines of code.
  • Embedded Devices or Small Applications: Its lightweight nature makes it suitable for resource-constrained environments.
  • Web Interface for Utility Software: Add a simple web control panel to command-line tools.
  • Microservices: Build small, single-function services.
  • Learning HTTP Protocol: The clear code structure makes it a great resource for learning HTTP implementation principles.

cpp-httplib is one of the most popular lightweight web libraries in the C++ domain. It perfectly embodies the design philosophy of “simplicity is beauty,” allowing C++ developers to easily create HTTP services and clients, much like using Flask in Python. If you are looking for a C++ web solution that requires no complex configuration and is ready to use out of the box, cpp-httplib is definitely a top choice.

Leave a Comment