This repository was archived by the owner on Oct 13, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 22
feat: add basic scaffolding for wasi http #85
Merged
eduardomourar
merged 20 commits into
bytecodealliance:main
from
eduardomourar:feat/wasi-http-experimental
Mar 17, 2023
Merged
Changes from 13 commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
c3af8fd
feat: add wasi http experimental
eduardomourar e707e13
feat: add bindings crate
eduardomourar c5da583
feat: return monadic type for http request
eduardomourar 6b7faa4
chore: rename main http function to send
eduardomourar 8c6043e
chore: update wit-bindgen in bindings crate
eduardomourar 9dc2233
chore: change http method to enum
eduardomourar 72116e3
chore: remove http status error
eduardomourar b2382e6
Merge branch 'main' into feat/wasi-http-experimental
eduardomourar bae5545
feat: use new wasi-http wit definition
eduardomourar 922f4a7
Merge remote-tracking branch 'origin/main' into feat/wasi-http-experi…
eduardomourar dd74ffc
Merge remote-tracking branch 'origin/main' into feat/wasi-http-experi…
eduardomourar 1e38e23
chore: add basic scaffolding for wasi http
eduardomourar e8cbfcd
Merge remote-tracking branch 'origin/main' into feat/wasi-http-experi…
eduardomourar 0bb1f0e
chore: revert rename for http types
eduardomourar 533894a
chore: changes based on review feedback
eduardomourar 0933bc4
chore: add modules to verify
eduardomourar 09b0c8d
chore: include features wasi bindings
eduardomourar 7f41229
chore: update lock file
eduardomourar bce17d1
chore: fix formatting
eduardomourar cdac89d
chore: fix casing for http imported names
eduardomourar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| use crate::{ | ||
| wasi, | ||
| wasi::http_types::{ | ||
| Error as HttpError, FutureIncomingResponse as Response, Method, OutgoingRequest as Request, | ||
| RequestOptions, | ||
| }, | ||
| WasiCtx, | ||
| }; | ||
|
|
||
| #[async_trait::async_trait] | ||
| impl wasi::default_outgoing_http::Host for WasiCtx { | ||
| async fn handle<'a>( | ||
| &'a mut self, | ||
| _req: Request, | ||
| _options: Option<RequestOptions>, | ||
| ) -> wasmtime::Result<Response> { | ||
| todo!() | ||
| } | ||
| } | ||
eduardomourar marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| impl From<reqwest::Error> for HttpError { | ||
| fn from(e: reqwest::Error) -> Self { | ||
| Self::UnexpectedError(e.to_string()) | ||
| } | ||
| } | ||
|
|
||
| impl From<Method> for reqwest::Method { | ||
| fn from(method: Method) -> Self { | ||
| match method { | ||
| Method::Get => reqwest::Method::GET, | ||
| Method::Post => reqwest::Method::POST, | ||
| Method::Put => reqwest::Method::PUT, | ||
| Method::Delete => reqwest::Method::DELETE, | ||
| Method::Patch => reqwest::Method::PATCH, | ||
| Method::Connect => reqwest::Method::CONNECT, | ||
| Method::Trace => reqwest::Method::TRACE, | ||
| Method::Head => reqwest::Method::HEAD, | ||
| Method::Options => reqwest::Method::OPTIONS, | ||
| _ => panic!("failed due to unsupported method, currently supported methods are: GET, POST, PUT, DELETE, PATCH, CONNECT, TRACE, HEAD, and OPTIONS"), | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| use crate::{ | ||
| wasi, | ||
| wasi::http_types::{IncomingRequest as Request, ResponseOutparam as Response}, | ||
| WasiCtx, | ||
| }; | ||
|
|
||
| #[async_trait::async_trait] | ||
| impl wasi::http::Host for WasiCtx { | ||
| async fn handle<'a>(&'a mut self, _req: Request, _resp: Response) -> anyhow::Result<()> { | ||
| todo!() | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,157 @@ | ||
| // 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. | ||
| default interface http-types { | ||
| use io.streams.{input-stream, output-stream} | ||
| use poll.poll.{pollable} | ||
|
|
||
| // This type corresponds to HTTP standard Methods. | ||
| variant method { | ||
| get, | ||
| head, | ||
| post, | ||
| put, | ||
| delete, | ||
| connect, | ||
| options, | ||
| trace, | ||
| patch, | ||
| other(string) | ||
| } | ||
|
|
||
| // This type corresponds to HTTP standard Related Schemes. | ||
| variant scheme { | ||
| HTTP, | ||
| HTTPS, | ||
| other(string) | ||
| } | ||
|
|
||
| // TODO: perhaps better align with HTTP semantics? | ||
| // This type enumerates the different kinds of errors that may occur when | ||
| // initially returning a response. | ||
| variant error { | ||
| invalid-url(string), | ||
| timeout-error(string), | ||
| protocol-error(string), | ||
| unexpected-error(string) | ||
| } | ||
|
|
||
| // This following block defines the `fields` resource which corresponds to | ||
| // HTTP standard Fields. Soon, when resource types are added, the `type | ||
| // fields = u32` type alias can be replaced by a proper `resource fields` | ||
| // definition containing all the functions using the method syntactic sugar. | ||
| type fields = u32 | ||
| drop-fields: func(fields: fields) | ||
| new-fields: func(entries: list<tuple<string,string>>) -> fields | ||
| fields-get: func(fields: fields, name: string) -> list<string> | ||
| fields-set: func(fields: fields, name: string, value: list<string>) | ||
| fields-delete: func(fields: fields, name: string) | ||
| fields-append: func(fields: fields, name: string, value: string) | ||
| fields-entries: func(fields: fields) -> list<tuple<string,string>> | ||
| fields-clone: func(fields: fields) -> fields | ||
|
|
||
| type headers = fields | ||
| type trailers = fields | ||
|
|
||
| // The following block defines stream types which corresponds to the HTTP | ||
| // standard Contents and Trailers. With Preview3, all of these fields can be | ||
| // replaced by a stream<u8, option<trailers>>. In the interim, we need to | ||
| // build on separate resource types defined by `wasi:io/streams`. The | ||
| // `finish-` functions emulate the stream's result value and MUST be called | ||
| // exactly once after the final read/write from/to the stream before dropping | ||
| // the stream. | ||
| type incoming-stream = input-stream | ||
| type outgoing-stream = output-stream | ||
| finish-incoming-stream: func(s: incoming-stream) -> option<trailers> | ||
| finish-outgoing-stream: func(s: outgoing-stream, trailers: option<trailers>) | ||
|
|
||
| // The following block defines the `incoming-request` and `outgoing-request` | ||
| // resource types that correspond to HTTP standard Requests. Soon, when | ||
| // resource types are added, the `u32` type aliases can be replaced by | ||
| // proper `resource` type definitions containing all the functions as | ||
| // methods. Later, Preview2 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). | ||
| type incoming-request = u32 | ||
| type outgoing-request = u32 | ||
| drop-incoming-request: func(request: incoming-request) | ||
| drop-outgoing-request: func(request: outgoing-request) | ||
| incoming-request-method: func(request: incoming-request) -> method | ||
| incoming-request-path: func(request: incoming-request) -> string | ||
| incoming-request-query: func(request: incoming-request) -> string | ||
| incoming-request-scheme: func(request: incoming-request) -> option<scheme> | ||
| incoming-request-authority: func(request: incoming-request) -> string | ||
| incoming-request-headers: func(request: incoming-request) -> headers | ||
| incoming-request-consume: func(request: incoming-request) -> result<incoming-stream> | ||
| new-outgoing-request: func( | ||
| method: method, | ||
| path: string, | ||
| query: string, | ||
| scheme: option<scheme>, | ||
| authority: string, | ||
| headers: headers | ||
| ) -> outgoing-request | ||
| outgoing-request-write: func(request: outgoing-request) -> result<outgoing-stream> | ||
|
|
||
| // Additional optional parameters that can be set when making a request. | ||
| record request-options { | ||
| // The following timeouts are specific to the HTTP protocol and work | ||
| // independently of the overall timeouts passed to `io.poll.poll-oneoff`. | ||
|
|
||
| // The timeout for the initial connect. | ||
| connect-timeout-ms: option<u32>, | ||
|
|
||
| // The timeout for receiving the first byte of the response body. | ||
| first-byte-timeout-ms: option<u32>, | ||
|
|
||
| // The timeout for receiving the next chunk of bytes in the response body | ||
| // stream. | ||
| between-bytes-timeout-ms: option<u32> | ||
| } | ||
|
|
||
| // The following block defines a special resource type used by the | ||
| // `wasi:http/incoming-handler` interface. When resource types are added, this | ||
| // block can be replaced by a proper `resource response-outparam { ... }` | ||
| // definition. Later, with Preview3, the need for an outparam goes away entirely | ||
| // (the `wasi:http/handler` interface used for both incoming and outgoing can | ||
| // simply return a `stream`). | ||
| type response-outparam = u32 | ||
| drop-response-outparam: func(response: response-outparam) | ||
| set-response-outparam: func(response: result<outgoing-response, error>) -> result | ||
|
|
||
| // This type corresponds to the HTTP standard Status Code. | ||
| type status-code = u16 | ||
|
|
||
| // The following block defines the `incoming-response` and `outgoing-response` | ||
| // resource types that correspond to HTTP standard Responses. Soon, when | ||
| // resource types are added, the `u32` type aliases can be replaced by proper | ||
| // `resource` type definitions containing all the functions as methods. Later, | ||
| // Preview2 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). | ||
| type incoming-response = u32 | ||
| type outgoing-response = u32 | ||
| drop-incoming-response: func(response: incoming-response) | ||
| drop-outgoing-response: func(response: outgoing-response) | ||
| incoming-response-status: func(response: incoming-response) -> status-code | ||
| incoming-response-headers: func(response: incoming-response) -> headers | ||
| incoming-response-consume: func(response: incoming-response) -> result<incoming-stream> | ||
| new-outgoing-response: func( | ||
| status-code: status-code, | ||
| headers: headers | ||
| ) -> outgoing-response | ||
| outgoing-response-write: func(response: outgoing-response) -> result<outgoing-stream> | ||
|
|
||
| // The following block defines a special resource type used by the | ||
| // `wasi:http/outgoing-handler` interface to emulate | ||
| // `future<result<response, error>>` 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 | ||
| // `io.poll.poll-oneoff`. | ||
| type future-incoming-response = u32 | ||
| drop-future-incoming-response: func(f: future-incoming-response) | ||
| future-incoming-response-get: func(f: future-incoming-response) -> option<result<incoming-response, error>> | ||
| listen-to-future-incoming-response: func(f: future-incoming-response) -> pollable | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| // 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. | ||
| // | ||
| default interface incoming-handler { | ||
| use pkg.http-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 `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. | ||
| handle: func( | ||
| request: incoming-request, | ||
| response-out: response-outparam | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| // 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. | ||
| // | ||
| default interface outgoing-handler { | ||
| use pkg.http-types.{outgoing-request, request-options, future-incoming-response} | ||
|
|
||
| // 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<request-options> | ||
| ) -> future-incoming-response | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.