/// The `wasi:http/types` interface is meant to be imported by components to /// define the HTTP resource types and operations used by the component's /// imported and exported interfaces. interface types { use wasi:io/streams@0.2.0-rc-2023-10-18.{input-stream, output-stream}; use wasi:io/poll@0.2.0-rc-2023-10-18.{pollable}; // This type corresponds to HTTP standard Methods. variant method { get, head, post, put, delete, connect, options, trace, patch, other(string) } /// This type corresponds to HTTP standard Related Schemes. variant scheme { HTTP, HTTPS, other(string) } // TODO: perhaps better align with HTTP semantics? /// This type enumerates the different kinds of errors that may occur when /// initially returning a response. variant error { invalid-url(string), timeout-error(string), protocol-error(string), unexpected-error(string) } /// This following block defines the `fields` resource which corresponds to /// HTTP standard Fields. resource fields { // Multiple values for a header are multiple entries in the list with the // same key. constructor(entries: list>>); // Values off wire are not necessarily well formed, so they are given by // list instead of string. get: func(name: string) -> list>; // Values off wire are not necessarily well formed, so they are given by // list instead of string. set: func(name: string, value: list>); delete: func(name: string); append: func(name: string, value: list); // Values off wire are not necessarily well formed, so they are given by // list instead of string. entries: func() -> list>>; // Deep copy of all contents in a fields. clone: func() -> fields; } type headers = fields; type trailers = fields; /// The following block defines the `incoming-request` and `outgoing-request` /// resource types that correspond to HTTP standard Requests. /// /// The `consume` and `write` methods may only be called once (and /// return failure thereafter). resource incoming-request { method: func() -> method; path-with-query: func() -> option; scheme: func() -> option; authority: func() -> option; headers: func() -> /* child */ headers; /// Returns the input-stream child at most once. /// /// If called more than once, subsequent calls return an error. consume: func() -> result; } resource outgoing-request { constructor( method: method, path-with-query: option, scheme: option, authority: option, headers: borrow ); /// Will return the outgoing-body child at most once. /// /// If called more than once, subsequent calls return an error. write: func() -> result< /* child */ outgoing-body>; } /// Additional optional parameters that can be set when making a request. record request-options { // The following timeouts are specific to the HTTP protocol and work // independently of the overall timeouts passed to `io.poll.poll-list`. /// The timeout for the initial connect. connect-timeout-ms: option, /// The timeout for receiving the first byte of the response body. first-byte-timeout-ms: option, /// The timeout for receiving the next chunk of bytes in the response body /// stream. between-bytes-timeout-ms: option } /// The following block defines a special resource type used by the /// `wasi:http/incoming-handler` interface. When resource types are added, this /// block can be replaced by a proper `resource response-outparam { ... }` /// definition. Later, with Preview3, the need for an outparam goes away entirely /// (the `wasi:http/handler` interface used for both incoming and outgoing can /// simply return a `stream`). resource response-outparam { set: static func(param: response-outparam, response: result); } // This type corresponds to the HTTP standard Status Code. type status-code = u16; /// The following block defines the `incoming-response` and `outgoing-response` /// resource types that correspond to HTTP standard Responses. /// /// The `consume` and `write` methods may only be called once (and return failure thereafter). resource incoming-response { status: func() -> status-code; headers: func() -> /* child */ headers; // May be called at most once. returns error if called additional times. // TODO: make incoming-request-consume work the same way, giving a child // incoming-body. consume: func() -> result; } resource incoming-body { // returned input-stream is a child - the implementation may trap if // incoming-body is dropped (or consumed by call to // incoming-body-finish) before the input-stream is dropped. // May be called at most once. returns error if called additional times. %stream: func() -> result; // takes ownership of incoming-body. this will trap if the // incoming-body-stream child is still alive! finish: static func(this: incoming-body) -> /* transitive child of the incoming-response of incoming-body */ future-trailers; } resource future-trailers { /// Pollable that resolves when the body has been fully read, and the trailers /// are ready to be consumed. subscribe: func() -> /* child */ pollable; /// Retrieve reference to trailers, if they are ready. get: func() -> option>; } resource outgoing-response { constructor(status-code: status-code, headers: borrow); /// Will give the child outgoing-response at most once. subsequent calls will /// return an error. write: func() -> result; } resource outgoing-body { /// Will give the child output-stream at most once. subsequent calls will /// return an error. 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. finish: static func(this: outgoing-body, trailers: option); } /// The following block defines a special resource type used by the /// `wasi:http/outgoing-handler` interface to emulate /// `future>` in advance of Preview3. Given a /// `future-incoming-response`, the client can call the non-blocking `get` /// method to get the result if it is available. If the result is not available, /// the client can call `listen` to get a `pollable` that can be passed to /// `wasi:io/poll.poll-list`. resource future-incoming-response { /// option indicates readiness. /// outer result indicates you are allowed to get the /// incoming-response-or-error at most once. subsequent calls after ready /// will return an error here. /// inner result indicates whether the incoming-response was available, or an /// error occured. get: func() -> option>>; subscribe: func() -> /* child */ pollable; } }