# libhttpserver v2: a lambda-first C++ REST server on libmicrohttpd

> libhttpserver is a C++20 library for building RESTful HTTP servers on GNU libmicrohttpd, and version 2.0 rebuilt the API around lambdas, value typed responses and two explicit contracts for thread safety and error propagation. It suits C++ developers who want a daemon style HTTP layer without writing the socket handling themselves.

**etr/libhttpserver** — C++ library for creating an embedded Rest HTTP server (and more)

- Repository: https://github.com/etr/libhttpserver
- Stars: 955 · Forks: 190
- Language: C++
- License: LGPL-2.1
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/etr-libhttpserver

## A daemon library for HTTP, not a framework

libhttpserver is meant to constitute an easy system to build HTTP servers in the REST fashion. It is built on top of GNU libmicrohttpd and, like its substrate, it is a daemon library. The stated mission is to expose every useful HTTP capability through a simple, modern C++ API so that application code can focus on business logic rather than on the mechanics of HTTP request handling.

That framing matters for expectations. This is a library you call from a main function, not a runtime you hand a routing table and a middleware stack. The README is explicit about the substrate relationship, and the feature list follows from it: an HTTP/1.1 compatible request parser, a RESTful oriented interface, cross platform support for Linux, BSD, macOS and Windows under MSYS2-MinGW, IPv6 and dual-stack support, and multiple threading models including an internal poll, an internal select, a thread pool and an external loop.

Version 2.0 is the reason to look at this now. The README describes it as a lambda-first redesign where a working server is ten lines, handlers are std::function objects, responses are value typed, and every public method is thread-safe by contract. The pre-2.0 line ended at 0.19.0 in June 2023, so this is a substantial rewrite rather than an incremental release, and the README carries a whole section on migrating from v1.

The licence situation is unusual and worth knowing up front. The library code is under the GNU Lesser General Public License 2.1, in COPYING.LESSER, while the reference manual itself is under the GNU Free Documentation License 1.3, in LICENSE. That split is deliberate and documented in the appendices of the README.

## The shortest server is ten lines and needs no inheritance

The README leads with the smallest complete program the library allows, and the file is reproduced byte for byte from the examples tree, with a CI gate in scripts/check-readme.sh enforcing that equality.

```cpp
#include <httpserver.hpp>
using namespace httpserver;  // NOLINT(build/namespaces) - keep the demo at <=10 LOC
int main() {
    webserver ws{create_webserver(8080)};
    ws.on_get("/hello", [](const http_request&) {
        return http_response::string("Hello, World!");
    });
    ws.start(true);
}
```

Every design decision in the v2 API is visible in those lines. The server is constructed from create_webserver on a port, so there is no separate configuration object to learn. A route is registered with on_get and a path, and the handler is a lambda rather than a subclass. The handler returns an http_response built by one of the static factories, here the string factory, and the response is a value rather than a pointer, so there is no ownership question and no raw pointer lifetime to manage. The final call starts the server, and the boolean argument selects the blocking behaviour.

The class form still exists and the README explains when to use it. The class based pattern, http_resource, is the right shape when several methods on one path share mutable state, which is the case the lambda form cannot express without capturing something shared. The examples tree carries both, with shared_state.cpp as the counterpart to the lambda demo, alongside handlers.cpp and a set of files covering methods, arguments processing, custom access logs, custom errors and daemon introspection.

Responses carry a fluent chaining surface, with with_ style methods for adjusting the result, and the README lists seven factories covering string, file, iovec scatter-gather, pipe streaming, a deferred callback, empty and a 401 unauthorized shape.

## Two contracts: thread safety and error propagation

The README singles out two load-bearing contracts and says both are stated explicitly rather than left implicit. That is unusual for a C++ library and it is the part of the design most worth reading before you adopt it.

The first is thread safety, tracked as DR-008 in section 5.1. Every public method on the webserver object is thread-safe and re-entrant, by contract rather than by accident. For a server library this is the difference between being able to call into the daemon from a worker thread and not being able to, so the guarantee being written down matters as much as the guarantee itself.

The second is error propagation, tracked as DR-009 in section 5.2. The README has a dedicated section for it, and separate sections for the threading contract and error propagation sit next to each other in the table of contents, which tells you the project treats them as first class design documents rather than footnotes.

The threading models offered match the two contracts. Internal poll and internal select let the library drive its own event loop, a thread pool spreads work across handlers, and the external loop hands the file descriptors to an application that already runs its own loop. The external model comes with the full integration surface listed in the README: run, run_wait, get_fdset and add_connection, plus daemon introspection for the bound port, the active connection count and the listen file descriptor.

There are also lower level tuning knobs that come with the same package, including turbo mode, TCP_FASTOPEN, suppressed Date headers and a configurable backlog. Whether you want them is a separate question from whether they exist.

## Authentication, TLS and IP access control

The optional security features are grouped together, and each one has a dependency or a condition attached.

TLS is provided through GnuTLS, and the README lists mTLS, SNI and TLS-PSK among the capabilities. It is optional, which means the build configuration decides whether those code paths exist.

Authentication comes in two shapes. Basic and Digest authentication are supported, with the digest variants listed as SHA-256, SHA-512/256 and MD5. On top of that there is optional centralized authentication with path based skip rules, which is the feature that matters for a real deployment: one authentication mechanism for the whole server, with a way to say that certain paths are exempt.

IP access control is the third piece, and it is described with unusual precision. There is a deny list through deny_ip and an allow list through allow_ip, both supporting IPv4 and IPv6, and the wording says IP access control with wildcard ranges. An allow list with wildcards is the useful case for a service exposed on a dual-stack host, since it lets you open a range without enumerating every address.

The WebSocket support is the one with a hard prerequisite. It requires libmicrohttpd built with WebSocket support, so the capability of your server depends on how your system package of libmicrohttpd was compiled. The README lists WebSocket support under optional features for that reason.

Requests are also handled incrementally. The README lists incremental POST processing for form-urlencoded data, multipart form data and file uploads, and the examples tree contains file_upload.cpp and file_upload_with_callback.cpp, which are the two shapes you are most likely to need in practice.

## Migrating from v1 and reading the architecture docs

If you already run libhttpserver 0.x, the 2.0 rewrite is not a drop in replacement, and the README carries a Migrating from v1 section for that reason. The change is large enough that the release line itself signals it, since the project jumped from 0.19.0 in June 2023 to 2.0.0 in July 2026 and then to 2.0.1 in October 2026.

For anyone evaluating the library from scratch, the documentation is unusually well organised. The README describes itself as a guided reference that walks the v2.0 API surface section by section, and it says it is comprehensive but not exhaustive, with the headers under src/httpserver/ as the source of truth and the examples tree as a runnable demonstration of every feature.

There is also a visual layer. The docs/architecture/ directory holds a class, relationship and filesystem map, and a request lifecycle and routing flow diagram, rendered as Mermaid inline on GitHub and as richer self-contained HTML pages.

The repository layout reflects a mature autotools project with a modern touch. There is configure.ac, Makefile.am, Makefile.cvs, acinclude.m4, aminclude.am, bootstrap, m4/ and a cmakemodule/ directory for CMake based builds, along with libhttpserver.pc.in for pkg-config. Testing lives in test/ and specs/, and the source lives in src/. Auxiliary files include CPPLINT.cfg, custom_iwyu.imp for include what you use analysis, msan_ignorelist.txt for the memory sanitiser, and a doxyconfig.in for the generated API documentation.

The last push was on 2026-10-16 and the latest tag is 2.0.1, published on 2026-10-09.

## Conclusion

libhttpserver fits C++ teams that want a small, daemon style HTTP layer with real threading contracts, optional TLS and incremental request handling rather than a full framework. It does not fit a project that wants async by default, since the available models are poll, select, thread pool and external loop rather than an event loop with coroutines. Verify first that your libmicrohttpd build has the features you need, since WebSocket support requires libmicrohttpd to be built with it, and read the DR-008 and DR-009 sections in the README before relying on the thread safety and error propagation guarantees.

## FAQ

### What does libhttpserver need to build and run a server?

It is a C++20 library built on GNU libmicrohttpd, and the shortest program constructs a webserver with create_webserver on a port, registers a route with on_get and a lambda, and calls start. The class form http_resource is used when several methods on one path share mutable state.

### Does libhttpserver support HTTPS and WebSockets?

Optional TLS is provided through GnuTLS, including mTLS, SNI and TLS-PSK. WebSocket support is optional and requires libmicrohttpd to be built with WebSocket support, so it depends on how your libmicrohttpd package was compiled.

### Which threading models does libhttpserver offer?

An internal poll, an internal select, a thread pool and an external event loop, with run, run_wait, get_fdset and add_connection for the external case. The README also documents a thread safety contract (DR-008) and an error propagation contract (DR-009).

### What licence is libhttpserver released under?

The library code is under the GNU Lesser General Public License 2.1, with the full text in COPYING.LESSER, and the reference manual is under the GNU Free Documentation License 1.3, with the full text in the LICENSE file.

## Sources

- [etr/libhttpserver on GitHub](https://github.com/etr/libhttpserver)
- [Issues](https://github.com/etr/libhttpserver/issues)
- [License: LGPL-2.1](https://github.com/etr/libhttpserver/blob/master/LICENSE)
- [README](https://github.com/etr/libhttpserver/blob/master/README.md)
- [Releases](https://github.com/etr/libhttpserver/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/etr-libhttpserver
