An open API service indexing awesome lists of open source software.

https://github.com/bytecodealliance/sample-wasi-http-cpp

Sample WASI HTTP Server implemented with C++ and `wit-bindgen cpp`
https://github.com/bytecodealliance/sample-wasi-http-cpp

Last synced: 27 days ago
JSON representation

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

Awesome Lists containing this project

README

          

# 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.1+
- wkg CLI

### Quick Start with Makefile

The easiest way to build is using the provided Makefile:

```bash
make
```

If you have WASI SDK installed in a non-standard location:
```bash
make WASI_SDK_PATH=/opt/wasi-sdk-28.0
```

Or set it as an environment variable:
```bash
export WASI_SDK_PATH=/opt/wasi-sdk-28.0
make
```

### Manual Build Steps

If you prefer to build manually:

1. **Fetch WIT dependencies**:
```bash
wkg wit fetch
```

2. **Generate C++ bindings**:
```bash
wit-bindgen cpp --out-dir bindings wit
```

3. **Compile the component**:
```bash
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:

```bash
wasmtime serve -Scli http-server.wasm
```

Then test the endpoints:
```bash
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](https://github.com/TartanLlama/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 `` 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.