Skip to content

A Mongoose custom header which support running Mongoose application in WAMR (WebAssembly)

License

Notifications You must be signed in to change notification settings

Stefan-J-Hanke/wamr_with_mongoose

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 

Repository files navigation

A Web Server in WebAssembly with Mongoose and WAMR

Mongoose is an embedded Webserver, MQTT, WebSocket, SMTP server and a whole lot more. You can find out more about Mongoose on the Mongoose GitHub Repository - cesanta/mongoose: Embedded Web Server (github.com)

WAMR is the Wasm Micro Runtime, it is a WebAssembly runtime designed to run on IoT and embedded devices. Running a WebServer in a WebAssembly sandbox allows us to:

  1. Provide some additional security, if the server is compromised the sandbox should limit the blast radius.
  2. Provide portable code; writing the same web interface for multiple devices can be a pain, this web server should be portable between devices.
  3. Run the webserver for a device on a development machine or other bit of hardware - super handy for debugging and development.

A Step by Step Guide to Building a Webserver for WAMR

There are a few gotcha's when building network enabled applications for WAMR and for building Mongoose for use on WAMR. This repository will go through the basics of getting these two great open source projects working together.

This repository will show you how to build the sample Mongoose HTTP server example and get it running as an wasm application for WAMR. - If all goes well, then at the end of this readme, you should have a working HTTP server running in a portable .wasm file.

Step 1 : Get WAMR and WASI SDK Installed

There is a step by step guide on how to get up and running with WAMR and the WASI SDK on my personal blog. But, to save you time, here's the highlights, assuming we're using Ubuntu, or Ubuntu for WSL (Windows Subsystem for Linux):

  • Install the necessary build packages using apt-get:

    sudo apt-get install build-essential clang cmake ninja-build wget curl git
  • Install WASI SDK; we'll download the tar file extract it and place it in the /opt directory:

    cd ~
    wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-21/wasi-sdk-21.0-linux.tar.gz
    tar -xf wasi-sdk-21.0-linux.tar.gz
    sudo mkdir /opt/wasi-sdk
    sudo mv ./wasi-sdk-21.0/* /opt/wasi-sdk/
  • Clone and build the WAMR Repository:

    git clone https://github.com/bytecodealliance/wasm-micro-runtime.git
    cd wasm-micro-runtime
    mdkir build
    cd build
    cmake ..
    make

Step 2 : Build WAMR's Socket Example Applications

The iwasm runtime for WAMR doesn't typically include thread or socket handling support. Instead you need to build iwasm with both sockets and pthreads enabled. Doing this is rather straight forward as the WAMR project already includes a set of socket sample applications, and a cmake file which will rebuild iwasm with all the additional functionality we need. You can find the example applications and the cmake file we need here - Socket API Sample. Simply follow the build instructions and you will end up with a socket enabled iwasm runtime. But, to save you time, here's the highlights:

  • Find the folder with the socket handling example could in it, and use cmake to build an updated iwasm along with all the example applications:

    cd ~/wasm-micro-runtime/samples/socket-api/
    mkdir build
    cd build
    cmake ..
    make
  • Copy the build iwasm command line tool, and place it somewhere handy for future reference:

    mkdir ~/bin
    cp ./iwasm ~/bin/iwasm

Step 3 : Clone the Mongoose Repository

Let's just clone the Mongoose repository:

cd ~
git clone https://github.com/cesanta/mongoose.git

Step 4 : Clone This Repository

You'll need a customized mongoose_custom.h which is part of this repository.

cd ~
git clone https://github.com/woodsmc/wamr_with_mongoose.git

Step 4 : Collect all the Necessary Parts

In order to build a working example http server we're going to need to collect all the necessary parts together from the three projects we've cloned so far.

  • Let's do this and create a new working directory with our http server code:

    cd ~
    mkdir wasm_http_server
    cd wasm_http_server
  • Now let's copy in our custom header:

    cp ~/wamr_with_mongoose/mongoose_custom.h .
  • The socket library files from WAMR:

    cp ~/wasm-micro-runtime/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c .
    cp ~/wasm-micro-runtime/core/iwasm/libraries/lib-socket/inc/wasi_socket_ext.h .
  • The Mongoose framework:

    cp ~/mongoose/mongoose.h .
    cp ~/mongoose/mongoose.c .
  • The Mongoose example http server:

    cp ~/mongoose/examples/http-server/main.c .

Updating the main.c

The Mongoose example http server includes a call to a file operation that WASI doesn't support, we do need to disable this, open up the main.c file in your editor of choice and comment out the following four lines, these start at line 107:

  // Root directory must not contain double dots. Make it absolute
  // Do the conversion only if the root dir spec does not contain overrides
  /* <-- comment out this if statement, realpath not supported
  if (strchr(s_root_dir, ',') == NULL) {
    realpath(s_root_dir, path);
    s_root_dir = path;
  }
  */

Building The Server

Now that everything is ready, we need to build the http server this can be done with the following command:

/opt/wasi-sdk/bin/clang -o3 -D_WASI_EMULATED_SIGNAL -DWAMR -I ./wamr_extra -I . -I ~/public_work/mongoose_wamr -o httpserver.wasm -lwasi-emulated-signal -lpthread -Wl,--allow-undefined ./wasi_soc
ket_ext.c ./mongoose.c ./main.c

This should produce a httpserver.wasm file in your local directory.

Executing WAMR

When you execute WAMR you have to tell it at the command line what permissions you will grant the running WebAssembly code. For the example WebServer to work you will need to provide the following command line switches:

  • --dir=. this tells WAMR to allow the running WASM code to see the current directory
  • --addr-pool=127.0.0.1/15 tells WAMR to allow the running WASM code to use the IP address for local host
~/bin/iwasm --dir=. --addr-pool=127.0.0.1/15 httpserver.wasm -l http://127.0.0.1:8090

This should give you a working webserver available on localhost at port 8090.

screencapture

About

A Mongoose custom header which support running Mongoose application in WAMR (WebAssembly)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C 100.0%