Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,10 @@ Following builtin functions are addionally available within JS scripts:
* `print(val)` - print arbitrary values *val* into dumbproxy log for debugging purposes.
* `readFile(path: string): string` - read file from *path* and return its content as a string.

Following objects are additionally available in global scope of JS scripts:

* `env` - readonly object containing all environment variables.

## Supported upstream proxy schemes

Supported proxy schemes are:
Expand Down
6 changes: 3 additions & 3 deletions access/jsfilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ func NewJSFilter(filename string, instances int, logger *clog.CondLogger, next F
vm := goja.New()
err = jsext.AddPrinter(vm, logger)
if err != nil {
return nil, errors.New("can't add print function to runtime")
return nil, fmt.Errorf("can't add print function to runtime: %w", err)
}
err = jsext.AddFileReader(vm)
err = jsext.ConfigureRuntime(vm)
if err != nil {
return nil, errors.New("can't add file reader function to runtime")
return nil, fmt.Errorf("can't configure runtime: %w", err)
}
vm.SetFieldNameMapper(goja.TagFieldNameMapper("json", true))
_, err = vm.RunString(string(script))
Expand Down
6 changes: 3 additions & 3 deletions dialer/jsrouter.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ func NewJSRouter(filename string, instances int, factory func(string) (Dialer, e
vm := goja.New()
err := jsext.AddPrinter(vm, logger)
if err != nil {
return nil, errors.New("can't add print function to runtime")
return nil, fmt.Errorf("can't add print function to runtime: %w", err)
}
err = jsext.AddFileReader(vm)
err = jsext.ConfigureRuntime(vm)
if err != nil {
return nil, errors.New("can't add file reader function to runtime")
return nil, fmt.Errorf("can't configure runtime runtime: %w", err)
}
vm.SetFieldNameMapper(goja.TagFieldNameMapper("json", true))
_, err = vm.RunString(string(script))
Expand Down
74 changes: 74 additions & 0 deletions jsext/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package jsext

import (
"os"
"slices"
"strings"
"sync"

"github.com/dop251/goja"
)

var (
createEnvObjectOnce sync.Once
envObject *goja.Object
)

type readonlyEnvObject struct {
m map[string]goja.String
k []string
}

func (o *readonlyEnvObject) Get(key string) goja.Value {
v, ok := o.m[key]
if ok {
return v
}
return goja.Undefined()
}

func (o *readonlyEnvObject) Set(_ string, _ goja.Value) bool {
return false
}

func (o *readonlyEnvObject) Has(key string) bool {
_, ok := o.m[key]
return ok
}

func (o *readonlyEnvObject) Delete(key string) bool {
return false
}

func (o *readonlyEnvObject) Keys() []string {
return o.k
}

func createEnvObject() *goja.Object {
env := os.Environ()
m := make(map[string]goja.String, len(env))
k := make([]string, 0, len(env))
for _, pair := range env {
key, value, _ := strings.Cut(pair, "=")
sb := new(goja.StringBuilder)
sb.WriteUTF8String(value)
m[key] = sb.String()
k = append(k, key)
}
slices.Sort(k)
return goja.NewSharedDynamicObject(&readonlyEnvObject{
m: m,
k: k,
})
}

func GetEnvSharedDynamicObject() *goja.Object {
createEnvObjectOnce.Do(func() {
envObject = createEnvObject()
})
return envObject
}

func ExportEnv(vm *goja.Runtime) error {
return vm.Set("env", GetEnvSharedDynamicObject())
}
13 changes: 13 additions & 0 deletions jsext/jsext.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package jsext

import "github.com/dop251/goja"

func ConfigureRuntime(vm *goja.Runtime) error {
if err := AddFileReader(vm); err != nil {
return err
}
if err := ExportEnv(vm); err != nil {
return err
}
return nil
}