diff --git a/ci/vendor-wit.sh b/ci/vendor-wit.sh index 4dd3aa883d17..315e4cbefd98 100755 --- a/ci/vendor-wit.sh +++ b/ci/vendor-wit.sh @@ -34,7 +34,7 @@ get_github() { } p2=0.2.6 -p3=0.3.0-rc-2025-09-16 +p3=0.3.0-rc-2026-01-06 rm -rf crates/wasi-io/wit/deps mkdir -p crates/wasi-io/wit/deps diff --git a/crates/test-programs/src/bin/p3_api_proxy.rs b/crates/test-programs/src/bin/p3_api_proxy.rs index 71fa8a6b31af..60a4fbb68c56 100644 --- a/crates/test-programs/src/bin/p3_api_proxy.rs +++ b/crates/test-programs/src/bin/p3_api_proxy.rs @@ -5,9 +5,9 @@ use wit_bindgen::spawn; struct T; -test_programs::p3::proxy::export!(T); +test_programs::p3::service::export!(T); -impl test_programs::p3::proxy::exports::wasi::http::handler::Guest for T { +impl test_programs::p3::service::exports::wasi::http::handler::Guest for T { async fn handle(request: Request) -> Result { assert!(request.get_scheme().is_some()); assert!(request.get_authority().is_some()); @@ -54,7 +54,7 @@ impl test_programs::p3::proxy::exports::wasi::http::handler::Guest for T { } } -// Technically this should not be here for a proxy, but given the current +// Technically this should not be here for a service, but given the current // framework for tests it's required since this file is built as a `bin` fn main() {} diff --git a/crates/test-programs/src/bin/p3_cli_serve_hello_world.rs b/crates/test-programs/src/bin/p3_cli_serve_hello_world.rs index 86cefcdcd349..71bb9d719eb0 100644 --- a/crates/test-programs/src/bin/p3_cli_serve_hello_world.rs +++ b/crates/test-programs/src/bin/p3_cli_serve_hello_world.rs @@ -1,11 +1,11 @@ use test_programs::p3::wasi::http::types::{ErrorCode, Fields, Request, Response}; -use test_programs::p3::{proxy, wit_future, wit_stream}; +use test_programs::p3::{service, wit_future, wit_stream}; struct T; -proxy::export!(T); +service::export!(T); -impl proxy::exports::wasi::http::handler::Guest for T { +impl service::exports::wasi::http::handler::Guest for T { async fn handle(_request: Request) -> Result { let (mut body_tx, body_rx) = wit_stream::new(); let (body_result_tx, body_result_rx) = wit_future::new(|| Ok(None)); diff --git a/crates/test-programs/src/bin/p3_cli_serve_sleep.rs b/crates/test-programs/src/bin/p3_cli_serve_sleep.rs index eed10b49bb66..3b37c64e5471 100644 --- a/crates/test-programs/src/bin/p3_cli_serve_sleep.rs +++ b/crates/test-programs/src/bin/p3_cli_serve_sleep.rs @@ -1,12 +1,12 @@ -use test_programs::p3::proxy; +use test_programs::p3::service; use test_programs::p3::wasi::clocks::monotonic_clock; use test_programs::p3::wasi::http::types::{ErrorCode, Request, Response}; struct T; -proxy::export!(T); +service::export!(T); -impl proxy::exports::wasi::http::handler::Guest for T { +impl service::exports::wasi::http::handler::Guest for T { async fn handle(_request: Request) -> Result { monotonic_clock::wait_for(u64::MAX).await; unreachable!() diff --git a/crates/test-programs/src/bin/p3_http_echo.rs b/crates/test-programs/src/bin/p3_http_echo.rs index a1ac89529de3..ba3f62bc2c42 100644 --- a/crates/test-programs/src/bin/p3_http_echo.rs +++ b/crates/test-programs/src/bin/p3_http_echo.rs @@ -1,6 +1,6 @@ use { test_programs::p3::{ - proxy::exports::wasi::http::handler::Guest as Handler, + service::exports::wasi::http::handler::Guest as Handler, wasi::http::types::{ErrorCode, Request, Response}, wit_future, wit_stream, }, @@ -9,7 +9,7 @@ use { struct Component; -test_programs::p3::proxy::export!(Component); +test_programs::p3::service::export!(Component); impl Handler for Component { /// Return a response which echoes the request headers, body, and trailers. diff --git a/crates/test-programs/src/bin/p3_http_middleware.rs b/crates/test-programs/src/bin/p3_http_middleware.rs index 30f733bec190..0c78a18d4bc2 100644 --- a/crates/test-programs/src/bin/p3_http_middleware.rs +++ b/crates/test-programs/src/bin/p3_http_middleware.rs @@ -5,7 +5,6 @@ use { }, std::{io::Write, mem}, test_programs::p3::{ - proxy::exports::wasi::http::handler::Guest as Handler, wasi::http::{ handler, types::{ErrorCode, Headers, Request, Response}, @@ -15,11 +14,31 @@ use { wit_bindgen::StreamResult, }; +wit_bindgen::generate!({ + path: "../wasi-http/src/p3/wit", + world: "wasi:http/middleware", + with: { + "wasi:http/handler@0.3.0-rc-2026-01-06": test_programs::p3::wasi::http::handler, + "wasi:http/types@0.3.0-rc-2026-01-06": test_programs::p3::wasi::http::types, + "wasi:http/client@0.3.0-rc-2026-01-06": test_programs::p3::wasi::http::client, + "wasi:random/random@0.3.0-rc-2026-01-06": test_programs::p3::wasi::random::random, + "wasi:random/insecure@0.3.0-rc-2026-01-06": test_programs::p3::wasi::random::insecure, + "wasi:random/insecure-seed@0.3.0-rc-2026-01-06": test_programs::p3::wasi::random::insecure_seed, + "wasi:cli/stdout@0.3.0-rc-2026-01-06": test_programs::p3::wasi::cli::stdout, + "wasi:cli/stderr@0.3.0-rc-2026-01-06": test_programs::p3::wasi::cli::stderr, + "wasi:cli/stdin@0.3.0-rc-2026-01-06": test_programs::p3::wasi::cli::stdin, + "wasi:cli/types@0.3.0-rc-2026-01-06": test_programs::p3::wasi::cli::types, + "wasi:clocks/monotonic-clock@0.3.0-rc-2026-01-06": test_programs::p3::wasi::clocks::monotonic_clock, + "wasi:clocks/system-clock@0.3.0-rc-2026-01-06": test_programs::p3::wasi::clocks::system_clock, + "wasi:clocks/types@0.3.0-rc-2026-01-06": test_programs::p3::wasi::clocks::types, + }, +}); + struct Component; -test_programs::p3::proxy::export!(Component); +export!(Component); -impl Handler for Component { +impl exports::wasi::http::handler::Guest for Component { /// Forward the specified request to the imported `wasi:http/handler`, transparently decoding the request body /// if it is `deflate`d and then encoding the response body if the client has provided an `accept-encoding: /// deflate` header. diff --git a/crates/test-programs/src/bin/p3_http_middleware_with_chain.rs b/crates/test-programs/src/bin/p3_http_middleware_with_chain.rs index aed9f70b5407..c2fa1c78c3ed 100644 --- a/crates/test-programs/src/bin/p3_http_middleware_with_chain.rs +++ b/crates/test-programs/src/bin/p3_http_middleware_with_chain.rs @@ -6,13 +6,13 @@ mod bindings { package local:local; world middleware-with-chain { - include wasi:http/proxy@0.3.0-rc-2025-09-16; + include wasi:http/service@0.3.0-rc-2026-01-06; import chain-http; } interface chain-http { - use wasi:http/types@0.3.0-rc-2025-09-16.{request, response, error-code}; + use wasi:http/types@0.3.0-rc-2026-01-06.{request, response, error-code}; handle: async func(request: request) -> result; } diff --git a/crates/test-programs/src/bin/p3_http_outbound_request_content_length.rs b/crates/test-programs/src/bin/p3_http_outbound_request_content_length.rs index d1642323e9e7..73271bc69730 100644 --- a/crates/test-programs/src/bin/p3_http_outbound_request_content_length.rs +++ b/crates/test-programs/src/bin/p3_http_outbound_request_content_length.rs @@ -1,5 +1,5 @@ use futures::join; -use test_programs::p3::wasi::http::handler; +use test_programs::p3::wasi::http::client; use test_programs::p3::wasi::http::types::{ErrorCode, Headers, Method, Request, Scheme, Trailers}; use test_programs::p3::{wit_future, wit_stream}; use wit_bindgen::{FutureReader, FutureWriter, StreamWriter}; @@ -47,7 +47,7 @@ impl test_programs::p3::exports::wasi::cli::run::Guest for Component { { let (request, mut contents_tx, trailers_tx, transmit) = make_request(); let (handle, transmit, ()) = join!( - async { handler::handle(request).await }, + async { client::send(request).await }, async { transmit.await }, async { let remaining = contents_tx.write_all(b"long enough".to_vec()).await; @@ -64,7 +64,7 @@ impl test_programs::p3::exports::wasi::cli::run::Guest for Component { { let (request, mut contents_tx, trailers_tx, transmit) = make_request(); let (handle, transmit, ()) = join!( - async { handler::handle(request).await }, + async { client::send(request).await }, async { transmit.await }, async { let remaining = contents_tx.write_all(b"msg".to_vec()).await; @@ -93,7 +93,7 @@ impl test_programs::p3::exports::wasi::cli::run::Guest for Component { { let (request, mut contents_tx, trailers_tx, transmit) = make_request(); let (handle, transmit, ()) = join!( - async { handler::handle(request).await }, + async { client::send(request).await }, async { transmit.await }, async { let remaining = contents_tx.write_all(b"more than 11 bytes".to_vec()).await; diff --git a/crates/test-programs/src/bin/p3_http_outbound_request_missing_path_and_query.rs b/crates/test-programs/src/bin/p3_http_outbound_request_missing_path_and_query.rs index d56e3e393df0..ebb5984e4185 100644 --- a/crates/test-programs/src/bin/p3_http_outbound_request_missing_path_and_query.rs +++ b/crates/test-programs/src/bin/p3_http_outbound_request_missing_path_and_query.rs @@ -1,4 +1,4 @@ -use test_programs::p3::wasi::http::handler::handle; +use test_programs::p3::wasi::http::client::send; use test_programs::p3::wasi::http::types::{Fields, Method, Request, Scheme}; use test_programs::p3::wit_future; @@ -18,7 +18,7 @@ impl test_programs::p3::exports::wasi::cli::run::Guest for Component { // Don't set path/query // req.set_path_with_query(Some("/")).unwrap(); - let res = handle(req).await; + let res = send(req).await; assert!(res.is_err()); Ok(()) } diff --git a/crates/test-programs/src/bin/p3_http_proxy.rs b/crates/test-programs/src/bin/p3_http_proxy.rs index 532d9d37e02c..df7737ee80f7 100644 --- a/crates/test-programs/src/bin/p3_http_proxy.rs +++ b/crates/test-programs/src/bin/p3_http_proxy.rs @@ -1,8 +1,8 @@ use { test_programs::p3::{ - proxy::exports::wasi::http::handler::Guest as Handler, + service::exports::wasi::http::handler::Guest as Handler, wasi::http::{ - handler, + client, types::{ErrorCode, Fields, Request, Response, Scheme}, }, wit_future, @@ -12,7 +12,7 @@ use { struct Component; -test_programs::p3::proxy::export!(Component); +test_programs::p3::service::export!(Component); impl Handler for Component { // Forward the request body and trailers to a URL specified in a header. @@ -42,7 +42,7 @@ impl Handler for Component { outgoing_request .set_authority(Some(url.authority())) .unwrap(); - handler::handle(outgoing_request).await? + client::send(outgoing_request).await? } else { bad_request() }, diff --git a/crates/test-programs/src/p3/http.rs b/crates/test-programs/src/p3/http.rs index c51f1221f286..bb6b7da07ee7 100644 --- a/crates/test-programs/src/p3/http.rs +++ b/crates/test-programs/src/p3/http.rs @@ -2,7 +2,7 @@ use anyhow::{Context as _, Result, anyhow}; use core::fmt; use futures::join; -use crate::p3::wasi::http::{handler, types}; +use crate::p3::wasi::http::{client, types}; use crate::p3::{wit_future, wit_stream}; pub struct Response { @@ -91,7 +91,7 @@ pub async fn request( let (transmit, handle) = join!( async { transmit.await.context("failed to transmit request") }, async { - let response = handler::handle(request).await?; + let response = client::send(request).await?; let status = response.get_status_code(); let headers = response.get_headers().copy_all(); let (_, result_rx) = wit_future::new(|| Ok(())); diff --git a/crates/test-programs/src/p3/mod.rs b/crates/test-programs/src/p3/mod.rs index 87ddddb2d7cf..eeabb4d6c105 100644 --- a/crates/test-programs/src/p3/mod.rs +++ b/crates/test-programs/src/p3/mod.rs @@ -6,10 +6,12 @@ wit_bindgen::generate!({ package wasmtime:test; world testp3 { - include wasi:cli/imports@0.3.0-rc-2025-09-16; - include wasi:http/imports@0.3.0-rc-2025-09-16; + include wasi:cli/imports@0.3.0-rc-2026-01-06; + import wasi:http/types@0.3.0-rc-2026-01-06; + import wasi:http/client@0.3.0-rc-2026-01-06; + import wasi:http/handler@0.3.0-rc-2026-01-06; - export wasi:cli/run@0.3.0-rc-2025-09-16; + export wasi:cli/run@0.3.0-rc-2026-01-06; } ", path: "../wasi-http/src/p3/wit", @@ -19,30 +21,26 @@ wit_bindgen::generate!({ generate_all, }); -pub mod proxy { +pub mod service { wit_bindgen::generate!({ - inline: " - package wasmtime:test; - - world proxyp3 { - include wasi:http/proxy@0.3.0-rc-2025-09-16; - } - ", path: "../wasi-http/src/p3/wit", - world: "wasmtime:test/proxyp3", - default_bindings_module: "test_programs::p3::proxy", + world: "wasi:http/service", + default_bindings_module: "test_programs::p3::service", pub_export_macro: true, with: { - "wasi:http/handler@0.3.0-rc-2025-09-16": generate, - "wasi:http/types@0.3.0-rc-2025-09-16": crate::p3::wasi::http::types, - "wasi:random/random@0.3.0-rc-2025-09-16": crate::p3::wasi::random::random, - "wasi:cli/stdout@0.3.0-rc-2025-09-16": crate::p3::wasi::cli::stdout, - "wasi:cli/stderr@0.3.0-rc-2025-09-16": crate::p3::wasi::cli::stderr, - "wasi:cli/stdin@0.3.0-rc-2025-09-16": crate::p3::wasi::cli::stdin, - "wasi:cli/types@0.3.0-rc-2025-09-16": crate::p3::wasi::cli::types, - "wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16": crate::p3::wasi::clocks::monotonic_clock, - "wasi:clocks/wall-clock@0.3.0-rc-2025-09-16": crate::p3::wasi::clocks::wall_clock, - "wasi:clocks/types@0.3.0-rc-2025-09-16": crate::p3::wasi::clocks::types, + "wasi:http/handler@0.3.0-rc-2026-01-06": crate::p3::wasi::http::handler, + "wasi:http/types@0.3.0-rc-2026-01-06": crate::p3::wasi::http::types, + "wasi:http/client@0.3.0-rc-2026-01-06": crate::p3::wasi::http::client, + "wasi:random/random@0.3.0-rc-2026-01-06": crate::p3::wasi::random::random, + "wasi:random/insecure@0.3.0-rc-2026-01-06": crate::p3::wasi::random::insecure, + "wasi:random/insecure-seed@0.3.0-rc-2026-01-06": crate::p3::wasi::random::insecure_seed, + "wasi:cli/stdout@0.3.0-rc-2026-01-06": crate::p3::wasi::cli::stdout, + "wasi:cli/stderr@0.3.0-rc-2026-01-06": crate::p3::wasi::cli::stderr, + "wasi:cli/stdin@0.3.0-rc-2026-01-06": crate::p3::wasi::cli::stdin, + "wasi:cli/types@0.3.0-rc-2026-01-06": crate::p3::wasi::cli::types, + "wasi:clocks/monotonic-clock@0.3.0-rc-2026-01-06": crate::p3::wasi::clocks::monotonic_clock, + "wasi:clocks/system-clock@0.3.0-rc-2026-01-06": crate::p3::wasi::clocks::system_clock, + "wasi:clocks/types@0.3.0-rc-2026-01-06": crate::p3::wasi::clocks::types, }, }); } diff --git a/crates/wasi-http/src/handler.rs b/crates/wasi-http/src/handler.rs index de875b0b533e..ccffdec27e30 100644 --- a/crates/wasi-http/src/handler.rs +++ b/crates/wasi-http/src/handler.rs @@ -52,7 +52,7 @@ pub enum ProxyPre { P2(p2::bindings::ProxyPre), /// A `wasi:http/handler@0.3.x` pre-instance. #[cfg(feature = "p3")] - P3(p3::bindings::ProxyPre), + P3(p3::bindings::ServicePre), } impl ProxyPre { @@ -75,7 +75,7 @@ pub enum Proxy { P2(p2::bindings::Proxy), /// A `wasi:http/handler@0.3.x` instance. #[cfg(feature = "p3")] - P3(p3::bindings::Proxy), + P3(p3::bindings::Service), } /// Represents a task to run using a `wasi:http/incoming-handler@0.2.x` or diff --git a/crates/wasi-http/src/p3/bindings.rs b/crates/wasi-http/src/p3/bindings.rs index 82c9fb57a3bc..886a08cdd2e5 100644 --- a/crates/wasi-http/src/p3/bindings.rs +++ b/crates/wasi-http/src/p3/bindings.rs @@ -4,9 +4,9 @@ mod generated { wasmtime::component::bindgen!({ path: "src/p3/wit", - world: "wasi:http/proxy", + world: "wasi:http/service", imports: { - "wasi:http/handler.handle": store | trappable | tracing, + "wasi:http/client.send": store | trappable | tracing, "wasi:http/types.[drop]request": store | trappable | tracing, "wasi:http/types.[drop]response": store | trappable | tracing, "wasi:http/types.[static]request.consume-body": store | trappable | tracing, @@ -37,8 +37,8 @@ mod generated { pub use self::generated::wasi::*; -/// Raw bindings to the `wasi:http/proxy` exports. +/// Raw bindings to the `wasi:http/service` exports. pub use self::generated::exports; -/// Bindings to the `wasi:http/proxy` world. -pub use self::generated::{Proxy, ProxyIndices, ProxyPre}; +/// Bindings to the `wasi:http/service` world. +pub use self::generated::{Service, ServiceIndices, ServicePre}; diff --git a/crates/wasi-http/src/p3/host/handler.rs b/crates/wasi-http/src/p3/host/handler.rs index 6bf52e0445a1..8e57d898257b 100644 --- a/crates/wasi-http/src/p3/host/handler.rs +++ b/crates/wasi-http/src/p3/host/handler.rs @@ -1,4 +1,4 @@ -use crate::p3::bindings::http::handler::{Host, HostWithStore}; +use crate::p3::bindings::http::client::{Host, HostWithStore}; use crate::p3::bindings::http::types::{ErrorCode, Request, Response}; use crate::p3::body::{Body, BodyExt as _}; use crate::p3::{HttpError, HttpResult, WasiHttp, WasiHttpCtxView}; @@ -34,7 +34,7 @@ async fn io_task_result( } impl HostWithStore for WasiHttp { - async fn handle( + async fn send( store: &Accessor, req: Resource, ) -> HttpResult> { diff --git a/crates/wasi-http/src/p3/mod.rs b/crates/wasi-http/src/p3/mod.rs index 352fdd8ee945..f931da78f703 100644 --- a/crates/wasi-http/src/p3/mod.rs +++ b/crates/wasi-http/src/p3/mod.rs @@ -23,7 +23,7 @@ pub use response::Response; use crate::p3::bindings::http::types::ErrorCode; use crate::types::DEFAULT_FORBIDDEN_HEADERS; -use bindings::http::{handler, types}; +use bindings::http::{client, types}; use bytes::Bytes; use core::ops::Deref; use http::HeaderName; @@ -225,7 +225,7 @@ pub fn add_to_linker(linker: &mut Linker) -> wasmtime::Result<()> where T: WasiHttpView + 'static, { - handler::add_to_linker::<_, WasiHttp>(linker, T::http)?; + client::add_to_linker::<_, WasiHttp>(linker, T::http)?; types::add_to_linker::<_, WasiHttp>(linker, T::http)?; Ok(()) } diff --git a/crates/wasi-http/src/p3/proxy.rs b/crates/wasi-http/src/p3/proxy.rs index eb08baa7d5a3..d5c0aa4337fa 100644 --- a/crates/wasi-http/src/p3/proxy.rs +++ b/crates/wasi-http/src/p3/proxy.rs @@ -1,11 +1,11 @@ use crate::p3::WasiHttpView; -use crate::p3::bindings::Proxy; +use crate::p3::bindings::Service; use crate::p3::bindings::http::types::{ErrorCode, Request, Response}; use wasmtime::component::{Accessor, TaskExit}; use wasmtime::error::Context as _; -impl Proxy { - /// Call `wasi:http/handler#handle` on [Proxy] getting a [Response] back. +impl Service { + /// Call `wasi:http/handler#handle` on [Service] getting a [Response] back. pub async fn handle( &self, store: &Accessor, diff --git a/crates/wasi-http/src/p3/wit/deps/cli.wit b/crates/wasi-http/src/p3/wit/deps/cli.wit index 5bee32e5a57f..0f987bf38b81 100644 --- a/crates/wasi-http/src/p3/wit/deps/cli.wit +++ b/crates/wasi-http/src/p3/wit/deps/cli.wit @@ -1,6 +1,6 @@ -package wasi:cli@0.3.0-rc-2025-09-16; +package wasi:cli@0.3.0-rc-2026-01-06; -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface environment { /// Get the POSIX-style environment variables. /// @@ -10,23 +10,23 @@ interface environment { /// Morally, these are a value import, but until value imports are available /// in the component model, this import function should return the same /// values each time it is called. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-environment: func() -> list>; /// Get the POSIX-style arguments to the program. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-arguments: func() -> list; /// Return a path that programs should use as their initial current working /// directory, interpreting `.` as shorthand for this. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-initial-cwd: func() -> option; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface exit { /// Exit the current instance and any linked instances. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) exit: func(status: result); /// Exit the current instance and any linked instances, reporting the @@ -41,16 +41,16 @@ interface exit { exit-with-code: func(status-code: u8); } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface run { /// Run the program. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) run: async func() -> result; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface types { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) enum error-code { /// Input/output error io, @@ -61,7 +61,7 @@ interface types { } } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface stdin { use types.{error-code}; @@ -78,11 +78,11 @@ interface stdin { /// /// Multiple streams may be active at the same time. The behavior of concurrent /// reads is implementation-specific. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) read-via-stream: func() -> tuple, future>>; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface stdout { use types.{error-code}; @@ -94,11 +94,11 @@ interface stdout { /// /// Otherwise if there is an error the readable end of the stream will be /// dropped and this function will return an error-code. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) write-via-stream: async func(data: stream) -> result<_, error-code>; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface stderr { use types.{error-code}; @@ -110,7 +110,7 @@ interface stderr { /// /// Otherwise if there is an error the readable end of the stream will be /// dropped and this function will return an error-code. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) write-via-stream: async func(data: stream) -> result<_, error-code>; } @@ -119,10 +119,10 @@ interface stderr { /// In the future, this may include functions for disabling echoing, /// disabling input buffering so that keyboard events are sent through /// immediately, querying supported features, and so on. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface terminal-input { /// The input side of a terminal. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) resource terminal-input; } @@ -131,126 +131,126 @@ interface terminal-input { /// In the future, this may include functions for querying the terminal /// size, being notified of terminal size changes, querying supported /// features, and so on. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface terminal-output { /// The output side of a terminal. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) resource terminal-output; } /// An interface providing an optional `terminal-input` for stdin as a /// link-time authority. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface terminal-stdin { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) use terminal-input.{terminal-input}; /// If stdin is connected to a terminal, return a `terminal-input` handle /// allowing further interaction with it. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-terminal-stdin: func() -> option; } /// An interface providing an optional `terminal-output` for stdout as a /// link-time authority. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface terminal-stdout { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) use terminal-output.{terminal-output}; /// If stdout is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-terminal-stdout: func() -> option; } /// An interface providing an optional `terminal-output` for stderr as a /// link-time authority. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface terminal-stderr { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) use terminal-output.{terminal-output}; /// If stderr is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-terminal-stderr: func() -> option; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) world imports { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import environment; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import exit; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import types; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import stdin; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import stdout; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import stderr; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-input; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-output; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-stdin; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-stdout; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-stderr; - import wasi:clocks/types@0.3.0-rc-2025-09-16; - import wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16; - import wasi:clocks/wall-clock@0.3.0-rc-2025-09-16; + import wasi:clocks/types@0.3.0-rc-2026-01-06; + import wasi:clocks/monotonic-clock@0.3.0-rc-2026-01-06; + import wasi:clocks/system-clock@0.3.0-rc-2026-01-06; @unstable(feature = clocks-timezone) - import wasi:clocks/timezone@0.3.0-rc-2025-09-16; - import wasi:filesystem/types@0.3.0-rc-2025-09-16; - import wasi:filesystem/preopens@0.3.0-rc-2025-09-16; - import wasi:sockets/types@0.3.0-rc-2025-09-16; - import wasi:sockets/ip-name-lookup@0.3.0-rc-2025-09-16; - import wasi:random/random@0.3.0-rc-2025-09-16; - import wasi:random/insecure@0.3.0-rc-2025-09-16; - import wasi:random/insecure-seed@0.3.0-rc-2025-09-16; + import wasi:clocks/timezone@0.3.0-rc-2026-01-06; + import wasi:filesystem/types@0.3.0-rc-2026-01-06; + import wasi:filesystem/preopens@0.3.0-rc-2026-01-06; + import wasi:sockets/types@0.3.0-rc-2026-01-06; + import wasi:sockets/ip-name-lookup@0.3.0-rc-2026-01-06; + import wasi:random/random@0.3.0-rc-2026-01-06; + import wasi:random/insecure@0.3.0-rc-2026-01-06; + import wasi:random/insecure-seed@0.3.0-rc-2026-01-06; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) world command { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import environment; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import exit; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import types; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import stdin; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import stdout; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import stderr; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-input; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-output; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-stdin; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-stdout; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-stderr; - import wasi:clocks/types@0.3.0-rc-2025-09-16; - import wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16; - import wasi:clocks/wall-clock@0.3.0-rc-2025-09-16; + import wasi:clocks/types@0.3.0-rc-2026-01-06; + import wasi:clocks/monotonic-clock@0.3.0-rc-2026-01-06; + import wasi:clocks/system-clock@0.3.0-rc-2026-01-06; @unstable(feature = clocks-timezone) - import wasi:clocks/timezone@0.3.0-rc-2025-09-16; - import wasi:filesystem/types@0.3.0-rc-2025-09-16; - import wasi:filesystem/preopens@0.3.0-rc-2025-09-16; - import wasi:sockets/types@0.3.0-rc-2025-09-16; - import wasi:sockets/ip-name-lookup@0.3.0-rc-2025-09-16; - import wasi:random/random@0.3.0-rc-2025-09-16; - import wasi:random/insecure@0.3.0-rc-2025-09-16; - import wasi:random/insecure-seed@0.3.0-rc-2025-09-16; + import wasi:clocks/timezone@0.3.0-rc-2026-01-06; + import wasi:filesystem/types@0.3.0-rc-2026-01-06; + import wasi:filesystem/preopens@0.3.0-rc-2026-01-06; + import wasi:sockets/types@0.3.0-rc-2026-01-06; + import wasi:sockets/ip-name-lookup@0.3.0-rc-2026-01-06; + import wasi:random/random@0.3.0-rc-2026-01-06; + import wasi:random/insecure@0.3.0-rc-2026-01-06; + import wasi:random/insecure-seed@0.3.0-rc-2026-01-06; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) export run; } diff --git a/crates/wasi-http/src/p3/wit/deps/clocks.wit b/crates/wasi-http/src/p3/wit/deps/clocks.wit index 8e631f9a5d81..fc59f5a21e2a 100644 --- a/crates/wasi-http/src/p3/wit/deps/clocks.wit +++ b/crates/wasi-http/src/p3/wit/deps/clocks.wit @@ -1,10 +1,10 @@ -package wasi:clocks@0.3.0-rc-2025-09-16; +package wasi:clocks@0.3.0-rc-2026-01-06; /// This interface common types used throughout wasi:clocks. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface types { /// A duration of time, in nanoseconds. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) type duration = u64; } @@ -16,15 +16,15 @@ interface types { /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface monotonic-clock { use types.{duration}; - /// An instant in time, in nanoseconds. An instant is relative to an + /// A mark on a monotonic clock is a number of nanoseconds since an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. - @since(version = 0.3.0-rc-2025-09-16) - type instant = u64; + @since(version = 0.3.0-rc-2026-01-06) + type mark = u64; /// Read the current value of the clock. /// @@ -32,46 +32,59 @@ interface monotonic-clock { /// produce a sequence of non-decreasing values. /// /// For completeness, this function traps if it's not possible to represent - /// the value of the clock in an `instant`. Consequently, implementations + /// the value of the clock in a `mark`. Consequently, implementations /// should ensure that the starting time is low enough to avoid the /// possibility of overflow in practice. - @since(version = 0.3.0-rc-2025-09-16) - now: func() -> instant; + @since(version = 0.3.0-rc-2026-01-06) + now: func() -> mark; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-resolution: func() -> duration; - /// Wait until the specified instant has occurred. - @since(version = 0.3.0-rc-2025-09-16) - wait-until: async func(when: instant); + /// Wait until the specified mark has occurred. + @since(version = 0.3.0-rc-2026-01-06) + wait-until: async func(when: mark); /// Wait for the specified duration to elapse. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) wait-for: async func(how-long: duration); } -/// WASI Wall Clock is a clock API intended to let users query the current -/// time. The name "wall" makes an analogy to a "clock on the wall", which -/// is not necessarily monotonic as it may be reset. +/// WASI System Clock is a clock API intended to let users query the current +/// time. The clock is not necessarily monotonic as it may be reset. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. /// -/// A wall clock is a clock which measures the date and time according to -/// some external reference. -/// /// External references may be reset, so this clock is not necessarily /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -@since(version = 0.3.0-rc-2025-09-16) -interface wall-clock { - /// A time and date in seconds plus nanoseconds. - @since(version = 0.3.0-rc-2025-09-16) - record datetime { - seconds: u64, +@since(version = 0.3.0-rc-2026-01-06) +interface system-clock { + use types.{duration}; + + /// An "instant", or "exact time", is a point in time without regard to any + /// time zone: just the time since a particular external reference point, + /// often called an "epoch". + /// + /// Here, the epoch is 1970-01-01T00:00:00Z, also known as + /// [POSIX's Seconds Since the Epoch], also known as [Unix Time]. + /// + /// Note that even if the seconds field is negative, incrementing + /// nanoseconds always represents moving forwards in time. + /// For example, `{ -1 seconds, 999999999 nanoseconds }` represents the + /// instant one nanosecond before the epoch. + /// For more on various different ways to represent time, see + /// https://tc39.es/proposal-temporal/docs/timezone.html + /// + /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 + /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + @since(version = 0.3.0-rc-2026-01-06) + record instant { + seconds: s64, nanoseconds: u32, } @@ -80,84 +93,69 @@ interface wall-clock { /// This clock is not monotonic, therefore calling this function repeatedly /// will not necessarily produce a sequence of non-decreasing values. /// - /// The returned timestamps represent the number of seconds since - /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], - /// also known as [Unix Time]. - /// /// The nanoseconds field of the output is always less than 1000000000. - /// - /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 - /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - @since(version = 0.3.0-rc-2025-09-16) - now: func() -> datetime; + @since(version = 0.3.0-rc-2026-01-06) + now: func() -> instant; - /// Query the resolution of the clock. - /// - /// The nanoseconds field of the output is always less than 1000000000. - @since(version = 0.3.0-rc-2025-09-16) - get-resolution: func() -> datetime; + /// Query the resolution of the clock. Returns the smallest duration of time + /// that the implementation permits distinguishing. + @since(version = 0.3.0-rc-2026-01-06) + get-resolution: func() -> duration; } @unstable(feature = clocks-timezone) interface timezone { @unstable(feature = clocks-timezone) - use wall-clock.{datetime}; + use system-clock.{instant}; - /// Information useful for displaying the timezone of a specific `datetime`. + /// Return the IANA identifier of the currently configured timezone. This + /// should be an identifier from the IANA Time Zone Database. + /// + /// For displaying to a user, the identifier should be converted into a + /// localized name by means of an internationalization API. /// - /// This information may vary within a single `timezone` to reflect daylight - /// saving time adjustments. + /// If the implementation does not expose an actual timezone, or is unable + /// to provide mappings from times to deltas between the configured timezone + /// and UTC, or determining the current timezone fails, or the timezone does + /// not have an IANA identifier, this returns nothing. @unstable(feature = clocks-timezone) - record timezone-display { - /// The number of seconds difference between UTC time and the local - /// time of the timezone. - /// - /// The returned value will always be less than 86400 which is the - /// number of seconds in a day (24*60*60). - /// - /// In implementations that do not expose an actual time zone, this - /// should return 0. - utc-offset: s32, - /// The abbreviated name of the timezone to display to a user. The name - /// `UTC` indicates Coordinated Universal Time. Otherwise, this should - /// reference local standards for the name of the time zone. - /// - /// In implementations that do not expose an actual time zone, this - /// should be the string `UTC`. - /// - /// In time zones that do not have an applicable name, a formatted - /// representation of the UTC offset may be returned, such as `-04:00`. - name: string, - /// Whether daylight saving time is active. - /// - /// In implementations that do not expose an actual time zone, this - /// should return false. - in-daylight-saving-time: bool, - } + iana-id: func() -> option; - /// Return information needed to display the given `datetime`. This includes - /// the UTC offset, the time zone name, and a flag indicating whether - /// daylight saving time is active. + /// The number of nanoseconds difference between UTC time and the local + /// time of the currently configured timezone, at the exact time of + /// `instant`. /// - /// If the timezone cannot be determined for the given `datetime`, return a - /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight - /// saving time. + /// The magnitude of the returned value will always be less than + /// 86,400,000,000,000 which is the number of nanoseconds in a day + /// (24*60*60*1e9). + /// + /// If the implementation does not expose an actual timezone, or is unable + /// to provide mappings from times to deltas between the configured timezone + /// and UTC, or determining the current timezone fails, this returns + /// nothing. @unstable(feature = clocks-timezone) - display: func(when: datetime) -> timezone-display; + utc-offset: func(when: instant) -> option; - /// The same as `display`, but only return the UTC offset. + /// Returns a string that is suitable to assist humans in debugging whether + /// any timezone is available, and if so, which. This may be the same string + /// as `iana-id`, or a formatted representation of the UTC offset such as + /// `-04:00`, or something else. + /// + /// WARNING: The returned string should not be consumed mechanically! It may + /// change across platforms, hosts, or other implementation details. Parsing + /// this string is a major platform-compatibility hazard. @unstable(feature = clocks-timezone) - utc-offset: func(when: datetime) -> s32; + to-debug-string: func() -> string; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) world imports { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import types; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import monotonic-clock; - @since(version = 0.3.0-rc-2025-09-16) - import wall-clock; + @since(version = 0.3.0-rc-2026-01-06) + import system-clock; @unstable(feature = clocks-timezone) import timezone; } diff --git a/crates/wasi-http/src/p3/wit/deps/filesystem.wit b/crates/wasi-http/src/p3/wit/deps/filesystem.wit index 94c87628d0d7..0ac149cb7ceb 100644 --- a/crates/wasi-http/src/p3/wit/deps/filesystem.wit +++ b/crates/wasi-http/src/p3/wit/deps/filesystem.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.3.0-rc-2025-09-16; +package wasi:filesystem@0.3.0-rc-2026-01-06; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without @@ -24,19 +24,19 @@ package wasi:filesystem@0.3.0-rc-2025-09-16; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface types { - @since(version = 0.3.0-rc-2025-09-16) - use wasi:clocks/wall-clock@0.3.0-rc-2025-09-16.{datetime}; + @since(version = 0.3.0-rc-2026-01-06) + use wasi:clocks/system-clock@0.3.0-rc-2026-01-06.{instant}; /// File size or length of a region within a file. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -60,7 +60,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -102,7 +102,7 @@ interface types { } /// Flags determining the method of how paths are resolved. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -110,7 +110,7 @@ interface types { } /// Open flags used by `open-at`. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -123,13 +123,13 @@ interface types { } /// Number of hard links to an inode. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) type link-count = u64; /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) record descriptor-stat { /// File type. %type: descriptor-type, @@ -142,21 +142,21 @@ interface types { /// /// If the `option` is none, the platform doesn't maintain an access /// timestamp for this file. - data-access-timestamp: option, + data-access-timestamp: option, /// Last data modification timestamp. /// /// If the `option` is none, the platform doesn't maintain a /// modification timestamp for this file. - data-modification-timestamp: option, + data-modification-timestamp: option, /// Last file status-change timestamp. /// /// If the `option` is none, the platform doesn't maintain a /// status-change timestamp for this file. - status-change-timestamp: option, + status-change-timestamp: option, } /// When setting a timestamp, this gives the value to set it to. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -164,7 +164,7 @@ interface types { /// with the filesystem. now, /// Set the timestamp to the given value. - timestamp(datetime), + timestamp(instant), } /// A directory entry. @@ -255,7 +255,7 @@ interface types { } /// File or memory access pattern advisory information. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -279,7 +279,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -290,7 +290,7 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) resource descriptor { /// Return a stream for reading from a file. /// @@ -308,7 +308,7 @@ interface types { /// resolves to `err` with an `error-code`. /// /// Note: This is similar to `pread` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) read-via-stream: func(offset: filesize) -> tuple, future>>; /// Return a stream for writing to a file, if available. /// @@ -322,7 +322,7 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `pwrite` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) write-via-stream: async func(data: stream, offset: filesize) -> result<_, error-code>; /// Return a stream for appending to a file, if available. /// @@ -332,12 +332,12 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `write` with `O_APPEND` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) append-via-stream: async func(data: stream) -> result<_, error-code>; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) advise: async func(offset: filesize, length: filesize, advice: advice) -> result<_, error-code>; /// Synchronize the data of a file to disk. /// @@ -345,7 +345,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) sync-data: async func() -> result<_, error-code>; /// Get flags associated with a descriptor. /// @@ -353,7 +353,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-flags: async func() -> result; /// Get the dynamic type of a descriptor. /// @@ -365,20 +365,20 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-type: async func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-size: async func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. /// /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-times: async func(data-access-timestamp: new-timestamp, data-modification-timestamp: new-timestamp) -> result<_, error-code>; /// Read directory entries from a directory. /// @@ -392,7 +392,7 @@ interface types { /// /// This function returns a future, which will resolve to an error code if /// reading full contents of the directory fails. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) read-directory: async func() -> tuple, future>>; /// Synchronize the data and metadata of a file to disk. /// @@ -400,12 +400,12 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) sync: async func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) create-directory-at: async func(path: string) -> result<_, error-code>; /// Return the attributes of an open file or directory. /// @@ -416,7 +416,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) stat: async func() -> result; /// Return the attributes of a file or directory. /// @@ -425,7 +425,7 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) stat-at: async func(path-flags: path-flags, path: string) -> result; /// Adjust the timestamps of a file or directory. /// @@ -433,7 +433,7 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-times-at: async func(path-flags: path-flags, path: string, data-access-timestamp: new-timestamp, data-modification-timestamp: new-timestamp) -> result<_, error-code>; /// Create a hard link. /// @@ -442,7 +442,7 @@ interface types { /// `error-code::not-permitted` if the old path is not a file. /// /// Note: This is similar to `linkat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) link-at: async func(old-path-flags: path-flags, old-path: string, new-descriptor: borrow, new-path: string) -> result<_, error-code>; /// Open a file or directory. /// @@ -456,7 +456,7 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) open-at: async func(path-flags: path-flags, path: string, open-flags: open-flags, %flags: descriptor-flags) -> result; /// Read the contents of a symbolic link. /// @@ -464,19 +464,19 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) readlink-at: async func(path: string) -> result; /// Remove a directory. /// /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) remove-directory-at: async func(path: string) -> result<_, error-code>; /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) rename-at: async func(old-path: string, new-descriptor: borrow, new-path: string) -> result<_, error-code>; /// Create a symbolic link (also known as a "symlink"). /// @@ -484,13 +484,13 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) symlink-at: async func(old-path: string, new-path: string) -> result<_, error-code>; /// Unlink a filesystem object that is not a directory. /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) unlink-file-at: async func(path: string) -> result<_, error-code>; /// Test whether two descriptors refer to the same filesystem object. /// @@ -498,7 +498,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) is-same-object: async func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred /// to by a descriptor. @@ -519,33 +519,35 @@ interface types { /// computed hash. /// /// However, none of these is required. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) metadata-hash: async func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) metadata-hash-at: async func(path-flags: path-flags, path: string) -> result; } } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface preopens { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) use types.{descriptor}; /// Return the set of preopened directories, and their paths. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-directories: func() -> list>; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) world imports { - @since(version = 0.3.0-rc-2025-09-16) - import wasi:clocks/wall-clock@0.3.0-rc-2025-09-16; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) + import wasi:clocks/types@0.3.0-rc-2026-01-06; + @since(version = 0.3.0-rc-2026-01-06) + import wasi:clocks/system-clock@0.3.0-rc-2026-01-06; + @since(version = 0.3.0-rc-2026-01-06) import types; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import preopens; } diff --git a/crates/wasi-http/src/p3/wit/deps/http.wit b/crates/wasi-http/src/p3/wit/deps/http.wit index b20ad64bbb06..3860af767887 100644 --- a/crates/wasi-http/src/p3/wit/deps/http.wit +++ b/crates/wasi-http/src/p3/wit/deps/http.wit @@ -1,9 +1,9 @@ -package wasi:http@0.3.0-rc-2025-09-16; +package wasi:http@0.3.0-rc-2026-01-06; /// This interface defines all of the types and methods for implementing HTTP /// Requests and Responses, as well as their headers, trailers, and bodies. interface types { - use wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16.{duration}; + use wasi:clocks/types@0.3.0-rc-2026-01-06.{duration}; /// This type corresponds to HTTP standard Methods. variant method { @@ -376,55 +376,82 @@ interface types { } } -/// This interface defines a handler of HTTP Requests. It may be imported by -/// components which wish to send HTTP Requests and also exported by components -/// which can respond to HTTP Requests. In addition, it may be used to pass -/// a request from one component to another without any use of a network. +/// This interface defines a handler of HTTP Requests. +/// +/// In a `wasi:http/service` this interface is exported to respond to an +/// incoming HTTP Request with a Response. +/// +/// In `wasi:http/middleware` this interface is both exported and imported as +/// the "downstream" and "upstream" directions of the middleware chain. interface handler { use types.{request, response, error-code}; - /// When exported, this function may be called with either an incoming - /// request read from the network or a request synthesized or forwarded by - /// another component. - /// - /// When imported, this function may be used to either send an outgoing - /// request over the network or pass it to another component. + /// This function may be called with either an incoming request read from the + /// network or a request synthesized or forwarded by another component. handle: async func(request: request) -> result; } -/// The `wasi:http/imports` world imports all the APIs for HTTP proxies. -/// It is intended to be `include`d in other worlds. -world imports { - import wasi:random/random@0.3.0-rc-2025-09-16; - import wasi:cli/types@0.3.0-rc-2025-09-16; - import wasi:cli/stdout@0.3.0-rc-2025-09-16; - import wasi:cli/stderr@0.3.0-rc-2025-09-16; - import wasi:cli/stdin@0.3.0-rc-2025-09-16; - import wasi:clocks/types@0.3.0-rc-2025-09-16; - import wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16; +/// This interface defines an HTTP client for sending "outgoing" requests. +/// +/// Most components are expected to import this interface to provide the +/// capability to send HTTP requests to arbitrary destinations on a network. +/// +/// The type signature of `client.send` is the same as `handler.handle`. This +/// duplication is currently necessary because some Component Model tooling +/// (including WIT itself) is unable to represent a component importing two +/// instances of the same interface. A `client.send` import may be linked +/// directly to a `handler.handle` export to bypass the network. +interface client { + use types.{request, response, error-code}; + + /// This function may be used to either send an outgoing request over the + /// network or to forward it to another component. + send: async func(request: request) -> result; +} + +/// The `wasi:http/service` world captures a broad category of HTTP services +/// including web applications, API servers, and proxies. It may be `include`d +/// in more specific worlds such as `wasi:http/middleware`. +world service { + import wasi:cli/types@0.3.0-rc-2026-01-06; + import wasi:cli/stdout@0.3.0-rc-2026-01-06; + import wasi:cli/stderr@0.3.0-rc-2026-01-06; + import wasi:cli/stdin@0.3.0-rc-2026-01-06; + import wasi:clocks/types@0.3.0-rc-2026-01-06; import types; - import handler; - import wasi:clocks/wall-clock@0.3.0-rc-2025-09-16; + import client; + import wasi:clocks/monotonic-clock@0.3.0-rc-2026-01-06; + import wasi:clocks/system-clock@0.3.0-rc-2026-01-06; @unstable(feature = clocks-timezone) - import wasi:clocks/timezone@0.3.0-rc-2025-09-16; + import wasi:clocks/timezone@0.3.0-rc-2026-01-06; + import wasi:random/random@0.3.0-rc-2026-01-06; + import wasi:random/insecure@0.3.0-rc-2026-01-06; + import wasi:random/insecure-seed@0.3.0-rc-2026-01-06; + + export handler; } -/// The `wasi:http/proxy` world captures a widely-implementable intersection of -/// hosts that includes HTTP forward and reverse proxies. Components targeting -/// this world may concurrently stream in and out any number of incoming and -/// outgoing HTTP requests. -world proxy { - import wasi:random/random@0.3.0-rc-2025-09-16; - import wasi:cli/types@0.3.0-rc-2025-09-16; - import wasi:cli/stdout@0.3.0-rc-2025-09-16; - import wasi:cli/stderr@0.3.0-rc-2025-09-16; - import wasi:cli/stdin@0.3.0-rc-2025-09-16; - import wasi:clocks/types@0.3.0-rc-2025-09-16; - import wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16; +/// The `wasi:http/middleware` world captures HTTP services that forward HTTP +/// Requests to another handler. +/// +/// Components may implement this world to allow them to participate in handler +/// "chains" where a `request` flows through handlers on its way to some terminal +/// `service` and corresponding `response` flows in the opposite direction. +world middleware { + import wasi:clocks/types@0.3.0-rc-2026-01-06; import types; import handler; - import wasi:clocks/wall-clock@0.3.0-rc-2025-09-16; + import wasi:cli/types@0.3.0-rc-2026-01-06; + import wasi:cli/stdout@0.3.0-rc-2026-01-06; + import wasi:cli/stderr@0.3.0-rc-2026-01-06; + import wasi:cli/stdin@0.3.0-rc-2026-01-06; + import client; + import wasi:clocks/monotonic-clock@0.3.0-rc-2026-01-06; + import wasi:clocks/system-clock@0.3.0-rc-2026-01-06; @unstable(feature = clocks-timezone) - import wasi:clocks/timezone@0.3.0-rc-2025-09-16; + import wasi:clocks/timezone@0.3.0-rc-2026-01-06; + import wasi:random/random@0.3.0-rc-2026-01-06; + import wasi:random/insecure@0.3.0-rc-2026-01-06; + import wasi:random/insecure-seed@0.3.0-rc-2026-01-06; export handler; } diff --git a/crates/wasi-http/src/p3/wit/deps/random.wit b/crates/wasi-http/src/p3/wit/deps/random.wit index 8dfc39b11b1b..8bb873145186 100644 --- a/crates/wasi-http/src/p3/wit/deps/random.wit +++ b/crates/wasi-http/src/p3/wit/deps/random.wit @@ -1,10 +1,10 @@ -package wasi:random@0.3.0-rc-2025-09-16; +package wasi:random@0.3.0-rc-2026-01-06; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -23,7 +23,7 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-insecure-seed: func() -> tuple; } @@ -31,7 +31,7 @@ interface insecure-seed { /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -41,14 +41,14 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-insecure-random-u64: func() -> u64; } @@ -56,7 +56,7 @@ interface insecure { /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -70,23 +70,23 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-random-u64: func() -> u64; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) world imports { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import random; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import insecure; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import insecure-seed; } diff --git a/crates/wasi-http/src/p3/wit/deps/sockets.wit b/crates/wasi-http/src/p3/wit/deps/sockets.wit index f3a7e86e2ecd..d7ebe150b49f 100644 --- a/crates/wasi-http/src/p3/wit/deps/sockets.wit +++ b/crates/wasi-http/src/p3/wit/deps/sockets.wit @@ -1,9 +1,9 @@ -package wasi:sockets@0.3.0-rc-2025-09-16; +package wasi:sockets@0.3.0-rc-2026-01-06; -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface types { - @since(version = 0.3.0-rc-2025-09-16) - use wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16.{duration}; + @since(version = 0.3.0-rc-2026-01-06) + use wasi:clocks/types@0.3.0-rc-2026-01-06.{duration}; /// Error codes. /// @@ -16,7 +16,7 @@ interface types { /// - `out-of-memory` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) enum error-code { /// Unknown error unknown, @@ -57,7 +57,7 @@ interface types { datagram-too-large, } - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) enum ip-address-family { /// Similar to `AF_INET` in POSIX. ipv4, @@ -65,19 +65,19 @@ interface types { ipv6, } - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) type ipv4-address = tuple; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) type ipv6-address = tuple; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) variant ip-address { ipv4(ipv4-address), ipv6(ipv6-address), } - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) record ipv4-socket-address { /// sin_port port: u16, @@ -85,7 +85,7 @@ interface types { address: ipv4-address, } - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) record ipv6-socket-address { /// sin6_port port: u16, @@ -97,7 +97,7 @@ interface types { scope-id: u32, } - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) variant ip-socket-address { ipv4(ipv4-socket-address), ipv6(ipv6-socket-address), @@ -122,7 +122,7 @@ interface types { /// In addition to the general error codes documented on the /// `types::error-code` type, TCP socket methods may always return /// `error(invalid-state)` when in the `closed` state. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) resource tcp-socket { /// Create a new TCP socket. /// @@ -138,7 +138,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. /// @@ -171,7 +171,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Connect to a remote endpoint. /// @@ -202,7 +202,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) connect: async func(remote-address: ip-socket-address) -> result<_, error-code>; /// Start listening and return a stream of new inbound connections. /// @@ -268,7 +268,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) listen: func() -> result, error-code>; /// Transmit data to peer. /// @@ -290,7 +290,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) send: async func(data: stream) -> result<_, error-code>; /// Read data from peer. /// @@ -323,7 +323,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) receive: func() -> tuple, future>>; /// Get the bound local address. /// @@ -341,7 +341,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-local-address: func() -> result; /// Get the remote address. /// @@ -353,19 +353,19 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-remote-address: func() -> result; /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-is-listening: func() -> bool; /// Whether this is a IPv4 or IPv6 socket. /// /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-address-family: func() -> ip-address-family; /// Hints the desired listen queue size. Implementations are free to ignore this. /// @@ -376,7 +376,7 @@ interface types { /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is in the `connecting` or `connected` state. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. /// @@ -387,9 +387,9 @@ interface types { /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. /// /// Equivalent to the SO_KEEPALIVE socket option. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-keep-alive-enabled: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. /// @@ -401,9 +401,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-keep-alive-idle-time: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; /// The time between keepalive packets. /// @@ -415,9 +415,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-keep-alive-interval: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-keep-alive-interval: func(value: duration) -> result<_, error-code>; /// The maximum amount of keepalive packets TCP should send before aborting the connection. /// @@ -429,9 +429,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-keep-alive-count: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-keep-alive-count: func(value: u32) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// @@ -439,9 +439,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-hop-limit: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. /// @@ -453,18 +453,18 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-receive-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-send-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } /// A UDP socket handle. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) resource udp-socket { /// Create a new UDP socket. /// @@ -480,7 +480,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. /// @@ -500,7 +500,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Associate this socket with a specific peer address. /// @@ -538,7 +538,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) connect: func(remote-address: ip-socket-address) -> result<_, error-code>; /// Dissociate this socket from its peer address. /// @@ -555,7 +555,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) disconnect: func() -> result<_, error-code>; /// Send a message on the socket to a particular peer. /// @@ -588,7 +588,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) send: async func(data: list, remote-address: option) -> result<_, error-code>; /// Receive a message on the socket. /// @@ -613,7 +613,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) receive: async func() -> result, ip-socket-address>, error-code>; /// Get the current bound address. /// @@ -631,7 +631,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-local-address: func() -> result; /// Get the address the socket is currently "connected" to. /// @@ -643,14 +643,14 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. /// /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-address-family: func() -> ip-address-family; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// @@ -658,9 +658,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-unicast-hop-limit: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. /// @@ -672,24 +672,24 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-receive-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-send-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface ip-name-lookup { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) use types.{ip-address}; /// Lookup error codes. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) enum error-code { /// Unknown error unknown, @@ -737,18 +737,16 @@ interface ip-name-lookup { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) resolve-addresses: async func(name: string) -> result, error-code>; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) world imports { - @since(version = 0.3.0-rc-2025-09-16) - import wasi:clocks/types@0.3.0-rc-2025-09-16; - @since(version = 0.3.0-rc-2025-09-16) - import wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) + import wasi:clocks/types@0.3.0-rc-2026-01-06; + @since(version = 0.3.0-rc-2026-01-06) import types; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import ip-name-lookup; } diff --git a/crates/wasi-http/src/p3/wit/world.wit b/crates/wasi-http/src/p3/wit/world.wit index 17d3ee0e5765..2c47442e8c3e 100644 --- a/crates/wasi-http/src/p3/wit/world.wit +++ b/crates/wasi-http/src/p3/wit/world.wit @@ -2,5 +2,5 @@ package wasmtime:wasi-http; world bindings { - include wasi:http/proxy@0.3.0-rc-2025-09-16; + include wasi:http/service@0.3.0-rc-2026-01-06; } diff --git a/crates/wasi-http/tests/all/p3/mod.rs b/crates/wasi-http/tests/all/p3/mod.rs index b1d8273f180a..9e66b452e6d6 100644 --- a/crates/wasi-http/tests/all/p3/mod.rs +++ b/crates/wasi-http/tests/all/p3/mod.rs @@ -17,7 +17,7 @@ use wasmtime::component::{Component, Linker, ResourceTable}; use wasmtime::{Result, Store, error::Context as _, format_err}; use wasmtime_wasi::p3::bindings::Command; use wasmtime_wasi::{TrappableError, WasiCtx, WasiCtxBuilder, WasiCtxView, WasiView}; -use wasmtime_wasi_http::p3::bindings::Proxy; +use wasmtime_wasi_http::p3::bindings::Service; use wasmtime_wasi_http::p3::bindings::http::types::ErrorCode; use wasmtime_wasi_http::p3::{ self, Request, RequestOptions, WasiHttpCtx, WasiHttpCtxView, WasiHttpView, @@ -166,7 +166,7 @@ async fn run_http + 'static>( wasmtime_wasi::p3::add_to_linker(&mut linker).context("failed to link `wasi:cli@0.3.x`")?; wasmtime_wasi_http::p3::add_to_linker(&mut linker) .context("failed to link `wasi:http@0.3.x`")?; - let proxy = Proxy::instantiate_async(&mut store, &component, &linker).await?; + let service = Service::instantiate_async(&mut store, &component, &linker).await?; let (req, io) = Request::from_http(req); let (tx, rx) = tokio::sync::oneshot::channel(); let ((handle_result, ()), res) = try_join!( @@ -175,7 +175,7 @@ async fn run_http + 'static>( .run_concurrent(async |store| { try_join!( async { - let (res, task) = match proxy.handle(store, req).await? { + let (res, task) = match service.handle(store, req).await? { Ok(pair) => pair, Err(err) => return Ok(Err(Some(err))), }; @@ -359,6 +359,8 @@ async fn compose(a: &[u8], b: &[u8]) -> Result> { let b_file = dir.path().join("b.wasm"); fs::write(&b_file, b).await?; + // The middleware imports `wasi:http/handler` which matches the echo's + // `wasi:http/handler` export, so wasm-compose can link them automatically. ComponentComposer::new( &a_file, &wasm_compose::config::Config { @@ -411,7 +413,7 @@ async fn test_http_middleware_with_chain(host_to_host: bool) -> Result<()> { "local:local/chain-http".to_owned(), InstantiationArg { instance: "local:local/chain-http".into(), - export: Some("wasi:http/handler@0.3.0-rc-2025-09-16".into()), + export: Some("wasi:http/handler@0.3.0-rc-2026-01-06".into()), }, )] .into_iter() diff --git a/crates/wasi/src/clocks.rs b/crates/wasi/src/clocks.rs index 9639d11d87e7..27d729dc0865 100644 --- a/crates/wasi/src/clocks.rs +++ b/crates/wasi/src/clocks.rs @@ -1,6 +1,8 @@ use cap_std::time::{Duration, Instant, SystemClock, SystemTime}; use cap_std::{AmbientAuthority, ambient_authority}; use cap_time_ext::{MonotonicClockExt as _, SystemClockExt as _}; +use std::error::Error; +use std::fmt; use wasmtime::component::{HasData, ResourceTable}; /// A helper struct which implements [`HasData`] for the `wasi:clocks` APIs. @@ -162,20 +164,51 @@ pub fn wall_clock() -> Box { } pub(crate) struct Datetime { - pub seconds: u64, + pub seconds: i64, pub nanoseconds: u32, } impl TryFrom for Datetime { - type Error = wasmtime::Error; + type Error = DatetimeError; fn try_from(time: SystemTime) -> Result { - let duration = - time.duration_since(SystemTime::from_std(std::time::SystemTime::UNIX_EPOCH))?; + let epoch = SystemTime::from_std(std::time::SystemTime::UNIX_EPOCH); + + if time >= epoch { + let duration = time.duration_since(epoch)?; + Ok(Self { + seconds: duration.as_secs().try_into()?, + nanoseconds: duration.subsec_nanos(), + }) + } else { + let duration = epoch.duration_since(time)?; + Ok(Self { + seconds: -duration.as_secs().try_into()?, + nanoseconds: duration.subsec_nanos(), + }) + } + } +} + +#[derive(Debug)] +pub struct DatetimeError; + +impl fmt::Display for DatetimeError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("couldn't represent time as a WASI `Datetime`") + } +} + +impl Error for DatetimeError {} + +impl From for DatetimeError { + fn from(_: std::time::SystemTimeError) -> Self { + DatetimeError + } +} - Ok(Self { - seconds: duration.as_secs(), - nanoseconds: duration.subsec_nanos(), - }) +impl From for DatetimeError { + fn from(_: std::num::TryFromIntError) -> Self { + DatetimeError } } diff --git a/crates/wasi/src/p2/host/clocks.rs b/crates/wasi/src/p2/host/clocks.rs index f4ec0d99fe2a..609783577894 100644 --- a/crates/wasi/src/p2/host/clocks.rs +++ b/crates/wasi/src/p2/host/clocks.rs @@ -9,40 +9,44 @@ use std::time::Duration; use wasmtime::component::Resource; use wasmtime_wasi_io::poll::{Pollable, subscribe}; -impl From for Datetime { - fn from( +impl TryFrom for Datetime { + type Error = crate::clocks::DatetimeError; + + fn try_from( crate::clocks::Datetime { seconds, nanoseconds, }: crate::clocks::Datetime, - ) -> Self { - Self { - seconds, + ) -> Result { + Ok(Self { + seconds: seconds.try_into()?, nanoseconds, - } + }) } } -impl From for crate::clocks::Datetime { - fn from( +impl TryFrom for crate::clocks::Datetime { + type Error = crate::clocks::DatetimeError; + + fn try_from( Datetime { seconds, nanoseconds, }: Datetime, - ) -> Self { - Self { - seconds, + ) -> Result { + Ok(Self { + seconds: seconds.try_into()?, nanoseconds, - } + }) } } impl TryFrom for Datetime { - type Error = wasmtime::Error; + type Error = crate::clocks::DatetimeError; fn try_from(time: SystemTime) -> Result { let time = crate::clocks::Datetime::try_from(time)?; - Ok(time.into()) + time.try_into() } } diff --git a/crates/wasi/src/p2/host/filesystem.rs b/crates/wasi/src/p2/host/filesystem.rs index 1bd63d3b3f62..c785b325ac48 100644 --- a/crates/wasi/src/p2/host/filesystem.rs +++ b/crates/wasi/src/p2/host/filesystem.rs @@ -235,7 +235,7 @@ impl HostDescriptor for WasiFilesystemCtxView<'_> { async fn stat(&mut self, fd: Resource) -> FsResult { let descriptor = self.table.get(&fd)?; let stat = descriptor.stat().await?; - Ok(stat.into()) + Ok(stat.try_into()?) } async fn stat_at( @@ -246,7 +246,7 @@ impl HostDescriptor for WasiFilesystemCtxView<'_> { ) -> FsResult { let d = self.table.get(&fd)?.dir()?; let stat = d.stat_at(path_flags.into(), path).await?; - Ok(stat.into()) + Ok(stat.try_into()?) } async fn set_times_at( @@ -576,8 +576,10 @@ impl From for types::MetadataHashValue { } } -impl From for types::DescriptorStat { - fn from( +impl TryFrom for types::DescriptorStat { + type Error = ErrorCode; + + fn try_from( crate::filesystem::DescriptorStat { type_, link_count, @@ -586,15 +588,17 @@ impl From for types::DescriptorStat { data_modification_timestamp, status_change_timestamp, }: crate::filesystem::DescriptorStat, - ) -> Self { - Self { + ) -> Result { + Ok(Self { type_: type_.into(), link_count, size, - data_access_timestamp: data_access_timestamp.map(Into::into), - data_modification_timestamp: data_modification_timestamp.map(Into::into), - status_change_timestamp: status_change_timestamp.map(Into::into), - } + data_access_timestamp: data_access_timestamp.map(|t| t.try_into()).transpose()?, + data_modification_timestamp: data_modification_timestamp + .map(|t| t.try_into()) + .transpose()?, + status_change_timestamp: status_change_timestamp.map(|t| t.try_into()).transpose()?, + }) } } @@ -758,6 +762,12 @@ fn systemtimespec_from( } } +impl From for ErrorCode { + fn from(_: crate::clocks::DatetimeError) -> ErrorCode { + ErrorCode::Overflow + } +} + #[cfg(test)] mod test { use super::*; diff --git a/crates/wasi/src/p3/bindings.rs b/crates/wasi/src/p3/bindings.rs index ab90a1279150..2e2391737760 100644 --- a/crates/wasi/src/p3/bindings.rs +++ b/crates/wasi/src/p3/bindings.rs @@ -23,7 +23,7 @@ //! // An example of extending the `wasi:cli/command` world with a //! // custom host interface. //! world my-world { -//! include wasi:cli/command@0.3.0-rc-2025-09-16; +//! include wasi:cli/command@0.3.0-rc-2026-01-06; //! //! import custom-host; //! } diff --git a/crates/wasi/src/p3/clocks/host.rs b/crates/wasi/src/p3/clocks/host.rs index e374c8a18f60..517e01eae666 100644 --- a/crates/wasi/src/p3/clocks/host.rs +++ b/crates/wasi/src/p3/clocks/host.rs @@ -1,32 +1,31 @@ use crate::clocks::WasiClocksCtxView; -use crate::p3::bindings::clocks::{monotonic_clock, wall_clock}; +use crate::p3::bindings::clocks::{monotonic_clock, system_clock, types}; use crate::p3::clocks::WasiClocks; use core::time::Duration; use tokio::time::sleep; use wasmtime::component::Accessor; -impl wall_clock::Host for WasiClocksCtxView<'_> { - fn now(&mut self) -> wasmtime::Result { +impl types::Host for WasiClocksCtxView<'_> {} + +impl system_clock::Host for WasiClocksCtxView<'_> { + fn now(&mut self) -> wasmtime::Result { let now = self.ctx.wall_clock.now(); - Ok(wall_clock::Datetime { - seconds: now.as_secs(), + Ok(system_clock::Instant { + seconds: now.as_secs().try_into()?, nanoseconds: now.subsec_nanos(), }) } - fn get_resolution(&mut self) -> wasmtime::Result { + fn get_resolution(&mut self) -> wasmtime::Result { let res = self.ctx.wall_clock.resolution(); - Ok(wall_clock::Datetime { - seconds: res.as_secs(), - nanoseconds: res.subsec_nanos(), - }) + Ok(res.as_nanos().try_into()?) } } impl monotonic_clock::HostWithStore for WasiClocks { async fn wait_until( store: &Accessor, - when: monotonic_clock::Instant, + when: monotonic_clock::Mark, ) -> wasmtime::Result<()> { let clock_now = store.with(|mut view| view.get().ctx.monotonic_clock.now()); if when > clock_now { @@ -37,7 +36,7 @@ impl monotonic_clock::HostWithStore for WasiClocks { async fn wait_for( _store: &Accessor, - duration: monotonic_clock::Duration, + duration: types::Duration, ) -> wasmtime::Result<()> { if duration > 0 { sleep(Duration::from_nanos(duration)).await; @@ -47,11 +46,11 @@ impl monotonic_clock::HostWithStore for WasiClocks { } impl monotonic_clock::Host for WasiClocksCtxView<'_> { - fn now(&mut self) -> wasmtime::Result { + fn now(&mut self) -> wasmtime::Result { Ok(self.ctx.monotonic_clock.now()) } - fn get_resolution(&mut self) -> wasmtime::Result { + fn get_resolution(&mut self) -> wasmtime::Result { Ok(self.ctx.monotonic_clock.resolution()) } } diff --git a/crates/wasi/src/p3/clocks/mod.rs b/crates/wasi/src/p3/clocks/mod.rs index 3c7ecdb58dd4..4cde6e9f71a9 100644 --- a/crates/wasi/src/p3/clocks/mod.rs +++ b/crates/wasi/src/p3/clocks/mod.rs @@ -1,8 +1,7 @@ mod host; use crate::clocks::{WasiClocks, WasiClocksView}; -use crate::p3::bindings::clocks::{monotonic_clock, wall_clock}; -use cap_std::time::SystemTime; +use crate::p3::bindings::clocks::{monotonic_clock, system_clock, types}; use wasmtime::component::Linker; /// Add all WASI interfaces from this module into the `linker` provided. @@ -58,12 +57,13 @@ pub fn add_to_linker(linker: &mut Linker) -> wasmtime::Result<()> where T: WasiClocksView + 'static, { + types::add_to_linker::<_, WasiClocks>(linker, T::clocks)?; monotonic_clock::add_to_linker::<_, WasiClocks>(linker, T::clocks)?; - wall_clock::add_to_linker::<_, WasiClocks>(linker, T::clocks)?; + system_clock::add_to_linker::<_, WasiClocks>(linker, T::clocks)?; Ok(()) } -impl From for wall_clock::Datetime { +impl From for system_clock::Instant { fn from( crate::clocks::Datetime { seconds, @@ -77,12 +77,12 @@ impl From for wall_clock::Datetime { } } -impl From for crate::clocks::Datetime { +impl From for crate::clocks::Datetime { fn from( - wall_clock::Datetime { + system_clock::Instant { seconds, nanoseconds, - }: wall_clock::Datetime, + }: system_clock::Instant, ) -> Self { Self { seconds, @@ -90,12 +90,3 @@ impl From for crate::clocks::Datetime { } } } - -impl TryFrom for wall_clock::Datetime { - type Error = wasmtime::Error; - - fn try_from(time: SystemTime) -> Result { - let time = crate::clocks::Datetime::try_from(time)?; - Ok(time.into()) - } -} diff --git a/crates/wasi/src/p3/filesystem/host.rs b/crates/wasi/src/p3/filesystem/host.rs index 0c4e0c294bda..3da6f5c1081a 100644 --- a/crates/wasi/src/p3/filesystem/host.rs +++ b/crates/wasi/src/p3/filesystem/host.rs @@ -1,5 +1,5 @@ use crate::filesystem::{Descriptor, Dir, File, WasiFilesystem, WasiFilesystemCtxView}; -use crate::p3::bindings::clocks::wall_clock; +use crate::p3::bindings::clocks::system_clock; use crate::p3::bindings::filesystem::types::{ self, Advice, DescriptorFlags, DescriptorStat, DescriptorType, DirectoryEntry, ErrorCode, Filesize, MetadataHashValue, NewTimestamp, OpenFlags, PathFlags, @@ -96,10 +96,19 @@ impl AccessorExt for Accessor { } } -fn systemtime_from(t: wall_clock::Datetime) -> Result { - std::time::SystemTime::UNIX_EPOCH - .checked_add(core::time::Duration::new(t.seconds, t.nanoseconds)) - .ok_or(ErrorCode::Overflow) +fn systemtime_from(t: system_clock::Instant) -> Result { + if let Ok(seconds) = t.seconds.try_into() { + std::time::SystemTime::UNIX_EPOCH + .checked_add(core::time::Duration::new(seconds, t.nanoseconds)) + .ok_or(ErrorCode::Overflow) + } else { + std::time::SystemTime::UNIX_EPOCH + .checked_sub(core::time::Duration::new( + t.seconds.unsigned_abs(), + t.nanoseconds, + )) + .ok_or(ErrorCode::Overflow) + } } fn systemtimespec_from(t: NewTimestamp) -> Result, ErrorCode> { diff --git a/crates/wasi/src/p3/wit/deps/cli.wit b/crates/wasi/src/p3/wit/deps/cli.wit index 5bee32e5a57f..0f987bf38b81 100644 --- a/crates/wasi/src/p3/wit/deps/cli.wit +++ b/crates/wasi/src/p3/wit/deps/cli.wit @@ -1,6 +1,6 @@ -package wasi:cli@0.3.0-rc-2025-09-16; +package wasi:cli@0.3.0-rc-2026-01-06; -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface environment { /// Get the POSIX-style environment variables. /// @@ -10,23 +10,23 @@ interface environment { /// Morally, these are a value import, but until value imports are available /// in the component model, this import function should return the same /// values each time it is called. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-environment: func() -> list>; /// Get the POSIX-style arguments to the program. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-arguments: func() -> list; /// Return a path that programs should use as their initial current working /// directory, interpreting `.` as shorthand for this. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-initial-cwd: func() -> option; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface exit { /// Exit the current instance and any linked instances. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) exit: func(status: result); /// Exit the current instance and any linked instances, reporting the @@ -41,16 +41,16 @@ interface exit { exit-with-code: func(status-code: u8); } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface run { /// Run the program. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) run: async func() -> result; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface types { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) enum error-code { /// Input/output error io, @@ -61,7 +61,7 @@ interface types { } } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface stdin { use types.{error-code}; @@ -78,11 +78,11 @@ interface stdin { /// /// Multiple streams may be active at the same time. The behavior of concurrent /// reads is implementation-specific. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) read-via-stream: func() -> tuple, future>>; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface stdout { use types.{error-code}; @@ -94,11 +94,11 @@ interface stdout { /// /// Otherwise if there is an error the readable end of the stream will be /// dropped and this function will return an error-code. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) write-via-stream: async func(data: stream) -> result<_, error-code>; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface stderr { use types.{error-code}; @@ -110,7 +110,7 @@ interface stderr { /// /// Otherwise if there is an error the readable end of the stream will be /// dropped and this function will return an error-code. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) write-via-stream: async func(data: stream) -> result<_, error-code>; } @@ -119,10 +119,10 @@ interface stderr { /// In the future, this may include functions for disabling echoing, /// disabling input buffering so that keyboard events are sent through /// immediately, querying supported features, and so on. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface terminal-input { /// The input side of a terminal. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) resource terminal-input; } @@ -131,126 +131,126 @@ interface terminal-input { /// In the future, this may include functions for querying the terminal /// size, being notified of terminal size changes, querying supported /// features, and so on. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface terminal-output { /// The output side of a terminal. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) resource terminal-output; } /// An interface providing an optional `terminal-input` for stdin as a /// link-time authority. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface terminal-stdin { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) use terminal-input.{terminal-input}; /// If stdin is connected to a terminal, return a `terminal-input` handle /// allowing further interaction with it. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-terminal-stdin: func() -> option; } /// An interface providing an optional `terminal-output` for stdout as a /// link-time authority. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface terminal-stdout { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) use terminal-output.{terminal-output}; /// If stdout is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-terminal-stdout: func() -> option; } /// An interface providing an optional `terminal-output` for stderr as a /// link-time authority. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface terminal-stderr { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) use terminal-output.{terminal-output}; /// If stderr is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-terminal-stderr: func() -> option; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) world imports { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import environment; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import exit; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import types; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import stdin; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import stdout; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import stderr; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-input; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-output; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-stdin; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-stdout; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-stderr; - import wasi:clocks/types@0.3.0-rc-2025-09-16; - import wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16; - import wasi:clocks/wall-clock@0.3.0-rc-2025-09-16; + import wasi:clocks/types@0.3.0-rc-2026-01-06; + import wasi:clocks/monotonic-clock@0.3.0-rc-2026-01-06; + import wasi:clocks/system-clock@0.3.0-rc-2026-01-06; @unstable(feature = clocks-timezone) - import wasi:clocks/timezone@0.3.0-rc-2025-09-16; - import wasi:filesystem/types@0.3.0-rc-2025-09-16; - import wasi:filesystem/preopens@0.3.0-rc-2025-09-16; - import wasi:sockets/types@0.3.0-rc-2025-09-16; - import wasi:sockets/ip-name-lookup@0.3.0-rc-2025-09-16; - import wasi:random/random@0.3.0-rc-2025-09-16; - import wasi:random/insecure@0.3.0-rc-2025-09-16; - import wasi:random/insecure-seed@0.3.0-rc-2025-09-16; + import wasi:clocks/timezone@0.3.0-rc-2026-01-06; + import wasi:filesystem/types@0.3.0-rc-2026-01-06; + import wasi:filesystem/preopens@0.3.0-rc-2026-01-06; + import wasi:sockets/types@0.3.0-rc-2026-01-06; + import wasi:sockets/ip-name-lookup@0.3.0-rc-2026-01-06; + import wasi:random/random@0.3.0-rc-2026-01-06; + import wasi:random/insecure@0.3.0-rc-2026-01-06; + import wasi:random/insecure-seed@0.3.0-rc-2026-01-06; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) world command { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import environment; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import exit; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import types; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import stdin; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import stdout; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import stderr; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-input; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-output; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-stdin; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-stdout; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import terminal-stderr; - import wasi:clocks/types@0.3.0-rc-2025-09-16; - import wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16; - import wasi:clocks/wall-clock@0.3.0-rc-2025-09-16; + import wasi:clocks/types@0.3.0-rc-2026-01-06; + import wasi:clocks/monotonic-clock@0.3.0-rc-2026-01-06; + import wasi:clocks/system-clock@0.3.0-rc-2026-01-06; @unstable(feature = clocks-timezone) - import wasi:clocks/timezone@0.3.0-rc-2025-09-16; - import wasi:filesystem/types@0.3.0-rc-2025-09-16; - import wasi:filesystem/preopens@0.3.0-rc-2025-09-16; - import wasi:sockets/types@0.3.0-rc-2025-09-16; - import wasi:sockets/ip-name-lookup@0.3.0-rc-2025-09-16; - import wasi:random/random@0.3.0-rc-2025-09-16; - import wasi:random/insecure@0.3.0-rc-2025-09-16; - import wasi:random/insecure-seed@0.3.0-rc-2025-09-16; + import wasi:clocks/timezone@0.3.0-rc-2026-01-06; + import wasi:filesystem/types@0.3.0-rc-2026-01-06; + import wasi:filesystem/preopens@0.3.0-rc-2026-01-06; + import wasi:sockets/types@0.3.0-rc-2026-01-06; + import wasi:sockets/ip-name-lookup@0.3.0-rc-2026-01-06; + import wasi:random/random@0.3.0-rc-2026-01-06; + import wasi:random/insecure@0.3.0-rc-2026-01-06; + import wasi:random/insecure-seed@0.3.0-rc-2026-01-06; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) export run; } diff --git a/crates/wasi/src/p3/wit/deps/clocks.wit b/crates/wasi/src/p3/wit/deps/clocks.wit index 8e631f9a5d81..fc59f5a21e2a 100644 --- a/crates/wasi/src/p3/wit/deps/clocks.wit +++ b/crates/wasi/src/p3/wit/deps/clocks.wit @@ -1,10 +1,10 @@ -package wasi:clocks@0.3.0-rc-2025-09-16; +package wasi:clocks@0.3.0-rc-2026-01-06; /// This interface common types used throughout wasi:clocks. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface types { /// A duration of time, in nanoseconds. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) type duration = u64; } @@ -16,15 +16,15 @@ interface types { /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface monotonic-clock { use types.{duration}; - /// An instant in time, in nanoseconds. An instant is relative to an + /// A mark on a monotonic clock is a number of nanoseconds since an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. - @since(version = 0.3.0-rc-2025-09-16) - type instant = u64; + @since(version = 0.3.0-rc-2026-01-06) + type mark = u64; /// Read the current value of the clock. /// @@ -32,46 +32,59 @@ interface monotonic-clock { /// produce a sequence of non-decreasing values. /// /// For completeness, this function traps if it's not possible to represent - /// the value of the clock in an `instant`. Consequently, implementations + /// the value of the clock in a `mark`. Consequently, implementations /// should ensure that the starting time is low enough to avoid the /// possibility of overflow in practice. - @since(version = 0.3.0-rc-2025-09-16) - now: func() -> instant; + @since(version = 0.3.0-rc-2026-01-06) + now: func() -> mark; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-resolution: func() -> duration; - /// Wait until the specified instant has occurred. - @since(version = 0.3.0-rc-2025-09-16) - wait-until: async func(when: instant); + /// Wait until the specified mark has occurred. + @since(version = 0.3.0-rc-2026-01-06) + wait-until: async func(when: mark); /// Wait for the specified duration to elapse. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) wait-for: async func(how-long: duration); } -/// WASI Wall Clock is a clock API intended to let users query the current -/// time. The name "wall" makes an analogy to a "clock on the wall", which -/// is not necessarily monotonic as it may be reset. +/// WASI System Clock is a clock API intended to let users query the current +/// time. The clock is not necessarily monotonic as it may be reset. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. /// -/// A wall clock is a clock which measures the date and time according to -/// some external reference. -/// /// External references may be reset, so this clock is not necessarily /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -@since(version = 0.3.0-rc-2025-09-16) -interface wall-clock { - /// A time and date in seconds plus nanoseconds. - @since(version = 0.3.0-rc-2025-09-16) - record datetime { - seconds: u64, +@since(version = 0.3.0-rc-2026-01-06) +interface system-clock { + use types.{duration}; + + /// An "instant", or "exact time", is a point in time without regard to any + /// time zone: just the time since a particular external reference point, + /// often called an "epoch". + /// + /// Here, the epoch is 1970-01-01T00:00:00Z, also known as + /// [POSIX's Seconds Since the Epoch], also known as [Unix Time]. + /// + /// Note that even if the seconds field is negative, incrementing + /// nanoseconds always represents moving forwards in time. + /// For example, `{ -1 seconds, 999999999 nanoseconds }` represents the + /// instant one nanosecond before the epoch. + /// For more on various different ways to represent time, see + /// https://tc39.es/proposal-temporal/docs/timezone.html + /// + /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 + /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + @since(version = 0.3.0-rc-2026-01-06) + record instant { + seconds: s64, nanoseconds: u32, } @@ -80,84 +93,69 @@ interface wall-clock { /// This clock is not monotonic, therefore calling this function repeatedly /// will not necessarily produce a sequence of non-decreasing values. /// - /// The returned timestamps represent the number of seconds since - /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], - /// also known as [Unix Time]. - /// /// The nanoseconds field of the output is always less than 1000000000. - /// - /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 - /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - @since(version = 0.3.0-rc-2025-09-16) - now: func() -> datetime; + @since(version = 0.3.0-rc-2026-01-06) + now: func() -> instant; - /// Query the resolution of the clock. - /// - /// The nanoseconds field of the output is always less than 1000000000. - @since(version = 0.3.0-rc-2025-09-16) - get-resolution: func() -> datetime; + /// Query the resolution of the clock. Returns the smallest duration of time + /// that the implementation permits distinguishing. + @since(version = 0.3.0-rc-2026-01-06) + get-resolution: func() -> duration; } @unstable(feature = clocks-timezone) interface timezone { @unstable(feature = clocks-timezone) - use wall-clock.{datetime}; + use system-clock.{instant}; - /// Information useful for displaying the timezone of a specific `datetime`. + /// Return the IANA identifier of the currently configured timezone. This + /// should be an identifier from the IANA Time Zone Database. + /// + /// For displaying to a user, the identifier should be converted into a + /// localized name by means of an internationalization API. /// - /// This information may vary within a single `timezone` to reflect daylight - /// saving time adjustments. + /// If the implementation does not expose an actual timezone, or is unable + /// to provide mappings from times to deltas between the configured timezone + /// and UTC, or determining the current timezone fails, or the timezone does + /// not have an IANA identifier, this returns nothing. @unstable(feature = clocks-timezone) - record timezone-display { - /// The number of seconds difference between UTC time and the local - /// time of the timezone. - /// - /// The returned value will always be less than 86400 which is the - /// number of seconds in a day (24*60*60). - /// - /// In implementations that do not expose an actual time zone, this - /// should return 0. - utc-offset: s32, - /// The abbreviated name of the timezone to display to a user. The name - /// `UTC` indicates Coordinated Universal Time. Otherwise, this should - /// reference local standards for the name of the time zone. - /// - /// In implementations that do not expose an actual time zone, this - /// should be the string `UTC`. - /// - /// In time zones that do not have an applicable name, a formatted - /// representation of the UTC offset may be returned, such as `-04:00`. - name: string, - /// Whether daylight saving time is active. - /// - /// In implementations that do not expose an actual time zone, this - /// should return false. - in-daylight-saving-time: bool, - } + iana-id: func() -> option; - /// Return information needed to display the given `datetime`. This includes - /// the UTC offset, the time zone name, and a flag indicating whether - /// daylight saving time is active. + /// The number of nanoseconds difference between UTC time and the local + /// time of the currently configured timezone, at the exact time of + /// `instant`. /// - /// If the timezone cannot be determined for the given `datetime`, return a - /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight - /// saving time. + /// The magnitude of the returned value will always be less than + /// 86,400,000,000,000 which is the number of nanoseconds in a day + /// (24*60*60*1e9). + /// + /// If the implementation does not expose an actual timezone, or is unable + /// to provide mappings from times to deltas between the configured timezone + /// and UTC, or determining the current timezone fails, this returns + /// nothing. @unstable(feature = clocks-timezone) - display: func(when: datetime) -> timezone-display; + utc-offset: func(when: instant) -> option; - /// The same as `display`, but only return the UTC offset. + /// Returns a string that is suitable to assist humans in debugging whether + /// any timezone is available, and if so, which. This may be the same string + /// as `iana-id`, or a formatted representation of the UTC offset such as + /// `-04:00`, or something else. + /// + /// WARNING: The returned string should not be consumed mechanically! It may + /// change across platforms, hosts, or other implementation details. Parsing + /// this string is a major platform-compatibility hazard. @unstable(feature = clocks-timezone) - utc-offset: func(when: datetime) -> s32; + to-debug-string: func() -> string; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) world imports { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import types; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import monotonic-clock; - @since(version = 0.3.0-rc-2025-09-16) - import wall-clock; + @since(version = 0.3.0-rc-2026-01-06) + import system-clock; @unstable(feature = clocks-timezone) import timezone; } diff --git a/crates/wasi/src/p3/wit/deps/filesystem.wit b/crates/wasi/src/p3/wit/deps/filesystem.wit index 94c87628d0d7..0ac149cb7ceb 100644 --- a/crates/wasi/src/p3/wit/deps/filesystem.wit +++ b/crates/wasi/src/p3/wit/deps/filesystem.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.3.0-rc-2025-09-16; +package wasi:filesystem@0.3.0-rc-2026-01-06; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without @@ -24,19 +24,19 @@ package wasi:filesystem@0.3.0-rc-2025-09-16; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface types { - @since(version = 0.3.0-rc-2025-09-16) - use wasi:clocks/wall-clock@0.3.0-rc-2025-09-16.{datetime}; + @since(version = 0.3.0-rc-2026-01-06) + use wasi:clocks/system-clock@0.3.0-rc-2026-01-06.{instant}; /// File size or length of a region within a file. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -60,7 +60,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -102,7 +102,7 @@ interface types { } /// Flags determining the method of how paths are resolved. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -110,7 +110,7 @@ interface types { } /// Open flags used by `open-at`. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -123,13 +123,13 @@ interface types { } /// Number of hard links to an inode. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) type link-count = u64; /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) record descriptor-stat { /// File type. %type: descriptor-type, @@ -142,21 +142,21 @@ interface types { /// /// If the `option` is none, the platform doesn't maintain an access /// timestamp for this file. - data-access-timestamp: option, + data-access-timestamp: option, /// Last data modification timestamp. /// /// If the `option` is none, the platform doesn't maintain a /// modification timestamp for this file. - data-modification-timestamp: option, + data-modification-timestamp: option, /// Last file status-change timestamp. /// /// If the `option` is none, the platform doesn't maintain a /// status-change timestamp for this file. - status-change-timestamp: option, + status-change-timestamp: option, } /// When setting a timestamp, this gives the value to set it to. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -164,7 +164,7 @@ interface types { /// with the filesystem. now, /// Set the timestamp to the given value. - timestamp(datetime), + timestamp(instant), } /// A directory entry. @@ -255,7 +255,7 @@ interface types { } /// File or memory access pattern advisory information. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -279,7 +279,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -290,7 +290,7 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) resource descriptor { /// Return a stream for reading from a file. /// @@ -308,7 +308,7 @@ interface types { /// resolves to `err` with an `error-code`. /// /// Note: This is similar to `pread` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) read-via-stream: func(offset: filesize) -> tuple, future>>; /// Return a stream for writing to a file, if available. /// @@ -322,7 +322,7 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `pwrite` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) write-via-stream: async func(data: stream, offset: filesize) -> result<_, error-code>; /// Return a stream for appending to a file, if available. /// @@ -332,12 +332,12 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `write` with `O_APPEND` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) append-via-stream: async func(data: stream) -> result<_, error-code>; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) advise: async func(offset: filesize, length: filesize, advice: advice) -> result<_, error-code>; /// Synchronize the data of a file to disk. /// @@ -345,7 +345,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) sync-data: async func() -> result<_, error-code>; /// Get flags associated with a descriptor. /// @@ -353,7 +353,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-flags: async func() -> result; /// Get the dynamic type of a descriptor. /// @@ -365,20 +365,20 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-type: async func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-size: async func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. /// /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-times: async func(data-access-timestamp: new-timestamp, data-modification-timestamp: new-timestamp) -> result<_, error-code>; /// Read directory entries from a directory. /// @@ -392,7 +392,7 @@ interface types { /// /// This function returns a future, which will resolve to an error code if /// reading full contents of the directory fails. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) read-directory: async func() -> tuple, future>>; /// Synchronize the data and metadata of a file to disk. /// @@ -400,12 +400,12 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) sync: async func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) create-directory-at: async func(path: string) -> result<_, error-code>; /// Return the attributes of an open file or directory. /// @@ -416,7 +416,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) stat: async func() -> result; /// Return the attributes of a file or directory. /// @@ -425,7 +425,7 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) stat-at: async func(path-flags: path-flags, path: string) -> result; /// Adjust the timestamps of a file or directory. /// @@ -433,7 +433,7 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-times-at: async func(path-flags: path-flags, path: string, data-access-timestamp: new-timestamp, data-modification-timestamp: new-timestamp) -> result<_, error-code>; /// Create a hard link. /// @@ -442,7 +442,7 @@ interface types { /// `error-code::not-permitted` if the old path is not a file. /// /// Note: This is similar to `linkat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) link-at: async func(old-path-flags: path-flags, old-path: string, new-descriptor: borrow, new-path: string) -> result<_, error-code>; /// Open a file or directory. /// @@ -456,7 +456,7 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) open-at: async func(path-flags: path-flags, path: string, open-flags: open-flags, %flags: descriptor-flags) -> result; /// Read the contents of a symbolic link. /// @@ -464,19 +464,19 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) readlink-at: async func(path: string) -> result; /// Remove a directory. /// /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) remove-directory-at: async func(path: string) -> result<_, error-code>; /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) rename-at: async func(old-path: string, new-descriptor: borrow, new-path: string) -> result<_, error-code>; /// Create a symbolic link (also known as a "symlink"). /// @@ -484,13 +484,13 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) symlink-at: async func(old-path: string, new-path: string) -> result<_, error-code>; /// Unlink a filesystem object that is not a directory. /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) unlink-file-at: async func(path: string) -> result<_, error-code>; /// Test whether two descriptors refer to the same filesystem object. /// @@ -498,7 +498,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) is-same-object: async func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred /// to by a descriptor. @@ -519,33 +519,35 @@ interface types { /// computed hash. /// /// However, none of these is required. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) metadata-hash: async func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) metadata-hash-at: async func(path-flags: path-flags, path: string) -> result; } } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface preopens { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) use types.{descriptor}; /// Return the set of preopened directories, and their paths. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-directories: func() -> list>; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) world imports { - @since(version = 0.3.0-rc-2025-09-16) - import wasi:clocks/wall-clock@0.3.0-rc-2025-09-16; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) + import wasi:clocks/types@0.3.0-rc-2026-01-06; + @since(version = 0.3.0-rc-2026-01-06) + import wasi:clocks/system-clock@0.3.0-rc-2026-01-06; + @since(version = 0.3.0-rc-2026-01-06) import types; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import preopens; } diff --git a/crates/wasi/src/p3/wit/deps/random.wit b/crates/wasi/src/p3/wit/deps/random.wit index 8dfc39b11b1b..8bb873145186 100644 --- a/crates/wasi/src/p3/wit/deps/random.wit +++ b/crates/wasi/src/p3/wit/deps/random.wit @@ -1,10 +1,10 @@ -package wasi:random@0.3.0-rc-2025-09-16; +package wasi:random@0.3.0-rc-2026-01-06; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -23,7 +23,7 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-insecure-seed: func() -> tuple; } @@ -31,7 +31,7 @@ interface insecure-seed { /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -41,14 +41,14 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-insecure-random-u64: func() -> u64; } @@ -56,7 +56,7 @@ interface insecure { /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -70,23 +70,23 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-random-u64: func() -> u64; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) world imports { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import random; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import insecure; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import insecure-seed; } diff --git a/crates/wasi/src/p3/wit/deps/sockets.wit b/crates/wasi/src/p3/wit/deps/sockets.wit index f3a7e86e2ecd..d7ebe150b49f 100644 --- a/crates/wasi/src/p3/wit/deps/sockets.wit +++ b/crates/wasi/src/p3/wit/deps/sockets.wit @@ -1,9 +1,9 @@ -package wasi:sockets@0.3.0-rc-2025-09-16; +package wasi:sockets@0.3.0-rc-2026-01-06; -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface types { - @since(version = 0.3.0-rc-2025-09-16) - use wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16.{duration}; + @since(version = 0.3.0-rc-2026-01-06) + use wasi:clocks/types@0.3.0-rc-2026-01-06.{duration}; /// Error codes. /// @@ -16,7 +16,7 @@ interface types { /// - `out-of-memory` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) enum error-code { /// Unknown error unknown, @@ -57,7 +57,7 @@ interface types { datagram-too-large, } - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) enum ip-address-family { /// Similar to `AF_INET` in POSIX. ipv4, @@ -65,19 +65,19 @@ interface types { ipv6, } - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) type ipv4-address = tuple; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) type ipv6-address = tuple; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) variant ip-address { ipv4(ipv4-address), ipv6(ipv6-address), } - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) record ipv4-socket-address { /// sin_port port: u16, @@ -85,7 +85,7 @@ interface types { address: ipv4-address, } - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) record ipv6-socket-address { /// sin6_port port: u16, @@ -97,7 +97,7 @@ interface types { scope-id: u32, } - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) variant ip-socket-address { ipv4(ipv4-socket-address), ipv6(ipv6-socket-address), @@ -122,7 +122,7 @@ interface types { /// In addition to the general error codes documented on the /// `types::error-code` type, TCP socket methods may always return /// `error(invalid-state)` when in the `closed` state. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) resource tcp-socket { /// Create a new TCP socket. /// @@ -138,7 +138,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. /// @@ -171,7 +171,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Connect to a remote endpoint. /// @@ -202,7 +202,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) connect: async func(remote-address: ip-socket-address) -> result<_, error-code>; /// Start listening and return a stream of new inbound connections. /// @@ -268,7 +268,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) listen: func() -> result, error-code>; /// Transmit data to peer. /// @@ -290,7 +290,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) send: async func(data: stream) -> result<_, error-code>; /// Read data from peer. /// @@ -323,7 +323,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) receive: func() -> tuple, future>>; /// Get the bound local address. /// @@ -341,7 +341,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-local-address: func() -> result; /// Get the remote address. /// @@ -353,19 +353,19 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-remote-address: func() -> result; /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-is-listening: func() -> bool; /// Whether this is a IPv4 or IPv6 socket. /// /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-address-family: func() -> ip-address-family; /// Hints the desired listen queue size. Implementations are free to ignore this. /// @@ -376,7 +376,7 @@ interface types { /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is in the `connecting` or `connected` state. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. /// @@ -387,9 +387,9 @@ interface types { /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. /// /// Equivalent to the SO_KEEPALIVE socket option. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-keep-alive-enabled: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. /// @@ -401,9 +401,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-keep-alive-idle-time: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; /// The time between keepalive packets. /// @@ -415,9 +415,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-keep-alive-interval: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-keep-alive-interval: func(value: duration) -> result<_, error-code>; /// The maximum amount of keepalive packets TCP should send before aborting the connection. /// @@ -429,9 +429,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-keep-alive-count: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-keep-alive-count: func(value: u32) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// @@ -439,9 +439,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-hop-limit: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. /// @@ -453,18 +453,18 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-receive-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-send-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } /// A UDP socket handle. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) resource udp-socket { /// Create a new UDP socket. /// @@ -480,7 +480,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. /// @@ -500,7 +500,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Associate this socket with a specific peer address. /// @@ -538,7 +538,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) connect: func(remote-address: ip-socket-address) -> result<_, error-code>; /// Dissociate this socket from its peer address. /// @@ -555,7 +555,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) disconnect: func() -> result<_, error-code>; /// Send a message on the socket to a particular peer. /// @@ -588,7 +588,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) send: async func(data: list, remote-address: option) -> result<_, error-code>; /// Receive a message on the socket. /// @@ -613,7 +613,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) receive: async func() -> result, ip-socket-address>, error-code>; /// Get the current bound address. /// @@ -631,7 +631,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-local-address: func() -> result; /// Get the address the socket is currently "connected" to. /// @@ -643,14 +643,14 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. /// /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-address-family: func() -> ip-address-family; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// @@ -658,9 +658,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-unicast-hop-limit: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. /// @@ -672,24 +672,24 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-receive-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) get-send-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) interface ip-name-lookup { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) use types.{ip-address}; /// Lookup error codes. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) enum error-code { /// Unknown error unknown, @@ -737,18 +737,16 @@ interface ip-name-lookup { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) resolve-addresses: async func(name: string) -> result, error-code>; } -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2026-01-06) world imports { - @since(version = 0.3.0-rc-2025-09-16) - import wasi:clocks/types@0.3.0-rc-2025-09-16; - @since(version = 0.3.0-rc-2025-09-16) - import wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) + import wasi:clocks/types@0.3.0-rc-2026-01-06; + @since(version = 0.3.0-rc-2026-01-06) import types; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2026-01-06) import ip-name-lookup; } diff --git a/src/commands/serve.rs b/src/commands/serve.rs index 7510efbe3aea..98d8b36368dd 100644 --- a/src/commands/serve.rs +++ b/src/commands/serve.rs @@ -431,7 +431,7 @@ impl ServeCommand { let instance = linker.instantiate_pre(&component)?; #[cfg(feature = "component-model-async")] - let instance = match wasmtime_wasi_http::p3::bindings::ProxyPre::new(instance.clone()) { + let instance = match wasmtime_wasi_http::p3::bindings::ServicePre::new(instance.clone()) { Ok(pre) => ProxyPre::P3(pre), Err(_) => ProxyPre::P2(p2::ProxyPre::new(instance)?), }; diff --git a/tests/wasi.rs b/tests/wasi.rs index fffe64b37a79..a404c58e7e86 100644 --- a/tests/wasi.rs +++ b/tests/wasi.rs @@ -93,6 +93,10 @@ const KNOWN_FAILURES: &[&str] = &[ "multi-clock-wait", "monotonic-clock", "filesystem-advise", + // Wasmtime's snapshot of WASIp3 APIs is different than what these tests are + // expecting. + "wall-clock", + "http-response", ]; fn main() -> Result<()> {