Skip to content
This repository was archived by the owner on Apr 24, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,12 @@ TinyGo's official release of WASI target will come soon, and after that you coul
just follow https://tinygo.org/getting-started/ to install the requirement on any platform. Stay tuned!


### compatible Envoy builds

| proxy-wasm-go-sdk| proxy-wasm ABI version | envoyproxy/envoy-wasm| istio/proxyv2|
|:-------------:|:-------------:|:-------------:|:-------------:|
| main | 0.2.0| N/A | v1.17.x |
| v0.0.4 | 0.2.0| N/A | v1.17.x |
| v0.0.3 | 0.2.0| N/A | v1.17.x |
| v0.0.2 | 0.1.0|release/v1.15 | N/A |
### compatible ABI / Envoy builds

| proxy-wasm-go-sdk| proxy-wasm ABI version |istio/proxyv2|
|:-------------:|:-------------:|:-------------:|
| main | 0.2.0| v1.17.x |
| v0.0.4 | 0.2.0| v1.17.x |


## run examples
Expand Down
6 changes: 3 additions & 3 deletions examples/helloworld/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func main() {

type helloWorld struct {
// you must embed the default context so that you need not to reimplement all the methods by yourself
proxywasm.DefaultContext
proxywasm.DefaultRootContext
contextID uint32
}

Expand All @@ -37,14 +37,14 @@ func newHelloWorld(contextID uint32) proxywasm.RootContext {
// override
func (ctx *helloWorld) OnVMStart(int) bool {
proxywasm.LogInfo("proxy_on_vm_start from Go!")
if err := proxywasm.HostCallSetTickPeriodMilliSeconds(tickMilliseconds); err != nil {
if err := proxywasm.SetTickPeriodMilliSeconds(tickMilliseconds); err != nil {
proxywasm.LogCriticalf("failed to set tick period: %v", err)
}
return true
}

// override
func (ctx *helloWorld) OnTick() {
t := proxywasm.HostCallGetCurrentTime()
t := proxywasm.GetCurrentTime()
proxywasm.LogInfof("OnTick on %d, it's %d", ctx.contextID, t)
}
25 changes: 17 additions & 8 deletions examples/helloworld/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package main
import (
"strings"
"testing"
"time"

"github.com/stretchr/testify/require"

"github.com/stretchr/testify/assert"

Expand All @@ -11,23 +14,29 @@ import (
)

func TestHelloWorld_OnTick(t *testing.T) {
ctx := newHelloWorld(100)
host, done := proxytest.NewRootFilterHost(ctx, nil, nil)
defer done() // release the host emulation lock so that other test cases can insert their own host emulation
ctx.OnTick()
opt := proxytest.NewEmulatorOption().
WithNewRootContext(newHelloWorld)
host := proxytest.NewHostEmulator(opt)
defer host.Done() // release the host emulation lock so that other test cases can insert their own host emulation

host.StartVM() // call OnVMStart

time.Sleep(time.Duration(tickMilliseconds) * 4 * time.Millisecond)

logs := host.GetLogs(types.LogLevelInfo)
require.Greater(t, len(logs), 0)
msg := logs[len(logs)-1]

assert.True(t, strings.Contains(msg, "OnTick on"))
}

func TestHelloWorld_OnVMStart(t *testing.T) {
ctx := newHelloWorld(0)
host, done := proxytest.NewRootFilterHost(ctx, nil, nil)
defer done() // release the host emulation lock so that other test cases can insert their own host emulation
opt := proxytest.NewEmulatorOption().
WithNewRootContext(newHelloWorld)
host := proxytest.NewHostEmulator(opt)
defer host.Done() // release the host emulation lock so that other test cases can insert their own host emulation

host.StartVM()
host.StartVM() // call OnVMStart
logs := host.GetLogs(types.LogLevelInfo)
msg := logs[len(logs)-1]

Expand Down
30 changes: 12 additions & 18 deletions examples/http_auth_random/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func main() {

type httpAuthRandom struct {
// you must embed the default context so that you need not to reimplement all the methods by yourself
proxywasm.DefaultContext
proxywasm.DefaultHttpContext
contextID uint32
}

Expand All @@ -39,7 +39,7 @@ func newContext(contextID uint32) proxywasm.HttpContext {

// override default
func (ctx *httpAuthRandom) OnHttpRequestHeaders(int, bool) types.Action {
hs, err := proxywasm.HostCallGetHttpRequestHeaders()
hs, err := proxywasm.GetHttpRequestHeaders()
if err != nil {
proxywasm.LogCriticalf("failed to get request headers: %v", err)
return types.ActionContinue
Expand All @@ -48,19 +48,18 @@ func (ctx *httpAuthRandom) OnHttpRequestHeaders(int, bool) types.Action {
proxywasm.LogInfof("request header: %s: %s", h[0], h[1])
}

if _, err := proxywasm.HostCallDispatchHttpCall(
clusterName, hs, "", [][2]string{}, 50000); err != nil {
if _, err := proxywasm.DispatchHttpCall(clusterName, hs, "", [][2]string{},
50000, httpCallResponseCallback); err != nil {
proxywasm.LogCriticalf("dipatch httpcall failed: %v", err)
return types.ActionContinue
}

proxywasm.LogInfof("http call dispatched to %s", clusterName)

return types.ActionPause
}

// override default
func (ctx *httpAuthRandom) OnHttpCallResponse(_ int, bodySize int, _ int) {
hs, err := proxywasm.HostCallGetHttpCallResponseHeaders()
func httpCallResponseCallback(_ int, bodySize int, _ int) {
hs, err := proxywasm.GetHttpCallResponseHeaders()
if err != nil {

proxywasm.LogCriticalf("failed to get response body: %v", err)
Expand All @@ -71,34 +70,29 @@ func (ctx *httpAuthRandom) OnHttpCallResponse(_ int, bodySize int, _ int) {
proxywasm.LogInfof("response header from %s: %s: %s", clusterName, h[0], h[1])
}

b, err := proxywasm.HostCallGetHttpCallResponseBody(0, bodySize)
b, err := proxywasm.GetHttpCallResponseBody(0, bodySize)
if err != nil {
proxywasm.LogCriticalf("failed to get response body: %v", err)
proxywasm.HostCallResumeHttpRequest()
proxywasm.ResumeHttpRequest()
return
}

s := fnv.New32a()
if _, err := s.Write(b); err != nil {
proxywasm.LogCriticalf("failed to calculate hash: %v", err)
proxywasm.HostCallResumeHttpRequest()
proxywasm.ResumeHttpRequest()
return
}

if s.Sum32()%2 == 0 {
proxywasm.LogInfo("access granted")
proxywasm.HostCallResumeHttpRequest()
proxywasm.ResumeHttpRequest()
return
}

msg := "access forbidden"
proxywasm.LogInfo(msg)
proxywasm.HostCallSendHttpResponse(403, [][2]string{
proxywasm.SendHttpResponse(403, [][2]string{
{"powered-by", "proxy-wasm-go-sdk!!"},
}, msg)
}

// override default
func (ctx *httpAuthRandom) OnLog() {
proxywasm.LogInfof("%d finished", ctx.contextID)
}
46 changes: 32 additions & 14 deletions examples/http_auth_random/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,20 @@ import (
)

func TestHttpAuthRandom_OnHttpRequestHeaders(t *testing.T) {
host, done := proxytest.NewHttpFilterHost(newContext)
defer done()
opt := proxytest.NewEmulatorOption().
WithNewHttpContext(newContext)
host := proxytest.NewHostEmulator(opt)
defer host.Done()

id := host.InitContext()
host.PutRequestHeaders(id, [][2]string{{"key", "value"}}) // OnHttpRequestHeaders called
contextID := host.HttpFilterInitContext()
host.HttpFilterPutRequestHeaders(contextID, [][2]string{{"key", "value"}}) // OnHttpRequestHeaders called

require.True(t, host.IsDispatchCalled(id)) // check if http call is dispatched
require.Equal(t, types.ActionPause, host.GetCurrentAction(id)) // check if the current action is pause
attrs := host.GetCalloutAttributesFromContext(contextID)
require.Equal(t, len(attrs), 1) // verify DispatchHttpCall is called

require.Equal(t, "httpbin", attrs[0].Upstream)
require.Equal(t, types.ActionPause,
host.HttpFilterGetCurrentStreamAction(contextID)) // check if the current action is pause

logs := host.GetLogs(types.LogLevelInfo)
require.GreaterOrEqual(t, len(logs), 2)
Expand All @@ -28,8 +34,10 @@ func TestHttpAuthRandom_OnHttpRequestHeaders(t *testing.T) {
}

func TestHttpAuthRandom_OnHttpCallResponse(t *testing.T) {
host, done := proxytest.NewHttpFilterHost(newContext)
defer done()
opt := proxytest.NewEmulatorOption().
WithNewHttpContext(newContext)
host := proxytest.NewHostEmulator(opt)
defer host.Done()

// http://httpbin.org/uuid
headers := [][2]string{
Expand All @@ -40,20 +48,30 @@ func TestHttpAuthRandom_OnHttpCallResponse(t *testing.T) {
}

// access granted body
id := host.InitContext()
contextID := host.HttpFilterInitContext()
host.HttpFilterPutRequestHeaders(contextID, nil) // OnHttpRequestHeaders called

body := []byte(`{"uuid": "7b10a67a-1c67-4199-835b-cbefcd4a63d4"}`)
host.PutCalloutResponse(id, headers, nil, body)
assert.Nil(t, host.GetSentLocalResponse(id))
attrs := host.GetCalloutAttributesFromContext(contextID)
require.Equal(t, len(attrs), 1) // verify DispatchHttpCall is called

host.PutCalloutResponse(attrs[0].CalloutID, headers, nil, body)
assert.Nil(t, host.HttpFilterGetSentLocalResponse(contextID))

logs := host.GetLogs(types.LogLevelInfo)
require.Greater(t, len(logs), 1)
assert.Equal(t, "access granted", logs[len(logs)-1])

// access denied body
id = host.InitContext()
contextID = host.HttpFilterInitContext()
host.HttpFilterPutRequestHeaders(contextID, nil) // OnHttpRequestHeaders called

body = []byte(`{"uuid": "aaaaaaaa-1c67-4199-835b-cbefcd4a63d4"}`)
host.PutCalloutResponse(id, headers, nil, body)
localResponse := host.GetSentLocalResponse(id) // check local responses
attrs = host.GetCalloutAttributesFromContext(contextID)
require.Equal(t, len(attrs), 1) // verify DispatchHttpCall is called

host.PutCalloutResponse(attrs[0].CalloutID, headers, nil, body)
localResponse := host.HttpFilterGetSentLocalResponse(contextID) // check local responses
assert.NotNil(t, localResponse)
logs = host.GetLogs(types.LogLevelInfo)
assert.Equal(t, "access forbidden", logs[len(logs)-1])
Expand Down
8 changes: 4 additions & 4 deletions examples/http_headers/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func main() {

type httpHeaders struct {
// you must embed the default context so that you need not to reimplement all the methods by yourself
proxywasm.DefaultContext
proxywasm.DefaultHttpContext
contextID uint32
}

Expand All @@ -35,7 +35,7 @@ func newContext(contextID uint32) proxywasm.HttpContext {

// override
func (ctx *httpHeaders) OnHttpRequestHeaders(int, bool) types.Action {
hs, err := proxywasm.HostCallGetHttpRequestHeaders()
hs, err := proxywasm.GetHttpRequestHeaders()
if err != nil {
proxywasm.LogCriticalf("failed to get request headers: %v", err)
}
Expand All @@ -48,7 +48,7 @@ func (ctx *httpHeaders) OnHttpRequestHeaders(int, bool) types.Action {

// override
func (ctx *httpHeaders) OnHttpResponseHeaders(int, bool) types.Action {
hs, err := proxywasm.HostCallGetHttpResponseHeaders()
hs, err := proxywasm.GetHttpResponseHeaders()
if err != nil {
proxywasm.LogCriticalf("failed to get request headers: %v", err)
}
Expand All @@ -60,6 +60,6 @@ func (ctx *httpHeaders) OnHttpResponseHeaders(int, bool) types.Action {
}

// override
func (ctx *httpHeaders) OnLog() {
func (ctx *httpHeaders) OnHttpStreamDone() {
proxywasm.LogInfof("%d finished", ctx.contextID)
}
34 changes: 22 additions & 12 deletions examples/http_headers/main_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -11,31 +12,40 @@ import (
)

func TestHttpHeaders_OnHttpRequestHeaders(t *testing.T) {
host, done := proxytest.NewHttpFilterHost(newContext)
defer done()
id := host.InitContext()
opt := proxytest.NewEmulatorOption().
WithNewHttpContext(newContext)
host := proxytest.NewHostEmulator(opt)
defer host.Done()
id := host.HttpFilterInitContext()

hs := [][2]string{{"key1", "value1"}, {"key2", "value2"}}
host.PutRequestHeaders(id, hs) // call OnHttpRequestHeaders
host.HttpFilterPutRequestHeaders(id, hs) // call OnHttpRequestHeaders

host.HttpFilterCompleteHttpStream(id)

logs := host.GetLogs(types.LogLevelInfo)
require.Greater(t, len(logs), 1)

assert.Equal(t, "request header --> key2: value2", logs[len(logs)-1])
assert.Equal(t, "request header --> key1: value1", logs[len(logs)-2])
assert.Equal(t, fmt.Sprintf("%d finished", id), logs[len(logs)-1])
assert.Equal(t, "request header --> key2: value2", logs[len(logs)-2])
assert.Equal(t, "request header --> key1: value1", logs[len(logs)-3])
}

func TestHttpHeaders_OnHttpResponseHeaders(t *testing.T) {
host, done := proxytest.NewHttpFilterHost(newContext)
defer done()
id := host.InitContext()
opt := proxytest.NewEmulatorOption().
WithNewHttpContext(newContext)
host := proxytest.NewHostEmulator(opt)
defer host.Done()
id := host.HttpFilterInitContext()

hs := [][2]string{{"key1", "value1"}, {"key2", "value2"}}
host.PutResponseHeaders(id, hs) // call OnHttpResponseHeaders
host.HttpFilterPutResponseHeaders(id, hs) // call OnHttpRequestHeaders
host.HttpFilterCompleteHttpStream(id) // call OnHttpStreamDone

logs := host.GetLogs(types.LogLevelInfo)
require.Greater(t, len(logs), 1)

assert.Equal(t, "response header <-- key2: value2", logs[len(logs)-1])
assert.Equal(t, "response header <-- key1: value1", logs[len(logs)-2])
assert.Equal(t, fmt.Sprintf("%d finished", id), logs[len(logs)-1])
assert.Equal(t, "response header <-- key2: value2", logs[len(logs)-2])
assert.Equal(t, "response header <-- key1: value1", logs[len(logs)-3])
}
Loading