diff --git a/.github/workflows/gotest.yaml b/.github/workflows/gotest.yaml index 6d39318f..8a764347 100644 --- a/.github/workflows/gotest.yaml +++ b/.github/workflows/gotest.yaml @@ -18,7 +18,7 @@ jobs: go-version: 1.14 - name: build examples - run: find ./ -type f -name "main.go" | xargs -Ip tinygo build -o p.wasm -target=wasm -wasm-abi=generic p + run: find ./examples -type f -name "main.go" | xargs -Ip tinygo build -o p.wasm -target=wasm -wasm-abi=generic p test: name: test diff --git a/examples/helloworld/main.go b/examples/helloworld/main.go index 970d13e3..cc63e4d7 100644 --- a/examples/helloworld/main.go +++ b/examples/helloworld/main.go @@ -23,7 +23,7 @@ func newHelloWorld(contextID uint32) runtime.RootContext { // override func (ctx *helloWorld) OnVMStart(_ int) bool { runtime.LogInfo("proxy_on_vm_start from Go!") - if err := ctx.SetTickPeriod(1000); err != nil { + if err := runtime.HostCallSetTickPeriodMilliSeconds(1000); err != nil { runtime.LogCritical("failed to set tick period: " + err.Error()) } return true @@ -31,7 +31,7 @@ func (ctx *helloWorld) OnVMStart(_ int) bool { // override func (ctx *helloWorld) OnTick() { - t := ctx.GetCurrentTime() + t := runtime.HostCallGetCurrentTime() msg := "OnTick on " + strconv.FormatUint(uint64(ctx.contextID), 10) msg += ", it's " + strconv.FormatInt(t, 10) runtime.LogInfo(msg) diff --git a/examples/http_auth_random/main.go b/examples/http_auth_random/main.go index d928a3ac..173a1c92 100644 --- a/examples/http_auth_random/main.go +++ b/examples/http_auth_random/main.go @@ -24,7 +24,7 @@ func newContext(contextID uint32) runtime.HttpContext { // override default func (ctx *httpHeaders) OnHttpRequestHeaders(_ int, _ bool) types.Action { - hs, err := ctx.GetHttpRequestHeaders() + hs, err := runtime.HostCallGetHttpRequestHeaders() if err != nil { runtime.LogCritical("failed to get request headers: " + err.Error()) return types.ActionContinue @@ -33,7 +33,7 @@ func (ctx *httpHeaders) OnHttpRequestHeaders(_ int, _ bool) types.Action { runtime.LogInfo("request header: " + h[0] + ": " + h[1]) } - if _, err := ctx.DispatchHttpCall( + if _, err := runtime.HostCallDispatchHttpCall( "httpbin", hs, "", [][2]string{}, 50000); err != nil { runtime.LogCritical("dipatch httpcall failed: " + err.Error()) } @@ -42,29 +42,29 @@ func (ctx *httpHeaders) OnHttpRequestHeaders(_ int, _ bool) types.Action { // override default func (ctx *httpHeaders) OnHttpCallResponse(_ uint32, _ int, bodySize int, _ int) { - b, err := ctx.GetHttpCallResponseBody(0, bodySize) + b, err := runtime.HostCallGetHttpCallResponseBody(0, bodySize) if err != nil { runtime.LogCritical("failed to get response body: " + err.Error()) - ctx.ResumeHttpRequest() + runtime.HostCallResumeHttpRequest() return } s := fnv.New32a() if _, err := s.Write(b); err != nil { runtime.LogCritical("failed to calculate hash: " + err.Error()) - ctx.ResumeHttpRequest() + runtime.HostCallResumeHttpRequest() return } if s.Sum32()%2 == 0 { runtime.LogInfo("access granted") - ctx.ResumeHttpRequest() + runtime.HostCallResumeHttpRequest() return } msg := "access forbidden" runtime.LogInfo(msg) - ctx.SendHttpResponse(403, [][2]string{ + runtime.HostCallSendHttpResponse(403, [][2]string{ {"powered-by", "proxy-wasm-go!!"}, }, msg) } diff --git a/examples/http_headers/main.go b/examples/http_headers/main.go index 1a834e51..f874d058 100644 --- a/examples/http_headers/main.go +++ b/examples/http_headers/main.go @@ -23,7 +23,7 @@ func newContext(contextID uint32) runtime.HttpContext { // override func (ctx *httpHeaders) OnHttpRequestHeaders(_ int, _ bool) types.Action { - hs, err := ctx.GetHttpRequestHeaders() + hs, err := runtime.HostCallGetHttpRequestHeaders() if err != nil { runtime.LogCritical("failed to get request headers: " + err.Error()) } @@ -36,7 +36,7 @@ func (ctx *httpHeaders) OnHttpRequestHeaders(_ int, _ bool) types.Action { // override func (ctx *httpHeaders) OnHttpResponseHeaders(_ int, _ bool) types.Action { - hs, err := ctx.GetHttpResponseHeaders() + hs, err := runtime.HostCallGetHttpResponseHeaders() if err != nil { runtime.LogCritical("failed to get request headers: " + err.Error()) } diff --git a/runtime/abi_l7.go b/runtime/abi_l7.go index b5c7037f..db5f6a8f 100644 --- a/runtime/abi_l7.go +++ b/runtime/abi_l7.go @@ -90,15 +90,15 @@ func proxyOnHttpCallResponse(_, calloutID uint32, numHeaders, bodySize, numTrail if ctx, ok := currentState.streamContexts[ctxID]; ok { currentState.setActiveContextID(ctxID) - setEffectiveContext(ctxID) + HostCallSetEffectiveContext(ctxID) ctx.OnHttpCallResponse(calloutID, numHeaders, bodySize, numTrailers) } else if ctx, ok := currentState.httpContexts[ctxID]; ok { currentState.setActiveContextID(ctxID) - setEffectiveContext(ctxID) + HostCallSetEffectiveContext(ctxID) ctx.OnHttpCallResponse(calloutID, numHeaders, bodySize, numTrailers) } else if ctx, ok := currentState.rootContexts[ctxID]; ok { currentState.activeContextID = ctxID - setEffectiveContext(ctxID) + HostCallSetEffectiveContext(ctxID) ctx.OnHttpCallResponse(calloutID, numHeaders, bodySize, numTrailers) } else { panic("invalid context on proxy_on_http_call_response") diff --git a/runtime/version.go b/runtime/abi_version.go similarity index 100% rename from runtime/version.go rename to runtime/abi_version.go diff --git a/runtime/context.go b/runtime/context.go index 50a5d2b0..655c3128 100644 --- a/runtime/context.go +++ b/runtime/context.go @@ -15,96 +15,41 @@ package runtime import ( - "strconv" - - "github.com/mathetake/proxy-wasm-go/runtime/hostcall" "github.com/mathetake/proxy-wasm-go/runtime/types" ) type Context interface { - DispatchHttpCall(upstream string, headers [][2]string, - body string, trailers [][2]string, timeoutMillisecond uint32) (calloutID uint32, status error) - OnHttpCallResponse(calloutID uint32, numHeaders, bodySize, numTrailers int) - GetHttpCallResponseHeaders() ([][2]string, error) - GetHttpCallResponseBody(start, maxSize int) ([]byte, error) - GetHttpCallResponseTrailers() ([][2]string, error) - GetCurrentTime() int64 OnDone() bool - Done() + OnHttpCallResponse(calloutID uint32, numHeaders, bodySize, numTrailers int) } type RootContext interface { Context - OnVMStart(vmConfigurationSize int) bool OnConfigure(pluginConfigurationSize int) bool - GetPluginConfiguration(dataSize int) ([]byte, error) - SetTickPeriod(period uint32) error + OnLog() OnQueueReady(queueID uint32) OnTick() - OnLog() + OnVMStart(vmConfigurationSize int) bool } type StreamContext interface { Context - OnNewConnection() types.Action OnDownstreamData(dataSize int, endOfStream bool) types.Action - GetDownStreamData(start, maxSize int) ([]byte, error) OnDownStreamClose(peerType types.PeerType) - + OnLog() + OnNewConnection() types.Action OnUpstreamData(dataSize int, endOfStream bool) types.Action - GetUpstreamData(start, maxSize int) ([]byte, error) OnUpstreamStreamClose(peerType types.PeerType) - OnLog() } type HttpContext interface { Context - - // request OnHttpRequestHeaders(numHeaders int, endOfStream bool) types.Action - GetHttpRequestHeaders() ([][2]string, error) - SetHttpRequestHeaders(headers [][2]string) error - GetHttpRequestHeader(key string) (string, error) - RemoveHttpRequestHeader(key string) error - SetHttpRequestHeader(key, value string) error - AddHttpRequestHeader(key, value string) error - OnHttpRequestBody(bodySize int, endOfStream bool) types.Action - GetHttpRequestBody(start, maxSize int) ([]byte, error) - OnHttpRequestTrailers(numTrailers int) types.Action - GetHttpRequestTrailers() ([][2]string, error) - SetHttpRequestTrailers(headers [][2]string) error - GetHttpRequestTrailer(key string) (string, error) - RemoveHttpRequestTrailer(key string) error - SetHttpRequestTrailer(key, value string) error - AddHttpRequestTrailer(key, value string) error - - ResumeHttpRequest() error - - // response OnHttpResponseHeaders(numHeaders int, endOfStream bool) types.Action - GetHttpResponseHeaders() ([][2]string, error) - SetHttpResponseHeaders(headers [][2]string) error - GetHttpResponseHeader(key string) (string, error) - RemoveHttpResponseHeader(key string) error - SetHttpResponseHeader(key, value string) error - AddHttpResponseHeader(key, value string) error - OnHttpResponseBody(bodySize int, endOfStream bool) types.Action - GetHttpResponseBody(start, maxSize int) ([]byte, error) - OnHttpResponseTrailers(numTrailers int) types.Action - GetHttpResponseTrailers() ([][2]string, error) - SetHttpResponseTrailers(headers [][2]string) error - GetHttpResponseTrailer(key string) (string, error) - RemoveHttpResponseTrailer(key string) error - SetHttpResponseTrailer(key, value string) error - AddHttpResponseTrailer(key, value string) error - - ResumeHttpResponse() error - - SendHttpResponse(statusCode uint32, headers [][2]string, body string) error OnLog() } @@ -117,301 +62,29 @@ var ( _ HttpContext = &DefaultContext{} ) -// impl Context -func (d *DefaultContext) GetCurrentTime() int64 { - var t int64 - hostcall.ProxyGetCurrentTimeNanoseconds(&t) - return t -} - -// impl Context -func (d *DefaultContext) DispatchHttpCall(upstream string, - headers [][2]string, body string, trailers [][2]string, timeoutMillisecond uint32) (uint32, error) { - ret, st := dispatchHttpCall(upstream, headers, body, trailers, timeoutMillisecond) - return ret, types.StatusToError(st) -} - -// impl Context -func (d *DefaultContext) GetHttpCallResponseHeaders() ([][2]string, error) { - ret, st := getMap(types.MapTypeHttpCallResponseHeaders) - return ret, types.StatusToError(st) -} - -// impl Context -func (d *DefaultContext) GetHttpCallResponseBody(start, maxSize int) ([]byte, error) { - ret, st := getBuffer(types.BufferTypeHttpCallResponseBody, start, maxSize) - return ret, types.StatusToError(st) -} - -// impl Context -func (d *DefaultContext) GetHttpCallResponseTrailers() ([][2]string, error) { - ret, st := getMap(types.MapTypeHttpCallResponseTrailers) - return ret, types.StatusToError(st) -} - -// impl Context -func (d *DefaultContext) OnHttpCallResponse(calloutID uint32, numHeaders, bodySize, numTrailers int) { -} - -// impl Context -func (d *DefaultContext) OnDone() bool { - return true -} - -// impl Context -func (d *DefaultContext) Done() { - switch st := hostcall.ProxyDone(); st { - case types.StatusOk: - return - default: - panic("unexpected status on proxy_done: " + strconv.FormatUint(uint64(st), 10)) - } -} - -// impl HttpContext, StreamContext, RootContext func (d *DefaultContext) OnLog() {} -// impl RootContext -func (d *DefaultContext) OnVMStart(_ int) bool { - return true -} - -// impl RootContext -func (d *DefaultContext) OnConfigure(_ int) bool { - return true -} - -// impl RootContext -func (d *DefaultContext) GetPluginConfiguration(dataSize int) ([]byte, error) { - ret, st := getBuffer(types.BufferTypePluginConfiguration, 0, dataSize) - return ret, types.StatusToError(st) -} - -// impl RootContext -func (d *DefaultContext) SetTickPeriod(milliSec uint32) error { - return types.StatusToError(setTickPeriodMilliSeconds(milliSec)) -} - -// impl RootContext -func (d *DefaultContext) OnTick() {} +// impl Context +func (d *DefaultContext) OnDone() bool { return true } +func (d *DefaultContext) OnHttpCallResponse(uint32, int, int, int) {} // impl RootContext -func (d *DefaultContext) OnQueueReady(_ uint32) {} - -// impl StreamContext -func (d *DefaultContext) OnNewConnection() types.Action { - return types.ActionContinue -} +func (d *DefaultContext) OnConfigure(int) bool { return true } +func (d *DefaultContext) OnQueueReady(uint32) {} +func (d *DefaultContext) OnTick() {} +func (d *DefaultContext) OnVMStart(int) bool { return true } // impl StreamContext -func (d *DefaultContext) OnDownstreamData(dataSize int, endOfStream bool) types.Action { - return types.ActionContinue -} - -// impl StreamContext -func (d *DefaultContext) GetDownStreamData(start, maxSize int) ([]byte, error) { - ret, st := getBuffer(types.BufferTypeDownstreamData, start, maxSize) - return ret, types.StatusToError(st) -} - -// impl StreamContext -func (d *DefaultContext) OnDownStreamClose(_ types.PeerType) {} - -// impl StreamContext -func (d *DefaultContext) OnUpstreamData(_ int, _ bool) types.Action { - return types.ActionContinue -} - -// impl StreamContext -func (d *DefaultContext) GetUpstreamData(start, maxSize int) ([]byte, error) { - ret, st := getBuffer(types.BufferTypeUpstreamData, start, maxSize) - return ret, types.StatusToError(st) -} - -// impl StreamContext -func (d *DefaultContext) OnUpstreamStreamClose(_ types.PeerType) {} - -// impl HttpContext -func (d *DefaultContext) OnHttpRequestHeaders(_ int, _ bool) types.Action { - return types.ActionContinue -} - -// impl HttpContext -func (d *DefaultContext) GetHttpRequestHeaders() ([][2]string, error) { - ret, st := getMap(types.MapTypeHttpRequestHeaders) - return ret, types.StatusToError(st) -} - -// impl HttpContext -func (d *DefaultContext) SetHttpRequestHeaders(headers [][2]string) error { - return types.StatusToError(setMap(types.MapTypeHttpRequestHeaders, headers)) -} - -// impl HttpContext -func (d *DefaultContext) GetHttpRequestHeader(key string) (string, error) { - ret, st := getMapValue(types.MapTypeHttpRequestHeaders, key) - return ret, types.StatusToError(st) -} - -// impl HttpContext -func (d *DefaultContext) RemoveHttpRequestHeader(key string) error { - return types.StatusToError(removeMapValue(types.MapTypeHttpRequestHeaders, key)) -} - -// impl HttpContext -func (d *DefaultContext) SetHttpRequestHeader(key, value string) error { - return types.StatusToError(setMapValue(types.MapTypeHttpRequestHeaders, key, value)) -} - -// impl HttpContext -func (d *DefaultContext) AddHttpRequestHeader(key, value string) error { - return types.StatusToError(addMapValue(types.MapTypeHttpRequestHeaders, key, value)) -} - -// impl HttpContext -func (d *DefaultContext) OnHttpRequestBody(_ int, _ bool) types.Action { - return types.ActionContinue -} - -// impl HttpContext -func (d *DefaultContext) GetHttpRequestBody(start, maxSize int) ([]byte, error) { - ret, st := getBuffer(types.BufferTypeHttpRequestBody, start, maxSize) - return ret, types.StatusToError(st) -} - -// impl HttpContext -func (d *DefaultContext) OnHttpRequestTrailers(numTrailers int) types.Action { - return types.ActionContinue -} - -// impl HttpContext -func (d *DefaultContext) GetHttpRequestTrailers() ([][2]string, error) { - ret, st := getMap(types.MapTypeHttpRequestTrailers) - return ret, types.StatusToError(st) -} - -// impl HttpContext -func (d *DefaultContext) SetHttpRequestTrailers(headers [][2]string) error { - return types.StatusToError(setMap(types.MapTypeHttpRequestTrailers, headers)) -} - -// impl HttpContext -func (d *DefaultContext) GetHttpRequestTrailer(key string) (string, error) { - ret, st := getMapValue(types.MapTypeHttpRequestTrailers, key) - return ret, types.StatusToError(st) -} - -// impl HttpContext -func (d *DefaultContext) RemoveHttpRequestTrailer(key string) error { - return types.StatusToError(removeMapValue(types.MapTypeHttpRequestTrailers, key)) -} - -// impl HttpContext -func (d *DefaultContext) SetHttpRequestTrailer(key, value string) error { - return types.StatusToError(setMapValue(types.MapTypeHttpRequestTrailers, key, value)) -} - -// impl HttpContext -func (d *DefaultContext) AddHttpRequestTrailer(key, value string) error { - return types.StatusToError(addMapValue(types.MapTypeHttpRequestTrailers, key, value)) -} - -// impl HttpContext -func (d *DefaultContext) ResumeHttpRequest() error { - return types.StatusToError(hostcall.ProxyContinueStream(types.StreamTypeRequest)) -} - -// impl HttpContext -func (d *DefaultContext) OnHttpResponseHeaders(_ int, _ bool) types.Action { - return types.ActionContinue -} - -// impl HttpContext -func (d *DefaultContext) GetHttpResponseHeaders() ([][2]string, error) { - ret, st := getMap(types.MapTypeHttpResponseHeaders) - return ret, types.StatusToError(st) -} - -// impl HttpContext -func (d *DefaultContext) SetHttpResponseHeaders(headers [][2]string) error { - return types.StatusToError(setMap(types.MapTypeHttpResponseHeaders, headers)) -} - -// impl HttpContext -func (d *DefaultContext) GetHttpResponseHeader(key string) (string, error) { - ret, st := getMapValue(types.MapTypeHttpResponseHeaders, key) - return ret, types.StatusToError(st) -} - -// impl HttpContext -func (d *DefaultContext) RemoveHttpResponseHeader(key string) error { - return types.StatusToError(removeMapValue(types.MapTypeHttpResponseHeaders, key)) -} - -// impl HttpContext -func (d *DefaultContext) SetHttpResponseHeader(key, value string) error { - return types.StatusToError(setMapValue(types.MapTypeHttpResponseHeaders, key, value)) -} - -// impl HttpContext -func (d *DefaultContext) AddHttpResponseHeader(key, value string) error { - return types.StatusToError(addMapValue(types.MapTypeHttpResponseHeaders, key, value)) -} - -// impl HttpContext -func (d *DefaultContext) OnHttpResponseBody(size int, endOfStream bool) types.Action { - return types.ActionContinue -} - -// impl HttpContext -func (d *DefaultContext) GetHttpResponseBody(start, maxSize int) ([]byte, error) { - ret, st := getBuffer(types.BufferTypeHttpResponseBody, start, maxSize) - return ret, types.StatusToError(st) -} - -// impl HttpContext -func (d *DefaultContext) OnHttpResponseTrailers(numTrailers int) types.Action { - return types.ActionContinue -} - -// impl HttpContext -func (d *DefaultContext) GetHttpResponseTrailers() ([][2]string, error) { - ret, st := getMap(types.MapTypeHttpResponseTrailers) - return ret, types.StatusToError(st) -} - -// impl HttpContext -func (d *DefaultContext) SetHttpResponseTrailers(headers [][2]string) error { - return types.StatusToError(setMap(types.MapTypeHttpResponseTrailers, headers)) -} - -// impl HttpContext -func (d *DefaultContext) GetHttpResponseTrailer(key string) (string, error) { - ret, st := getMapValue(types.MapTypeHttpResponseTrailers, key) - return ret, types.StatusToError(st) -} - -// impl HttpContext -func (d *DefaultContext) RemoveHttpResponseTrailer(key string) error { - return types.StatusToError(removeMapValue(types.MapTypeHttpResponseTrailers, key)) -} - -// impl HttpContext -func (d *DefaultContext) SetHttpResponseTrailer(key, value string) error { - return types.StatusToError(setMapValue(types.MapTypeHttpResponseTrailers, key, value)) -} - -// impl HttpContext -func (d *DefaultContext) AddHttpResponseTrailer(key, value string) error { - return types.StatusToError(addMapValue(types.MapTypeHttpResponseTrailers, key, value)) -} - -// impl HttpContext -func (d *DefaultContext) ResumeHttpResponse() error { - return types.StatusToError(hostcall.ProxyContinueStream(types.StreamTypeResponse)) -} - -// impl HttpContext -func (d *DefaultContext) SendHttpResponse(statusCode uint32, headers [][2]string, body string) error { - return types.StatusToError(sendHttpResponse(statusCode, headers, body)) -} +func (d *DefaultContext) OnDownstreamData(int, bool) types.Action { return types.ActionContinue } +func (d *DefaultContext) OnDownStreamClose(_ types.PeerType) {} +func (d *DefaultContext) OnNewConnection() types.Action { return types.ActionContinue } +func (d *DefaultContext) OnUpstreamData(int, bool) types.Action { return types.ActionContinue } +func (d *DefaultContext) OnUpstreamStreamClose(types.PeerType) {} + +// impl HttpContext +func (d *DefaultContext) OnHttpRequestHeaders(int, bool) types.Action { return types.ActionContinue } +func (d *DefaultContext) OnHttpRequestBody(int, bool) types.Action { return types.ActionContinue } +func (d *DefaultContext) OnHttpRequestTrailers(int) types.Action { return types.ActionContinue } +func (d *DefaultContext) OnHttpResponseHeaders(int, bool) types.Action { return types.ActionContinue } +func (d *DefaultContext) OnHttpResponseBody(int, bool) types.Action { return types.ActionContinue } +func (d *DefaultContext) OnHttpResponseTrailers(int) types.Action { return types.ActionContinue } diff --git a/runtime/conv_go.go b/runtime/conv_go.go index c12a430f..caf24d99 100644 --- a/runtime/conv_go.go +++ b/runtime/conv_go.go @@ -14,6 +14,9 @@ // +build proxytest +// since the difference of the types in SliceHeader.{Len, Cap} between tinygo and go, +// we have to have separated functions for converting bytes + package runtime import ( @@ -21,9 +24,6 @@ import ( "unsafe" ) -// since the difference of the types in SliceHeader.{Len, Cap} between tinygo and go, -// we have to have separated functions for converting bytes utilities - func rawBytePtrToString(raw *byte, size int) string { return *(*string)(unsafe.Pointer(&reflect.SliceHeader{ Data: uintptr(unsafe.Pointer(raw)), diff --git a/runtime/conv_tinygo.go b/runtime/conv_tinygo.go index 9e58fe3c..c70b0078 100644 --- a/runtime/conv_tinygo.go +++ b/runtime/conv_tinygo.go @@ -14,6 +14,9 @@ // +build !proxytest +// since the difference of the types in SliceHeader.{Len, Cap} between tinygo and go, +// we have to have separated functions for converting bytes + package runtime import ( @@ -21,9 +24,6 @@ import ( "unsafe" ) -// since the difference of the types in SliceHeader.{Len, Cap} between tinygo and go, -// we have to have separated functions for converting bytes - func rawBytePtrToString(raw *byte, size int) string { return *(*string)(unsafe.Pointer(&reflect.SliceHeader{ Data: uintptr(unsafe.Pointer(raw)), diff --git a/runtime/hostcall.go b/runtime/hostcall.go new file mode 100644 index 00000000..492b3b33 --- /dev/null +++ b/runtime/hostcall.go @@ -0,0 +1,303 @@ +// Copyright 2020 Takeshi Yoneda(@mathetake) +// +// 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 runtime + +import ( + "strconv" + + "github.com/mathetake/proxy-wasm-go/runtime/rawhostcall" + "github.com/mathetake/proxy-wasm-go/runtime/types" +) + +// wrappers on raw runtime/rawhostcall package + +func HostCallGetPluginConfiguration(dataSize int) ([]byte, error) { + ret, st := getBuffer(types.BufferTypePluginConfiguration, 0, dataSize) + return ret, types.StatusToError(st) +} + +func HostCallGetVMConfiguration(dataSize int) ([]byte, error) { + ret, st := getBuffer(types.BufferTypeVMConfiguration, 0, dataSize) + return ret, types.StatusToError(st) +} + +func HostCallSendHttpResponse(statusCode uint32, headers [][2]string, body string) types.Status { + shs := serializeMap(headers) + hp := &shs[0] + hl := len(shs) + return rawhostcall.ProxySendLocalResponse(statusCode, nil, 0, + stringToBytePtr(body), len(body), hp, hl, -1, + ) +} + +func HostCallSetEffectiveContext(contextID uint32) types.Status { + return rawhostcall.ProxySetEffectiveContext(contextID) +} + +func HostCallSetTickPeriodMilliSeconds(millSec uint32) error { + return types.StatusToError(rawhostcall.ProxySetTickPeriodMilliseconds(millSec)) +} + +func HostCallGetCurrentTime() int64 { + var t int64 + rawhostcall.ProxyGetCurrentTimeNanoseconds(&t) + return t +} + +func HostCallDispatchHttpCall(upstream string, + headers [][2]string, body string, trailers [][2]string, timeoutMillisecond uint32) (uint32, error) { + shs := serializeMap(headers) + hp := &shs[0] + hl := len(shs) + + sts := serializeMap(trailers) + tp := &sts[0] + tl := len(sts) + + var calloutID uint32 + + u := []byte(upstream) + switch st := rawhostcall.ProxyHttpCall(&u[0], len(u), + hp, hl, stringToBytePtr(body), len(body), tp, tl, timeoutMillisecond, &calloutID); st { + case types.StatusOk: + currentState.registerCallout(calloutID) + return calloutID, nil + default: + return 0, types.StatusToError(st) + } +} + +func HostCallGetHttpCallResponseHeaders() ([][2]string, error) { + ret, st := getMap(types.MapTypeHttpCallResponseHeaders) + return ret, types.StatusToError(st) +} + +func HostCallGetHttpCallResponseBody(start, maxSize int) ([]byte, error) { + ret, st := getBuffer(types.BufferTypeHttpCallResponseBody, start, maxSize) + return ret, types.StatusToError(st) +} + +func HostCallGetHttpCallResponseTrailers() ([][2]string, error) { + ret, st := getMap(types.MapTypeHttpCallResponseTrailers) + return ret, types.StatusToError(st) +} + +func HostCallDone() { + switch st := rawhostcall.ProxyDone(); st { + case types.StatusOk: + return + default: + panic("unexpected status on proxy_done: " + strconv.FormatUint(uint64(st), 10)) + } +} + +func HostCallGetDownStreamData(start, maxSize int) ([]byte, error) { + ret, st := getBuffer(types.BufferTypeDownstreamData, start, maxSize) + return ret, types.StatusToError(st) +} + +func HostCallGetUpstreamData(start, maxSize int) ([]byte, error) { + ret, st := getBuffer(types.BufferTypeUpstreamData, start, maxSize) + return ret, types.StatusToError(st) +} + +func HostCallGetHttpRequestHeaders() ([][2]string, error) { + ret, st := getMap(types.MapTypeHttpRequestHeaders) + return ret, types.StatusToError(st) +} + +func HostCallSetHttpRequestHeaders(headers [][2]string) error { + return types.StatusToError(setMap(types.MapTypeHttpRequestHeaders, headers)) +} + +func HostCallGetHttpRequestHeader(key string) (string, error) { + ret, st := getMapValue(types.MapTypeHttpRequestHeaders, key) + return ret, types.StatusToError(st) +} + +func HostCallRemoveHttpRequestHeader(key string) error { + return types.StatusToError(removeMapValue(types.MapTypeHttpRequestHeaders, key)) +} + +func HostCallSetHttpRequestHeader(key, value string) error { + return types.StatusToError(setMapValue(types.MapTypeHttpRequestHeaders, key, value)) +} + +func HostCallAddHttpRequestHeader(key, value string) error { + return types.StatusToError(addMapValue(types.MapTypeHttpRequestHeaders, key, value)) +} + +func HostCallGetHttpRequestBody(start, maxSize int) ([]byte, error) { + ret, st := getBuffer(types.BufferTypeHttpRequestBody, start, maxSize) + return ret, types.StatusToError(st) +} + +func HostCallGetHttpRequestTrailers() ([][2]string, error) { + ret, st := getMap(types.MapTypeHttpRequestTrailers) + return ret, types.StatusToError(st) +} + +func HostCallSetHttpRequestTrailers(headers [][2]string) error { + return types.StatusToError(setMap(types.MapTypeHttpRequestTrailers, headers)) +} + +func HostCallGetHttpRequestTrailer(key string) (string, error) { + ret, st := getMapValue(types.MapTypeHttpRequestTrailers, key) + return ret, types.StatusToError(st) +} + +func HostCallRemoveHttpRequestTrailer(key string) error { + return types.StatusToError(removeMapValue(types.MapTypeHttpRequestTrailers, key)) +} + +func HostCallSetHttpRequestTrailer(key, value string) error { + return types.StatusToError(setMapValue(types.MapTypeHttpRequestTrailers, key, value)) +} + +func HostCallAddHttpRequestTrailer(key, value string) error { + return types.StatusToError(addMapValue(types.MapTypeHttpRequestTrailers, key, value)) +} + +func HostCallResumeHttpRequest() error { + return types.StatusToError(rawhostcall.ProxyContinueStream(types.StreamTypeRequest)) +} + +func HostCallGetHttpResponseHeaders() ([][2]string, error) { + ret, st := getMap(types.MapTypeHttpResponseHeaders) + return ret, types.StatusToError(st) +} + +func HostCallSetHttpResponseHeaders(headers [][2]string) error { + return types.StatusToError(setMap(types.MapTypeHttpResponseHeaders, headers)) +} + +func HostCallGetHttpResponseHeader(key string) (string, error) { + ret, st := getMapValue(types.MapTypeHttpResponseHeaders, key) + return ret, types.StatusToError(st) +} + +func HostCallRemoveHttpResponseHeader(key string) error { + return types.StatusToError(removeMapValue(types.MapTypeHttpResponseHeaders, key)) +} + +func HostCallSetHttpResponseHeader(key, value string) error { + return types.StatusToError(setMapValue(types.MapTypeHttpResponseHeaders, key, value)) +} + +func HostCallAddHttpResponseHeader(key, value string) error { + return types.StatusToError(addMapValue(types.MapTypeHttpResponseHeaders, key, value)) +} + +func HostCallGetHttpResponseBody(start, maxSize int) ([]byte, error) { + ret, st := getBuffer(types.BufferTypeHttpResponseBody, start, maxSize) + return ret, types.StatusToError(st) +} + +func HostCallGetHttpResponseTrailers() ([][2]string, error) { + ret, st := getMap(types.MapTypeHttpResponseTrailers) + return ret, types.StatusToError(st) +} + +func HostCallSetHttpResponseTrailers(headers [][2]string) error { + return types.StatusToError(setMap(types.MapTypeHttpResponseTrailers, headers)) +} + +func HostCallGetHttpResponseTrailer(key string) (string, error) { + ret, st := getMapValue(types.MapTypeHttpResponseTrailers, key) + return ret, types.StatusToError(st) +} + +func HostCallRemoveHttpResponseTrailer(key string) error { + return types.StatusToError(removeMapValue(types.MapTypeHttpResponseTrailers, key)) +} + +func HostCallSetHttpResponseTrailer(key, value string) error { + return types.StatusToError(setMapValue(types.MapTypeHttpResponseTrailers, key, value)) +} + +func HostCallAddHttpResponseTrailer(key, value string) error { + return types.StatusToError(addMapValue(types.MapTypeHttpResponseTrailers, key, value)) +} + +func HostCallResumeHttpResponse() error { + return types.StatusToError(rawhostcall.ProxyContinueStream(types.StreamTypeResponse)) +} + +func setMap(mapType types.MapType, headers [][2]string) types.Status { + shs := serializeMap(headers) + hp := &shs[0] + hl := len(shs) + return rawhostcall.ProxySetHeaderMapPairs(mapType, hp, hl) +} + +func getMapValue(mapType types.MapType, key string) (string, types.Status) { + var rvs int + var raw *byte + if st := rawhostcall.ProxyGetHeaderMapValue(mapType, stringToBytePtr(key), len(key), &raw, &rvs); st != types.StatusOk { + return "", st + } + + ret := rawBytePtrToString(raw, rvs) + return ret, types.StatusOk +} + +func removeMapValue(mapType types.MapType, key string) types.Status { + return rawhostcall.ProxyRemoveHeaderMapValue(mapType, stringToBytePtr(key), len(key)) +} + +func setMapValue(mapType types.MapType, key, value string) types.Status { + return rawhostcall.ProxyReplaceHeaderMapValue(mapType, stringToBytePtr(key), len(key), stringToBytePtr(value), len(value)) +} + +func addMapValue(mapType types.MapType, key, value string) types.Status { + return rawhostcall.ProxyAddHeaderMapValue(mapType, stringToBytePtr(key), len(key), stringToBytePtr(value), len(value)) +} + +func getMap(mapType types.MapType) ([][2]string, types.Status) { + var rvs int + var raw *byte + + st := rawhostcall.ProxyGetHeaderMapPairs(mapType, &raw, &rvs) + if st != types.StatusOk { + return nil, st + } + + bs := rawBytePtrToByteSlice(raw, rvs) + return deserializeMap(bs), types.StatusOk +} + +func getBuffer(bufType types.BufferType, start, maxSize int) ([]byte, types.Status) { + var retData *byte + var retSize int + switch st := rawhostcall.ProxyGetBufferBytes(bufType, start, maxSize, &retData, &retSize); st { + case types.StatusOk: + // is this correct handling...? + if retData == nil { + return nil, types.StatusNotFound + } + return rawBytePtrToByteSlice(retData, retSize), st + default: + return nil, st + } +} + +func stringToBytePtr(in string) *byte { + var ret *byte + if len(in) > 0 { + b := []byte(in) + ret = &b[0] + } + return ret +} diff --git a/runtime/hostcall/README.md b/runtime/hostcall/README.md deleted file mode 100644 index 0c2b000d..00000000 --- a/runtime/hostcall/README.md +++ /dev/null @@ -1,3 +0,0 @@ -The collection of functions implemented in proxy-wasm host environments. - -With `// +build test` tag, you can insert mock host environment that emulates the host environment during unittests. diff --git a/runtime/logging.go b/runtime/logging.go index 9280c88c..3eaf89c9 100644 --- a/runtime/logging.go +++ b/runtime/logging.go @@ -18,36 +18,38 @@ import ( "reflect" "unsafe" - "github.com/mathetake/proxy-wasm-go/runtime/hostcall" + "github.com/mathetake/proxy-wasm-go/runtime/rawhostcall" "github.com/mathetake/proxy-wasm-go/runtime/types" ) func LogTrace(msg string) { - hostcall.ProxyLog(types.LogLevelTrace, unsafeGetStringBytePtr(msg), len(msg)) + rawhostcall.ProxyLog(types.LogLevelTrace, unsafeGetStringBytePtr(msg), len(msg)) } func LogDebug(msg string) { - hostcall.ProxyLog(types.LogLevelDebug, unsafeGetStringBytePtr(msg), len(msg)) + rawhostcall.ProxyLog(types.LogLevelDebug, unsafeGetStringBytePtr(msg), len(msg)) } func LogInfo(msg string) { - hostcall.ProxyLog(types.LogLevelInfo, unsafeGetStringBytePtr(msg), len(msg)) + rawhostcall.ProxyLog(types.LogLevelInfo, unsafeGetStringBytePtr(msg), len(msg)) } func LogWarn(msg string) { - hostcall.ProxyLog(types.LogLevelWarn, unsafeGetStringBytePtr(msg), len(msg)) + rawhostcall.ProxyLog(types.LogLevelWarn, unsafeGetStringBytePtr(msg), len(msg)) } func LogError(msg string) { - hostcall.ProxyLog(types.LogLevelWarn, unsafeGetStringBytePtr(msg), len(msg)) + rawhostcall.ProxyLog(types.LogLevelWarn, unsafeGetStringBytePtr(msg), len(msg)) } func LogCritical(msg string) { - hostcall.ProxyLog(types.LogLevelWarn, unsafeGetStringBytePtr(msg), len(msg)) + rawhostcall.ProxyLog(types.LogLevelWarn, unsafeGetStringBytePtr(msg), len(msg)) } func unsafeGetStringBytePtr(msg string) *byte { sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&msg)) + + // TODO: seems redundant and we should use sliceHeader.Data directly (probably possible) bt := *(*[]byte)(unsafe.Pointer(&reflect.StringHeader{ Data: sliceHeader.Data, Len: sliceHeader.Len, diff --git a/runtime/rawhostcall/README.md b/runtime/rawhostcall/README.md new file mode 100644 index 00000000..992cc810 --- /dev/null +++ b/runtime/rawhostcall/README.md @@ -0,0 +1,3 @@ +The collection of raw functions implemented in proxy-wasm host environments. + +With `// +build proxytest` tag, you can insert mock host environment that emulates the host environment during unittests. diff --git a/runtime/hostcall/hostcall.go b/runtime/rawhostcall/rawhostcall.go similarity index 99% rename from runtime/hostcall/hostcall.go rename to runtime/rawhostcall/rawhostcall.go index 30e9303d..f0aec933 100644 --- a/runtime/hostcall/hostcall.go +++ b/runtime/rawhostcall/rawhostcall.go @@ -14,7 +14,7 @@ // +build !proxytest -package hostcall +package rawhostcall import ( "github.com/mathetake/proxy-wasm-go/runtime/types" diff --git a/runtime/hostcall/hostcall_mock.go b/runtime/rawhostcall/rawhostcall_mock.go similarity index 99% rename from runtime/hostcall/hostcall_mock.go rename to runtime/rawhostcall/rawhostcall_mock.go index 3b6ace93..05a895e6 100644 --- a/runtime/hostcall/hostcall_mock.go +++ b/runtime/rawhostcall/rawhostcall_mock.go @@ -14,7 +14,7 @@ // +build proxytest -package hostcall +package rawhostcall import "github.com/mathetake/proxy-wasm-go/runtime/types" diff --git a/runtime/types/types.go b/runtime/types/types.go index f1933f88..d6f9f66c 100644 --- a/runtime/types/types.go +++ b/runtime/types/types.go @@ -71,7 +71,7 @@ const ( BufferTypeUpstreamData BufferType = 3 BufferTypeHttpCallResponseBody BufferType = 4 BufferTypeGrpcReceiveBuffer BufferType = 5 - BufferTypeVmConfiguration BufferType = 6 + BufferTypeVMConfiguration BufferType = 6 BufferTypePluginConfiguration BufferType = 7 BufferTypeCallData BufferType = 8 ) diff --git a/runtime/wrapper.go b/runtime/wrapper.go deleted file mode 100644 index 01559b73..00000000 --- a/runtime/wrapper.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright 2020 Takeshi Yoneda(@mathetake) -// -// 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 runtime - -import ( - "github.com/mathetake/proxy-wasm-go/runtime/hostcall" - "github.com/mathetake/proxy-wasm-go/runtime/types" -) - -// thin wrappers of raw host calls - -func setMap(mapType types.MapType, headers [][2]string) types.Status { - shs := serializeMap(headers) - hp := &shs[0] - hl := len(shs) - return hostcall.ProxySetHeaderMapPairs(mapType, hp, hl) -} - -// TODO: not tested yet -func getMapValue(mapType types.MapType, key string) (string, types.Status) { - var rvs int - var raw *byte - if st := hostcall.ProxyGetHeaderMapValue(mapType, stringToBytePtr(key), len(key), &raw, &rvs); st != types.StatusOk { - return "", st - } - - ret := rawBytePtrToString(raw, rvs) - return ret, types.StatusOk -} - -// TODO: not tested yet -func removeMapValue(mapType types.MapType, key string) types.Status { - return hostcall.ProxyRemoveHeaderMapValue(mapType, stringToBytePtr(key), len(key)) -} - -// TODO: not tested yet -func setMapValue(mapType types.MapType, key, value string) types.Status { - return hostcall.ProxyReplaceHeaderMapValue(mapType, stringToBytePtr(key), len(key), stringToBytePtr(value), len(value)) -} - -// TODO: not tested yet -func addMapValue(mapType types.MapType, key, value string) types.Status { - return hostcall.ProxyAddHeaderMapValue(mapType, stringToBytePtr(key), len(key), stringToBytePtr(value), len(value)) -} - -func getMap(mapType types.MapType) ([][2]string, types.Status) { - var rvs int - var raw *byte - - st := hostcall.ProxyGetHeaderMapPairs(mapType, &raw, &rvs) - if st != types.StatusOk { - return nil, st - } - - bs := rawBytePtrToByteSlice(raw, rvs) - return deserializeMap(bs), types.StatusOk -} - -func getBuffer(bufType types.BufferType, start, maxSize int) ([]byte, types.Status) { - var retData *byte - var retSize int - switch st := hostcall.ProxyGetBufferBytes(bufType, start, maxSize, &retData, &retSize); st { - case types.StatusOk: - // is this correct handling...? - if retData == nil { - return nil, types.StatusNotFound - } - return rawBytePtrToByteSlice(retData, retSize), st - default: - return nil, st - } -} - -func sendHttpResponse(statusCode uint32, headers [][2]string, body string) types.Status { - shs := serializeMap(headers) - hp := &shs[0] - hl := len(shs) - return hostcall.ProxySendLocalResponse(statusCode, nil, 0, - stringToBytePtr(body), len(body), hp, hl, -1, - ) -} - -func setEffectiveContext(contextID uint32) types.Status { - return hostcall.ProxySetEffectiveContext(contextID) -} - -func dispatchHttpCall(upstream string, - headers [][2]string, body string, trailers [][2]string, timeoutMillisecond uint32) (uint32, types.Status) { - shs := serializeMap(headers) - hp := &shs[0] - hl := len(shs) - - sts := serializeMap(trailers) - tp := &sts[0] - tl := len(sts) - - var calloutID uint32 - - u := []byte(upstream) - switch retStatus := hostcall.ProxyHttpCall(&u[0], len(u), - hp, hl, stringToBytePtr(body), len(body), tp, tl, timeoutMillisecond, &calloutID); retStatus { - case types.StatusOk: - currentState.registerCallout(calloutID) - return calloutID, types.StatusOk - default: - return 0, retStatus - } -} - -func setTickPeriodMilliSeconds(millSec uint32) types.Status { - return hostcall.ProxySetTickPeriodMilliseconds(millSec) -} - -func stringToBytePtr(in string) *byte { - var ret *byte - if len(in) > 0 { - b := []byte(in) // TODO: zero alloc - ret = &b[0] - } - return ret -}