From e9b604b4a73cff99a8bb0093a9f9f41566ffcaa4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 28 May 2026 12:37:28 -0700 Subject: [PATCH 1/6] Document concurrent instance reuse in `wasi:http/service` This commit adds a documentation block to the `wasi:http/service` world that's the result of discussions in today's WASI subgroup meeting, #918, and #919. The documentation here indicates a few properties around concurrent instance reuse, namely: * Guests should expect to be concurrently reused. If this is not acceptable then guests should disable reuse through backpressure mechanisms. * Guests should ensure that outgoing HTTP requests are done within the context of the original root task, or the original invocation of `handler`. If guests can't implement this then they're expected to use backpressure mechanisms instead. The overall conclusion of the various discussions that have happened over the past week or so is that it's not possible to provide the attribute behavior some hosts require exclusively through either in-guest interactions or pure-host interactions. Instead being able to reliably provide accurate attribution requires specifically outlining guidelines for both guests and hosts. The mechanism intended to be used for attribution is then: * For hosts such as Wasmtime calls to imports will be able to reflect on the current async call stack, notably the root export task. Hosts can then use this to correlate an identifier provided when a root task is created, providing a strong link from the import call to whatever export initiated it. This is expected to work as-is for some guest languages, such as Rust, but this is also not a bulletproof solution. Guests can always internally call imports from any currently-running task, and additionally languages such as JS and Go at this time are structured in such a way where imports are not always naturally called from the originating export task. * To enable languages like JS and Go to be able to leverage concurrent reuse while providing accurate attribution of outgoing requests to incoming requests, the plan is to eventually add and specify intrinsics on the component model level to, in a scoped fashion, mutate the async call stack. For example a guest would be able to say "I'm about to do some work for this component model task". When Wasmtime reflects on the async call graph at that time it'd see this and understand that the attribution needs to be slightly adjusted to what it would otherwise by default be. The goal with these addition is to enable hosts to be able to reliably expect to attribute outgoing requests to incoming requests (via async call graph inspection), provide guests the ability to work today (either naturally or disabling concurrent reuse via backpressure), and ensure that well-behaved and idiomatic guests can work reliably with concurrent reuse in the long-run (via component model intrinsics to massage the async backtrace that hosts operate with). When this is all combined it's expected to resolve the concerns of #918 and #919 with idiomatic bindings in guests and hosts alike. Closes #918 Closes #919 --- proposals/http/wit-0.3.0-draft/worlds.wit | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/proposals/http/wit-0.3.0-draft/worlds.wit b/proposals/http/wit-0.3.0-draft/worlds.wit index 9917e054..6543db78 100644 --- a/proposals/http/wit-0.3.0-draft/worlds.wit +++ b/proposals/http/wit-0.3.0-draft/worlds.wit @@ -31,6 +31,32 @@ world service { /// /// This may also be used to receive synthesized or forwarded requests from /// another component. + /// + /// # Concurrent instance reuse + /// + /// Hosts may concurrently invoke this `handler` interface multiple times, + /// even when previous requests have yet to finish processing. This means that + /// the guest, if it blocks, may be required to service multiple requests at + /// the same time. Guests can opt-out of this behavior with component-model + /// backpressure to avoid sending more requests to this instance while a + /// previous one is being processed, however. + /// + /// Another requirement that hosts place on guests implementing this + /// interface, in addition to being able to concurrently invoke it, is that + /// the guest sends outgoing HTTP requests, via the `client` import above + /// or the `handler` import in the `middleware` world, in such a way that the + /// host can accurately attribute which invocation of `handler` induced the + /// outgoing HTTP request to be sent. This requirement enables embedders, + /// for example, to correctly implement the CDN-Loop header automatically and + /// ensure that outgoing requests correctly build on incoming requests. In + /// general this is not a hard requirement that embedders can rely on, but + /// well-behaved guests are expected to provide this guarantee. Hosts which + /// require a hard guarantee regardless of guest will not invoke `handler` + /// more than once concurrently. Guests which export `handler` are expected to + /// ensure that calls to imported interfaces happen on the same component + /// model task that the `handler` was originally invoked on. If guests cannot + /// provide this guarantee then they're expected to opt-out of concurrent + /// through the component model's backpressure mechanisms. export handler; } From f9b39902a47343f35e00ccc40d0fc0a8b20f2458 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 1 Jun 2026 07:08:47 -0700 Subject: [PATCH 2/6] Review comments --- proposals/http/wit-0.3.0-draft/worlds.wit | 46 +++++++++++++---------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/worlds.wit b/proposals/http/wit-0.3.0-draft/worlds.wit index 6543db78..6c581d56 100644 --- a/proposals/http/wit-0.3.0-draft/worlds.wit +++ b/proposals/http/wit-0.3.0-draft/worlds.wit @@ -36,27 +36,33 @@ world service { /// /// Hosts may concurrently invoke this `handler` interface multiple times, /// even when previous requests have yet to finish processing. This means that - /// the guest, if it blocks, may be required to service multiple requests at - /// the same time. Guests can opt-out of this behavior with component-model - /// backpressure to avoid sending more requests to this instance while a - /// previous one is being processed, however. + /// the guest, if it becomes idle while being blocked on I/O, may be required + /// to service multiple requests at the same time. Guests can opt-out of + /// this behavior with component-model backpressure to avoid sending more + /// requests to this instance while a previous one is being processed, + /// however. /// - /// Another requirement that hosts place on guests implementing this - /// interface, in addition to being able to concurrently invoke it, is that - /// the guest sends outgoing HTTP requests, via the `client` import above - /// or the `handler` import in the `middleware` world, in such a way that the - /// host can accurately attribute which invocation of `handler` induced the - /// outgoing HTTP request to be sent. This requirement enables embedders, - /// for example, to correctly implement the CDN-Loop header automatically and - /// ensure that outgoing requests correctly build on incoming requests. In - /// general this is not a hard requirement that embedders can rely on, but - /// well-behaved guests are expected to provide this guarantee. Hosts which - /// require a hard guarantee regardless of guest will not invoke `handler` - /// more than once concurrently. Guests which export `handler` are expected to - /// ensure that calls to imported interfaces happen on the same component - /// model task that the `handler` was originally invoked on. If guests cannot - /// provide this guarantee then they're expected to opt-out of concurrent - /// through the component model's backpressure mechanisms. + /// In some contexts, correct attribution of resource usage and I/O operations + /// is an important requirement. For example, correct implementation of the + /// CDN-Loop header in the context of a proxy server requires that outgoing + /// HTTP requests can be attributed to the incoming HTTP request that induced + /// them. + /// + /// Hosts with this requirement must associate work happening on the same + /// component model task that the `handler` was originally invoked on with the + /// same incoming HTTP request. + /// + /// Conversely, guests must ensure that calls to imported interfaces happen on + /// the same component model task that the `handler` was originally invoked + /// on. Guest runtime implementations that do not provide this guarantee are + /// expected to opt-out of concurrent through the component model's + /// backpressure mechanisms. + /// + /// Note that hosts can't rely on this guarantee being upheld by all guests, + /// and shouldn't treat it as part of their security model. Instead, the + /// combination of the above host and guest requirements enable hosts to + /// enforce correctness properties on behalf of the overall system a guest is + /// part of. export handler; } From d587e8213b8e409a002714755353c17894416fb7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 10 Jun 2026 15:23:35 -0500 Subject: [PATCH 3/6] Apply suggestions from code review Co-authored-by: Joel Dice --- proposals/http/wit-0.3.0-draft/worlds.wit | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/worlds.wit b/proposals/http/wit-0.3.0-draft/worlds.wit index 6c581d56..58431b95 100644 --- a/proposals/http/wit-0.3.0-draft/worlds.wit +++ b/proposals/http/wit-0.3.0-draft/worlds.wit @@ -52,10 +52,10 @@ world service { /// component model task that the `handler` was originally invoked on with the /// same incoming HTTP request. /// - /// Conversely, guests must ensure that calls to imported interfaces happen on + /// Conversely, guests should ensure that calls to imported interfaces happen on /// the same component model task that the `handler` was originally invoked /// on. Guest runtime implementations that do not provide this guarantee are - /// expected to opt-out of concurrent through the component model's + /// encouraged to opt-out of concurrent through the component model's /// backpressure mechanisms. /// /// Note that hosts can't rely on this guarantee being upheld by all guests, From 94e017faeec09fc5de64a37b20fe996350e9b44c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 10 Jun 2026 15:59:33 -0500 Subject: [PATCH 4/6] Update proposals/http/wit-0.3.0-draft/worlds.wit Co-authored-by: Joel Dice --- proposals/http/wit-0.3.0-draft/worlds.wit | 234 +++++++++++----------- 1 file changed, 117 insertions(+), 117 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/worlds.wit b/proposals/http/wit-0.3.0-draft/worlds.wit index 58431b95..0f1aa686 100644 --- a/proposals/http/wit-0.3.0-draft/worlds.wit +++ b/proposals/http/wit-0.3.0-draft/worlds.wit @@ -1,118 +1,118 @@ -package wasi:http@0.3.0-rc-2026-03-15; - -/// 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`. -@since(version = 0.3.0-rc-2026-03-15) -world service { - /// HTTP services have access to time and randomness. - include wasi:clocks/imports@0.3.0-rc-2026-03-15; - include wasi:random/imports@0.3.0-rc-2026-03-15; - - /// Services have standard output and error streams which are expected to - /// terminate in a developer-facing console provided by the host. - import wasi:cli/stdout@0.3.0-rc-2026-03-15; - import wasi:cli/stderr@0.3.0-rc-2026-03-15; - - /// TODO: this is a temporary workaround until component tooling is able to - /// gracefully handle the absence of stdin. Hosts must return an eof stream - /// for this import, which is what wasi-libc + tooling will do automatically - /// when this import is properly removed. - import wasi:cli/stdin@0.3.0-rc-2026-03-15; - - /// This is the default `client` to use when user code simply wants to make an - /// HTTP request (e.g., via `fetch()`). - import client; - - /// The host delivers incoming HTTP requests to a component by calling the - /// `handle` function of this exported interface. A host may arbitrarily reuse - /// or not reuse component instance when delivering incoming HTTP requests and - /// thus a component must be able to handle 0..N calls to `handle`. - /// - /// This may also be used to receive synthesized or forwarded requests from - /// another component. - /// - /// # Concurrent instance reuse - /// - /// Hosts may concurrently invoke this `handler` interface multiple times, - /// even when previous requests have yet to finish processing. This means that - /// the guest, if it becomes idle while being blocked on I/O, may be required - /// to service multiple requests at the same time. Guests can opt-out of - /// this behavior with component-model backpressure to avoid sending more - /// requests to this instance while a previous one is being processed, - /// however. - /// - /// In some contexts, correct attribution of resource usage and I/O operations - /// is an important requirement. For example, correct implementation of the - /// CDN-Loop header in the context of a proxy server requires that outgoing - /// HTTP requests can be attributed to the incoming HTTP request that induced - /// them. - /// - /// Hosts with this requirement must associate work happening on the same - /// component model task that the `handler` was originally invoked on with the - /// same incoming HTTP request. - /// +package wasi:http@0.3.0-rc-2026-03-15; + +/// 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`. +@since(version = 0.3.0-rc-2026-03-15) +world service { + /// HTTP services have access to time and randomness. + include wasi:clocks/imports@0.3.0-rc-2026-03-15; + include wasi:random/imports@0.3.0-rc-2026-03-15; + + /// Services have standard output and error streams which are expected to + /// terminate in a developer-facing console provided by the host. + import wasi:cli/stdout@0.3.0-rc-2026-03-15; + import wasi:cli/stderr@0.3.0-rc-2026-03-15; + + /// TODO: this is a temporary workaround until component tooling is able to + /// gracefully handle the absence of stdin. Hosts must return an eof stream + /// for this import, which is what wasi-libc + tooling will do automatically + /// when this import is properly removed. + import wasi:cli/stdin@0.3.0-rc-2026-03-15; + + /// This is the default `client` to use when user code simply wants to make an + /// HTTP request (e.g., via `fetch()`). + import client; + + /// The host delivers incoming HTTP requests to a component by calling the + /// `handle` function of this exported interface. A host may arbitrarily reuse + /// or not reuse component instance when delivering incoming HTTP requests and + /// thus a component must be able to handle 0..N calls to `handle`. + /// + /// This may also be used to receive synthesized or forwarded requests from + /// another component. + /// + /// # Concurrent instance reuse + /// + /// Hosts may concurrently invoke this `handler` interface multiple times, + /// even when previous requests have yet to finish processing. This means that + /// the guest, if it becomes idle while being blocked on I/O, may be required + /// to service multiple requests at the same time. Guests can opt-out of + /// this behavior with component-model backpressure to avoid sending more + /// requests to this instance while a previous one is being processed, + /// however. + /// + /// In some contexts, correct attribution of resource usage and I/O operations + /// is an important requirement. For example, correct implementation of the + /// CDN-Loop header in the context of a proxy server requires that outgoing + /// HTTP requests can be attributed to the incoming HTTP request that induced + /// them. + /// + /// Hosts with this requirement must associate work happening on the same + /// component model task that the `handler` was originally invoked on with the + /// same incoming HTTP request. + /// /// Conversely, guests should ensure that calls to imported interfaces happen on - /// the same component model task that the `handler` was originally invoked - /// on. Guest runtime implementations that do not provide this guarantee are - /// encouraged to opt-out of concurrent through the component model's - /// backpressure mechanisms. - /// - /// Note that hosts can't rely on this guarantee being upheld by all guests, - /// and shouldn't treat it as part of their security model. Instead, the - /// combination of the above host and guest requirements enable hosts to - /// enforce correctness properties on behalf of the overall system a guest is - /// part of. - export handler; -} - -/// 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. -@since(version = 0.3.0-rc-2026-03-15) -world middleware { - include service; - import handler; -} - -/// 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. -@since(version = 0.3.0-rc-2026-03-15) -interface handler { - use types.{request, response, error-code}; - - /// 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; -} - -/// 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. -@since(version = 0.3.0-rc-2026-03-15) -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 same component model task that the `handler` was originally invoked + /// on. Guest runtime implementations that do not provide this guarantee are + /// encouraged to opt-out of concurrent reuse through the component model's + /// backpressure mechanisms. + /// + /// Note that hosts can't rely on this guarantee being upheld by all guests, + /// and shouldn't treat it as part of their security model. Instead, the + /// combination of the above host and guest requirements enable hosts to + /// enforce correctness properties on behalf of the overall system a guest is + /// part of. + export handler; +} + +/// 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. +@since(version = 0.3.0-rc-2026-03-15) +world middleware { + include service; + import handler; +} + +/// 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. +@since(version = 0.3.0-rc-2026-03-15) +interface handler { + use types.{request, response, error-code}; + + /// 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; +} + +/// 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. +@since(version = 0.3.0-rc-2026-03-15) +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; +} From 1c9961692afc36981ac85bda8ece42d7bc8af355 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 11 Jun 2026 10:44:04 -0400 Subject: [PATCH 5/6] fix(http): depend on latest fs in dep lock --- proposals/http/wit-0.3.0-draft/deps.lock | 8 +++++--- proposals/http/wit-0.3.0-draft/deps.toml | 3 +++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/deps.lock b/proposals/http/wit-0.3.0-draft/deps.lock index 6c3947e6..1abde0a7 100644 --- a/proposals/http/wit-0.3.0-draft/deps.lock +++ b/proposals/http/wit-0.3.0-draft/deps.lock @@ -1,8 +1,7 @@ [cli] path = "../../cli/wit-0.3.0-draft" -sha256 = "5be8d35b6397517777497279f1978c71aea0d91c7d63d4f4e0b54d0c1d33efd3" -sha512 = "faf89924d5d5210d3b4df52d634deb8507c44c632bc0fd1a6fa4351a15ac36e92a039daf945c59c862ea002a748ac213b27c51affa68a90dbe529551f3d63a9b" -deps = ["filesystem", "random", "sockets"] +sha256 = "ba19261a3c370fcafd06b549ffb0bbcc7efa10f2dd0c1c33ed36c07a25ea6471" +sha512 = "121d0a87bdc9b4bd780a542b3efb74e6d9c972e8c537bde0bb471e06e2d9ca250a30f586d6d94c130c4b4664f9698afa452cc9650a13680c3dc1cf81318da676" [clocks] path = "../../clocks/wit-0.3.0-draft" @@ -10,13 +9,16 @@ sha256 = "a8702c42e23c22a458207d0efa38cc1b64c8c6299b0e3152aa84327a7c1c952b" sha512 = "da69a5d498b6afe0facf77ec3d21f6e8a2a4d4661ebfec310a2ce6f943cb01f92131a746765648febf96563ddac788e9f218941d3db2b905f3746dc8e05cf54d" [filesystem] +path = "../../filesystem/wit-0.3.0-draft" sha256 = "d9db43c43b4e09899a9e54c76544eef17439fb42e2f730ed96d40eac994b0dfd" sha512 = "3b7a1bef322ba36b1e9df768d740e4238f58d3c15d3e4c51fe899b93cf1e6641a79b5a8665ae71d38a80e1e0f852b30b023ecf318f4cbeacb36dd1ae0ac7e37b" [random] +path = "../../random/wit-0.3.0-draft" sha256 = "d44de4e427505fdfd584a23479dba5899ad80aa8e174dc0528df840db8ae9a43" sha512 = "6b08b32a197aee74076d0cdca6a09f78da9040eedd9ab3f64e5f14901ad5a0c5bbc592ad46a0d575dc6705249b3e10a413e09835616f753788aa598af605c776" [sockets] +path = "../../sockets/wit-0.3.0-draft" sha256 = "ee64b45d3826b6ff2cd27f6ac24fe23c41e65ba4d155294671dc7d0a0b47ddfe" sha512 = "dd797ab47b899aee52799f797497fa286f5e217307e8a451a7ba89bd05b7b9bfe2a6e0cf39c0e609ed4c76ed102487adff6e73156340f14baf70a9cc9e48ecbc" diff --git a/proposals/http/wit-0.3.0-draft/deps.toml b/proposals/http/wit-0.3.0-draft/deps.toml index 46265d48..d16cfcda 100644 --- a/proposals/http/wit-0.3.0-draft/deps.toml +++ b/proposals/http/wit-0.3.0-draft/deps.toml @@ -1,2 +1,5 @@ cli = "../../cli/wit-0.3.0-draft" clocks = "../../clocks/wit-0.3.0-draft" +filesystem = "../../filesystem/wit-0.3.0-draft" +random = "../../random/wit-0.3.0-draft" +sockets = "../../sockets/wit-0.3.0-draft" From 98127f5db2c7945d3d11e6788a464659d2227afa Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 11 Jun 2026 11:00:31 -0400 Subject: [PATCH 6/6] fix(http): renormalize to LF --- proposals/http/wit-0.3.0-draft/worlds.wit | 236 +++++++++++----------- 1 file changed, 118 insertions(+), 118 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/worlds.wit b/proposals/http/wit-0.3.0-draft/worlds.wit index 0f1aa686..a7006e71 100644 --- a/proposals/http/wit-0.3.0-draft/worlds.wit +++ b/proposals/http/wit-0.3.0-draft/worlds.wit @@ -1,118 +1,118 @@ -package wasi:http@0.3.0-rc-2026-03-15; - -/// 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`. -@since(version = 0.3.0-rc-2026-03-15) -world service { - /// HTTP services have access to time and randomness. - include wasi:clocks/imports@0.3.0-rc-2026-03-15; - include wasi:random/imports@0.3.0-rc-2026-03-15; - - /// Services have standard output and error streams which are expected to - /// terminate in a developer-facing console provided by the host. - import wasi:cli/stdout@0.3.0-rc-2026-03-15; - import wasi:cli/stderr@0.3.0-rc-2026-03-15; - - /// TODO: this is a temporary workaround until component tooling is able to - /// gracefully handle the absence of stdin. Hosts must return an eof stream - /// for this import, which is what wasi-libc + tooling will do automatically - /// when this import is properly removed. - import wasi:cli/stdin@0.3.0-rc-2026-03-15; - - /// This is the default `client` to use when user code simply wants to make an - /// HTTP request (e.g., via `fetch()`). - import client; - - /// The host delivers incoming HTTP requests to a component by calling the - /// `handle` function of this exported interface. A host may arbitrarily reuse - /// or not reuse component instance when delivering incoming HTTP requests and - /// thus a component must be able to handle 0..N calls to `handle`. - /// - /// This may also be used to receive synthesized or forwarded requests from - /// another component. - /// - /// # Concurrent instance reuse - /// - /// Hosts may concurrently invoke this `handler` interface multiple times, - /// even when previous requests have yet to finish processing. This means that - /// the guest, if it becomes idle while being blocked on I/O, may be required - /// to service multiple requests at the same time. Guests can opt-out of - /// this behavior with component-model backpressure to avoid sending more - /// requests to this instance while a previous one is being processed, - /// however. - /// - /// In some contexts, correct attribution of resource usage and I/O operations - /// is an important requirement. For example, correct implementation of the - /// CDN-Loop header in the context of a proxy server requires that outgoing - /// HTTP requests can be attributed to the incoming HTTP request that induced - /// them. - /// - /// Hosts with this requirement must associate work happening on the same - /// component model task that the `handler` was originally invoked on with the - /// same incoming HTTP request. - /// - /// Conversely, guests should ensure that calls to imported interfaces happen on - /// the same component model task that the `handler` was originally invoked - /// on. Guest runtime implementations that do not provide this guarantee are - /// encouraged to opt-out of concurrent reuse through the component model's - /// backpressure mechanisms. - /// - /// Note that hosts can't rely on this guarantee being upheld by all guests, - /// and shouldn't treat it as part of their security model. Instead, the - /// combination of the above host and guest requirements enable hosts to - /// enforce correctness properties on behalf of the overall system a guest is - /// part of. - export handler; -} - -/// 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. -@since(version = 0.3.0-rc-2026-03-15) -world middleware { - include service; - import handler; -} - -/// 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. -@since(version = 0.3.0-rc-2026-03-15) -interface handler { - use types.{request, response, error-code}; - - /// 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; -} - -/// 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. -@since(version = 0.3.0-rc-2026-03-15) -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; -} +package wasi:http@0.3.0-rc-2026-03-15; + +/// 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`. +@since(version = 0.3.0-rc-2026-03-15) +world service { + /// HTTP services have access to time and randomness. + include wasi:clocks/imports@0.3.0-rc-2026-03-15; + include wasi:random/imports@0.3.0-rc-2026-03-15; + + /// Services have standard output and error streams which are expected to + /// terminate in a developer-facing console provided by the host. + import wasi:cli/stdout@0.3.0-rc-2026-03-15; + import wasi:cli/stderr@0.3.0-rc-2026-03-15; + + /// TODO: this is a temporary workaround until component tooling is able to + /// gracefully handle the absence of stdin. Hosts must return an eof stream + /// for this import, which is what wasi-libc + tooling will do automatically + /// when this import is properly removed. + import wasi:cli/stdin@0.3.0-rc-2026-03-15; + + /// This is the default `client` to use when user code simply wants to make an + /// HTTP request (e.g., via `fetch()`). + import client; + + /// The host delivers incoming HTTP requests to a component by calling the + /// `handle` function of this exported interface. A host may arbitrarily reuse + /// or not reuse component instance when delivering incoming HTTP requests and + /// thus a component must be able to handle 0..N calls to `handle`. + /// + /// This may also be used to receive synthesized or forwarded requests from + /// another component. + /// + /// # Concurrent instance reuse + /// + /// Hosts may concurrently invoke this `handler` interface multiple times, + /// even when previous requests have yet to finish processing. This means that + /// the guest, if it becomes idle while being blocked on I/O, may be required + /// to service multiple requests at the same time. Guests can opt-out of + /// this behavior with component-model backpressure to avoid sending more + /// requests to this instance while a previous one is being processed, + /// however. + /// + /// In some contexts, correct attribution of resource usage and I/O operations + /// is an important requirement. For example, correct implementation of the + /// CDN-Loop header in the context of a proxy server requires that outgoing + /// HTTP requests can be attributed to the incoming HTTP request that induced + /// them. + /// + /// Hosts with this requirement must associate work happening on the same + /// component model task that the `handler` was originally invoked on with the + /// same incoming HTTP request. + /// + /// Conversely, guests should ensure that calls to imported interfaces happen on + /// the same component model task that the `handler` was originally invoked + /// on. Guest runtime implementations that do not provide this guarantee are + /// encouraged to opt-out of concurrent reuse through the component model's + /// backpressure mechanisms. + /// + /// Note that hosts can't rely on this guarantee being upheld by all guests, + /// and shouldn't treat it as part of their security model. Instead, the + /// combination of the above host and guest requirements enable hosts to + /// enforce correctness properties on behalf of the overall system a guest is + /// part of. + export handler; +} + +/// 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. +@since(version = 0.3.0-rc-2026-03-15) +world middleware { + include service; + import handler; +} + +/// 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. +@since(version = 0.3.0-rc-2026-03-15) +interface handler { + use types.{request, response, error-code}; + + /// 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; +} + +/// 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. +@since(version = 0.3.0-rc-2026-03-15) +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; +}