Skip to content

Commit

Permalink
feat(wasm): update component to use wasip2 target
Browse files Browse the repository at this point in the history
Signed-off-by: Brooks Townsend <[email protected]>

feat(wasm): update component to use wasip2 target

Signed-off-by: Brooks Townsend <[email protected]>

feat(wasm): update component to use wasip2 target

Signed-off-by: Brooks Townsend <[email protected]>
  • Loading branch information
brooksmtownsend committed Aug 15, 2024
1 parent 8f35cf8 commit c2444a8
Show file tree
Hide file tree
Showing 82 changed files with 74 additions and 5,796 deletions.
8 changes: 3 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,6 @@ socks = ["dep:tokio-socks"]
# Use the system's proxy configuration.
macos-system-configuration = ["dep:system-configuration"]

# Wasm features
# Build Wasm as a wasi-p2 component with wasi-http bindings.
wasm-component = ["dep:wit-bindgen"]

# Experimental HTTP/3 client.
http3 = ["rustls-tls-manual-roots", "dep:h3", "dep:h3-quinn", "dep:quinn", "dep:slab", "dep:futures-channel"]

Expand Down Expand Up @@ -198,7 +194,9 @@ serde_json = "1.0"
wasm-bindgen = "0.2.68"
wasm-bindgen-futures = "0.4.18"
wasm-streams = { version = "0.4", optional = true }
wit-bindgen = { version = "0.24.0", optional = true }

[target.'cfg(all(target_os = "wasi", target_env = "p2"))'.dependencies]
wasi = { version = "0.13.0" }

[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys]
version = "0.3.28"
Expand Down
10 changes: 8 additions & 2 deletions examples/wasm_component/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,11 @@ crate-type = ["cdylib"]

[dependencies]
futures = "0.3.30"
reqwest = { version = "0.12.4", path = "../../", features = [ "wasm-component" ] }
wit-bindgen = { version = "0.24", features = ["default"] }
reqwest = { version = "0.12.4", path = "../../", features = ["stream"] }
wasi = "0.13.2"

[profile.release]
# Optimize for small code size
lto = true
opt-level = "s"
strip = true
17 changes: 7 additions & 10 deletions examples/wasm_component/README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
# HTTP Reqwest

This is a simple Rust Wasm example that sends an outgoing http request using the `reqwest` library to [https://example.com](https://example.com).
This is a simple Rust Wasm example that sends an outgoing http request using the `reqwest` library to [https://hyper.rs](https://hyper.rs).

## Prerequisites

- `cargo` 1.75+
- [wasm-tools](https://github.com/bytecodealliance/wasm-tools)
- [wasmtime](https://github.com/bytecodealliance/wasmtime) >=20.0.0
- `wasi_snapshot_preview1.reactor.wasm` adapter, downloaded from [wasmtime release](https://github.com/bytecodealliance/wasmtime/releases/tag/v20.0.0)
- `cargo` 1.80+
- `rustup target add wasm32-wasip2`
- [wasmtime 23.0.0+](https://github.com/bytecodealliance/wasmtime)

## Building

```bash
# Build Wasm module
cargo build --release --target wasm32-wasi
# Create a Wasm component from the Wasm module by using the adapter
wasm-tools component new ./target/wasm32-wasi/release/http_reqwest.wasm -o ./component.wasm --adapt ./wasi_snapshot_preview1.reactor.wasm
# Build Wasm component
cargo +nightly build --target wasm32-wasip2
```

## Running with wasmtime

```bash
wasmtime serve -Scommon ./component.wasm
wasmtime serve -Scommon ./target/wasm32-wasip2/debug/http_reqwest.wasm
```

Then send a request to `localhost:8080`
Expand Down
54 changes: 39 additions & 15 deletions examples/wasm_component/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,52 @@
wit_bindgen::generate!();

use exports::wasi::http::incoming_handler::Guest;
use wasi::http::types::*;
use wasi::{
http::types::{Fields, IncomingRequest, OutgoingBody, OutgoingResponse, ResponseOutparam},
io::streams::{InputStream, OutputStream, StreamError},
};

#[allow(unused)]
struct ReqwestComponent;

impl Guest for ReqwestComponent {
impl wasi::exports::http::incoming_handler::Guest for ReqwestComponent {
fn handle(_request: IncomingRequest, response_out: ResponseOutparam) {
let response = OutgoingResponse::new(Fields::new());
response.set_status_code(200).unwrap();
let response_body = response.body().unwrap();
let response_body = response
.body()
.expect("should be able to get response body");
ResponseOutparam::set(response_out, Ok(response));

let exampledotcom = reqwest::Client::new().get("http://example.com").send();
let response = futures::executor::block_on(exampledotcom).expect("should get response");
let bytes = futures::executor::block_on(response.bytes()).expect("should get bytes");
let response =
futures::executor::block_on(reqwest::Client::new().get("https://hyper.rs").send())
.expect("should get response bytes");
let incoming_body = response.bytes_stream().expect("should get incoming body");
let stream = incoming_body.stream().expect("should get bytes stream");
stream_input_to_output(
stream,
response_body
.write()
.expect("should be able to write to response body"),
)
.expect("should be able to stream input to output");

response_body
.write()
.unwrap()
.blocking_write_and_flush(&bytes)
.unwrap();
OutgoingBody::finish(response_body, None).expect("failed to finish response body");
}
}

export!(ReqwestComponent);
pub fn stream_input_to_output(data: InputStream, out: OutputStream) -> Result<(), StreamError> {
loop {
match out.blocking_splice(&data, u64::MAX) {
Ok(bytes_spliced) if bytes_spliced == 0 => return Ok(()),
Ok(_) => {}
Err(e) => match e {
StreamError::Closed => {
return Ok(());
}
StreamError::LastOperationFailed(e) => {
return Err(StreamError::LastOperationFailed(e));
}
},
}
}
}

wasi::http::proxy::export!(ReqwestComponent);
Binary file not shown.
29 changes: 0 additions & 29 deletions examples/wasm_component/wit/deps.lock

This file was deleted.

1 change: 0 additions & 1 deletion examples/wasm_component/wit/deps.toml

This file was deleted.

7 changes: 0 additions & 7 deletions examples/wasm_component/wit/deps/cli/command.wit

This file was deleted.

18 changes: 0 additions & 18 deletions examples/wasm_component/wit/deps/cli/environment.wit

This file was deleted.

4 changes: 0 additions & 4 deletions examples/wasm_component/wit/deps/cli/exit.wit

This file was deleted.

20 changes: 0 additions & 20 deletions examples/wasm_component/wit/deps/cli/imports.wit

This file was deleted.

4 changes: 0 additions & 4 deletions examples/wasm_component/wit/deps/cli/run.wit

This file was deleted.

17 changes: 0 additions & 17 deletions examples/wasm_component/wit/deps/cli/stdio.wit

This file was deleted.

49 changes: 0 additions & 49 deletions examples/wasm_component/wit/deps/cli/terminal.wit

This file was deleted.

45 changes: 0 additions & 45 deletions examples/wasm_component/wit/deps/clocks/monotonic-clock.wit

This file was deleted.

42 changes: 0 additions & 42 deletions examples/wasm_component/wit/deps/clocks/wall-clock.wit

This file was deleted.

6 changes: 0 additions & 6 deletions examples/wasm_component/wit/deps/clocks/world.wit

This file was deleted.

Loading

0 comments on commit c2444a8

Please sign in to comment.