All Projects → deislabs → wasi-experimental-http

deislabs / wasi-experimental-http

Licence: MIT license
Experimental outbound HTTP support for WebAssembly and WASI

Programming Languages

rust
11053 projects
typescript
32286 projects

Projects that are alternatives of or similar to wasi-experimental-http

Lunatic
Lunatic is an Erlang-inspired runtime for WebAssembly
Stars: ✭ 2,074 (+1838.32%)
Mutual labels:  wasi, wasmtime
Wasmtime
Standalone JIT-style runtime for WebAssembly, using Cranelift
Stars: ✭ 6,413 (+5893.46%)
Mutual labels:  wasi, wasmtime
chimera-admission
A Kubernetes dynamic admission controller that uses WebAssembly policies to validate incoming requests
Stars: ✭ 25 (-76.64%)
Mutual labels:  wasi
wasmtime-dotnet
.NET embedding of Wasmtime https://bytecodealliance.github.io/wasmtime-dotnet/
Stars: ✭ 270 (+152.34%)
Mutual labels:  wasmtime
dotnet-opa-wasm
Call Open Policy Agent (OPA) policies in WASM (Web Assembly) from .NET Core
Stars: ✭ 36 (-66.36%)
Mutual labels:  wasmtime
Krustlet
Kubernetes Rust Kubelet
Stars: ✭ 2,391 (+2134.58%)
Mutual labels:  wasi
Wasmer
🚀 The leading WebAssembly Runtime supporting WASI and Emscripten
Stars: ✭ 11,047 (+10224.3%)
Mutual labels:  wasi
Tinygo
Go compiler for small places. Microcontrollers, WebAssembly (WASM/WASI), and command-line tools. Based on LLVM.
Stars: ✭ 9,068 (+8374.77%)
Mutual labels:  wasi
Lucet
Lucet, the Sandboxing WebAssembly Compiler.
Stars: ✭ 4,006 (+3643.93%)
Mutual labels:  wasi
node-wasm-trace
Instruments wasm files and traces execution
Stars: ✭ 24 (-77.57%)
Mutual labels:  wasi
wasmer-zig
Zig bindings for the Wasmer WebAssembly runtime
Stars: ✭ 24 (-77.57%)
Mutual labels:  wasi
oasis-rs
A humane blockchain programming framework.
Stars: ✭ 71 (-33.64%)
Mutual labels:  wasi
wasi-worker
WASM / WASI interface for browser service workers
Stars: ✭ 31 (-71.03%)
Mutual labels:  wasi
node-wasi
WASI for Node.js
Stars: ✭ 64 (-40.19%)
Mutual labels:  wasi
webassembly-tour
⚙️ Take you through a tour of WebAssembly (WASM targets on WASI) with wasmCloud, Krustlet, WAGI, etc. 🌟 Give it a star if you like it.
Stars: ✭ 111 (+3.74%)
Mutual labels:  wasi
libclang rt.builtins-wasm32.a
The missing libclang_rt.builtins-wasm32.a file to compile to WebAssembly.
Stars: ✭ 25 (-76.64%)
Mutual labels:  wasi
etheryal-kernel
Open Source Rust kernel; Runs WASM and WASI as lightweight containers.
Stars: ✭ 32 (-70.09%)
Mutual labels:  wasi
wazero
wazero: the zero dependency WebAssembly runtime for Go developers
Stars: ✭ 2,065 (+1829.91%)
Mutual labels:  wasi
krustlet
Kubernetes Rust Kubelet
Stars: ✭ 3,154 (+2847.66%)
Mutual labels:  wasi
wasmtime-py
Python WebAssembly runtime powered by Wasmtime
Stars: ✭ 191 (+78.5%)
Mutual labels:  wasmtime

wasi-experimental-http

This is an experiment intended to provide a temporary workaround until the WASI networking API is stable, and is compatible with Wasmtime v0.26 by using the wasi_experiemental_http_wasmtime crate. We expect that once the WASI sockets proposal gets adopted and implemented in language toolchains, the need for this library will vanish.

Writing a module that makes an HTTP request

We use the wasi-experimental-http crate (from this repository) and the http crate to create an HTTP request from a WebAssembly module, make a host call to the runtime using the request, then get a response back:

use bytes::Bytes;
use http;
use wasi_experimental_http;

#[no_mangle]
pub extern "C" fn _start() {
    let url = "https://postman-echo.com/post".to_string();
    let req = http::request::Builder::new()
        .method(http::Method::POST)
        .uri(&url)
        .header("Content-Type", "text/plain")
        .header("abc", "def");
    let b = Bytes::from("Testing with a request body. Does this actually work?");
    let req = req.body(Some(b)).unwrap();

    let res = wasi_experimental_http::request(req).expect("cannot make request");
    let str = std::str::from_utf8(&res.body_read_all()).unwrap().to_string();
    println!("{:#?}", res.header_get("Content-Type"));
    println!("{}", str);
    println!("{:#?}", res.status_code);
}

Build the module using the wasm32-wasi target, then follow the next section to update a Wasmtime runtime with the experimental HTTP support.

Adding support to a Wasmtime runtime

The easiest way to add support is by using the Wasmtime linker:

let store = Store::default();
let mut linker = Linker::new(&store);
let wasi = Wasi::new(&store, ctx);

// link the WASI core functions
wasi.add_to_linker(&mut linker)?;

// link the experimental HTTP support
let allowed_hosts = Some(vec!["https://postman-echo.com".to_string()]);
let max_concurrent_requests = Some(42);

let http = HttpCtx::new(allowed_domains, max_concurrent_requests)?;
http.add_to_linker(&mut linker)?;

Then, executing the module above will send the HTTP request and write the response:

{
    "content-length": "374",
    "connection": "keep-alive",
    "set-cookie": "sails.Path=/; HttpOnly",
    "vary": "Accept-Encoding",
    "content-type": "application/json; charset=utf-8",
    "date": "Fri, 26 Feb 2021 18:31:03 GMT",
    "etag": "W/\"176-Ky4OTmr3Xbcl3yNah8w2XIQapGU\"",
}
{"args":{},"data":"Testing with a request body. Does this actually work?","files":{},"form":{},"headers":{"x-forwarded-proto":"https","x-forwarded-port":"443","host":"postman-echo.com","x-amzn-trace-id":"Root=1-60393e67-02d1c8033bcf4f1e74a4523e","content-length":"53","content-type":"text/plain","abc":"def","accept":"*/*"},"json":null,"url":"https://postman-echo.com/post"}
"200 OK"

The Wasmtime implementation also enables allowed hosts - an optional and configurable list of domains or hosts that guest modules are allowed to send requests to. If None or an empty vector is passed, guest modules are NOT allowed to make HTTP requests to any server. (Note that the hosts passed MUST have the protocol also specified - i.e. https://my-domain.com, or http://192.168.0.1, and if making requests to a subdomain, the subdomain MUST be in the allowed list. See the the library tests for more examples).

Note that the Wasmtime version currently supported is 0.26.

Sending HTTP requests from AssemblyScript

This repository also contains an AssemblyScript implementation for sending HTTP requests:

// @ts-ignore
import * as wasi from "as-wasi";
import {
  Method,
  RequestBuilder,
  Response,
} from "@deislabs/wasi-experimental-http";

export function _start_(): void {
  let body = String.UTF8.encode("testing the body");
  let res = new RequestBuilder("https://postman-echo.com/post")
    .header("Content-Type", "text/plain")
    .method(Method.POST)
    .body(body)
    .send();
  wasi.Console.log(res.status.toString());
  wasi.Console.log(res.headersGetAll.toString());
  wasi.Console.log(String.UTF8.decode(res.bodyReadAll().buffer));
}

Testing using the wasmtime-http binary

This project also adds a convenience binary for testing modules with HTTP support, wasmtime-http - a simple program that mimics the wasmtime run command, but also adds support for sending HTTP requests.

➜ cargo run --bin wasmtime-http -- --help
wasmtime-http 0.1.0

USAGE:
    wasmtime-http [OPTIONS] <module> [--] [ARGS]...

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -a, --allowed-host <allowed-hosts>...    Host the guest module is allowed to make outbound HTTP requests to
    -i, --invoke <invoke>                    The name of the function to run [default: _start]
    -c, --concurrency <max-concurrency>      The maximum number of concurrent requests a module can make to allowed
                                             hosts
    -e, --env <NAME=VAL>...                  Pass an environment variable to the program

ARGS:
    <module>     The path of the WebAssembly module to run
    <ARGS>...    The arguments to pass to the module```

Known limitations

  • there is no support for streaming HTTP responses, which this means guest modules have to wait until the entire body has been written by the runtime before reading it.
  • request and response bodies are Bytes.
  • the current WITX definitions are experimental, and currently only used to generate guest bindings.
  • this library does not aim to add support for running HTTP servers in WebAssembly.

Code of Conduct

This project has adopted the Microsoft Open Source Code of Conduct.

For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.


Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].