diff --git a/ci/vendor-wit.sh b/ci/vendor-wit.sh index e50edc802558..cbb9948fedbc 100755 --- a/ci/vendor-wit.sh +++ b/ci/vendor-wit.sh @@ -43,7 +43,6 @@ make_vendor "wasi" " io@v0.2.1 random@v0.2.1 sockets@v0.2.1 - http@v0.2.1 " make_vendor "wasi-http" " diff --git a/crates/test-programs/src/bin/cli_serve_keyvalue.rs b/crates/test-programs/src/bin/cli_serve_keyvalue.rs index 0534fd2fa5c1..be806d390b63 100644 --- a/crates/test-programs/src/bin/cli_serve_keyvalue.rs +++ b/crates/test-programs/src/bin/cli_serve_keyvalue.rs @@ -1,7 +1,7 @@ -use test_programs::keyvalue::wasi::keyvalue; use test_programs::proxy; -use test_programs::wasi::http::types::{ - Fields, IncomingRequest, OutgoingBody, OutgoingResponse, ResponseOutparam, +use test_programs::wasi::{ + http::types::{Fields, IncomingRequest, OutgoingBody, OutgoingResponse, ResponseOutparam}, + keyvalue, }; struct T; diff --git a/crates/test-programs/src/bin/cli_serve_runtime_config.rs b/crates/test-programs/src/bin/cli_serve_runtime_config.rs index 48b1027a96e8..d56227dc4039 100644 --- a/crates/test-programs/src/bin/cli_serve_runtime_config.rs +++ b/crates/test-programs/src/bin/cli_serve_runtime_config.rs @@ -1,7 +1,7 @@ -use test_programs::config::wasi::config::runtime; use test_programs::proxy; -use test_programs::wasi::http::types::{ - Fields, IncomingRequest, OutgoingBody, OutgoingResponse, ResponseOutparam, +use test_programs::wasi::{ + config::runtime, + http::types::{Fields, IncomingRequest, OutgoingBody, OutgoingResponse, ResponseOutparam}, }; struct T; diff --git a/crates/test-programs/src/bin/keyvalue_main.rs b/crates/test-programs/src/bin/keyvalue_main.rs index 5fc884a82860..0a5dfe5bfc05 100644 --- a/crates/test-programs/src/bin/keyvalue_main.rs +++ b/crates/test-programs/src/bin/keyvalue_main.rs @@ -1,4 +1,4 @@ -use test_programs::keyvalue::wasi::keyvalue::{atomics, batch, store}; +use test_programs::wasi::keyvalue::{atomics, batch, store}; fn main() { let bucket = store::open("").unwrap(); diff --git a/crates/test-programs/src/bin/runtime_config_get.rs b/crates/test-programs/src/bin/runtime_config_get.rs index 42522f37953c..e3013cdb2236 100644 --- a/crates/test-programs/src/bin/runtime_config_get.rs +++ b/crates/test-programs/src/bin/runtime_config_get.rs @@ -1,4 +1,4 @@ -use test_programs::config::wasi::config::runtime; +use test_programs::wasi::config::runtime; fn main() { let v = runtime::get("hello").unwrap().unwrap(); diff --git a/crates/test-programs/src/lib.rs b/crates/test-programs/src/lib.rs index ecfc3abc5a3e..9b5d8f8d98d6 100644 --- a/crates/test-programs/src/lib.rs +++ b/crates/test-programs/src/lib.rs @@ -4,8 +4,23 @@ pub mod preview1; pub mod sockets; wit_bindgen::generate!({ - world: "test-command", - path: "../wasi/wit", + inline: " + package wasmtime:test; + + world test { + include wasi:cli/imports@0.2.1; + include wasi:config/imports@0.2.0-draft; + include wasi:keyvalue/imports@0.2.0-draft; + import wasi:http/types@0.2.1; + import wasi:http/outgoing-handler@0.2.1; + } + ", + path: [ + "../wasi-http/wit", + "../wasi-runtime-config/wit", + "../wasi-keyvalue/wit", + ], + world: "wasmtime:test/test", generate_all, }); @@ -30,18 +45,3 @@ pub mod proxy { }, }); } - -pub mod config { - wit_bindgen::generate!({ - path: "../wasi-runtime-config/wit", - world: "wasi:config/imports", - }); -} - -pub mod keyvalue { - wit_bindgen::generate!({ - path: "../wasi-keyvalue/wit", - world: "wasi:keyvalue/imports", - type_section_suffix: "keyvalue", - }); -} diff --git a/crates/wasi-http/wit/command-extended.wit b/crates/wasi-http/wit/command-extended.wit deleted file mode 100644 index 0e99bf2725bc..000000000000 --- a/crates/wasi-http/wit/command-extended.wit +++ /dev/null @@ -1,6 +0,0 @@ -// All of the same imports and exports available in the wasi:cli/command world -// with addition of HTTP proxy related imports: -world command-extended { - include wasi:cli/command@0.2.1; - import wasi:http/outgoing-handler@0.2.1; -} diff --git a/crates/wasi-http/wit/test.wit b/crates/wasi-http/wit/test.wit deleted file mode 100644 index d9d6c3d5b3ca..000000000000 --- a/crates/wasi-http/wit/test.wit +++ /dev/null @@ -1,22 +0,0 @@ -package wasmtime:wasi; - -// only used as part of `test-programs` -world test-reactor { - include wasi:cli/imports@0.2.1; - - export add-strings: func(s: list) -> u32; - export get-strings: func() -> list; - - use wasi:io/streams@0.2.1.{output-stream}; - - export write-strings-to: func(o: output-stream) -> result; - - use wasi:filesystem/types@0.2.1.{descriptor-stat}; - export pass-an-imported-record: func(d: descriptor-stat) -> string; -} - -world test-command { - include wasi:cli/imports@0.2.1; - import wasi:http/types@0.2.1; - import wasi:http/outgoing-handler@0.2.1; -} diff --git a/crates/wasi-http/wit/world.wit b/crates/wasi-http/wit/world.wit new file mode 100644 index 000000000000..0875bb30612f --- /dev/null +++ b/crates/wasi-http/wit/world.wit @@ -0,0 +1,6 @@ +// We actually don't use this; it's just to let bindgen! find the corresponding world in wit/deps. +package wasmtime:wasi-http; + +world bindings { + include wasi:http/proxy@0.2.1; +} diff --git a/crates/wasi-keyvalue/wit/world.wit b/crates/wasi-keyvalue/wit/world.wit index 1d4c6ab44218..af5b0bd5524b 100644 --- a/crates/wasi-keyvalue/wit/world.wit +++ b/crates/wasi-keyvalue/wit/world.wit @@ -1,5 +1,5 @@ // We actually don't use this; it's just to let bindgen! find the corresponding world in wit/deps. -package wasmtime:wasi; +package wasmtime:wasi-keyvalue; world bindings { include wasi:keyvalue/imports@0.2.0-draft; diff --git a/crates/wasi-preview1-component-adapter/src/lib.rs b/crates/wasi-preview1-component-adapter/src/lib.rs index a74be83dc663..0cb4957f432e 100644 --- a/crates/wasi-preview1-component-adapter/src/lib.rs +++ b/crates/wasi-preview1-component-adapter/src/lib.rs @@ -97,6 +97,7 @@ pub mod bindings { import wasi:cli/stdin@0.2.1; } "#, + world: "wasmtime:adapter/adapter", std_feature, raw_strings, runtime_path: "crate::bindings::wit_bindgen_rt_shim", diff --git a/crates/wasi-runtime-config/wit/world.wit b/crates/wasi-runtime-config/wit/world.wit index 5dce2388bc02..35a25fd746d0 100644 --- a/crates/wasi-runtime-config/wit/world.wit +++ b/crates/wasi-runtime-config/wit/world.wit @@ -1,5 +1,5 @@ // We actually don't use this; it's just to let bindgen! find the corresponding world in wit/deps. -package wasmtime:wasi; +package wasmtime:wasi-config; world bindings { include wasi:config/imports@0.2.0-draft; diff --git a/crates/wasi/wit/command-extended.wit b/crates/wasi/wit/command-extended.wit deleted file mode 100644 index 0e99bf2725bc..000000000000 --- a/crates/wasi/wit/command-extended.wit +++ /dev/null @@ -1,6 +0,0 @@ -// All of the same imports and exports available in the wasi:cli/command world -// with addition of HTTP proxy related imports: -world command-extended { - include wasi:cli/command@0.2.1; - import wasi:http/outgoing-handler@0.2.1; -} diff --git a/crates/wasi/wit/deps/http/handler.wit b/crates/wasi/wit/deps/http/handler.wit deleted file mode 100644 index 6a6c62966f11..000000000000 --- a/crates/wasi/wit/deps/http/handler.wit +++ /dev/null @@ -1,49 +0,0 @@ -/// This interface defines a handler of incoming HTTP Requests. It should -/// be exported by components which can respond to HTTP Requests. -@since(version = 0.2.0) -interface incoming-handler { - @since(version = 0.2.0) - use types.{incoming-request, response-outparam}; - - /// This function is invoked with an incoming HTTP Request, and a resource - /// `response-outparam` which provides the capability to reply with an HTTP - /// Response. The response is sent by calling the `response-outparam.set` - /// method, which allows execution to continue after the response has been - /// sent. This enables both streaming to the response body, and performing other - /// work. - /// - /// The implementor of this function must write a response to the - /// `response-outparam` before returning, or else the caller will respond - /// with an error on its behalf. - @since(version = 0.2.0) - handle: func( - request: incoming-request, - response-out: response-outparam - ); -} - -/// This interface defines a handler of outgoing HTTP Requests. It should be -/// imported by components which wish to make HTTP Requests. -@since(version = 0.2.0) -interface outgoing-handler { - @since(version = 0.2.0) - use types.{ - outgoing-request, request-options, future-incoming-response, error-code - }; - - /// This function is invoked with an outgoing HTTP Request, and it returns - /// a resource `future-incoming-response` which represents an HTTP Response - /// which may arrive in the future. - /// - /// The `options` argument accepts optional parameters for the HTTP - /// protocol's transport layer. - /// - /// This function may return an error if the `outgoing-request` is invalid - /// or not allowed to be made. Otherwise, protocol errors are reported - /// through the `future-incoming-response`. - @since(version = 0.2.0) - handle: func( - request: outgoing-request, - options: option - ) -> result; -} diff --git a/crates/wasi/wit/deps/http/proxy.wit b/crates/wasi/wit/deps/http/proxy.wit deleted file mode 100644 index 415d2ee1cbcc..000000000000 --- a/crates/wasi/wit/deps/http/proxy.wit +++ /dev/null @@ -1,50 +0,0 @@ -package wasi:http@0.2.1; - -/// The `wasi:http/imports` world imports all the APIs for HTTP proxies. -/// It is intended to be `include`d in other worlds. -@since(version = 0.2.0) -world imports { - /// HTTP proxies have access to time and randomness. - @since(version = 0.2.0) - import wasi:clocks/monotonic-clock@0.2.1; - @since(version = 0.2.0) - import wasi:clocks/wall-clock@0.2.1; - @since(version = 0.2.0) - import wasi:random/random@0.2.1; - - /// Proxies have standard output and error streams which are expected to - /// terminate in a developer-facing console provided by the host. - @since(version = 0.2.0) - import wasi:cli/stdout@0.2.1; - @since(version = 0.2.0) - import wasi:cli/stderr@0.2.1; - - /// 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. - @since(version = 0.2.0) - import wasi:cli/stdin@0.2.1; - - /// This is the default handler to use when user code simply wants to make an - /// HTTP request (e.g., via `fetch()`). - @since(version = 0.2.0) - import outgoing-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. -@since(version = 0.2.0) -world proxy { - @since(version = 0.2.0) - include imports; - - /// 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`. - @since(version = 0.2.0) - export incoming-handler; -} diff --git a/crates/wasi/wit/deps/http/types.wit b/crates/wasi/wit/deps/http/types.wit deleted file mode 100644 index 3c45cd08b7d3..000000000000 --- a/crates/wasi/wit/deps/http/types.wit +++ /dev/null @@ -1,655 +0,0 @@ -/// This interface defines all of the types and methods for implementing -/// HTTP Requests and Responses, both incoming and outgoing, as well as -/// their headers, trailers, and bodies. -@since(version = 0.2.0) -interface types { - @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.1.{duration}; - @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{input-stream, output-stream}; - @since(version = 0.2.0) - use wasi:io/error@0.2.1.{error as io-error}; - @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; - - /// This type corresponds to HTTP standard Methods. - @since(version = 0.2.0) - variant method { - get, - head, - post, - put, - delete, - connect, - options, - trace, - patch, - other(string) - } - - /// This type corresponds to HTTP standard Related Schemes. - @since(version = 0.2.0) - variant scheme { - HTTP, - HTTPS, - other(string) - } - - /// These cases are inspired by the IANA HTTP Proxy Error Types: - /// https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types - @since(version = 0.2.0) - variant error-code { - DNS-timeout, - DNS-error(DNS-error-payload), - destination-not-found, - destination-unavailable, - destination-IP-prohibited, - destination-IP-unroutable, - connection-refused, - connection-terminated, - connection-timeout, - connection-read-timeout, - connection-write-timeout, - connection-limit-reached, - TLS-protocol-error, - TLS-certificate-error, - TLS-alert-received(TLS-alert-received-payload), - HTTP-request-denied, - HTTP-request-length-required, - HTTP-request-body-size(option), - HTTP-request-method-invalid, - HTTP-request-URI-invalid, - HTTP-request-URI-too-long, - HTTP-request-header-section-size(option), - HTTP-request-header-size(option), - HTTP-request-trailer-section-size(option), - HTTP-request-trailer-size(field-size-payload), - HTTP-response-incomplete, - HTTP-response-header-section-size(option), - HTTP-response-header-size(field-size-payload), - HTTP-response-body-size(option), - HTTP-response-trailer-section-size(option), - HTTP-response-trailer-size(field-size-payload), - HTTP-response-transfer-coding(option), - HTTP-response-content-coding(option), - HTTP-response-timeout, - HTTP-upgrade-failed, - HTTP-protocol-error, - loop-detected, - configuration-error, - /// This is a catch-all error for anything that doesn't fit cleanly into a - /// more specific case. It also includes an optional string for an - /// unstructured description of the error. Users should not depend on the - /// string for diagnosing errors, as it's not required to be consistent - /// between implementations. - internal-error(option) - } - - /// Defines the case payload type for `DNS-error` above: - @since(version = 0.2.0) - record DNS-error-payload { - rcode: option, - info-code: option - } - - /// Defines the case payload type for `TLS-alert-received` above: - @since(version = 0.2.0) - record TLS-alert-received-payload { - alert-id: option, - alert-message: option - } - - /// Defines the case payload type for `HTTP-response-{header,trailer}-size` above: - @since(version = 0.2.0) - record field-size-payload { - field-name: option, - field-size: option - } - - /// Attempts to extract a http-related `error` from the wasi:io `error` - /// provided. - /// - /// Stream operations which return - /// `wasi:io/stream/stream-error::last-operation-failed` have a payload of - /// type `wasi:io/error/error` with more information about the operation - /// that failed. This payload can be passed through to this function to see - /// if there's http-related information about the error to return. - /// - /// Note that this function is fallible because not all io-errors are - /// http-related errors. - @since(version = 0.2.0) - http-error-code: func(err: borrow) -> option; - - /// This type enumerates the different kinds of errors that may occur when - /// setting or appending to a `fields` resource. - @since(version = 0.2.0) - variant header-error { - /// This error indicates that a `field-key` or `field-value` was - /// syntactically invalid when used with an operation that sets headers in a - /// `fields`. - invalid-syntax, - - /// This error indicates that a forbidden `field-key` was used when trying - /// to set a header in a `fields`. - forbidden, - - /// This error indicates that the operation on the `fields` was not - /// permitted because the fields are immutable. - immutable, - } - - /// Field keys are always strings. - @since(version = 0.2.0) - type field-key = string; - - /// Field values should always be ASCII strings. However, in - /// reality, HTTP implementations often have to interpret malformed values, - /// so they are provided as a list of bytes. - @since(version = 0.2.0) - type field-value = list; - - /// This following block defines the `fields` resource which corresponds to - /// HTTP standard Fields. Fields are a common representation used for both - /// Headers and Trailers. - /// - /// A `fields` may be mutable or immutable. A `fields` created using the - /// constructor, `from-list`, or `clone` will be mutable, but a `fields` - /// resource given by other means (including, but not limited to, - /// `incoming-request.headers`, `outgoing-request.headers`) might be be - /// immutable. In an immutable fields, the `set`, `append`, and `delete` - /// operations will fail with `header-error.immutable`. - @since(version = 0.2.0) - resource fields { - - /// Construct an empty HTTP Fields. - /// - /// The resulting `fields` is mutable. - @since(version = 0.2.0) - constructor(); - - /// Construct an HTTP Fields. - /// - /// The resulting `fields` is mutable. - /// - /// The list represents each key-value pair in the Fields. Keys - /// which have multiple values are represented by multiple entries in this - /// list with the same key. - /// - /// The tuple is a pair of the field key, represented as a string, and - /// Value, represented as a list of bytes. - /// - /// An error result will be returned if any `field-key` or `field-value` is - /// syntactically invalid, or if a field is forbidden. - @since(version = 0.2.0) - from-list: static func( - entries: list> - ) -> result; - - /// Get all of the values corresponding to a key. If the key is not present - /// in this `fields` or is syntactically invalid, an empty list is returned. - /// However, if the key is present but empty, this is represented by a list - /// with one or more empty field-values present. - @since(version = 0.2.0) - get: func(name: field-key) -> list; - - /// Returns `true` when the key is present in this `fields`. If the key is - /// syntactically invalid, `false` is returned. - @since(version = 0.2.0) - has: func(name: field-key) -> bool; - - /// Set all of the values for a key. Clears any existing values for that - /// key, if they have been set. - /// - /// Fails with `header-error.immutable` if the `fields` are immutable. - /// - /// Fails with `header-error.invalid-syntax` if the `field-key` or any of - /// the `field-value`s are syntactically invalid. - @since(version = 0.2.0) - set: func(name: field-key, value: list) -> result<_, header-error>; - - /// Delete all values for a key. Does nothing if no values for the key - /// exist. - /// - /// Fails with `header-error.immutable` if the `fields` are immutable. - /// - /// Fails with `header-error.invalid-syntax` if the `field-key` is - /// syntactically invalid. - @since(version = 0.2.0) - delete: func(name: field-key) -> result<_, header-error>; - - /// Append a value for a key. Does not change or delete any existing - /// values for that key. - /// - /// Fails with `header-error.immutable` if the `fields` are immutable. - /// - /// Fails with `header-error.invalid-syntax` if the `field-key` or - /// `field-value` are syntactically invalid. - @since(version = 0.2.0) - append: func(name: field-key, value: field-value) -> result<_, header-error>; - - /// Retrieve the full set of keys and values in the Fields. Like the - /// constructor, the list represents each key-value pair. - /// - /// The outer list represents each key-value pair in the Fields. Keys - /// which have multiple values are represented by multiple entries in this - /// list with the same key. - @since(version = 0.2.0) - entries: func() -> list>; - - /// Make a deep copy of the Fields. Equivalent in behavior to calling the - /// `fields` constructor on the return value of `entries`. The resulting - /// `fields` is mutable. - @since(version = 0.2.0) - clone: func() -> fields; - } - - /// Headers is an alias for Fields. - @since(version = 0.2.0) - type headers = fields; - - /// Trailers is an alias for Fields. - @since(version = 0.2.0) - type trailers = fields; - - /// Represents an incoming HTTP Request. - @since(version = 0.2.0) - resource incoming-request { - - /// Returns the method of the incoming request. - @since(version = 0.2.0) - method: func() -> method; - - /// Returns the path with query parameters from the request, as a string. - @since(version = 0.2.0) - path-with-query: func() -> option; - - /// Returns the protocol scheme from the request. - @since(version = 0.2.0) - scheme: func() -> option; - - /// Returns the authority of the Request's target URI, if present. - @since(version = 0.2.0) - authority: func() -> option; - - /// Get the `headers` associated with the request. - /// - /// The returned `headers` resource is immutable: `set`, `append`, and - /// `delete` operations will fail with `header-error.immutable`. - /// - /// The `headers` returned are a child resource: it must be dropped before - /// the parent `incoming-request` is dropped. Dropping this - /// `incoming-request` before all children are dropped will trap. - @since(version = 0.2.0) - headers: func() -> headers; - - /// Gives the `incoming-body` associated with this request. Will only - /// return success at most once, and subsequent calls will return error. - @since(version = 0.2.0) - consume: func() -> result; - } - - /// Represents an outgoing HTTP Request. - @since(version = 0.2.0) - resource outgoing-request { - - /// Construct a new `outgoing-request` with a default `method` of `GET`, and - /// `none` values for `path-with-query`, `scheme`, and `authority`. - /// - /// * `headers` is the HTTP Headers for the Request. - /// - /// It is possible to construct, or manipulate with the accessor functions - /// below, an `outgoing-request` with an invalid combination of `scheme` - /// and `authority`, or `headers` which are not permitted to be sent. - /// It is the obligation of the `outgoing-handler.handle` implementation - /// to reject invalid constructions of `outgoing-request`. - @since(version = 0.2.0) - constructor( - headers: headers - ); - - /// Returns the resource corresponding to the outgoing Body for this - /// Request. - /// - /// Returns success on the first call: the `outgoing-body` resource for - /// this `outgoing-request` can be retrieved at most once. Subsequent - /// calls will return error. - @since(version = 0.2.0) - body: func() -> result; - - /// Get the Method for the Request. - @since(version = 0.2.0) - method: func() -> method; - /// Set the Method for the Request. Fails if the string present in a - /// `method.other` argument is not a syntactically valid method. - @since(version = 0.2.0) - set-method: func(method: method) -> result; - - /// Get the combination of the HTTP Path and Query for the Request. - /// When `none`, this represents an empty Path and empty Query. - @since(version = 0.2.0) - path-with-query: func() -> option; - /// Set the combination of the HTTP Path and Query for the Request. - /// When `none`, this represents an empty Path and empty Query. Fails is the - /// string given is not a syntactically valid path and query uri component. - @since(version = 0.2.0) - set-path-with-query: func(path-with-query: option) -> result; - - /// Get the HTTP Related Scheme for the Request. When `none`, the - /// implementation may choose an appropriate default scheme. - @since(version = 0.2.0) - scheme: func() -> option; - /// Set the HTTP Related Scheme for the Request. When `none`, the - /// implementation may choose an appropriate default scheme. Fails if the - /// string given is not a syntactically valid uri scheme. - @since(version = 0.2.0) - set-scheme: func(scheme: option) -> result; - - /// Get the authority of the Request's target URI. A value of `none` may be used - /// with Related Schemes which do not require an authority. The HTTP and - /// HTTPS schemes always require an authority. - @since(version = 0.2.0) - authority: func() -> option; - /// Set the authority of the Request's target URI. A value of `none` may be used - /// with Related Schemes which do not require an authority. The HTTP and - /// HTTPS schemes always require an authority. Fails if the string given is - /// not a syntactically valid URI authority. - @since(version = 0.2.0) - set-authority: func(authority: option) -> result; - - /// Get the headers associated with the Request. - /// - /// The returned `headers` resource is immutable: `set`, `append`, and - /// `delete` operations will fail with `header-error.immutable`. - /// - /// This headers resource is a child: it must be dropped before the parent - /// `outgoing-request` is dropped, or its ownership is transferred to - /// another component by e.g. `outgoing-handler.handle`. - @since(version = 0.2.0) - headers: func() -> headers; - } - - /// Parameters for making an HTTP Request. Each of these parameters is - /// currently an optional timeout applicable to the transport layer of the - /// HTTP protocol. - /// - /// These timeouts are separate from any the user may use to bound a - /// blocking call to `wasi:io/poll.poll`. - @since(version = 0.2.0) - resource request-options { - /// Construct a default `request-options` value. - @since(version = 0.2.0) - constructor(); - - /// The timeout for the initial connect to the HTTP Server. - @since(version = 0.2.0) - connect-timeout: func() -> option; - - /// Set the timeout for the initial connect to the HTTP Server. An error - /// return value indicates that this timeout is not supported. - @since(version = 0.2.0) - set-connect-timeout: func(duration: option) -> result; - - /// The timeout for receiving the first byte of the Response body. - @since(version = 0.2.0) - first-byte-timeout: func() -> option; - - /// Set the timeout for receiving the first byte of the Response body. An - /// error return value indicates that this timeout is not supported. - @since(version = 0.2.0) - set-first-byte-timeout: func(duration: option) -> result; - - /// The timeout for receiving subsequent chunks of bytes in the Response - /// body stream. - @since(version = 0.2.0) - between-bytes-timeout: func() -> option; - - /// Set the timeout for receiving subsequent chunks of bytes in the Response - /// body stream. An error return value indicates that this timeout is not - /// supported. - @since(version = 0.2.0) - set-between-bytes-timeout: func(duration: option) -> result; - } - - /// Represents the ability to send an HTTP Response. - /// - /// This resource is used by the `wasi:http/incoming-handler` interface to - /// allow a Response to be sent corresponding to the Request provided as the - /// other argument to `incoming-handler.handle`. - @since(version = 0.2.0) - resource response-outparam { - - /// Set the value of the `response-outparam` to either send a response, - /// or indicate an error. - /// - /// This method consumes the `response-outparam` to ensure that it is - /// called at most once. If it is never called, the implementation - /// will respond with an error. - /// - /// The user may provide an `error` to `response` to allow the - /// implementation determine how to respond with an HTTP error response. - @since(version = 0.2.0) - set: static func( - param: response-outparam, - response: result, - ); - } - - /// This type corresponds to the HTTP standard Status Code. - @since(version = 0.2.0) - type status-code = u16; - - /// Represents an incoming HTTP Response. - @since(version = 0.2.0) - resource incoming-response { - - /// Returns the status code from the incoming response. - @since(version = 0.2.0) - status: func() -> status-code; - - /// Returns the headers from the incoming response. - /// - /// The returned `headers` resource is immutable: `set`, `append`, and - /// `delete` operations will fail with `header-error.immutable`. - /// - /// This headers resource is a child: it must be dropped before the parent - /// `incoming-response` is dropped. - @since(version = 0.2.0) - headers: func() -> headers; - - /// Returns the incoming body. May be called at most once. Returns error - /// if called additional times. - @since(version = 0.2.0) - consume: func() -> result; - } - - /// Represents an incoming HTTP Request or Response's Body. - /// - /// A body has both its contents - a stream of bytes - and a (possibly - /// empty) set of trailers, indicating that the full contents of the - /// body have been received. This resource represents the contents as - /// an `input-stream` and the delivery of trailers as a `future-trailers`, - /// and ensures that the user of this interface may only be consuming either - /// the body contents or waiting on trailers at any given time. - @since(version = 0.2.0) - resource incoming-body { - - /// Returns the contents of the body, as a stream of bytes. - /// - /// Returns success on first call: the stream representing the contents - /// can be retrieved at most once. Subsequent calls will return error. - /// - /// The returned `input-stream` resource is a child: it must be dropped - /// before the parent `incoming-body` is dropped, or consumed by - /// `incoming-body.finish`. - /// - /// This invariant ensures that the implementation can determine whether - /// the user is consuming the contents of the body, waiting on the - /// `future-trailers` to be ready, or neither. This allows for network - /// backpressure is to be applied when the user is consuming the body, - /// and for that backpressure to not inhibit delivery of the trailers if - /// the user does not read the entire body. - @since(version = 0.2.0) - %stream: func() -> result; - - /// Takes ownership of `incoming-body`, and returns a `future-trailers`. - /// This function will trap if the `input-stream` child is still alive. - @since(version = 0.2.0) - finish: static func(this: incoming-body) -> future-trailers; - } - - /// Represents a future which may eventually return trailers, or an error. - /// - /// In the case that the incoming HTTP Request or Response did not have any - /// trailers, this future will resolve to the empty set of trailers once the - /// complete Request or Response body has been received. - @since(version = 0.2.0) - resource future-trailers { - - /// Returns a pollable which becomes ready when either the trailers have - /// been received, or an error has occurred. When this pollable is ready, - /// the `get` method will return `some`. - @since(version = 0.2.0) - subscribe: func() -> pollable; - - /// Returns the contents of the trailers, or an error which occurred, - /// once the future is ready. - /// - /// The outer `option` represents future readiness. Users can wait on this - /// `option` to become `some` using the `subscribe` method. - /// - /// The outer `result` is used to retrieve the trailers or error at most - /// once. It will be success on the first call in which the outer option - /// is `some`, and error on subsequent calls. - /// - /// The inner `result` represents that either the HTTP Request or Response - /// body, as well as any trailers, were received successfully, or that an - /// error occurred receiving them. The optional `trailers` indicates whether - /// or not trailers were present in the body. - /// - /// When some `trailers` are returned by this method, the `trailers` - /// resource is immutable, and a child. Use of the `set`, `append`, or - /// `delete` methods will return an error, and the resource must be - /// dropped before the parent `future-trailers` is dropped. - @since(version = 0.2.0) - get: func() -> option, error-code>>>; - } - - /// Represents an outgoing HTTP Response. - @since(version = 0.2.0) - resource outgoing-response { - - /// Construct an `outgoing-response`, with a default `status-code` of `200`. - /// If a different `status-code` is needed, it must be set via the - /// `set-status-code` method. - /// - /// * `headers` is the HTTP Headers for the Response. - @since(version = 0.2.0) - constructor(headers: headers); - - /// Get the HTTP Status Code for the Response. - @since(version = 0.2.0) - status-code: func() -> status-code; - - /// Set the HTTP Status Code for the Response. Fails if the status-code - /// given is not a valid http status code. - @since(version = 0.2.0) - set-status-code: func(status-code: status-code) -> result; - - /// Get the headers associated with the Request. - /// - /// The returned `headers` resource is immutable: `set`, `append`, and - /// `delete` operations will fail with `header-error.immutable`. - /// - /// This headers resource is a child: it must be dropped before the parent - /// `outgoing-request` is dropped, or its ownership is transferred to - /// another component by e.g. `outgoing-handler.handle`. - @since(version = 0.2.0) - headers: func() -> headers; - - /// Returns the resource corresponding to the outgoing Body for this Response. - /// - /// Returns success on the first call: the `outgoing-body` resource for - /// this `outgoing-response` can be retrieved at most once. Subsequent - /// calls will return error. - @since(version = 0.2.0) - body: func() -> result; - } - - /// Represents an outgoing HTTP Request or Response's Body. - /// - /// A body has both its contents - a stream of bytes - and a (possibly - /// empty) set of trailers, inducating the full contents of the body - /// have been sent. This resource represents the contents as an - /// `output-stream` child resource, and the completion of the body (with - /// optional trailers) with a static function that consumes the - /// `outgoing-body` resource, and ensures that the user of this interface - /// may not write to the body contents after the body has been finished. - /// - /// If the user code drops this resource, as opposed to calling the static - /// method `finish`, the implementation should treat the body as incomplete, - /// and that an error has occurred. The implementation should propagate this - /// error to the HTTP protocol by whatever means it has available, - /// including: corrupting the body on the wire, aborting the associated - /// Request, or sending a late status code for the Response. - @since(version = 0.2.0) - resource outgoing-body { - - /// Returns a stream for writing the body contents. - /// - /// The returned `output-stream` is a child resource: it must be dropped - /// before the parent `outgoing-body` resource is dropped (or finished), - /// otherwise the `outgoing-body` drop or `finish` will trap. - /// - /// Returns success on the first call: the `output-stream` resource for - /// this `outgoing-body` may be retrieved at most once. Subsequent calls - /// will return error. - @since(version = 0.2.0) - write: func() -> result; - - /// Finalize an outgoing body, optionally providing trailers. This must be - /// called to signal that the response is complete. If the `outgoing-body` - /// is dropped without calling `outgoing-body.finalize`, the implementation - /// should treat the body as corrupted. - /// - /// Fails if the body's `outgoing-request` or `outgoing-response` was - /// constructed with a Content-Length header, and the contents written - /// to the body (via `write`) does not match the value given in the - /// Content-Length. - @since(version = 0.2.0) - finish: static func( - this: outgoing-body, - trailers: option - ) -> result<_, error-code>; - } - - /// Represents a future which may eventually return an incoming HTTP - /// Response, or an error. - /// - /// This resource is returned by the `wasi:http/outgoing-handler` interface to - /// provide the HTTP Response corresponding to the sent Request. - @since(version = 0.2.0) - resource future-incoming-response { - /// Returns a pollable which becomes ready when either the Response has - /// been received, or an error has occurred. When this pollable is ready, - /// the `get` method will return `some`. - @since(version = 0.2.0) - subscribe: func() -> pollable; - - /// Returns the incoming HTTP Response, or an error, once one is ready. - /// - /// The outer `option` represents future readiness. Users can wait on this - /// `option` to become `some` using the `subscribe` method. - /// - /// The outer `result` is used to retrieve the response or error at most - /// once. It will be success on the first call in which the outer option - /// is `some`, and error on subsequent calls. - /// - /// The inner `result` represents that either the incoming HTTP Response - /// status and headers have received successfully, or that an error - /// occurred. Errors may also occur while consuming the response body, - /// but those will be reported by the `incoming-body` and its - /// `output-stream` child. - @since(version = 0.2.0) - get: func() -> option>>; - } -} diff --git a/crates/wasi/wit/test.wit b/crates/wasi/wit/test.wit index d9d6c3d5b3ca..14e531d08d14 100644 --- a/crates/wasi/wit/test.wit +++ b/crates/wasi/wit/test.wit @@ -1,6 +1,3 @@ -package wasmtime:wasi; - -// only used as part of `test-programs` world test-reactor { include wasi:cli/imports@0.2.1; @@ -14,9 +11,3 @@ world test-reactor { use wasi:filesystem/types@0.2.1.{descriptor-stat}; export pass-an-imported-record: func(d: descriptor-stat) -> string; } - -world test-command { - include wasi:cli/imports@0.2.1; - import wasi:http/types@0.2.1; - import wasi:http/outgoing-handler@0.2.1; -} diff --git a/crates/wasi/wit/world.wit b/crates/wasi/wit/world.wit new file mode 100644 index 000000000000..e540b1f6d8ef --- /dev/null +++ b/crates/wasi/wit/world.wit @@ -0,0 +1,6 @@ +// We actually don't use this; it's just to let bindgen! find the corresponding world in wit/deps. +package wasmtime:wasi; + +world bindings { + include wasi:cli/imports@0.2.1; +}