Replaces http wasm middleware with more flexible implementation (#2922)

Currently, http wasm middleware uses a proof of concept simple rewrite
function. This replaces it with a faster executing and more complete
middleware, http-wasm, added https://github.com/http-wasm/components-contrib/pull/2

Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
Crypt Keeper 2023-03-20 08:12:25 +08:00 committed by GitHub
parent ed26d8681f
commit 570700769c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 64 additions and 16 deletions

View File

@ -11,10 +11,11 @@ WebAssembly is a way to safely run code compiled in other languages. Runtimes
execute WebAssembly Modules (Wasm), which are most often binaries with a `.wasm` execute WebAssembly Modules (Wasm), which are most often binaries with a `.wasm`
extension. extension.
The Wasm [HTTP middleware]({{< ref middleware.md >}}) allows you to rewrite a The Wasm [HTTP middleware]({{< ref middleware.md >}}) allows you to manipulate
request URI with custom logic compiled to a Wasm binary. In other words, you an incoming request or serve a response with custom logic compiled to a Wasm
can extend Dapr using external files that are not pre-compiled into the `daprd` binary. In other words, you can extend Dapr using external files that are not
binary. Dapr embeds [wazero](https://wazero.io) to accomplish this without CGO. pre-compiled into the `daprd` binary. Dapr embeds [wazero](https://wazero.io)
to accomplish this without CGO.
Wasm modules are loaded from a filesystem path. On Kubernetes, see [mounting Wasm modules are loaded from a filesystem path. On Kubernetes, see [mounting
volumes to the Dapr sidecar]({{< ref kubernetes-volume-mounts.md >}}) to configure volumes to the Dapr sidecar]({{< ref kubernetes-volume-mounts.md >}}) to configure
@ -28,27 +29,21 @@ kind: Component
metadata: metadata:
name: wasm name: wasm
spec: spec:
type: middleware.http.wasm.basic type: middleware.http.wasm
version: v1 version: v1
metadata: metadata:
- name: path - name: path
value: "./hello.wasm" value: "./router.wasm"
- name: poolSize
value: 1
``` ```
## Spec metadata fields ## Spec metadata fields
Minimally, a user must specify a Wasm binary that contains the custom logic Minimally, a user must specify a Wasm binary implements the [http-handler](https://http-wasm.io/http-handler/).
used to rewrite requests. An instance of the Wasm binary is not safe to use How to compile this is described later.
concurrently. The below configuration fields control both the binary to
instantiate and how large an instance pool to use. A larger pool allows higher
concurrency while consuming more memory.
| Field | Details | Required | Example | | Field | Details | Required | Example |
|----------|----------------------------------------------------------------|----------|----------------| |----------|----------------------------------------------------------------|----------|----------------|
| path | A relative or absolute path to the Wasm binary to instantiate. | true | "./hello.wasm" | | path | A relative or absolute path to the Wasm binary to instantiate. | true | "./hello.wasm" |
| poolSize | Number of concurrent instances of the Wasm binary. Default: 10 | false | 1 |
## Dapr configuration ## Dapr configuration
@ -64,7 +59,60 @@ spec:
httpPipeline: httpPipeline:
handlers: handlers:
- name: wasm - name: wasm
type: middleware.http.wasm.basic type: middleware.http.wasm
```
*Note*: WebAssembly middleware uses more resources than native middleware. This
result in a resource constraint faster than the same logic in native code.
Production usage should [Control max concurrency]({{< ref control-concurrency.md >}}).
### Generating Wasm
This component lets you manipulate an incoming request or serve a response with
custom logic compiled using the [http-handler](https://http-wasm.io/http-handler/)
Application Binary Interface (ABI). The `handle_request` function receives an
incoming request and can manipulate it or serve a response as necessary.
To compile your Wasm, you must compile source using a http-handler compliant
guest SDK such as [TinyGo](https://github.com/http-wasm/http-wasm-guest-tinygo).
Here's an example in TinyGo:
```go
package main
import (
"strings"
"github.com/http-wasm/http-wasm-guest-tinygo/handler"
"github.com/http-wasm/http-wasm-guest-tinygo/handler/api"
)
func main() {
handler.HandleRequestFn = handleRequest
}
// handleRequest implements a simple HTTP router.
func handleRequest(req api.Request, resp api.Response) (next bool, reqCtx uint32) {
// If the URI starts with /host, trim it and dispatch to the next handler.
if uri := req.GetURI(); strings.HasPrefix(uri, "/host") {
req.SetURI(uri[5:])
next = true // proceed to the next handler on the host.
return
}
// Serve a static response
resp.Headers().Set("Content-Type", "text/plain")
resp.Body().WriteString("hello")
return // skip the next handler, as we wrote a response.
}
```
If using TinyGo, compile as shown below and set the spec metadata field named
"path" to the location of the output (ex "router.wasm"):
```bash
tinygo build -o router.wasm -scheduler=none --no-debug -target=wasi router.go`
``` ```
### Generating Wasm ### Generating Wasm
@ -108,4 +156,4 @@ tinygo build -o example.wasm -scheduler=none --no-debug -target=wasi example.go
- [Middleware]({{< ref middleware.md >}}) - [Middleware]({{< ref middleware.md >}})
- [Configuration concept]({{< ref configuration-concept.md >}}) - [Configuration concept]({{< ref configuration-concept.md >}})
- [Configuration overview]({{< ref configuration-overview.md >}}) - [Configuration overview]({{< ref configuration-overview.md >}})
- [waPC protocol](https://wapc.io/docs/spec/) - [Control max concurrency]({{< ref control-concurrency.md >}})