From 83004fb3d2b196c8f7fb6b19b47f627931c67083 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Oct 2023 14:03:26 -0700 Subject: [PATCH 1/6] handler.wit: convert all comments to doc-comments --- wit/handler.wit | 56 ++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/wit/handler.wit b/wit/handler.wit index 3140d8c..bdec50e 100644 --- a/wit/handler.wit +++ b/wit/handler.wit @@ -1,43 +1,43 @@ -// The `wasi:http/incoming-handler` interface is meant to be exported by -// components and called by the host in response to a new incoming HTTP -// response. -// -// NOTE: in Preview3, this interface will be merged with -// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface -// that takes a `request` parameter and returns a `response` result. -// +/// The `wasi:http/incoming-handler` interface is meant to be exported by +/// components and called by the host in response to a new incoming HTTP +/// response. +/// +/// NOTE: in Preview3, this interface will be merged with +/// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface +/// that takes a `request` parameter and returns a `response` result. +/// interface incoming-handler { use types.{incoming-request, response-outparam}; - // The `handle` function takes an outparam instead of returning its response - // so that the component may stream its response while streaming any other - // request or response bodies. The callee MUST write a response to the - // `response-outparam` and then finish the response before returning. The `handle` - // function is allowed to continue execution after finishing the response's - // output stream. While this post-response execution is taken off the - // critical path, since there is no return value, there is no way to report - // its success or failure. + /// The `handle` function takes an outparam instead of returning its response + /// so that the component may stream its response while streaming any other + /// request or response bodies. The callee MUST write a response to the + /// `response-out` and then finish the response before returning. The caller + /// is expected to start streaming the response once `set-response-outparam` + /// is called and finish streaming the response when `drop-response-outparam` + /// is called. The `handle` function is then allowed to continue executing + /// any post-response logic before returning. While this post-response + /// execution is taken off the critical path, since there is no return value, + /// there is no way to report its success or failure. handle: func( request: incoming-request, response-out: response-outparam ); } -// The `wasi:http/outgoing-handler` interface is meant to be imported by -// components and implemented by the host. -// -// NOTE: in Preview3, this interface will be merged with -// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface -// that takes a `request` parameter and returns a `response` result. -// +/// The `wasi:http/outgoing-handler` interface is meant to be imported by +/// components and implemented by the host. +/// +/// NOTE: in Preview3, this interface will be merged with +/// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface +/// that takes a `request` parameter and returns a `response` result. +/// interface outgoing-handler { use types.{outgoing-request, request-options, future-incoming-response, error}; - // The parameter and result types of the `handle` function allow the caller - // to concurrently stream the bodies of the outgoing request and the incoming - // response. - // Consumes the outgoing-request. Gives an error if the outgoing-request - // is invalid or cannot be satisfied by this handler. + /// The parameter and result types of the `handle` function allow the caller + /// to concurrently stream the bodies of the outgoing request and the incoming + /// response. handle: func( request: outgoing-request, options: option From c6531f00707dd618f62ac76a4c7c08c896691dfc Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Oct 2023 14:04:06 -0700 Subject: [PATCH 2/6] proxy.wit: make all comments doc comments --- wit/proxy.wit | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/wit/proxy.wit b/wit/proxy.wit index 8ee5892..557ab45 100644 --- a/wit/proxy.wit +++ b/wit/proxy.wit @@ -1,34 +1,34 @@ package wasi:http; -// 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. +/// 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 { - // HTTP proxies have access to time and randomness. + /// HTTP proxies have access to time and randomness. import wasi:clocks/wall-clock; import wasi:clocks/monotonic-clock; import wasi:clocks/timezone; import wasi:random/random; - // Proxies have standard output and error streams which are expected to - // terminate in a developer-facing console provided by the host. + /// Proxies have standard output and error streams which are expected to + /// terminate in a developer-facing console provided by the host. import wasi:cli/stdout; import wasi:cli/stderr; - // 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. + /// 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; - // This is the default handler to use when user code simply wants to make an - // HTTP request (e.g., via `fetch()`). + /// This is the default handler to use when user code simply wants to make an + /// HTTP request (e.g., via `fetch()`). import outgoing-handler; - // 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`. + /// 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`. export incoming-handler; } From df00dec2aeab27a06a1433e8f6da9961609dc8dc Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Oct 2023 16:42:07 -0700 Subject: [PATCH 3/6] http types: elaborate takes the liberty of defining new type-aliases field-key and field-value, which make writing the docs a lot clearer Co-authored-by: Trevor Elliott --- wit/handler.wit | 52 +++++---- wit/types.wit | 276 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 224 insertions(+), 104 deletions(-) diff --git a/wit/handler.wit b/wit/handler.wit index bdec50e..21b97a3 100644 --- a/wit/handler.wit +++ b/wit/handler.wit @@ -1,43 +1,39 @@ -/// The `wasi:http/incoming-handler` interface is meant to be exported by -/// components and called by the host in response to a new incoming HTTP -/// response. -/// -/// NOTE: in Preview3, this interface will be merged with -/// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface -/// that takes a `request` parameter and returns a `response` result. -/// +/// This interface defines a handler of incoming HTTP Requests. It should +/// be exported by components which can respond to HTTP Requests. interface incoming-handler { use types.{incoming-request, response-outparam}; - /// The `handle` function takes an outparam instead of returning its response - /// so that the component may stream its response while streaming any other - /// request or response bodies. The callee MUST write a response to the - /// `response-out` and then finish the response before returning. The caller - /// is expected to start streaming the response once `set-response-outparam` - /// is called and finish streaming the response when `drop-response-outparam` - /// is called. The `handle` function is then allowed to continue executing - /// any post-response logic before returning. While this post-response - /// execution is taken off the critical path, since there is no return value, - /// there is no way to report its success or failure. + /// 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. handle: func( request: incoming-request, response-out: response-outparam ); } -/// The `wasi:http/outgoing-handler` interface is meant to be imported by -/// components and implemented by the host. -/// -/// NOTE: in Preview3, this interface will be merged with -/// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface -/// that takes a `request` parameter and returns a `response` result. -/// +/// This interface defines a handler of outgoing HTTP Requests. It should be +/// imported by components which wish to make HTTP Requests. interface outgoing-handler { use types.{outgoing-request, request-options, future-incoming-response, error}; - /// The parameter and result types of the `handle` function allow the caller - /// to concurrently stream the bodies of the outgoing request and the incoming - /// response. + /// 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`. handle: func( request: outgoing-request, options: option diff --git a/wit/types.wit b/wit/types.wit index e589464..2a4b67d 100644 --- a/wit/types.wit +++ b/wit/types.wit @@ -1,6 +1,6 @@ -/// 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. +/// 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. interface types { use wasi:io/streams.{input-stream, output-stream}; use wasi:io/poll.{pollable}; @@ -36,40 +36,69 @@ interface types { 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>; + /// Field keys are always strings. + type field-key = string; - /// 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); + /// Field values should always be UTF-8 encoded strings. However, in + /// reality, HTTP implementations often have to interpret malformed values, + /// so they are provided as a list of bytes. + type field-value = list; - /// Values off wire are not necessarily well formed, so they are given by - /// list instead of string. - entries: func() -> 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. + resource fields { - /// Deep copy of all contents in a fields. + /// Construct an HTTP Fields. + /// + /// 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. + constructor(entries: list>); + + /// Get all of the values corresponding to a key. + get: func(name: field-key) -> list; + + /// Set all of the values for a key. Clears any existing values for that + /// key, if they have been set. + set: func(name: field-key, value: list); + + /// Delete all values for a key. Does nothing if no values for the key + /// exist. + delete: func(name: field-key); + + /// Append a value for a key. Does not change or delete any existing + /// values for that key. + append: func(name: field-key, value: field-value); + + + /// 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. + entries: func() -> list>; + + /// Make a deep copy of the Fields. Equivelant in behavior to calling the + /// `fields` constructor on the return value of `entries` clone: func() -> fields; } + /// Headers is an alias for Fields. type headers = fields; + + /// Trailers is an alias for Fields. type trailers = fields; - /// The following block defines the `incoming-request` and `outgoing-request` - /// resource types that correspond to HTTP standard Requests. Later, Preview3 - /// will allow both types to be merged together into a single `request` type - /// (that uses the single `stream` type mentioned above). The `consume` and - /// `write` methods may only be called once (and return failure thereafter). + /// Represents an incoming HTTP Request. resource incoming-request { + /// Returns the method of the incoming request. method: func() -> method; @@ -82,15 +111,21 @@ interface types { /// Returns the authority from the request, if it was present. authority: func() -> option; - /// Returns the headers from the request. + /// Returns the `headers` from the request. + /// + /// 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. headers: func() -> headers; - /// Will return the incoming-body child at most once. If called more than - /// once, subsequent calls will return error. + /// Gives the `incoming-body` associated with this request. Will only + /// return success at most once, and subsequent calls will return error. consume: func() -> result; } + /// Represents an outgoing HTTP Request. resource outgoing-request { + /// Construct a new `outgoing-request`. constructor( method: method, @@ -105,29 +140,42 @@ interface types { write: func() -> result; } - /// Additional optional parameters that can be set when making a request. + /// Parameters for making an HTTP Request. Each of these parameters is an + /// optional timeout, with the unit in milliseconds, 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-list`. + /// + /// FIXME: Make this a resource to allow it to be optionally extended by + /// future evolution of the standard and/or other interfaces at some later + /// date? 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. + /// The timeout for the initial connect to the HTTP Server. connect-timeout-ms: option, - /// The timeout for receiving the first byte of the response body. + /// 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. + /// The timeout for receiving subsequent chunks 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. 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`). + /// 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`. resource response-outparam { - /// Set the value of the `response-outparam` to indicate either a response, - /// or an error. + + /// 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. set: static func( param: response-outparam, response: result, @@ -137,55 +185,119 @@ interface types { /// 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. Later, Preview3 will allow both types to be merged together - /// into a single `response` type (that uses the single `stream` type - /// mentioned above). The `consume` and `write` methods may only be called - /// once (and return failure thereafter). + /// Represents an incoming HTTP Response. resource incoming-response { - /// Returns the status code from the `incoming-response`. + + /// Returns the status code from the incoming response. status: func() -> status-code; - /// Returns the headers from the `incoming-response`. + /// Returns the headers from the incoming response. headers: func() -> headers; - /// May be called at most once. returns error if called additional times. + /// Returns the incoming body. May be called at most once. returns error + /// if called additional times. 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. 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. + + /// 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. %stream: func() -> result; - /// Takes ownership of incoming-body and will trap if the - /// input-stream child is still alive. + /// Takes ownership of `incoming-body`, and returns a `future-trailers`. + /// This function will trap if the `input-stream` child is still alive. finish: static func(this: incoming-body) -> future-trailers; } + /// 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. resource future-trailers { - /// Pollable that resolves when the the trailers are ready to be consumed. + + /// 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`. subscribe: func() -> pollable; - /// Retrieve reference to trailers, if they are ready. + /// 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 `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. get: func() -> option>; } + /// Represents an outgoing HTTP Response. resource outgoing-response { + /// Construct an `outgoing-response`. constructor(status-code: status-code, headers: borrow); - /// Will give the child outgoing-response at most once. subsequent calls - /// will return an error. + /// 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. Sunsequent + /// calls will return error. + /// + /// FIXME: rename this method to `body`. write: 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 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. resource outgoing-body { - /// Will give the child output-stream at most once. subsequent calls will - /// return an error. + + /// 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. write: func() -> result; /// Finalize an outgoing body, optionally providing trailers. This must be @@ -195,20 +307,32 @@ interface types { 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`. + /// 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. resource future-incoming-response { - /// The option indicates readiness. The outer result must return failure if - /// `get` is called after returning a non-empty result. The inner result - /// indicates whether the incoming response successfully started. + /// 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`. + 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 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. get: func() -> option>>; - /// Pollable that resolves when the `get` method will resolve to a `Some` - /// result. - subscribe: func() -> pollable; } } From bcd52e1e43d200f57f190a67f2f48d6c4f6bb49f Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 18 Oct 2023 09:39:30 -0700 Subject: [PATCH 4/6] Update wit/types.wit Co-authored-by: Luke Wagner --- wit/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wit/types.wit b/wit/types.wit index 2a4b67d..70731f9 100644 --- a/wit/types.wit +++ b/wit/types.wit @@ -39,7 +39,7 @@ interface types { /// Field keys are always strings. type field-key = string; - /// Field values should always be UTF-8 encoded strings. However, in + /// 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. type field-value = list; From 22a9f08457c2cac763f565222ec3708c634775c1 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 18 Oct 2023 09:39:36 -0700 Subject: [PATCH 5/6] Update wit/types.wit Co-authored-by: Luke Wagner --- wit/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wit/types.wit b/wit/types.wit index 70731f9..a903f51 100644 --- a/wit/types.wit +++ b/wit/types.wit @@ -194,7 +194,7 @@ interface types { /// Returns the headers from the incoming response. headers: func() -> headers; - /// Returns the incoming body. May be called at most once. returns error + /// Returns the incoming body. May be called at most once. Returns error /// if called additional times. consume: func() -> result; } From 5e8e68086e0c25c138f9564d08add0ae1896427f Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 18 Oct 2023 09:40:20 -0700 Subject: [PATCH 6/6] markdown generated --- proxy.md | 217 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 153 insertions(+), 64 deletions(-) diff --git a/proxy.md b/proxy.md index b3693b3..203c9cc 100644 --- a/proxy.md +++ b/proxy.md @@ -1,4 +1,8 @@

World proxy

+

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.

  • Imports:

    Import interface wasi:http/types

    -

    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.

    +

    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.


    Types

    type input-stream

    @@ -669,33 +673,46 @@ initially returning a response.

  • protocol-error: string
  • unexpected-error: string
+

type field-key

+

string

+

Field keys are always strings. +

type field-value

+

field-value

+

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.

resource fields

type headers

fields

-

-#### `type trailers` -[`fields`](#fields) -

-#### `resource incoming-request` +

Headers is an alias for Fields. +

type trailers

+

fields

+

Trailers is an alias for Fields. +

resource incoming-request

resource outgoing-request

record request-options

-

Additional optional parameters that can be set when making a request.

+

Parameters for making an HTTP Request. Each of these parameters is an +optional timeout, with the unit in milliseconds, 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-list.

+

FIXME: Make this a resource to allow it to be optionally extended by +future evolution of the standard and/or other interfaces at some later +date?

Record Fields
  • connect-timeout-ms: option<u32>

    -

    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. +

    The timeout for the initial connect to the HTTP Server.

  • first-byte-timeout-ms: option<u32>

    -

    The timeout for receiving the first byte of the response body. +

    The timeout for receiving the first byte of the Response body.

  • between-bytes-timeout-ms: option<u32>

    -

    The timeout for receiving the next chunk of bytes in the response body -stream. +

    The timeout for receiving subsequent chunks of bytes in the Response +body stream.

resource response-outparam

@@ -711,63 +728,76 @@ stream.

Functions

[constructor]fields: func

-

Multiple values for a header are multiple entries in the list with the -same key.

+

Construct an HTTP Fields.

+

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.

Params
Return values

[method]fields.get: func

-

Values off wire are not necessarily well formed, so they are given by -list instead of string.

+

Get all of the values corresponding to a key.

Params
Return values

[method]fields.set: func

-

Values off wire are not necessarily well formed, so they are given by -list instead of string.

+

Set all of the values for a key. Clears any existing values for that +key, if they have been set.

Params

[method]fields.delete: func

+

Delete all values for a key. Does nothing if no values for the key +exist.

Params

[method]fields.append: func

+

Append a value for a key. Does not change or delete any existing +values for that key.

Params

[method]fields.entries: func

-

Values off wire are not necessarily well formed, so they are given by -list instead of string.

+

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.

Params
Return values

[method]fields.clone: func

-

Deep copy of all contents in a fields.

+

Make a deep copy of the Fields. Equivelant in behavior to calling the +fields constructor on the return value of entries

Params
  • self: borrow<fields>
  • @@ -817,7 +847,10 @@ list instead of string.

  • option<string>

[method]incoming-request.headers: func

-

Returns the headers from the request.

+

Returns the headers from the request.

+

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.

Params

[method]incoming-request.consume: func

-

Will return the incoming-body child at most once. If called more than -once, subsequent calls will return error.

+

Gives the incoming-body associated with this request. Will only +return success at most once, and subsequent calls will return error.

Params

[static]response-outparam.set: func

-

Set the value of the response-outparam to indicate either a response, -or an error.

+

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.

Params

[method]incoming-response.status: func

-

Returns the status code from the incoming-response.

+

Returns the status code from the incoming response.

Params

[method]incoming-response.headers: func

-

Returns the headers from the incoming-response.

+

Returns the headers from the incoming response.

Params

[method]incoming-response.consume: func

-

May be called at most once. returns error if called additional times.

+

Returns the incoming body. May be called at most once. Returns error +if called additional times.

Params

[method]incoming-body.stream: func

-

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.

+

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.

Params
  • self: borrow<incoming-body>
  • @@ -914,8 +959,8 @@ May be called at most once. Returns error if called additional times.

  • result<own<input-stream>>

[static]incoming-body.finish: func

-

Takes ownership of incoming-body and will trap if the -input-stream child is still alive.

+

Takes ownership of incoming-body, and returns a future-trailers. +This function will trap if the input-stream child is still alive.

Params

[method]future-trailers.subscribe: func

-

Pollable that resolves when the the trailers are ready to be consumed.

+

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.

Params

[method]future-trailers.get: func

-

Retrieve reference to trailers, if they are ready.

+

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 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.

Params

[method]outgoing-response.write: func

-

Will give the child outgoing-response at most once. subsequent calls -will return an error.

+

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. Sunsequent +calls will return error.

+

FIXME: rename this method to body.

Params

[method]outgoing-body.write: func

-

Will give the child output-stream at most once. subsequent calls will -return an error.

+

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.

Params
-

[method]future-incoming-response.get: func

-

The option indicates readiness. The outer result must return failure if -get is called after returning a non-empty result. The inner result -indicates whether the incoming response successfully started.

+

[method]future-incoming-response.subscribe: func

+

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.

Params
Return values
-

[method]future-incoming-response.subscribe: func

-

Pollable that resolves when the get method will resolve to a Some -result.

+

[method]future-incoming-response.get: func

+

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.

Params
Return values

Import interface wasi:http/outgoing-handler

+

This interface defines a handler of outgoing HTTP Requests. It should be +imported by components which wish to make HTTP Requests.


Types

type outgoing-request

@@ -1028,6 +1100,14 @@ result.

----

Functions

handle: func

+

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.

Params
  • request: own<outgoing-request>
  • @@ -1049,6 +1129,15 @@ result.

    ----

    Functions

    handle: func

    +

    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.

    Params