diff --git a/.idea/webResources.xml b/.idea/webResources.xml index 99dd24c..9300696 100644 --- a/.idea/webResources.xml +++ b/.idea/webResources.xml @@ -14,6 +14,7 @@ + diff --git a/README.md b/README.md index e4456ad..38cefc4 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ What is **Capsule**? > πŸ– **The functions are developed with GoLang and compiled to wasm with TinyGo** -πŸ“¦ Before executing or running a function, you need to download the last release of **Capsule**: https://github.com/bots-garden/capsule/releases/tag/0.1.8 (`v0.1.8 πŸ™[octopus]`) +πŸ“¦ Before executing or running a function, you need to download the last release of **Capsule**: https://github.com/bots-garden/capsule/releases/tag/0.1.9 (`v0.1.9 🐞[ladybug]`) > - **Capsule** is developed with GoLang and thanks to the πŸ’œ **[Wazero](https://github.com/tetratelabs/wazero)** project > - The wasm modules are developed in GoLang and compiled with TinyGo (with the WASI specification) @@ -105,13 +105,13 @@ func main() { hf.SetHandleHttp(Handle) } -func Handle(bodyReq string, headersReq map[string]string) (bodyResp string, headersResp map[string]string, errResp error) { - hf.Log("πŸ“ body: " + bodyReq) +func Handle(request hf.Request) (response hf.Response, errResp error) { + hf.Log("πŸ“ Body: " + request.Body) // Read the request headers - hf.Log("Content-Type: " + headersReq["Content-Type"]) - hf.Log("Content-Length: " + headersReq["Content-Length"]) - hf.Log("User-Agent: " + headersReq["User-Agent"]) + hf.Log("Content-Type: " + request.Headers["Content-Type"]) + hf.Log("Content-Length: " + request.Headers["Content-Length"]) + hf.Log("User-Agent: " + request.Headers["User-Agent"]) // Read the MESSAGE environment variable envMessage, err := hf.GetEnv("MESSAGE") @@ -122,14 +122,14 @@ func Handle(bodyReq string, headersReq map[string]string) (bodyResp string, head } // Set the response content type and add a message header - headersResp = map[string]string{ + headersResp := map[string]string{ "Content-Type": "application/json; charset=utf-8", "Message": "πŸ‘‹ hello world 🌍", } jsonResponse := `{"message": "hey people!"}` - return jsonResponse, headersResp, err + return hf.Response{Body: jsonResponse, Headers: headersResp}, err } ``` > - `hf.SetHandleHttp(Handle)` defines the called wasm function @@ -224,7 +224,7 @@ func main() { hf.SetHandleHttp(Handle) } -func Handle(bodyReq string, headersReq map[string]string) (bodyResp string, headersResp map[string]string, errResp error) { +func Handle(request hf.Request) (response hf.Response, errResp error) { html := ` @@ -239,11 +239,11 @@ func Handle(bodyReq string, headersReq map[string]string) (bodyResp string, head ` - headersResp = map[string]string{ + headersResp := map[string]string{ "Content-Type": "text/html; charset=utf-8", } - return html, headersResp, nil + return hf.Response{Body: html, Headers: headersResp}, nil } ``` diff --git a/capsule-launcher/hostfunctions/http.go b/capsule-launcher/hostfunctions/http.go index b542831..81c1bf2 100644 --- a/capsule-launcher/hostfunctions/http.go +++ b/capsule-launcher/hostfunctions/http.go @@ -28,11 +28,11 @@ func Http(ctx context.Context, module api.Module, headersStr := memory.ReadStringFromMemory(ctx, module, headersOffSet, headersByteCount) //TODO: choose another separator: Β° - headersSlice := commons.CreateSliceFromString(headersStr, "|") + headersSlice := commons.CreateSliceFromString(headersStr, commons.StrSeparator) //fmt.Println(headersSlice) - headersMap := commons.CreateMapFromSlice(headersSlice, ":") + headersMap := commons.CreateMapFromSlice(headersSlice, commons.FieldSeparator) //fmt.Println(headersMap) //fmt.Println(headersMap["Accept"]) diff --git a/capsule-launcher/services/http/headers.go b/capsule-launcher/services/http/headers.go index ff448a8..9d6e986 100644 --- a/capsule-launcher/services/http/headers.go +++ b/capsule-launcher/services/http/headers.go @@ -6,7 +6,7 @@ import ( ) func GetHeadersMapFromString(headersStr string) map[string]string { - return commons.CreateMapFromSlice(commons.CreateSliceFromString(headersStr, "|"), ":") + return commons.CreateMapFromSlice(commons.CreateSliceFromString(headersStr, commons.StrSeparator), commons.FieldSeparator) } //TODO: add other content types diff --git a/capsule-launcher/services/http/http.go b/capsule-launcher/services/http/http.go index 9f7253b..a988f40 100644 --- a/capsule-launcher/services/http/http.go +++ b/capsule-launcher/services/http/http.go @@ -1,122 +1,133 @@ package capsulehttp import ( - "encoding/json" - "fmt" - "github.com/bots-garden/capsule/capsule-launcher/hostfunctions" - "github.com/bots-garden/capsule/capsule-launcher/services/wasmrt" - "github.com/bots-garden/capsule/commons" - "github.com/gin-gonic/gin" - "github.com/shirou/gopsutil/v3/mem" - "net/http" + "encoding/json" + "fmt" + "github.com/bots-garden/capsule/capsule-launcher/hostfunctions" + "github.com/bots-garden/capsule/capsule-launcher/services/wasmrt" + "github.com/bots-garden/capsule/commons" + "github.com/gin-gonic/gin" + "github.com/shirou/gopsutil/v3/mem" + "net/http" ) func Serve(httpPort string, wasmFile []byte, crt, key string) { - //fmt.Println("πŸ‘‹[checking]capsulehttp.Serve") + //fmt.Println("πŸ‘‹[checking]capsulehttp.Serve") - hostfunctions.HostInformation = `{"httpPort":` + httpPort + `}` + hostfunctions.HostInformation = `{"httpPort":` + httpPort + `}` - v, _ := mem.VirtualMemory() + v, _ := mem.VirtualMemory() - if commons.GetEnv("DEBUG", "false") == "false" { - gin.SetMode(gin.ReleaseMode) - } else { - gin.SetMode(gin.DebugMode) - } + if commons.GetEnv("DEBUG", "false") == "false" { + gin.SetMode(gin.ReleaseMode) + } else { + gin.SetMode(gin.DebugMode) + } - router := gin.New() + router := gin.New() - router.GET("/host-metrics", func(c *gin.Context) { - jsonMap := make(map[string]interface{}) - json.Unmarshal([]byte(v.String()), &jsonMap) - c.JSON(http.StatusOK, jsonMap) - }) + router.GET("/host-metrics", func(c *gin.Context) { + jsonMap := make(map[string]interface{}) + json.Unmarshal([]byte(v.String()), &jsonMap) + c.JSON(http.StatusOK, jsonMap) + }) - router.GET("/health", func(c *gin.Context) { - c.String(http.StatusOK, "OK") - }) + router.GET("/health", func(c *gin.Context) { + c.String(http.StatusOK, "OK") + }) - //TODO: be able to get the query string from the wasm module - // we need to be able to return json, html, txt - router.GET("/", func(c *gin.Context) { - wasmRuntime, wasmModule, wasmFunction, ctx := capsule.GetNewWasmRuntimeForHttp(wasmFile) - defer wasmRuntime.Close(ctx) + router.GET("/", func(c *gin.Context) { - query := "empty" //🚧 - queryPos, queryLen, free, err := capsule.ReserveMemorySpaceFor(query, wasmModule, ctx) - defer free.Call(ctx, queryPos) + jsonStr, _ := GetJsonStringFromPayloadRequest(c) + headersStr := GetHeadersStringFromHeadersRequest(c) + uri := c.Request.RequestURI + method := c.Request.Method - headersStr := GetHeadersStringFromHeadersRequest(c) - headersStrPos, headersStrLen, free, err := capsule.ReserveMemorySpaceFor(headersStr, wasmModule, ctx) - defer free.Call(ctx, headersStrPos) + wasmRuntime, wasmModule, wasmFunction, ctx := capsule.GetNewWasmRuntimeForHttp(wasmFile) + defer wasmRuntime.Close(ctx) - bytes, err := capsule.ExecHandleFunction(wasmFunction, wasmModule, ctx, queryPos, queryLen, headersStrPos, headersStrLen) - if err != nil { - c.String(500, "out of range of memory size") - } - bodyStr, headers := GetBodyAndHeaders(bytes, c) + uriPos, uriLen, free, err := capsule.ReserveMemorySpaceFor(uri, wasmModule, ctx) + defer free.Call(ctx, uriPos) - // check the return value - if commons.IsErrorString(bodyStr) { - SendErrorMessage(bodyStr, headers, c) - } else if IsBodyString(bodyStr) { - SendBodyMessage(bodyStr, headers, c) - } else { - c.String(http.StatusOK, bodyStr) - } + jsonStrPos, jsonStrLen, free, err := capsule.ReserveMemorySpaceFor(jsonStr, wasmModule, ctx) + defer free.Call(ctx, jsonStrPos) - }) + headersStrPos, headersStrLen, free, err := capsule.ReserveMemorySpaceFor(headersStr, wasmModule, ctx) + defer free.Call(ctx, headersStrPos) - router.POST("/", func(c *gin.Context) { + methodPos, methodLen, free, err := capsule.ReserveMemorySpaceFor(method, wasmModule, ctx) + defer free.Call(ctx, methodPos) - // Parameters "setup" - jsonStr, _ := GetJsonStringFromPayloadRequest(c) - headersStr := GetHeadersStringFromHeadersRequest(c) + bytes, err := capsule.ExecHandleFunction(wasmFunction, wasmModule, ctx, jsonStrPos, jsonStrLen, uriPos, uriLen, headersStrPos, headersStrLen, methodPos, methodLen) + if err != nil { + c.String(500, "out of range of memory size") + } + bodyStr, headers := GetBodyAndHeaders(bytes, c) - //time.Sleep(500 * time.Millisecond) + // check the return value + if commons.IsErrorString(bodyStr) { + SendErrorMessage(bodyStr, headers, c) + } else if IsBodyString(bodyStr) { + SendBodyMessage(bodyStr, headers, c) + } else { + c.String(http.StatusOK, bodyStr) + } - wasmRuntime, wasmModule, wasmFunction, ctx := capsule.GetNewWasmRuntimeForHttp(wasmFile) + }) - defer wasmRuntime.Close(ctx) + router.POST("/", func(c *gin.Context) { - jsonStrPos, jsonStrLen, free, err := capsule.ReserveMemorySpaceFor(jsonStr, wasmModule, ctx) + // Parameters "setup" + jsonStr, _ := GetJsonStringFromPayloadRequest(c) + headersStr := GetHeadersStringFromHeadersRequest(c) + uri := c.Request.RequestURI + method := c.Request.Method - defer free.Call(ctx, jsonStrPos) + wasmRuntime, wasmModule, wasmFunction, ctx := capsule.GetNewWasmRuntimeForHttp(wasmFile) + defer wasmRuntime.Close(ctx) - headersStrPos, headersStrLen, free, err := capsule.ReserveMemorySpaceFor(headersStr, wasmModule, ctx) + uriPos, uriLen, free, err := capsule.ReserveMemorySpaceFor(uri, wasmModule, ctx) + defer free.Call(ctx, uriPos) - defer free.Call(ctx, headersStrPos) + jsonStrPos, jsonStrLen, free, err := capsule.ReserveMemorySpaceFor(jsonStr, wasmModule, ctx) + defer free.Call(ctx, jsonStrPos) - bytes, err := capsule.ExecHandleFunction(wasmFunction, wasmModule, ctx, jsonStrPos, jsonStrLen, headersStrPos, headersStrLen) + headersStrPos, headersStrLen, free, err := capsule.ReserveMemorySpaceFor(headersStr, wasmModule, ctx) + defer free.Call(ctx, headersStrPos) - if err != nil { - c.String(500, "out of range of memory size") - } + methodPos, methodLen, free, err := capsule.ReserveMemorySpaceFor(method, wasmModule, ctx) + defer free.Call(ctx, methodPos) - bodyStr, headers := GetBodyAndHeaders(bytes, c) + bytes, err := capsule.ExecHandleFunction(wasmFunction, wasmModule, ctx, jsonStrPos, jsonStrLen, uriPos, uriLen, headersStrPos, headersStrLen, methodPos, methodLen) - // check the return value - if commons.IsErrorString(bodyStr) { - SendErrorMessage(bodyStr, headers, c) - } else if IsBodyString(bodyStr) { - SendJsonMessage(bodyStr, headers, c) - } else { - c.String(http.StatusOK, bodyStr) - } + if err != nil { + c.String(500, "out of range of memory size") + } - //c.String(http.StatusOK, bodyStr) + bodyStr, headers := GetBodyAndHeaders(bytes, c) - }) + // check the return value + if commons.IsErrorString(bodyStr) { + SendErrorMessage(bodyStr, headers, c) + } else if IsBodyString(bodyStr) { + SendJsonMessage(bodyStr, headers, c) + } else { + c.String(http.StatusOK, bodyStr) + } - if crt != "" { - // certs/procyon-registry.local.crt - // certs/procyon-registry.local.key - fmt.Println("πŸ’Š Capsule (", commons.CapsuleVersion(), ") http server is listening on:", httpPort, "πŸ”πŸŒ") + //c.String(http.StatusOK, bodyStr) - router.RunTLS(":"+httpPort, crt, key) - } else { - fmt.Println("πŸ’Š Capsule (", commons.CapsuleVersion(), ") http server is listening on:", httpPort, "🌍") - router.Run(":" + httpPort) - } + }) + + if crt != "" { + // certs/procyon-registry.local.crt + // certs/procyon-registry.local.key + fmt.Println("πŸ’Š Capsule (", commons.CapsuleVersion(), ") http server is listening on:", httpPort, "πŸ”πŸŒ") + + router.RunTLS(":"+httpPort, crt, key) + } else { + fmt.Println("πŸ’Š Capsule (", commons.CapsuleVersion(), ") http server is listening on:", httpPort, "🌍") + router.Run(":" + httpPort) + } } diff --git a/capsule-launcher/services/http/request.go b/capsule-launcher/services/http/request.go index 87d7b11..045ac78 100644 --- a/capsule-launcher/services/http/request.go +++ b/capsule-launcher/services/http/request.go @@ -27,7 +27,7 @@ func GetHeadersStringFromHeadersRequest(c *gin.Context) string { headersMap[key] = values[0] } headersSlice := commons.CreateSliceFromMap(headersMap) - headersParameter := commons.CreateStringFromSlice(headersSlice, "|") + headersParameter := commons.CreateStringFromSlice(headersSlice, commons.StrSeparator) return headersParameter } diff --git a/capsulemodule/go.mod b/capsulemodule/go.mod index b4d1c3c..a6a8e15 100644 --- a/capsulemodule/go.mod +++ b/capsulemodule/go.mod @@ -2,4 +2,6 @@ module github.com/bots-garden/capsule/capsulemodule go 1.18 -require github.com/bots-garden/capsule/commons v0.0.0-20220903062354-1c48dd250b77 +replace github.com/bots-garden/capsule/commons => ../commons + +require github.com/bots-garden/capsule/commons v0.0.0-20220903105536-e833f3d14593 diff --git a/capsulemodule/go.sum b/capsulemodule/go.sum index 5b468d2..e69de29 100644 --- a/capsulemodule/go.sum +++ b/capsulemodule/go.sum @@ -1,4 +0,0 @@ -github.com/bots-garden/capsule/commons v0.0.0-20220821060842-d1dc9f030021 h1:cBeILASaSUdrsImLP6wR6a747SHYBJqIwuADm2BMDO4= -github.com/bots-garden/capsule/commons v0.0.0-20220821060842-d1dc9f030021/go.mod h1:5ctHSZAwy3GEi4tR9YKFTfWtBUXDcOMFHNiJYXbV61c= -github.com/bots-garden/capsule/commons v0.0.0-20220903062354-1c48dd250b77 h1:CyywCzVyAuT7fHf5iHgjx0IqUvEVevtbVMwbSkS2VnA= -github.com/bots-garden/capsule/commons v0.0.0-20220903062354-1c48dd250b77/go.mod h1:5ctHSZAwy3GEi4tR9YKFTfWtBUXDcOMFHNiJYXbV61c= diff --git a/capsulemodule/hostfunctions/handlehttp.go b/capsulemodule/hostfunctions/handlehttp.go index 14dee2f..92716e7 100644 --- a/capsulemodule/hostfunctions/handlehttp.go +++ b/capsulemodule/hostfunctions/handlehttp.go @@ -2,47 +2,63 @@ package hostfunctions // TODO: move this to another package: exposedFunctions import ( - "github.com/bots-garden/capsule/capsulemodule/memory" - "github.com/bots-garden/capsule/commons" + "github.com/bots-garden/capsule/capsulemodule/memory" + "github.com/bots-garden/capsule/commons" ) -var handleHttpFunction func(bodyReq string, headersReq map[string]string) (bodyResp string, headersResp map[string]string, errResp error) +/* previous version +var handleHttpFunction func(bodyReq string, headersReq map[string]string) ( + bodyResp string, headersResp map[string]string, errResp error) +*/ +var handleHttpFunction func(req Request) ( + resp Response, errResp error) + +/* previous version func SetHandleHttp(function func(string, map[string]string) (string, map[string]string, error)) { - handleHttpFunction = function +*/ + +func SetHandleHttp(function func(request Request) (Response, error)) { + handleHttpFunction = function } -// TODO add detailed comments +// The name "callHandleHttp" of the exported function is defined/declared +// in `wasmrunner.go`, function: GetNewWasmRuntimeForHttp + //export callHandleHttp //go:linkname callHandleHttp -func callHandleHttp(strPtrPos, size uint32, headersPtrPos, headersSize uint32) (strPtrPosSize uint64) { - //posted JSON data - stringParameter := memory.GetStringParam(strPtrPos, size) - headersParameter := memory.GetStringParam(headersPtrPos, headersSize) +func callHandleHttp(bodyPtrPos, bodySize, uriPtrPos, uriSize, headersPtrPos, headersSize, methodPtrPos, methodSize uint32) (strPtrPosSize uint64) { + //posted JSON data + bodyParameter := memory.GetStringParam(bodyPtrPos, bodySize) + headersParameter := memory.GetStringParam(headersPtrPos, headersSize) + uriParameter := memory.GetStringParam(uriPtrPos, uriSize) + methodParameter := memory.GetStringParam(methodPtrPos, methodSize) - headersSlice := commons.CreateSliceFromString(headersParameter, "|") - headers := commons.CreateMapFromSlice(headersSlice, ":") + headersSlice := commons.CreateSliceFromString(headersParameter, commons.StrSeparator) + headers := commons.CreateMapFromSlice(headersSlice, commons.FieldSeparator) - var result string - stringReturnByHandleFunction, headersReturnByHandleFunction, errorReturnByHandleFunction := handleHttpFunction(stringParameter, headers) + var result string + //stringReturnByHandleFunction, headersReturnByHandleFunction, errorReturnByHandleFunction := handleHttpFunction(bodyParameter, headers) + responseReturnByHandleFunction, errorReturnByHandleFunction := handleHttpFunction(Request{bodyParameter, headers, uriParameter, methodParameter}) - returnHeaderString := commons.CreateStringFromSlice(commons.CreateSliceFromMap(headersReturnByHandleFunction), "|") + returnHeaderString := commons.CreateStringFromSlice(commons.CreateSliceFromMap(responseReturnByHandleFunction.Headers), commons.StrSeparator) - if errorReturnByHandleFunction != nil { - result = commons.CreateStringError(errorReturnByHandleFunction.Error(), 0) - } else { - result = CreateBodyString(stringReturnByHandleFunction) - } + if errorReturnByHandleFunction != nil { + result = commons.CreateStringError(errorReturnByHandleFunction.Error(), 0) + } else { + result = CreateBodyString(responseReturnByHandleFunction.Body) + } - pos, length := memory.GetStringPtrPositionAndSize(CreateResponseString(result, returnHeaderString)) + // merge body and headers response + pos, length := memory.GetStringPtrPositionAndSize(CreateResponseString(result, returnHeaderString)) - return memory.PackPtrPositionAndSize(pos, length) + return memory.PackPtrPositionAndSize(pos, length) } func CreateBodyString(message string) string { - return "[BODY]" + message + return "[BODY]" + message } func CreateResponseString(result, headers string) string { - return result + "[HEADERS]" + headers + return result + "[HEADERS]" + headers } diff --git a/capsulemodule/hostfunctions/http.go b/capsulemodule/hostfunctions/http.go index e8019e1..0175176 100644 --- a/capsulemodule/hostfunctions/http.go +++ b/capsulemodule/hostfunctions/http.go @@ -2,11 +2,11 @@ package hostfunctions import ( - "errors" - "github.com/bots-garden/capsule/capsulemodule/memory" - "github.com/bots-garden/capsule/commons" - "strconv" - _ "unsafe" + "errors" + "github.com/bots-garden/capsule/capsulemodule/memory" + "github.com/bots-garden/capsule/commons" + "strconv" + _ "unsafe" ) //export hostHttp @@ -14,49 +14,49 @@ import ( func hostHttp(urlOffset uint32, urlByteCount uint32, methodOffSet uint32, methodByteCount uint32, headersOffSet uint32, headersMethodByteCount uint32, bodyOffset uint32, bodyByteCount uint32, retBuffPtrPos **byte, retBuffSize *int) func Http(url, method string, headers map[string]string, body string) (string, error) { - // Get parameters from the wasm module - // Prepare parameters for the host function call - urlStrPos, urlStrSize := memory.GetStringPtrPositionAndSize(url) - methodStrPos, methodStrSize := memory.GetStringPtrPositionAndSize(method) + // Get parameters from the wasm module + // Prepare parameters for the host function call + urlStrPos, urlStrSize := memory.GetStringPtrPositionAndSize(url) + methodStrPos, methodStrSize := memory.GetStringPtrPositionAndSize(method) - /* - headers := map[string]string{"Accept": "application/json", "Content-Type": " text/html; charset=UTF-8"} + /* + headers := map[string]string{"Accept": "application/json", "Content-Type": " text/html; charset=UTF-8"} - headersStringSlice => ["Accept:application/json", ”Content-Type:text/html; charset=UTF-8"] + headersStringSlice => ["Accept:application/json", ”Content-Type:text/html; charset=UTF-8"] - headerString => "Accept:application/json|Content-Type:text/html; charset=UTF-8" - */ + headerString => "Accept:application/json|Content-Type:text/html; charset=UTF-8" + */ - headersStringSlice := commons.CreateSliceFromMap(headers) - headerString := commons.CreateStringFromSlice(headersStringSlice, "|") + headersStringSlice := commons.CreateSliceFromMap(headers) + headerString := commons.CreateStringFromSlice(headersStringSlice, commons.StrSeparator) - headersStrPos, headersStrSize := memory.GetStringPtrPositionAndSize(headerString) + headersStrPos, headersStrSize := memory.GetStringPtrPositionAndSize(headerString) - bodyStrPos, bodyStrSize := memory.GetStringPtrPositionAndSize(body) + bodyStrPos, bodyStrSize := memory.GetStringPtrPositionAndSize(body) - // This will be used to retrieve the return value (result) - var buffPtr *byte - var buffSize int + // This will be used to retrieve the return value (result) + var buffPtr *byte + var buffSize int - // πŸ– call the host function - // buffPtr, buffSize allows to retrieve the result of the function call - hostHttp(urlStrPos, urlStrSize, methodStrPos, methodStrSize, headersStrPos, headersStrSize, bodyStrPos, bodyStrSize, &buffPtr, &buffSize) + // πŸ– call the host function + // buffPtr, buffSize allows to retrieve the result of the function call + hostHttp(urlStrPos, urlStrSize, methodStrPos, methodStrSize, headersStrPos, headersStrSize, bodyStrPos, bodyStrSize, &buffPtr, &buffSize) - var resultStr = "" - var err error - valueStr := memory.GetStringResult(buffPtr, buffSize) + var resultStr = "" + var err error + valueStr := memory.GetStringResult(buffPtr, buffSize) - // check the return value - if commons.IsErrorString(valueStr) { - errorMessage, errorCode := commons.GetErrorStringInfo(valueStr) - if errorCode == 0 { - err = errors.New(errorMessage) - } else { - err = errors.New(errorMessage + " (" + strconv.Itoa(errorCode) + ")") - } + // check the return value + if commons.IsErrorString(valueStr) { + errorMessage, errorCode := commons.GetErrorStringInfo(valueStr) + if errorCode == 0 { + err = errors.New(errorMessage) + } else { + err = errors.New(errorMessage + " (" + strconv.Itoa(errorCode) + ")") + } - } else { - resultStr = valueStr - } - return resultStr, err + } else { + resultStr = valueStr + } + return resultStr, err } diff --git a/capsulemodule/hostfunctions/request.go b/capsulemodule/hostfunctions/request.go new file mode 100644 index 0000000..5392574 --- /dev/null +++ b/capsulemodule/hostfunctions/request.go @@ -0,0 +1,41 @@ +package hostfunctions + +import ( + "github.com/bots-garden/capsule/commons" + "strings" +) + +type Request struct { + Body string + Headers map[string]string + Uri string + Method string +} + +func (req Request) ParseQueryString() map[string]string { + uriParts := strings.Split(req.Uri, "/?") + if len(uriParts) > 1 { + queryString := uriParts[1] + slice := commons.CreateSliceFromString(queryString, "&") + if len(slice) > 0 { + params := commons.CreateMapFromSlice(slice, "=") + if len(params) > 0 { + return params + } else { + return nil + } + } else { + return nil + } + + } else { + return nil + } +} + +/* TODO: +- add url +- GetHeader method +- QueryString +- ... +*/ diff --git a/capsulemodule/hostfunctions/response.go b/capsulemodule/hostfunctions/response.go new file mode 100644 index 0000000..234a9ca --- /dev/null +++ b/capsulemodule/hostfunctions/response.go @@ -0,0 +1,12 @@ +package hostfunctions + +type Response struct { + Body string + Headers map[string]string +} + +/* TODO: +- add status code +- SetHeader method +- ... +*/ diff --git a/commons/constants.go b/commons/constants.go new file mode 100644 index 0000000..a4114ea --- /dev/null +++ b/commons/constants.go @@ -0,0 +1,4 @@ +package commons + +const StrSeparator = string(rune(178)) +const FieldSeparator = ":" diff --git a/commons/helpers-map-slice-string.go b/commons/helpers-map-slice-string.go index ce57e48..cba40e7 100644 --- a/commons/helpers-map-slice-string.go +++ b/commons/helpers-map-slice-string.go @@ -28,7 +28,9 @@ func CreateMapFromSlice(strSlice []string, separator string) map[string]string { strMap := make(map[string]string) for _, item := range strSlice { res := strings.Split(item, separator) - strMap[res[0]] = res[1] + if len(res) > 1 { + strMap[res[0]] = res[1] + } } return strMap } diff --git a/commons/version.go b/commons/version.go index 4cb23fe..c9b394b 100644 --- a/commons/version.go +++ b/commons/version.go @@ -1,5 +1,5 @@ package commons func CapsuleVersion() string { - return "v0.1.8 πŸ™[octopus]" + return "v0.1.9 🐞[ladybug]" } diff --git a/install-all-capsule-elements.sh b/install-all-capsule-elements.sh index 9af0893..d1876a9 100755 --- a/install-all-capsule-elements.sh +++ b/install-all-capsule-elements.sh @@ -1,6 +1,6 @@ #!/bin/bash -LAST_CAPSULE_VERSION="0.1.8" +LAST_CAPSULE_VERSION="0.1.9" echo "System: ${OSTYPE} $(uname -m)" if [[ $1 = "help" ]] diff --git a/install-capsule-ctl.sh b/install-capsule-ctl.sh index da1c198..f2a5ea4 100755 --- a/install-capsule-ctl.sh +++ b/install-capsule-ctl.sh @@ -1,5 +1,5 @@ #!/bin/bash -LAST_CAPSULE_VERSION="0.1.8" +LAST_CAPSULE_VERSION="0.1.9" echo "System: ${OSTYPE} $(uname -m)" if [[ $1 = "help" ]] diff --git a/install-capsule-launcher.sh b/install-capsule-launcher.sh index 5ad0262..0dcb648 100755 --- a/install-capsule-launcher.sh +++ b/install-capsule-launcher.sh @@ -1,5 +1,5 @@ #!/bin/bash -LAST_CAPSULE_VERSION="0.1.8" +LAST_CAPSULE_VERSION="0.1.9" echo "System: ${OSTYPE} $(uname -m)" if [[ $1 = "help" ]] diff --git a/install-capsule-registry.sh b/install-capsule-registry.sh index 5856c28..2f52798 100755 --- a/install-capsule-registry.sh +++ b/install-capsule-registry.sh @@ -1,5 +1,5 @@ #!/bin/bash -LAST_CAPSULE_VERSION="0.1.8" +LAST_CAPSULE_VERSION="0.1.0" echo "System: ${OSTYPE} $(uname -m)" if [[ $1 = "help" ]] diff --git a/install-capsule-reverse-proxy.sh b/install-capsule-reverse-proxy.sh index 2706d0c..3baa37f 100755 --- a/install-capsule-reverse-proxy.sh +++ b/install-capsule-reverse-proxy.sh @@ -1,5 +1,5 @@ #!/bin/bash -LAST_CAPSULE_VERSION="0.1.8" +LAST_CAPSULE_VERSION="0.1.9" echo "System: ${OSTYPE} $(uname -m)" if [[ $1 = "help" ]] diff --git a/install-capsule-worker.sh b/install-capsule-worker.sh index 093c120..0fc5d1c 100755 --- a/install-capsule-worker.sh +++ b/install-capsule-worker.sh @@ -1,5 +1,5 @@ #!/bin/bash -LAST_CAPSULE_VERSION="0.1.8" +LAST_CAPSULE_VERSION="0.1.9" echo "System: ${OSTYPE} $(uname -m)" if [[ $1 = "help" ]] diff --git a/sandbox/src/functions/hey/build.sh b/sandbox/src/functions/hey/build.sh index 19f1fee..36adec4 100755 --- a/sandbox/src/functions/hey/build.sh +++ b/sandbox/src/functions/hey/build.sh @@ -1,3 +1,4 @@ #!/bin/bash +go mod tidy tinygo build -o hey.wasm -scheduler=none -target wasi ./hey.go ls -lh *.wasm diff --git a/sandbox/src/functions/hey/go.mod b/sandbox/src/functions/hey/go.mod index 709a092..d8877f9 100644 --- a/sandbox/src/functions/hey/go.mod +++ b/sandbox/src/functions/hey/go.mod @@ -4,14 +4,16 @@ go 1.18 replace github.com/bots-garden/capsule/capsulemodule => ../../../../capsulemodule +replace github.com/bots-garden/capsule/commons => ../../../../commons + require ( - github.com/bots-garden/capsule/capsulemodule v0.0.0-20220821063800-09667c0e1624 + github.com/bots-garden/capsule/capsulemodule v0.0.0-20220903105536-e833f3d14593 github.com/tidwall/gjson v1.14.3 github.com/tidwall/sjson v1.2.5 ) require ( - github.com/bots-garden/capsule/commons v0.0.0-20220821063800-09667c0e1624 // indirect + github.com/bots-garden/capsule/commons v0.0.0-20220903105536-e833f3d14593 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect ) diff --git a/sandbox/src/functions/hey/go.sum b/sandbox/src/functions/hey/go.sum index ce5169d..4b4fa42 100644 --- a/sandbox/src/functions/hey/go.sum +++ b/sandbox/src/functions/hey/go.sum @@ -1,5 +1,3 @@ -github.com/bots-garden/capsule/commons v0.0.0-20220821063800-09667c0e1624 h1:8F1EV4zfsI2XYdABB1rGyiCJUoWfAIeWjF5b3vWnoKA= -github.com/bots-garden/capsule/commons v0.0.0-20220821063800-09667c0e1624/go.mod h1:5ctHSZAwy3GEi4tR9YKFTfWtBUXDcOMFHNiJYXbV61c= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw= github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= diff --git a/sandbox/src/functions/hey/hey.go b/sandbox/src/functions/hey/hey.go index 976a43e..2dce8c5 100644 --- a/sandbox/src/functions/hey/hey.go +++ b/sandbox/src/functions/hey/hey.go @@ -14,29 +14,29 @@ func main() { hf.SetHandleHttp(Handle) } -func Handle(bodyReq string, headersReq map[string]string) (bodyResp string, headersResp map[string]string, errResp error) { +func Handle(req hf.Request) (resp hf.Response, errResp error) { - hf.Log("πŸ“ body: " + bodyReq) + hf.Log("πŸ“ body: " + req.Body) - author := gjson.Get(bodyReq, "author") - message := gjson.Get(bodyReq, "message") + author := gjson.Get(req.Body, "author") + message := gjson.Get(req.Body, "message") hf.Log("πŸ‘‹ " + message.String() + " by " + author.String() + " πŸ˜„") // πŸ‘€ https://github.com/bots-garden/capsule/issues/91 - hf.Log("🟒 Content-Type: " + headersReq["Content-Type"]) - hf.Log("πŸ”΅ Content-Length: " + headersReq["Content-Length"]) - hf.Log("🟠 User-Agent: " + headersReq["User-Agent"]) - hf.Log("πŸ”΄ My-Token: " + headersReq["My-Token"]) + hf.Log("🟒 Content-Type: " + req.Headers["Content-Type"]) + hf.Log("πŸ”΅ Content-Length: " + req.Headers["Content-Length"]) + hf.Log("🟠 User-Agent: " + req.Headers["User-Agent"]) + hf.Log("πŸ”΄ My-Token: " + req.Headers["My-Token"]) - headersResp = map[string]string{ + headersResp := map[string]string{ "Content-Type": "application/json; charset=utf-8", "Message": "πŸ‘‹ hello world 🌍", - "MyToken": headersReq["My-Token"], + "MyToken": req.Headers["My-Token"], } jsondoc := `{"message": "", "author": ""}` jsondoc, _ = sjson.Set(jsondoc, "message", "πŸ‘‹ hey! What's up?") jsondoc, _ = sjson.Set(jsondoc, "author", "Bob") - return jsondoc, headersResp, nil + return hf.Response{Body: jsondoc, Headers: headersResp}, nil } diff --git a/sandbox/src/functions/yo/build.sh b/sandbox/src/functions/yo/build.sh index 6d99f89..4800888 100755 --- a/sandbox/src/functions/yo/build.sh +++ b/sandbox/src/functions/yo/build.sh @@ -1,4 +1,5 @@ #!/bin/bash +go mod tidy tinygo build -o yo.wasm -scheduler=none -target wasi ./yo.go ls -lh *.wasm diff --git a/sandbox/src/functions/yo/go.mod b/sandbox/src/functions/yo/go.mod index 5cc39f5..d56ce71 100644 --- a/sandbox/src/functions/yo/go.mod +++ b/sandbox/src/functions/yo/go.mod @@ -4,6 +4,8 @@ go 1.18 replace github.com/bots-garden/capsule/capsulemodule => ../../../../capsulemodule -require github.com/bots-garden/capsule/capsulemodule v0.0.0-20220811130424-72fd5964059b +replace github.com/bots-garden/capsule/commons => ../../../../commons -require github.com/bots-garden/capsule/commons v0.0.0-20220821060842-d1dc9f030021 // indirect +require github.com/bots-garden/capsule/capsulemodule v0.0.0-20220903105536-e833f3d14593 + +require github.com/bots-garden/capsule/commons v0.0.0-20220903105536-e833f3d14593 // indirect diff --git a/sandbox/src/functions/yo/go.sum b/sandbox/src/functions/yo/go.sum index e9694fc..e69de29 100644 --- a/sandbox/src/functions/yo/go.sum +++ b/sandbox/src/functions/yo/go.sum @@ -1,2 +0,0 @@ -github.com/bots-garden/capsule/commons v0.0.0-20220821060842-d1dc9f030021 h1:cBeILASaSUdrsImLP6wR6a747SHYBJqIwuADm2BMDO4= -github.com/bots-garden/capsule/commons v0.0.0-20220821060842-d1dc9f030021/go.mod h1:5ctHSZAwy3GEi4tR9YKFTfWtBUXDcOMFHNiJYXbV61c= diff --git a/sandbox/src/functions/yo/yo.go b/sandbox/src/functions/yo/yo.go index 1956c05..3988b48 100644 --- a/sandbox/src/functions/yo/yo.go +++ b/sandbox/src/functions/yo/yo.go @@ -2,16 +2,16 @@ package main // TinyGo wasm module import ( - hf "github.com/bots-garden/capsule/capsulemodule/hostfunctions" + hf "github.com/bots-garden/capsule/capsulemodule/hostfunctions" ) func main() { - hf.SetHandleHttp(Handle) + hf.SetHandleHttp(Handle) } -func Handle(bodyReq string, headersReq map[string]string) (bodyResp string, headersResp map[string]string, errResp error) { - message, _ := hf.GetEnv("MESSAGE") - html := ` +func Handle(req hf.Request) (resp hf.Response, errResp error) { + message, _ := hf.GetEnv("MESSAGE") + html := ` @@ -41,9 +41,9 @@ func Handle(bodyReq string, headersReq map[string]string) (bodyResp string, head ` - headersResp = map[string]string{ - "Content-Type": "text/html; charset=utf-8", - } + headersResp := map[string]string{ + "Content-Type": "text/html; charset=utf-8", + } - return html, headersResp, nil + return hf.Response{Body: html, Headers: headersResp}, nil } diff --git a/vm-capsule/src/functions/hey/build.sh b/vm-capsule/src/functions/hey/build.sh index 19f1fee..36adec4 100755 --- a/vm-capsule/src/functions/hey/build.sh +++ b/vm-capsule/src/functions/hey/build.sh @@ -1,3 +1,4 @@ #!/bin/bash +go mod tidy tinygo build -o hey.wasm -scheduler=none -target wasi ./hey.go ls -lh *.wasm diff --git a/vm-capsule/src/functions/hey/go.mod b/vm-capsule/src/functions/hey/go.mod index 709a092..213db82 100644 --- a/vm-capsule/src/functions/hey/go.mod +++ b/vm-capsule/src/functions/hey/go.mod @@ -4,6 +4,8 @@ go 1.18 replace github.com/bots-garden/capsule/capsulemodule => ../../../../capsulemodule +replace github.com/bots-garden/capsule/commons => ../../../../commons + require ( github.com/bots-garden/capsule/capsulemodule v0.0.0-20220821063800-09667c0e1624 github.com/tidwall/gjson v1.14.3 @@ -11,7 +13,7 @@ require ( ) require ( - github.com/bots-garden/capsule/commons v0.0.0-20220821063800-09667c0e1624 // indirect + github.com/bots-garden/capsule/commons v0.0.0-20220903105536-e833f3d14593 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect ) diff --git a/vm-capsule/src/functions/hey/go.sum b/vm-capsule/src/functions/hey/go.sum index ce5169d..4b4fa42 100644 --- a/vm-capsule/src/functions/hey/go.sum +++ b/vm-capsule/src/functions/hey/go.sum @@ -1,5 +1,3 @@ -github.com/bots-garden/capsule/commons v0.0.0-20220821063800-09667c0e1624 h1:8F1EV4zfsI2XYdABB1rGyiCJUoWfAIeWjF5b3vWnoKA= -github.com/bots-garden/capsule/commons v0.0.0-20220821063800-09667c0e1624/go.mod h1:5ctHSZAwy3GEi4tR9YKFTfWtBUXDcOMFHNiJYXbV61c= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw= github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= diff --git a/vm-capsule/src/functions/hey/hey.go b/vm-capsule/src/functions/hey/hey.go index 976a43e..4b4aa9d 100644 --- a/vm-capsule/src/functions/hey/hey.go +++ b/vm-capsule/src/functions/hey/hey.go @@ -14,29 +14,29 @@ func main() { hf.SetHandleHttp(Handle) } -func Handle(bodyReq string, headersReq map[string]string) (bodyResp string, headersResp map[string]string, errResp error) { +func Handle(req hf.Request) (rest hf.Response, errResp error) { - hf.Log("πŸ“ body: " + bodyReq) + hf.Log("πŸ“ body: " + req.Body) - author := gjson.Get(bodyReq, "author") - message := gjson.Get(bodyReq, "message") + author := gjson.Get(req.Body, "author") + message := gjson.Get(req.Body, "message") hf.Log("πŸ‘‹ " + message.String() + " by " + author.String() + " πŸ˜„") // πŸ‘€ https://github.com/bots-garden/capsule/issues/91 - hf.Log("🟒 Content-Type: " + headersReq["Content-Type"]) - hf.Log("πŸ”΅ Content-Length: " + headersReq["Content-Length"]) - hf.Log("🟠 User-Agent: " + headersReq["User-Agent"]) - hf.Log("πŸ”΄ My-Token: " + headersReq["My-Token"]) + hf.Log("🟒 Content-Type: " + req.Headers["Content-Type"]) + hf.Log("πŸ”΅ Content-Length: " + req.Headers["Content-Length"]) + hf.Log("🟠 User-Agent: " + req.Headers["User-Agent"]) + hf.Log("πŸ”΄ My-Token: " + req.Headers["My-Token"]) - headersResp = map[string]string{ + headers := map[string]string{ "Content-Type": "application/json; charset=utf-8", "Message": "πŸ‘‹ hello world 🌍", - "MyToken": headersReq["My-Token"], + "MyToken": req.Headers["My-Token"], } jsondoc := `{"message": "", "author": ""}` jsondoc, _ = sjson.Set(jsondoc, "message", "πŸ‘‹ hey! What's up?") jsondoc, _ = sjson.Set(jsondoc, "author", "Bob") - return jsondoc, headersResp, nil + return hf.Response{Body: jsondoc, Headers: headers}, nil } diff --git a/vm-capsule/src/functions/yo/build.sh b/vm-capsule/src/functions/yo/build.sh index 6d99f89..4800888 100755 --- a/vm-capsule/src/functions/yo/build.sh +++ b/vm-capsule/src/functions/yo/build.sh @@ -1,4 +1,5 @@ #!/bin/bash +go mod tidy tinygo build -o yo.wasm -scheduler=none -target wasi ./yo.go ls -lh *.wasm diff --git a/vm-capsule/src/functions/yo/go.mod b/vm-capsule/src/functions/yo/go.mod index 5cc39f5..83c2dd6 100644 --- a/vm-capsule/src/functions/yo/go.mod +++ b/vm-capsule/src/functions/yo/go.mod @@ -4,6 +4,8 @@ go 1.18 replace github.com/bots-garden/capsule/capsulemodule => ../../../../capsulemodule +replace github.com/bots-garden/capsule/commons => ../../../../commons + require github.com/bots-garden/capsule/capsulemodule v0.0.0-20220811130424-72fd5964059b -require github.com/bots-garden/capsule/commons v0.0.0-20220821060842-d1dc9f030021 // indirect +require github.com/bots-garden/capsule/commons v0.0.0-20220903105536-e833f3d14593 // indirect diff --git a/vm-capsule/src/functions/yo/go.sum b/vm-capsule/src/functions/yo/go.sum index e9694fc..e69de29 100644 --- a/vm-capsule/src/functions/yo/go.sum +++ b/vm-capsule/src/functions/yo/go.sum @@ -1,2 +0,0 @@ -github.com/bots-garden/capsule/commons v0.0.0-20220821060842-d1dc9f030021 h1:cBeILASaSUdrsImLP6wR6a747SHYBJqIwuADm2BMDO4= -github.com/bots-garden/capsule/commons v0.0.0-20220821060842-d1dc9f030021/go.mod h1:5ctHSZAwy3GEi4tR9YKFTfWtBUXDcOMFHNiJYXbV61c= diff --git a/vm-capsule/src/functions/yo/yo.go b/vm-capsule/src/functions/yo/yo.go index 1956c05..4e80d21 100644 --- a/vm-capsule/src/functions/yo/yo.go +++ b/vm-capsule/src/functions/yo/yo.go @@ -2,16 +2,16 @@ package main // TinyGo wasm module import ( - hf "github.com/bots-garden/capsule/capsulemodule/hostfunctions" + hf "github.com/bots-garden/capsule/capsulemodule/hostfunctions" ) func main() { - hf.SetHandleHttp(Handle) + hf.SetHandleHttp(Handle) } -func Handle(bodyReq string, headersReq map[string]string) (bodyResp string, headersResp map[string]string, errResp error) { - message, _ := hf.GetEnv("MESSAGE") - html := ` +func Handle(req hf.Request) (resp hf.Response, errResp error) { + message, _ := hf.GetEnv("MESSAGE") + html := ` @@ -41,9 +41,9 @@ func Handle(bodyReq string, headersReq map[string]string) (bodyResp string, head ` - headersResp = map[string]string{ - "Content-Type": "text/html; charset=utf-8", - } + headers := map[string]string{ + "Content-Type": "text/html; charset=utf-8", + } - return html, headersResp, nil + return hf.Response{Body: html, Headers: headers}, nil } diff --git a/wasm_faas/hello/build.sh b/wasm_faas/hello/build.sh index 67129bb..e4f26de 100755 --- a/wasm_faas/hello/build.sh +++ b/wasm_faas/hello/build.sh @@ -1,4 +1,5 @@ #!/bin/bash +go mod tidy tinygo build -o hello.wasm -scheduler=none -target wasi ./hello.go ls -lh *.wasm diff --git a/wasm_faas/hello/go.mod b/wasm_faas/hello/go.mod index 31ff518..fc513ca 100644 --- a/wasm_faas/hello/go.mod +++ b/wasm_faas/hello/go.mod @@ -4,6 +4,8 @@ go 1.18 replace github.com/bots-garden/capsule/capsulemodule => ../../capsulemodule +replace github.com/bots-garden/capsule/commons => ../../commons + require github.com/bots-garden/capsule/capsulemodule v0.0.0-20220815065503-73f5c5e0cecb -require github.com/bots-garden/capsule/commons v0.0.0-20220821060842-d1dc9f030021 // indirect +require github.com/bots-garden/capsule/commons v0.0.0-20220903105536-e833f3d14593 // indirect diff --git a/wasm_faas/hello/go.sum b/wasm_faas/hello/go.sum index e9694fc..e69de29 100644 --- a/wasm_faas/hello/go.sum +++ b/wasm_faas/hello/go.sum @@ -1,2 +0,0 @@ -github.com/bots-garden/capsule/commons v0.0.0-20220821060842-d1dc9f030021 h1:cBeILASaSUdrsImLP6wR6a747SHYBJqIwuADm2BMDO4= -github.com/bots-garden/capsule/commons v0.0.0-20220821060842-d1dc9f030021/go.mod h1:5ctHSZAwy3GEi4tR9YKFTfWtBUXDcOMFHNiJYXbV61c= diff --git a/wasm_faas/hello/hello.go b/wasm_faas/hello/hello.go index f00a37d..4ec4362 100644 --- a/wasm_faas/hello/hello.go +++ b/wasm_faas/hello/hello.go @@ -9,7 +9,7 @@ func main() { hf.SetHandleHttp(Handle) } -func Handle(bodyReq string, headersReq map[string]string) (bodyResp string, headersResp map[string]string, errResp error) { +func Handle(req hf.Request) (resp hf.Response, errResp error) { message, _ := hf.GetEnv("MESSAGE") token, _ := hf.GetEnv("TOKEN") html := ` @@ -19,7 +19,7 @@ func Handle(bodyReq string, headersReq map[string]string) (bodyResp string, head Wasm is fantastic 😍 - +