A modern HTTP server for experimentation and development supporting HTTP/3, HTTP/2, and HTTP/1.1.
Version 0.5 is out now, Yarr!
- Wide protocol support
- Stand-alone first —
microserve --dir ./publicis enough. YAML and federation are opt-in. - Multi-site YAML — several
server_nameblocks, per-site TLS, locations (root/proxy_pass), named backends, index files, and access logs. - CLI listen overlay —
--listen,--address, and--protoignore YAMLserversand start a single site. - Process isolation — one child process per site when two or more sites are resolved. A single site still runs in-process.
- Reverse proxy — nginx-style
proxy_passto a host or named backend (backend://api/); hop-by-hop headers stripped; failures return 502/504. - H2C origins — h2c-only sockets (HTTP/1.1 closed unless configured). The proxy can speak HTTP/2 prior-knowledge (
h2c://). - Dual-stack —
--ipv6/--no-ipv4expand unspecified binds; explicit addresses stay as written. - Optional federation (
-f federation.yaml) — hub or member; certified vs. unverified membership; certs can be revoked. Default remains stand-alone. - HTTP Basic Authorization — per location with
{SHA512}.htpasswd(RFC 7617). - Logging and timeouts — per-site error logs, YAML
access_log, and connect/read/write timeouts. - Self-contained — Mini YAML parser for config (no extra YAML library, Boost dependency is probably temporary).
- C++20 modules — The only deps are Boost.Asio/Beast, nlohmann_json, nghttp2, ngtcp2/nghttp3, OpenSSL.
- Over 100 test cases and 700 assertions — Based on the Catch2 framework.
- Microserve is also a static library — Can be easily embedded into other applications.
Note: After v1.0 the Boost dependencies are scheduled for removal, considering replacement of nlohmann_json as well.
sudo dnf install spdlog-devel \
libnghttp3-devel libnghttp2-devel \
ngtcp2-devel ngtcp2-crypto-ossl-devel \
boost-devel boost-thread boost-program-optionscd deps/
./get_boost.sh
cd ..Install dependencies:
pacman -S mingw-w64-ucrt-x86_64-boost \
mingw-w64-ucrt-x86_64-nlohmann-json \
mingw-w64-ucrt-x86_64-zstd \
mingw-w64-ucrt-x86_64-spdlogpacman -S msys/libnghttp3 msys/libnghttp3-devel \
msys/libngtcp2 msys/libngtcp2-devel Requires CMake 3.31+ and a C++20 compiler with modules support. Install the dependencies above first, then:
cmake -S . -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=gcc \
-DCMAKE_CXX_COMPILER=g++ \
-DCMAKE_INSTALL_PREFIX=/opt/microserve
cmake --build build
sudo cmake --install buildIf Ninja is not installed, use Unix Makefiles instead:
cmake -S . -B build -G "Unix Makefiles" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=gcc \
-DCMAKE_CXX_COMPILER=g++ \
-DCMAKE_INSTALL_PREFIX=/opt/microserve
cmake --build build
sudo cmake --install buildThis installs:
microserver → /opt/microserve/bin/microserver
sample public/ and private/ → /opt/microserve/share/microserve/
sample certs/ → /opt/microserve/share/microserve/certs
dist/*.yaml → /opt/microserve/etc/microserve/
Configs in dist/ are written for prefix /. Install rewrites absolute
filesystem paths when the prefix is not / (both -DCMAKE_INSTALL_PREFIX
and cmake --install --prefix). With the prefix above,
pid: /run/microserve/microserve.pid becomes
pid: /opt/microserve/run/microserve/microserve.pid.
Run from the prefix (adjust --dir / TLS paths as needed):
/opt/microserve/bin/microserver --dir /opt/microserve/share/microserve/publicTo skip tests or Tailwind during the build:
cmake -S . -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=gcc \
-DCMAKE_CXX_COMPILER=g++ \
-DCMAKE_INSTALL_PREFIX=/opt/microserve \
-DMICROSERVE_BUILD_TESTS=OFF \
-DMICROSERVE_BUILD_TAILWIND=OFFopenssl req -x509 -newkey rsa:2048 -nodes \
-keyout server.key -out server.crt -days 365 \
-subj "//CN=localhost"microserve supports HTTP Basic Authorization (RFC 7617) per location.
locations:
- path: /
root: ../public
- path: /secret
root: ../private
auth: basic
auth_realm: secret space
auth_file: ../.htpasswdprintf "admin:{SHA512}" > .htpasswd
printf "change-me" | openssl dgst -sha512 -binary | openssl base64 -A >> .htpasswd
printf "\n" >> .htpasswd- Install
/or/optready configuration files. - Support all compressions:
Accept-Encoding: gzip, deflate, br, zstd - Support smart caching (lower priority, needed mostly for production)
API pages use the m.css Doxygen theme
with a custom Earth Heaven palette (doc/m-theme-earth-heaven.css, moss and
clay earth, sunlight gold, sky-blue info). doc/conf.py and doc/Doxyfile-mcss
drive that pipeline. The stock Doxygen HTML theme is still available from the
same Doxyfile.
On Linux or macOS:
python3 -m venv .venv && source .venv/bin/activate
python3 -m pip install jinja2 Pygments
git clone --depth 1 https://github.com/mosra/m.css /tmp/m.css
python3 /tmp/m.css/documentation/doxygen.py doc/conf.pyOn MSYS2/Windows (UCRT64):
pacman -S mingw-w64-ucrt-x86_64-doxygen
python3 -m venv .venv && source .venv/bin/activate
python3 -m pip install jinja2 Pygments
git clone --depth 1 https://github.com/mosra/m.css "$HOME/m.css"Issue with modules (temporary)
Doxygen 1.18 writes C++20 module XML that m.css does not handle. In
$HOME/m.css/documentation/doxygen.py, after the language skip in
parse_xml(), add:
diff --git a/documentation/doxygen.py b/documentation/doxygen.py
index 008c197..f92832c 100755
--- a/documentation/doxygen.py
+++ b/documentation/doxygen.py
@@ -2783,6 +2783,9 @@ def parse_xml(state: State, xml: str):
# See extract_metadata() for why `in []` is used
if compounddef.attrib.get('language', 'C++') not in ['C++']:
return
+ if compounddef.attrib['kind'] in ['dir', 'module', 'concept']:
+ logging.warning("{}: skipping unsupported compound kind {}".format(state.current, compounddef.attrib['kind']))
+ return
assert len([i for i in root]) == 1Then:
python3 "$HOME/m.css/documentation/doxygen.py" doc/conf.pycd doc && doxygen Doxyfile- ngtcp2/nghttp3 (HTTP/3 library written in C)
- Chrome's QUIC Implementation
- CloudFlare QUIC Test URL