diff --git a/src/test/go-examples/postpone_requests/README.md b/src/test/go-examples/postpone_requests/README.md new file mode 100644 index 0000000..daeaf90 --- /dev/null +++ b/src/test/go-examples/postpone_requests/README.md @@ -0,0 +1,5 @@ +## Attribution + +This example originally came from: +https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/ab4161dcf9246a828008b539a82a1556cf0f2e24/examples/postpone_requests +``` diff --git a/src/test/go-examples/postpone_requests/go.mod b/src/test/go-examples/postpone_requests/go.mod new file mode 100644 index 0000000..cc0bb00 --- /dev/null +++ b/src/test/go-examples/postpone_requests/go.mod @@ -0,0 +1,5 @@ +module github.com/proxy-wasm/proxy-wasm-go-sdk/examples/postpone_requests + +go 1.24 + +require github.com/proxy-wasm/proxy-wasm-go-sdk v0.0.0-20250212164326-ab4161dcf924 diff --git a/src/test/go-examples/postpone_requests/go.sum b/src/test/go-examples/postpone_requests/go.sum new file mode 100644 index 0000000..3ddb896 --- /dev/null +++ b/src/test/go-examples/postpone_requests/go.sum @@ -0,0 +1,10 @@ +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= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/src/test/go-examples/postpone_requests/main.go b/src/test/go-examples/postpone_requests/main.go new file mode 100644 index 0000000..18b905f --- /dev/null +++ b/src/test/go-examples/postpone_requests/main.go @@ -0,0 +1,95 @@ +// 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 ( + "github.com/proxy-wasm/proxy-wasm-go-sdk/proxywasm" + "github.com/proxy-wasm/proxy-wasm-go-sdk/proxywasm/types" +) + +const tickMilliseconds uint32 = 1000 + +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{ + contextID: contextID, + postponed: make([]uint32, 0, 1024), + } +} + +// 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 + contextID uint32 + postponed []uint32 +} + +// OnPluginStart implements types.PluginContext. +func (ctx *pluginContext) OnPluginStart(pluginConfigurationSize int) types.OnPluginStartStatus { + if err := proxywasm.SetTickPeriodMilliSeconds(tickMilliseconds); err != nil { + proxywasm.LogCriticalf("failed to set tick period: %v", err) + } + + return types.OnPluginStartStatusOK +} + +// OnTick implements types.PluginContext. +func (ctx *pluginContext) OnTick() { + for len(ctx.postponed) > 0 { + httpCtxId, tail := ctx.postponed[0], ctx.postponed[1:] + proxywasm.LogInfof("resume request with contextID=%v", httpCtxId) + _ = proxywasm.SetEffectiveContext(httpCtxId) + _ = proxywasm.ResumeHttpRequest() + ctx.postponed = tail + } +} + +// NewHttpContext implements types.PluginContext. +func (ctx *pluginContext) NewHttpContext(contextID uint32) types.HttpContext { + return &httpContext{ + contextID: contextID, + pluginCtx: ctx, + } +} + +// httpContext implements types.HttpContext. +type httpContext struct { + // Embed the default http context here, + // so that we don't need to reimplement all the methods. + types.DefaultHttpContext + contextID uint32 + pluginCtx *pluginContext +} + +// OnHttpRequestHeaders implements types.HttpContext. +func (ctx *httpContext) OnHttpRequestHeaders(numHeaders int, endOfStream bool) types.Action { + proxywasm.LogInfof("postpone request with contextID=%d", ctx.contextID) + ctx.pluginCtx.postponed = append(ctx.pluginCtx.postponed, ctx.contextID) + return types.ActionPause +} diff --git a/src/test/go-examples/postpone_requests/main.wasm b/src/test/go-examples/postpone_requests/main.wasm new file mode 100644 index 0000000..a6fb18d Binary files /dev/null and b/src/test/go-examples/postpone_requests/main.wasm differ diff --git a/src/test/java/io/roastedroot/proxywasm/PostponeRequestsTest.java b/src/test/java/io/roastedroot/proxywasm/PostponeRequestsTest.java new file mode 100644 index 0000000..fa761eb --- /dev/null +++ b/src/test/java/io/roastedroot/proxywasm/PostponeRequestsTest.java @@ -0,0 +1,43 @@ +package io.roastedroot.proxywasm; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.dylibso.chicory.wasm.Parser; +import io.roastedroot.proxywasm.v1.Action; +import io.roastedroot.proxywasm.v1.ProxyWasm; +import io.roastedroot.proxywasm.v1.StartException; +import java.nio.file.Path; +import org.junit.jupiter.api.Test; + +/** + * Java port of https://github.com/proxy-wasm/proxy-wasm-go-sdk/blob/master/examples/postpone_requests/main_test.go + */ +public class PostponeRequestsTest { + + @Test + public void testSetEffectiveContext() throws StartException { + + var handler = new MockHandler(); + // Load the WASM module + var module = Parser.parse(Path.of("./src/test/go-examples/postpone_requests/main.wasm")); + + // Create and configure the ProxyWasm instance + try (var host = ProxyWasm.builder().withPluginHandler(handler).build(module)) { + + // Initialize context + try (var context = host.createHttpContext(handler)) { + + // Call OnHttpRequestHeaders + Action action = context.callOnRequestHeaders(false); + assertEquals( + Action.PAUSE, action, "Expected PAUSE action for OnHttpRequestHeaders"); + + // Call OnTick + host.tick(); + + action = handler.getAction(); + assertEquals(Action.CONTINUE, action, "Expected CONTINUE action after OnTick"); + } + } + } +}