Начальный импорт

main v0.0.1
commit c7e7709165
  1. 21
      LICENSE
  2. 14
      go.mod
  3. 21
      go.sum
  4. 120
      ottomain.go

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Valery Stadchenko
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,14 @@
module github.com/PCManiac/ottoman
go 1.17
require (
github.com/caarlos0/env v3.5.0+incompatible
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
gopkg.in/sourcemap.v1 v1.0.5 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)

@ -0,0 +1,21 @@
github.com/caarlos0/env v3.5.0+incompatible h1:Yy0UN8o9Wtr/jGHZDpCBLpNrzcFLLM2yixi/rBrKyJs=
github.com/caarlos0/env v3.5.0+incompatible/go.mod h1:tdCsowwCzMLdkqRYDlHpZCp2UooDD3MspDBjZ2AD02Y=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f h1:a7clxaGmmqtdNTXyvrp/lVO/Gnkzlhc/+dLs5v965GM=
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f/go.mod h1:/mK7FZ3mFYEn9zvNPhpngTyatyehSwte5bJZ4ehL5Xw=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/readline.v1 v1.0.0-20160726135117-62c6fe619375/go.mod h1:lNEQeAhU009zbRxng+XOj5ITVgY24WcbNnQopyfKoYQ=
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

@ -0,0 +1,120 @@
package ottoman
import (
"encoding/base64"
"errors"
"fmt"
"reflect"
"time"
"github.com/caarlos0/env"
"github.com/robertkrimen/otto"
)
type otto_config struct {
Timeout int `env:"JS_TIMEOUT" envDefault:"2"`
}
func jsBtoa(b string) string {
return base64.StdEncoding.EncodeToString([]byte(b))
}
func jsAtob(str string) string {
b, err := base64.StdEncoding.DecodeString(str)
if err != nil {
v, _ := otto.ToValue("Failed to execute 'jsAtob': The string to be decoded is not correctly encoded.")
panic(v)
}
return string(b)
}
func jsRegisterFunctions(vm *otto.Otto) (err error) {
err = vm.Set("btoa", jsBtoa)
if err != nil {
return err
}
err = vm.Set("atob", jsAtob)
if err != nil {
return err
}
return
}
func ProcessRequest(script string, params map[string]interface{}) (response map[string]interface{}, err error) {
var cfg otto_config
if err := env.Parse(&cfg); err != nil {
return nil, fmt.Errorf("env vars parse error: %w", err)
}
vm := otto.New()
err = jsRegisterFunctions(vm)
if err != nil {
return nil, fmt.Errorf("otto registreing standart functions error: %w", err)
}
for key, uf := range params {
err = vm.Set(key, uf)
if err != nil {
return nil, fmt.Errorf("otto setting variables error: %w", err)
}
}
vm.Interrupt = make(chan func(), 1)
go func() {
time.Sleep(time.Duration(cfg.Timeout) * time.Second)
vm.Interrupt <- func() {
panic(errors.New("some code took to long! Stopping after timeout"))
}
}()
_, err = vm.Run(script)
if err != nil {
return nil, fmt.Errorf("otto run error: %w", err)
}
getOttoValue := func(variable string, err error) (interface{}, error) {
if err != nil {
return nil, err
}
value, err := vm.Get(variable)
if err != nil {
return nil, err
}
exported, err := value.Export()
if err != nil {
return nil, err
}
return exported, nil
}
response = make(map[string]interface{})
for v := range params {
message, err := getOttoValue(v, err)
if err != nil {
return nil, fmt.Errorf("otto get value error: %w", err)
}
switch message := message.(type) {
case string,
int, int8, int16, int32, int64,
float32, float64,
bool:
response[v] = message
default:
rt := reflect.TypeOf(message)
switch rt.Kind() {
case reflect.Slice, reflect.Array:
response[v] = []byte(message.([]byte))
default:
response[v] = nil
}
}
}
return
}
Loading…
Cancel
Save