Skip to content
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
10 changes: 10 additions & 0 deletions src/main/java/io/roastedroot/proxywasm/v1/ProxyWasm.java
Original file line number Diff line number Diff line change
Expand Up @@ -307,11 +307,21 @@ public HostFunction[] toHostFunctions() {
return Imports_ModuleFactory.toHostFunctions(imports);
}

public ProxyWasm.Builder withVmConfig(byte[] vmConfig) {
this.vmConfig = vmConfig;
return this;
}

public ProxyWasm.Builder withVmConfig(String vmConfig) {
this.vmConfig = vmConfig.getBytes(StandardCharsets.UTF_8);
return this;
}

public ProxyWasm.Builder withPluginConfig(byte[] pluginConfig) {
this.pluginConfig = pluginConfig;
return this;
}

public ProxyWasm.Builder withPluginConfig(String pluginConfig) {
this.pluginConfig = pluginConfig.getBytes(StandardCharsets.UTF_8);
return this;
Expand Down
2 changes: 1 addition & 1 deletion src/test/go-examples/dispatch_call_on_tick/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## Attribution

This example originally came from:
https://github.com/proxy-wasm/proxy-wasm-go-sdk/tree/main/examples/dispatch_call_on_tick
https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/dispatch_call_on_tick

2 changes: 1 addition & 1 deletion src/test/go-examples/foreign_call_on_tick/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Attribution

This example originally came from:
https://github.com/proxy-wasm/proxy-wasm-go-sdk/tree/main/examples/foreign_call_on_tick
https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/foreign_call_on_tick
2 changes: 1 addition & 1 deletion src/test/go-examples/helloworld/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Attribution

This example originally came from:
https://github.com/proxy-wasm/proxy-wasm-go-sdk/tree/main/examples/helloworld
https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/helloworld
2 changes: 1 addition & 1 deletion src/test/go-examples/http_auth_random/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Attribution

This example originally came from:
https://github.com/proxy-wasm/proxy-wasm-go-sdk/tree/main/examples/http_auth_random
https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/http_auth_random
2 changes: 1 addition & 1 deletion src/test/go-examples/http_body/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Attribution

This example originally came from:
https://github.com/proxy-wasm/proxy-wasm-go-sdk/tree/main/examples/http_body
https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/http_body
2 changes: 1 addition & 1 deletion src/test/go-examples/http_body_chunk/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Attribution

This example originally came from:
https://github.com/proxy-wasm/proxy-wasm-go-sdk/tree/main/examples/http_body_chunk
https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/http_body_chunk
2 changes: 1 addition & 1 deletion src/test/go-examples/http_headers/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## Attribution

This example originally came from:
https://github.com/proxy-wasm/proxy-wasm-go-sdk/tree/main/examples/http_headers
https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/http_headers
```
5 changes: 5 additions & 0 deletions src/test/go-examples/http_routing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Attribution

This example originally came from:
https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/http_routing
```
15 changes: 15 additions & 0 deletions src/test/go-examples/http_routing/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module github.com/proxy-wasm/proxy-wasm-go-sdk/examples/http_routing

go 1.24

require (
github.com/proxy-wasm/proxy-wasm-go-sdk v0.0.0-20250212164326-ab4161dcf924
github.com/stretchr/testify v1.9.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/tetratelabs/wazero v1.7.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
14 changes: 14 additions & 0 deletions src/test/go-examples/http_routing/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/proxy-wasm/proxy-wasm-go-sdk v0.0.0-20250212164326-ab4161dcf924 h1:wTcK6gcyTKJMeDka69AMjZYvisdI8CBXzTEfZ+2pOxI=
github.com/proxy-wasm/proxy-wasm-go-sdk v0.0.0-20250212164326-ab4161dcf924/go.mod h1:9mBRvh8I6Td6sg3CwEY+zGFE4DKaIoieCaca1kQnDBE=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tetratelabs/wazero v1.7.2 h1:1+z5nXJNwMLPAWaTePFi49SSTL0IMx/i3Fg8Yc25GDc=
github.com/tetratelabs/wazero v1.7.2/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
114 changes: 114 additions & 0 deletions src/test/go-examples/http_routing/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright 2020-2024 Tetrate
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"crypto/rand"
"encoding/binary"

"github.com/proxy-wasm/proxy-wasm-go-sdk/proxywasm"
"github.com/proxy-wasm/proxy-wasm-go-sdk/proxywasm/types"
)

func main() {}
func init() {
proxywasm.SetVMContext(&vmContext{})
}

// vmContext implements types.VMContext.
type vmContext struct {
// Embed the default VM context here,
// so that we don't need to reimplement all the methods.
types.DefaultVMContext
}

// NewPluginContext implements types.VMContext.
func (*vmContext) NewPluginContext(contextID uint32) types.PluginContext {
return &pluginContext{}
}

// pluginContext implements types.PluginContext.
type pluginContext struct {
// Embed the default plugin context here,
// so that we don't need to reimplement all the methods.
types.DefaultPluginContext

diceOverride uint32 // For unit test
}

// OnPluginStart implements types.PluginContext.
func (ctx *pluginContext) OnPluginStart(pluginConfigurationSize int) types.OnPluginStartStatus {
data, err := proxywasm.GetPluginConfiguration()
if err != nil && err != types.ErrorStatusNotFound {
proxywasm.LogCriticalf("error reading plugin configuration: %v", err)
return types.OnPluginStartStatusFailed
}

// If the configuration data is not empty, we use its value to override the routing
// decision for unit tests.
if len(data) > 0 {
ctx.diceOverride = uint32(data[0])
}

return types.OnPluginStartStatusOK
}

// NewHttpContext implements types.PluginContext.
func (ctx *pluginContext) NewHttpContext(contextID uint32) types.HttpContext {
return &httpRouting{diceOverride: ctx.diceOverride}
}

// httpRouting implements types.HttpContext.
type httpRouting struct {
// Embed the default http context here,
// so that we don't need to reimplement all the methods.
types.DefaultHttpContext

diceOverride uint32 // For unit test
}

// dice returns a random value to be used to determine the route.
func dice() uint32 {
buf := make([]byte, 4)
_, _ = rand.Read(buf)
return binary.LittleEndian.Uint32(buf)
}

// OnHttpRequestHeaders implements types.HttpContext.
func (ctx *httpRouting) OnHttpRequestHeaders(numHeaders int, endOfStream bool) types.Action {
// Randomly routing to the canary cluster.
var value uint32
if ctx.diceOverride != 0 {
value = ctx.diceOverride
} else {
value = dice()
}
proxywasm.LogInfof("value: %d\n", value)
if value%2 == 0 {
const authorityKey = ":authority"
value, err := proxywasm.GetHttpRequestHeader(authorityKey)
if err != nil {
proxywasm.LogCritical("failed to get request header: ':authority'")
return types.ActionPause
}
// Append "-canary" suffix to route this request to the canary cluster.
value += "-canary"
if err := proxywasm.ReplaceHttpRequestHeader(":authority", value); err != nil {
proxywasm.LogCritical("failed to set request header: test")
return types.ActionPause
}
}
return types.ActionContinue
}
Binary file added src/test/go-examples/http_routing/main.wasm
Binary file not shown.
80 changes: 80 additions & 0 deletions src/test/go-examples/http_routing/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// The framework emulates the expected behavior of Envoyproxy, and you can test your extensions without running Envoy and with
// the standard Go CLI. To run tests, simply run
// go test ./...

package main

import (
"os"
"testing"

"github.com/proxy-wasm/proxy-wasm-go-sdk/proxywasm/proxytest"
"github.com/proxy-wasm/proxy-wasm-go-sdk/proxywasm/types"
"github.com/stretchr/testify/require"
)

func TestHttpRouting_OnHttpRequestHeaders(t *testing.T) {
vmTest(t, func(t *testing.T, vm types.VMContext) {
t.Run("canary", func(t *testing.T) {
opt := proxytest.NewEmulatorOption().WithVMContext(vm).WithPluginConfiguration([]byte{2})
host, reset := proxytest.NewHostEmulator(opt)
defer reset()

require.Equal(t, types.OnPluginStartStatusOK, host.StartPlugin())

// Initialize http context.
id := host.InitializeHttpContext()
hs := [][2]string{{":authority", "my-host.com"}}
// Call OnHttpResponseHeaders.
action := host.CallOnRequestHeaders(id,
hs, false)
require.Equal(t, types.ActionContinue, action)
resultHeaders := host.GetCurrentRequestHeaders(id)
require.Len(t, resultHeaders, 1)
require.Equal(t, ":authority", resultHeaders[0][0])
require.Equal(t, "my-host.com-canary", resultHeaders[0][1])
})

t.Run("non-canary", func(t *testing.T) {
opt := proxytest.NewEmulatorOption().WithVMContext(vm).WithPluginConfiguration([]byte{1})
host, reset := proxytest.NewHostEmulator(opt)
defer reset()

require.Equal(t, types.OnPluginStartStatusOK, host.StartPlugin())

// Initialize http context.
id := host.InitializeHttpContext()
hs := [][2]string{{":authority", "my-host.com"}}
// Call OnHttpResponseHeaders.
action := host.CallOnRequestHeaders(id,
hs, false)
require.Equal(t, types.ActionContinue, action)
resultHeaders := host.GetCurrentRequestHeaders(id)
require.Len(t, resultHeaders, 1)
require.Equal(t, ":authority", resultHeaders[0][0])
require.Equal(t, "my-host.com", resultHeaders[0][1])
})
})
}

// vmTest executes f twice, once with a types.VMContext that executes plugin code directly
// in the host, and again by executing the plugin code within the compiled main.wasm binary.
// Execution with main.wasm will be skipped if the file cannot be found.
func vmTest(t *testing.T, f func(*testing.T, types.VMContext)) {
t.Helper()

t.Run("go", func(t *testing.T) {
f(t, &vmContext{})
})

t.Run("wasm", func(t *testing.T) {
wasm, err := os.ReadFile("main.wasm")
if err != nil {
t.Skip("wasm not found")
}
v, err := proxytest.NewWasmVMContext(wasm)
require.NoError(t, err)
defer v.Close()
f(t, v)
})
}
2 changes: 1 addition & 1 deletion src/test/go-examples/properties/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Attribution

This example originally came from:
https://github.com/proxy-wasm/proxy-wasm-go-sdk/tree/main/examples/properties
https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/properties
2 changes: 1 addition & 1 deletion src/test/go-examples/vm_plugin_configuration/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Attribution

This example originally came from:
https://github.com/proxy-wasm/proxy-wasm-go-sdk/tree/main/examples/vm_plugin_configuration
https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/vm_plugin_configuration
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.junit.jupiter.api.Test;

/**
* Java port of https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/dispatch_call_on_tick/main_test.go
*/
public class DispatchCallOnTickTest {

Expand Down
3 changes: 3 additions & 0 deletions src/test/java/io/roastedroot/proxywasm/EchoHttpBodyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

/**
* Java port of https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/http_body/main_test.go
*/
public class EchoHttpBodyTest {

private MockHandler handler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.junit.jupiter.api.Test;

/**
* Java port of https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/foreign_call_on_tick/main_test.go
*/
public class ForeignCallOnTickTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

/**
* Java port of https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/http_auth_random/main_test.go
*/
public class HttpAuthRandomTest {

private static String clusterName = "httpbin";
Expand Down
3 changes: 3 additions & 0 deletions src/test/java/io/roastedroot/proxywasm/HttpBodyChunkTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

/**
* Java port of https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/http_body_chunk/main_test.go
*/
public class HttpBodyChunkTest {

private MockHandler handler;
Expand Down
3 changes: 3 additions & 0 deletions src/test/java/io/roastedroot/proxywasm/HttpBodyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

/**
* Java port of https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/http_body/main_test.go
*/
public class HttpBodyTest {

private MockHandler handler;
Expand Down
3 changes: 3 additions & 0 deletions src/test/java/io/roastedroot/proxywasm/HttpHeadersTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
import java.util.Map;
import org.junit.jupiter.api.Test;

/**
* Java port of https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/http_headers/main_test.go
*/
public class HttpHeadersTest {

private MockHandler handler = new MockHandler();
Expand Down
Loading