From 3fafb7ef9d0e9a2218d016216ebd91156e828e03 Mon Sep 17 00:00:00 2001
From: Pat Hickey
Date: Mon, 16 Mar 2026 12:31:08 -0700
Subject: [PATCH] update to use wstd 0.6
---
Cargo.lock | 130 ++++++++++++++++++++++++++++++++++++++++++++---------
Cargo.toml | 7 +--
src/lib.rs | 78 ++++++++++++++++----------------
3 files changed, 149 insertions(+), 66 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 1bed836..aa6b1da 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,6 +2,18 @@
# It is not intended for manual editing.
version = 4
+[[package]]
+name = "anyhow"
+version = "1.0.102"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
+
+[[package]]
+name = "async-task"
+version = "4.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
+
[[package]]
name = "autocfg"
version = "1.4.0"
@@ -16,9 +28,24 @@ checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "bytes"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
+
+[[package]]
+name = "fastrand"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
+checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
+dependencies = [
+ "instant",
+]
[[package]]
name = "fnv"
@@ -32,6 +59,27 @@ version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+[[package]]
+name = "futures-io"
+version = "0.3.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
+
+[[package]]
+name = "futures-lite"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce"
+dependencies = [
+ "fastrand",
+ "futures-core",
+ "futures-io",
+ "memchr",
+ "parking",
+ "pin-project-lite",
+ "waker-fn",
+]
+
[[package]]
name = "http"
version = "1.2.0"
@@ -43,6 +91,38 @@ dependencies = [
"itoa",
]
+[[package]]
+name = "http-body"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
+dependencies = [
+ "bytes",
+ "http",
+]
+
+[[package]]
+name = "http-body-util"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "http",
+ "http-body",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "instant"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
+dependencies = [
+ "cfg-if",
+]
+
[[package]]
name = "itoa"
version = "1.0.14"
@@ -55,6 +135,12 @@ version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+[[package]]
+name = "parking"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
+
[[package]]
name = "pin-project-lite"
version = "0.2.16"
@@ -89,7 +175,7 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
name = "sample-wasi-http-rust"
version = "0.0.0"
dependencies = [
- "wit-bindgen-rt 0.41.0",
+ "http-body-util",
"wstd",
]
@@ -152,54 +238,56 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11cd88e12b17c6494200a9c1b683a04fcac9573ed74cd1b62aeb2727c5592243"
[[package]]
-name = "wasi"
-version = "0.14.0+wasi-0.2.3"
+name = "waker-fn"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3d67b0bdfec72b9fbaba698033291c327ef19ce3b34efbdcd7dc402a53850d9"
-dependencies = [
- "wit-bindgen-rt 0.37.0",
-]
+checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7"
[[package]]
-name = "wit-bindgen-rt"
-version = "0.37.0"
+name = "wasip2"
+version = "1.0.2+wasi-0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc801b991c56492f87ab3086e786468f75c285a4d73017ab0ebc2fa1aed5d82c"
+checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
dependencies = [
- "bitflags",
+ "wit-bindgen",
]
[[package]]
-name = "wit-bindgen-rt"
-version = "0.41.0"
+name = "wit-bindgen"
+version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4db52a11d4dfb0a59f194c064055794ee6564eb1ced88c25da2cf76e50c5621"
+checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
dependencies = [
"bitflags",
]
[[package]]
name = "wstd"
-version = "0.5.4"
+version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5f51495e1ae93476d1629b5810bd6068fdf22545a8ada7ea5929e2faed7b793"
+checksum = "0903606f1acdecad11576768ecc61ce215d6848652ac16c0e4592bb265e4200e"
dependencies = [
- "futures-core",
+ "anyhow",
+ "async-task",
+ "bytes",
+ "futures-lite",
"http",
+ "http-body",
+ "http-body-util",
"itoa",
"pin-project-lite",
"serde",
"serde_json",
"slab",
- "wasi",
+ "wasip2",
"wstd-macro",
]
[[package]]
name = "wstd-macro"
-version = "0.5.4"
+version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "225ac858e4405bdf164d92d070422c0b3b9b81f9b0b68836841f4d1bafc446b3"
+checksum = "d6a9df01a7fb39fbe7e9b5ef76f586f06425dd6f2be350de4781936f72f9899d"
dependencies = [
"quote",
"syn",
diff --git a/Cargo.toml b/Cargo.toml
index 0a946ce..d5a68f7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,9 +4,6 @@ version = "0.0.0"
edition = "2021"
publish = false
-[lib]
-crate-type = ["cdylib"]
-
[dependencies]
-wit-bindgen-rt = { version = "0.41.0", features = ["bitflags"] }
-wstd = "0.5.4"
+http-body-util = "0.1.3"
+wstd = "0.6"
diff --git a/src/lib.rs b/src/lib.rs
index d7f0b43..1474e36 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,28 +1,24 @@
-use wstd::http::body::{BodyForthcoming, IncomingBody};
-use wstd::http::server::{Finished, Responder};
-use wstd::http::{IntoBody, Request, Response, StatusCode};
-use wstd::io::{copy, empty, AsyncWrite};
+use wstd::http::{body::Bytes, Body, Request, Response, Result, StatusCode};
use wstd::time::{Duration, Instant};
#[wstd::http_server]
-async fn main(req: Request, res: Responder) -> Finished {
+async fn main(req: Request) -> Result> {
match req.uri().path_and_query().unwrap().as_str() {
- "/wait" => wait(req, res).await,
- "/echo" => echo(req, res).await,
- "/echo-headers" => echo_headers(req, res).await,
- "/echo-trailers" => echo_trailers(req, res).await,
- "/" => home(req, res).await,
- _ => not_found(req, res).await,
+ "/wait" => wait(req).await,
+ "/echo" => echo(req).await,
+ "/echo-headers" => echo_headers(req).await,
+ "/echo-trailers" => echo_trailers(req).await,
+ "/" => home(req).await,
+ _ => not_found(req).await,
}
}
-async fn home(_req: Request, res: Responder) -> Finished {
- // To send a single string as the response body, use `res::respond`.
- res.respond(Response::new("Hello, wasi:http/proxy world!\n".into_body()))
- .await
+async fn home(_req: Request) -> Result> {
+ // To send a single string as the response body:
+ Ok(Response::new("Hello, wasi:http/proxy world!\n".into()))
}
-async fn wait(_req: Request, res: Responder) -> Finished {
+async fn wait(_req: Request) -> Result> {
// Get the time now
let now = Instant::now();
@@ -32,41 +28,43 @@ async fn wait(_req: Request, res: Responder) -> Finished {
// Compute how long we slept for.
let elapsed = Instant::now().duration_since(now).as_millis();
- // To stream data to the response body, use `res::start_response`.
- let mut body = res.start_response(Response::new(BodyForthcoming));
- let result = body
- .write_all(format!("slept for {elapsed} millis\n").as_bytes())
- .await;
- Finished::finish(body, result, None)
+ Ok(Response::new(
+ format!("slept for {elapsed} millis\n").into(),
+ ))
}
-async fn echo(mut req: Request, res: Responder) -> Finished {
+async fn echo(req: Request) -> Result> {
// Stream data from the req body to the response body.
- let mut body = res.start_response(Response::new(BodyForthcoming));
- let result = copy(req.body_mut(), &mut body).await;
- Finished::finish(body, result, None)
+ let req_body = req.into_body();
+ Ok(Response::new(req_body))
}
-async fn echo_headers(req: Request, responder: Responder) -> Finished {
+async fn echo_headers(req: Request) -> Result> {
let mut res = Response::builder();
*res.headers_mut().unwrap() = req.into_parts().0.headers;
- let res = res.body(empty()).unwrap();
- responder.respond(res).await
+ Ok(res.body(().into()).expect("builder success"))
}
-async fn echo_trailers(req: Request, res: Responder) -> Finished {
- let body = res.start_response(Response::new(BodyForthcoming));
- let (trailers, result) = match req.into_body().finish().await {
- Ok(trailers) => (trailers, Ok(())),
- Err(err) => (Default::default(), Err(std::io::Error::other(err))),
+async fn echo_trailers(req: Request) -> Result> {
+ use http_body_util::{BodyExt, Full};
+ let collected = req.into_body().into_boxed_body().collect().await?;
+ let (trailers, report) = if let Some(trailers) = collected.trailers() {
+ (
+ Some(Ok(trailers.clone())),
+ format!("recieved trailers: {trailers:?}"),
+ )
+ } else {
+ (None, "request had no trailers".to_owned())
};
- Finished::finish(body, result, trailers)
+
+ Ok(Response::new(Body::from_http_body(
+ Full::new(Bytes::from(report)).with_trailers(async { trailers }),
+ )))
}
-async fn not_found(_req: Request, responder: Responder) -> Finished {
- let res = Response::builder()
+async fn not_found(_req: Request) -> Result> {
+ Ok(Response::builder()
.status(StatusCode::NOT_FOUND)
- .body(empty())
- .unwrap();
- responder.respond(res).await
+ .body(().into())
+ .expect("builder succeeds"))
}