Skip to content

ricochet/sample-wasi-http-cpp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

C++ HTTP Server WebAssembly Component

A simple HTTP server built using C++ and WebAssembly Components with wasi:http.

Building

Prerequisites

  • WASI SDK 28.0 (wasm32-wasip2)
  • wit-bindgen 0.48.0+
  • wkg CLI

Quick Start with Makefile

The easiest way to build is using the provided Makefile:

make

If you have WASI SDK installed in a non-standard location:

make WASI_SDK_PATH=/opt/wasi-sdk-28.0

Or set it as an environment variable:

export WASI_SDK_PATH=/opt/wasi-sdk-28.0
make

Manual Build Steps

If you prefer to build manually:

  1. Fetch WIT dependencies:

    wkg wit fetch
  2. Generate C++ bindings:

    wit-bindgen cpp --out-dir bindings wit
  3. Compile the component:

    wasm32-wasip2-clang++ \
      server.cpp \
      bindings/http_server.cpp \
      bindings/http_server_component_type.o \
      -I bindings \
      -I include \
      -Wall -Wextra -Werror -Wno-unused-parameter \
      -std=c++20 \
      -fno-exceptions \
      -mexec-model=reactor \
      -o http-server.wasm

Running

You can run this component with any WASI HTTP host, such as wasmtime:

wasmtime serve -Scli http-server.wasm

Then test the endpoints:

curl http://localhost:8080/
curl http://localhost:8080/hello
curl http://localhost:8080/echo/test

Endpoints

  • / - Returns "Hello, World!"
  • /hello - Returns a greeting from the C++ component
  • /echo/* - Echoes back the request method and path
  • Other paths return 404

Implementation Notes

  • Uses wasi:http imported resources (IncomingRequest, ResponseOutparam, etc.)
  • Demonstrates proper use of && move semantics for imported resources
  • Shows how to work with wit::string, std::expected, and std::variant
  • Properly handles resource lifetimes and cleanup

Generated with

Built using wit-bindgen with the following fixes:

  1. Type alias resolution for imported resources
  2. Proper && usage instead of ::Owned for imported resources
  3. Move semantics for std::expected in optional emplacement

Dependencies

This project uses tl::expected (included in include/tl/) to provide std::expected compatibility for WASI SDK.

Why tl::expected?

The generated C++ bindings use std::expected, which is a C++23 feature. While WASI SDK 28.0 uses LLVM 21 (which has libc++ 21 with std::expected support), the WASI SDK distribution may not include the <expected> header in its sysroot.

tl::expected is a header-only, single-file implementation of std::expected that:

  • Works with C++11 and later (we use C++20)
  • Is API-compatible with the C++23 standard
  • Is released under CC0-1.0 license (public domain)
  • Requires no external dependencies

The include/expected header provides a compatibility layer that aliases tl::expected to std::expected, making the code work seamlessly with generated bindings.

About

Sample WASI HTTP Server implemented with C++ and `wit-bindgen cpp`

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages