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")) }