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 @@
+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:
@@ -621,9 +625,9 @@ the output stream.
own<input-stream
>
-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
@@ -669,33 +673,46 @@ initially returning a response.
protocol-error
: string
unexpected-error
: string
+
+string
+Field keys are always strings.
+
+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.
fields
-
-#### `type trailers`
-[`fields`](#fields)
-
-#### `resource incoming-request`
+
Headers is an alias for Fields.
+
+fields
+Trailers is an alias for Fields.
+
-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.
@@ -711,63 +728,76 @@ stream.
Functions
-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
-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
-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
+Delete all values for a key. Does nothing if no values for the key
+exist.
Params
+Append a value for a key. Does not change or delete any existing
+values for that key.
Params
-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
-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
>
-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
-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
-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
-Returns the status code from the incoming-response
.
+Returns the status code from the incoming response.
Params
-Returns the headers from the incoming-response
.
+Returns the headers from the incoming response.
Params
-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
-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
-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
-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
-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
-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
-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
-
-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
.
Params
Return values
-
-Pollable that resolves when the get
method will resolve to a Some
-result.
+
+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
+This interface defines a handler of outgoing HTTP Requests. It should be
+imported by components which wish to make HTTP Requests.
Types
@@ -1028,6 +1100,14 @@ result.
----
Functions
+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
+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