2024-12-14 01:15:08 +00:00
|
|
|
package wasi:http@0.2.0;
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
interface types {
|
|
|
|
use wasi:clocks/monotonic-clock@0.2.0.{duration};
|
|
|
|
use wasi:io/streams@0.2.0.{input-stream, output-stream};
|
|
|
|
use wasi:io/error@0.2.0.{error as io-error};
|
|
|
|
use wasi:io/poll@0.2.0.{pollable};
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// This type corresponds to HTTP standard Methods.
|
2024-12-14 01:15:08 +00:00
|
|
|
variant method {
|
|
|
|
get,
|
|
|
|
head,
|
|
|
|
post,
|
|
|
|
put,
|
|
|
|
delete,
|
|
|
|
connect,
|
|
|
|
options,
|
|
|
|
trace,
|
|
|
|
patch,
|
|
|
|
other(string),
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// This type corresponds to HTTP standard Related Schemes.
|
2024-12-14 01:15:08 +00:00
|
|
|
variant scheme {
|
|
|
|
HTTP,
|
|
|
|
HTTPS,
|
|
|
|
other(string),
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Defines the case payload type for `DNS-error` above:
|
2024-12-14 01:15:08 +00:00
|
|
|
record DNS-error-payload {
|
|
|
|
rcode: option<string>,
|
|
|
|
info-code: option<u16>,
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Defines the case payload type for `TLS-alert-received` above:
|
2024-12-14 01:15:08 +00:00
|
|
|
record TLS-alert-received-payload {
|
|
|
|
alert-id: option<u8>,
|
|
|
|
alert-message: option<string>,
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Defines the case payload type for `HTTP-response-{header,trailer}-size` above:
|
2024-12-14 01:15:08 +00:00
|
|
|
record field-size-payload {
|
|
|
|
field-name: option<string>,
|
|
|
|
field-size: option<u32>,
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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
|
2024-12-14 01:15:08 +00:00
|
|
|
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<u64>),
|
|
|
|
HTTP-request-method-invalid,
|
|
|
|
HTTP-request-URI-invalid,
|
|
|
|
HTTP-request-URI-too-long,
|
|
|
|
HTTP-request-header-section-size(option<u32>),
|
|
|
|
HTTP-request-header-size(option<field-size-payload>),
|
|
|
|
HTTP-request-trailer-section-size(option<u32>),
|
|
|
|
HTTP-request-trailer-size(field-size-payload),
|
|
|
|
HTTP-response-incomplete,
|
|
|
|
HTTP-response-header-section-size(option<u32>),
|
|
|
|
HTTP-response-header-size(field-size-payload),
|
|
|
|
HTTP-response-body-size(option<u64>),
|
|
|
|
HTTP-response-trailer-section-size(option<u32>),
|
|
|
|
HTTP-response-trailer-size(field-size-payload),
|
|
|
|
HTTP-response-transfer-coding(option<string>),
|
|
|
|
HTTP-response-content-coding(option<string>),
|
|
|
|
HTTP-response-timeout,
|
|
|
|
HTTP-upgrade-failed,
|
|
|
|
HTTP-protocol-error,
|
|
|
|
loop-detected,
|
|
|
|
configuration-error,
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
internal-error(option<string>),
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// This type enumerates the different kinds of errors that may occur when
|
|
|
|
/// setting or appending to a `fields` resource.
|
2024-12-14 01:15:08 +00:00
|
|
|
variant header-error {
|
2024-12-16 19:34:52 +00:00
|
|
|
/// This error indicates that a `field-key` or `field-value` was
|
|
|
|
/// syntactically invalid when used with an operation that sets headers in a
|
|
|
|
/// `fields`.
|
2024-12-14 01:15:08 +00:00
|
|
|
invalid-syntax,
|
2024-12-16 19:34:52 +00:00
|
|
|
/// This error indicates that a forbidden `field-key` was used when trying
|
|
|
|
/// to set a header in a `fields`.
|
2024-12-14 01:15:08 +00:00
|
|
|
forbidden,
|
2024-12-16 19:34:52 +00:00
|
|
|
/// This error indicates that the operation on the `fields` was not
|
|
|
|
/// permitted because the fields are immutable.
|
2024-12-14 01:15:08 +00:00
|
|
|
immutable,
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Field keys are always strings.
|
2024-12-14 01:15:08 +00:00
|
|
|
type field-key = string;
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
type field-value = list<u8>;
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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`.
|
2024-12-14 01:15:08 +00:00
|
|
|
resource fields {
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Construct an empty HTTP Fields.
|
|
|
|
///
|
|
|
|
/// The resulting `fields` is mutable.
|
2024-12-14 01:15:08 +00:00
|
|
|
constructor();
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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. In a valid Fields, all keys
|
|
|
|
/// and values are valid UTF-8 strings. However, values are not always
|
|
|
|
/// well-formed, so they are represented as a raw list of bytes.
|
|
|
|
///
|
|
|
|
/// An error result will be returned if any header or value was
|
|
|
|
/// syntactically invalid, or if a header was forbidden.
|
2024-12-14 01:15:08 +00:00
|
|
|
from-list: static func(entries: list<tuple<field-key, field-value>>) -> result<fields, header-error>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Get all of the values corresponding to a key. If the key is not present
|
|
|
|
/// in this `fields`, 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
get: func(name: field-key) -> list<field-value>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Returns `true` when the key is present in this `fields`. If the key is
|
|
|
|
/// syntactically invalid, `false` is returned.
|
2024-12-14 01:15:08 +00:00
|
|
|
has: func(name: field-key) -> bool;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
set: func(name: field-key, value: list<field-value>) -> result<_, header-error>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
delete: func(name: field-key) -> result<_, header-error>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
append: func(name: field-key, value: field-value) -> result<_, header-error>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
entries: func() -> list<tuple<field-key, field-value>>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Make a deep copy of the Fields. Equivelant in behavior to calling the
|
|
|
|
/// `fields` constructor on the return value of `entries`. The resulting
|
|
|
|
/// `fields` is mutable.
|
2024-12-14 01:15:08 +00:00
|
|
|
clone: func() -> fields;
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Headers is an alias for Fields.
|
2024-12-14 01:15:08 +00:00
|
|
|
type headers = fields;
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Trailers is an alias for Fields.
|
2024-12-14 01:15:08 +00:00
|
|
|
type trailers = fields;
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Represents an incoming HTTP Request.
|
2024-12-14 01:15:08 +00:00
|
|
|
resource incoming-request {
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Returns the method of the incoming request.
|
2024-12-14 01:15:08 +00:00
|
|
|
method: func() -> method;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Returns the path with query parameters from the request, as a string.
|
2024-12-14 01:15:08 +00:00
|
|
|
path-with-query: func() -> option<string>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Returns the protocol scheme from the request.
|
2024-12-14 01:15:08 +00:00
|
|
|
scheme: func() -> option<scheme>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Returns the authority from the request, if it was present.
|
2024-12-14 01:15:08 +00:00
|
|
|
authority: func() -> option<string>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
headers: func() -> headers;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Gives the `incoming-body` associated with this request. Will only
|
|
|
|
/// return success at most once, and subsequent calls will return error.
|
2024-12-14 01:15:08 +00:00
|
|
|
consume: func() -> result<incoming-body>;
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Represents an outgoing HTTP Request.
|
2024-12-14 01:15:08 +00:00
|
|
|
resource outgoing-request {
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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`.
|
2024-12-14 01:15:08 +00:00
|
|
|
constructor(headers: headers);
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
body: func() -> result<outgoing-body>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Get the Method for the Request.
|
2024-12-14 01:15:08 +00:00
|
|
|
method: func() -> method;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Set the Method for the Request. Fails if the string present in a
|
|
|
|
/// `method.other` argument is not a syntactically valid method.
|
2024-12-14 01:15:08 +00:00
|
|
|
set-method: func(method: method) -> result;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Get the combination of the HTTP Path and Query for the Request.
|
|
|
|
/// When `none`, this represents an empty Path and empty Query.
|
2024-12-14 01:15:08 +00:00
|
|
|
path-with-query: func() -> option<string>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
set-path-with-query: func(path-with-query: option<string>) -> result;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Get the HTTP Related Scheme for the Request. When `none`, the
|
|
|
|
/// implementation may choose an appropriate default scheme.
|
2024-12-14 01:15:08 +00:00
|
|
|
scheme: func() -> option<scheme>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
set-scheme: func(scheme: option<scheme>) -> result;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Get the HTTP Authority for the Request. 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
authority: func() -> option<string>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Set the HTTP Authority for the Request. 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
set-authority: func(authority: option<string>) -> result;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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 transfered to
|
|
|
|
/// another component by e.g. `outgoing-handler.handle`.
|
2024-12-14 01:15:08 +00:00
|
|
|
headers: func() -> headers;
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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`.
|
2024-12-14 01:15:08 +00:00
|
|
|
resource request-options {
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Construct a default `request-options` value.
|
2024-12-14 01:15:08 +00:00
|
|
|
constructor();
|
2024-12-16 19:34:52 +00:00
|
|
|
/// The timeout for the initial connect to the HTTP Server.
|
2024-12-14 01:15:08 +00:00
|
|
|
connect-timeout: func() -> option<duration>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Set the timeout for the initial connect to the HTTP Server. An error
|
|
|
|
/// return value indicates that this timeout is not supported.
|
2024-12-14 01:15:08 +00:00
|
|
|
set-connect-timeout: func(duration: option<duration>) -> result;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// The timeout for receiving the first byte of the Response body.
|
2024-12-14 01:15:08 +00:00
|
|
|
first-byte-timeout: func() -> option<duration>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Set the timeout for receiving the first byte of the Response body. An
|
|
|
|
/// error return value indicates that this timeout is not supported.
|
2024-12-14 01:15:08 +00:00
|
|
|
set-first-byte-timeout: func(duration: option<duration>) -> result;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// The timeout for receiving subsequent chunks of bytes in the Response
|
|
|
|
/// body stream.
|
2024-12-14 01:15:08 +00:00
|
|
|
between-bytes-timeout: func() -> option<duration>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
set-between-bytes-timeout: func(duration: option<duration>) -> result;
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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`.
|
2024-12-14 01:15:08 +00:00
|
|
|
resource response-outparam {
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
set: static func(param: response-outparam, response: result<outgoing-response, error-code>);
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// This type corresponds to the HTTP standard Status Code.
|
2024-12-14 01:15:08 +00:00
|
|
|
type status-code = u16;
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Represents an incoming HTTP Response.
|
2024-12-14 01:15:08 +00:00
|
|
|
resource incoming-response {
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Returns the status code from the incoming response.
|
2024-12-14 01:15:08 +00:00
|
|
|
status: func() -> status-code;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
headers: func() -> headers;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Returns the incoming body. May be called at most once. Returns error
|
|
|
|
/// if called additional times.
|
2024-12-14 01:15:08 +00:00
|
|
|
consume: func() -> result<incoming-body>;
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
resource incoming-body {
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
%stream: func() -> result<input-stream>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Takes ownership of `incoming-body`, and returns a `future-trailers`.
|
|
|
|
/// This function will trap if the `input-stream` child is still alive.
|
2024-12-14 01:15:08 +00:00
|
|
|
finish: static func(this: incoming-body) -> future-trailers;
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Represents a future which may eventaully 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
resource future-trailers {
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Returns a pollable which becomes ready when either the trailers have
|
|
|
|
/// been received, or an error has occured. When this pollable is ready,
|
|
|
|
/// the `get` method will return `some`.
|
2024-12-14 01:15:08 +00:00
|
|
|
subscribe: func() -> pollable;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Returns the contents of the trailers, or an error which occured,
|
|
|
|
/// 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 occured 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
get: func() -> option<result<result<option<trailers>, error-code>>>;
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Represents an outgoing HTTP Response.
|
2024-12-14 01:15:08 +00:00
|
|
|
resource outgoing-response {
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
constructor(headers: headers);
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Get the HTTP Status Code for the Response.
|
2024-12-14 01:15:08 +00:00
|
|
|
status-code: func() -> status-code;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Set the HTTP Status Code for the Response. Fails if the status-code
|
|
|
|
/// given is not a valid http status code.
|
2024-12-14 01:15:08 +00:00
|
|
|
set-status-code: func(status-code: status-code) -> result;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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 transfered to
|
|
|
|
/// another component by e.g. `outgoing-handler.handle`.
|
2024-12-14 01:15:08 +00:00
|
|
|
headers: func() -> headers;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
body: func() -> result<outgoing-body>;
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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 occured. The implementation should propogate 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
resource outgoing-body {
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
write: func() -> result<output-stream>;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
finish: static func(this: outgoing-body, trailers: option<trailers>) -> result<_, error-code>;
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Represents a future which may eventaully 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
resource future-incoming-response {
|
2024-12-16 19:34:52 +00:00
|
|
|
/// Returns a pollable which becomes ready when either the Response has
|
|
|
|
/// been received, or an error has occured. When this pollable is ready,
|
|
|
|
/// the `get` method will return `some`.
|
2024-12-14 01:15:08 +00:00
|
|
|
subscribe: func() -> pollable;
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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 recieved successfully, or that an error
|
|
|
|
/// occured. Errors may also occur while consuming the response body,
|
|
|
|
/// but those will be reported by the `incoming-body` and its
|
|
|
|
/// `output-stream` child.
|
2024-12-14 01:15:08 +00:00
|
|
|
get: func() -> option<result<result<incoming-response, error-code>>>;
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
http-error-code: func(err: borrow<io-error>) -> option<error-code>;
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// This interface defines a handler of incoming HTTP Requests. It should
|
|
|
|
/// be exported by components which can respond to HTTP Requests.
|
2024-12-14 01:15:08 +00:00
|
|
|
interface incoming-handler {
|
|
|
|
use types.{incoming-request, response-outparam};
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.
|
2024-12-14 01:15:08 +00:00
|
|
|
handle: func(request: incoming-request, response-out: response-outparam);
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// This interface defines a handler of outgoing HTTP Requests. It should be
|
|
|
|
/// imported by components which wish to make HTTP Requests.
|
2024-12-14 01:15:08 +00:00
|
|
|
interface outgoing-handler {
|
|
|
|
use types.{outgoing-request, request-options, future-incoming-response, error-code};
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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`.
|
2024-12-14 01:15:08 +00:00
|
|
|
handle: func(request: outgoing-request, options: option<request-options>) -> result<future-incoming-response, error-code>;
|
|
|
|
}
|
|
|
|
|
2024-12-16 19:34:52 +00:00
|
|
|
/// 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.2.0;
|
|
|
|
import wasi:io/error@0.2.0;
|
|
|
|
import wasi:io/poll@0.2.0;
|
|
|
|
import wasi:io/streams@0.2.0;
|
|
|
|
import wasi:cli/stdout@0.2.0;
|
|
|
|
import wasi:cli/stderr@0.2.0;
|
|
|
|
import wasi:cli/stdin@0.2.0;
|
|
|
|
import wasi:clocks/monotonic-clock@0.2.0;
|
|
|
|
import types;
|
|
|
|
import outgoing-handler;
|
|
|
|
import wasi:clocks/wall-clock@0.2.0;
|
|
|
|
|
|
|
|
export incoming-handler;
|
|
|
|
}
|