diff --git a/wit/http2-handler.wit b/wit/http2-handler.wit new file mode 100644 index 0000000..bfde8a7 --- /dev/null +++ b/wit/http2-handler.wit @@ -0,0 +1,57 @@ +/// This interface defines a handler of incoming HTTP/2 Requests. It should +/// be exported by components which can respond to HTTP/2 Requests. +/// +/// Note: This interface specifically enforces use of HTTP/2, and must not be +/// provided in environments that aren't able to provide an HTTP/2 connection +/// or otherwise implement the full semantics of an HTTP/2 connection. +@since(version = 0.2.2) +interface http2-incoming-handler { + @since(version = 0.2.2) + use types.{incoming-request, response-outparam}; + + /// This function is invoked with an incoming HTTP Request, and a resource + /// `response-outparam` which provides the capability to reply with an HTTP + /// Response. The response is sent by calling the `response-outparam.set` + /// method, which allows execution to continue after the response has been + /// sent. This enables both streaming to the response body, and performing other + /// work. + /// + /// The implementor of this function must write a response to the + /// `response-outparam` before returning, or else the caller will respond + /// with an error on its behalf. + @since(version = 0.2.2) + handle: func( + request: incoming-request, + response-out: response-outparam + ); +} + +/// This interface defines a handler of outgoing HTTP/2 Requests. It should be +/// imported by components which wish to make HTTP/2 Requests. +/// +/// Note: This interface specifically enforces use of HTTP/2, and must not be +/// provided in environments that aren't able to provide an HTTP/2 connection +/// or otherwise implement the full semantics of an HTTP/2 connection. +@since(version = 0.2.2) +interface http2-outgoing-handler { + @since(version = 0.2.2) + use types.{ + outgoing-request, request-options, future-incoming-response, error-code + }; + + /// This function is invoked with an outgoing HTTP Request, and it returns + /// a resource `future-incoming-response` which represents an HTTP Response + /// which may arrive in the future. + /// + /// The `options` argument accepts optional parameters for the HTTP + /// protocol's transport layer. + /// + /// This function may return an error if the `outgoing-request` is invalid + /// or not allowed to be made. Otherwise, protocol errors are reported + /// through the `future-incoming-response`. + @since(version = 0.2.2) + handle: func( + request: outgoing-request, + options: option + ) -> result; +} diff --git a/wit/proxy.wit b/wit/proxy.wit index 415d2ee..5b09fc1 100644 --- a/wit/proxy.wit +++ b/wit/proxy.wit @@ -1,9 +1,10 @@ -package wasi:http@0.2.1; +package wasi:http@0.2.2; -/// The `wasi:http/imports` world imports all the APIs for HTTP proxies. +/// The `wasi:http/imports-no-handler` world imports all the APIs for HTTP proxies +/// except for the `outgoing-handler`. /// It is intended to be `include`d in other worlds. -@since(version = 0.2.0) -world imports { +@since(version = 0.2.2) +world imports-no-handler { /// HTTP proxies have access to time and randomness. @since(version = 0.2.0) import wasi:clocks/monotonic-clock@0.2.1; @@ -25,6 +26,14 @@ world imports { /// when this import is properly removed. @since(version = 0.2.0) import wasi:cli/stdin@0.2.1; +} + +/// The `wasi:http/imports` world imports all the APIs for HTTP proxies. +/// It is intended to be `include`d in other worlds. +@since(version = 0.2.0) +world imports { + @since(version = 0.2.0) + include imports-no-handler; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). @@ -36,6 +45,8 @@ world imports { /// 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. +/// `wasi:http/proxy` doesn't specify the HTTP version to be used, leaving that +/// decision to the host. @since(version = 0.2.0) world proxy { @since(version = 0.2.0) @@ -48,3 +59,29 @@ world proxy { @since(version = 0.2.0) export incoming-handler; } + +/// The `wasi:http/http2-proxy` world captures a widely-implementable intersection of +/// hosts that includes HTTP/2 forward and reverse proxies. Components targeting +/// this world may concurrently stream in and out any number of incoming and +/// outgoing HTTP requests. +/// In difference to `wasi:http/proxy`, `wasi:http/http2-proxy` specifies that exactly +/// HTTP/2 must be used, making it usable for scenarios that require HTTP/2. +/// In particular, gRPC must use HTTP/2 as the transport, so gRPC clients and servers +/// should target this world. +@since(version = 0.2.2) +world http2-proxy { + @since(version = 0.2.2) + include imports-no-handler; + + /// This is the default handler to use when user code simply wants to make an + /// HTTP request (e.g., via `fetch()`). + @since(version = 0.2.2) + import http2-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`. + @since(version = 0.2.2) + export http2-incoming-handler; +} diff --git a/wit/types.wit b/wit/types.wit index 30b3642..e8c1552 100644 --- a/wit/types.wit +++ b/wit/types.wit @@ -34,6 +34,16 @@ interface types { HTTPS, other(string) } + } + + /// This type corresponds to HTTP protocol versions. + @since(version = 0.2.2) + variant http-version { + HTTP11, + HTTP2, + HTTP3 + other(string) + } /// These cases are inspired by the IANA HTTP Proxy Error Types: /// https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types @@ -149,9 +159,9 @@ interface types { /// /// Field keys should always be treated as case insensitive by the `fields` /// resource for the purposes of equality checking. - /// + /// /// # Deprecation - /// + /// /// This type has been deprecated in favor of the `field-name` type. @since(version = 0.2.0) @deprecated(version = 0.2.2) @@ -273,6 +283,10 @@ interface types { @since(version = 0.2.0) resource incoming-request { + /// Returns the HTTP version of the incoming request. + @since(version = 0.2.2) + http-version: func() -> http-version; + /// Returns the method of the incoming request. @since(version = 0.2.0) method: func() -> method; @@ -460,6 +474,10 @@ interface types { @since(version = 0.2.0) resource incoming-response { + /// Returns the HTTP version of the incoming request. + @since(version = 0.2.2) + http-version: func() -> http-version; + /// Returns the status code from the incoming response. @since(version = 0.2.0) status: func() -> status-code;