Skip to content

Commit

Permalink
Merge pull request #55 from krakend/lua-helpers
Browse files Browse the repository at this point in the history
Rearrange decorators
  • Loading branch information
kpacha authored Dec 3, 2024
2 parents d1fac4a + b3332aa commit 42aa840
Show file tree
Hide file tree
Showing 17 changed files with 527 additions and 515 deletions.
4 changes: 4 additions & 0 deletions binder.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import (
"github.com/krakendio/binder"
)

type Binder = binder.Binder
type Context = binder.Context
type Handler = binder.Handler

type BinderWrapper struct {
binder *binder.Binder
sourceMap *SourceMap
Expand Down
24 changes: 24 additions & 0 deletions decorator/custom_error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package decorator

import (
"fmt"

"github.com/krakendio/binder"
)

const separator = " || "

func RegisterErrors(b *binder.Binder) {
b.Func("custom_error", func(c *binder.Context) error {
switch c.Top() {
case 0:
return ErrNeedsArguments
case 1:
return fmt.Errorf("%s%s%d", c.Arg(1).String(), separator, -1)
case 2:
return fmt.Errorf("%s%s%d", c.Arg(1).String(), separator, int(c.Arg(2).Number()))
default:
return fmt.Errorf("%s%s%d%s%s", c.Arg(1).String(), separator, int(c.Arg(2).Number()), separator, c.Arg(3).String())
}
})
}
14 changes: 14 additions & 0 deletions decorator/decorator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package decorator

import (
"errors"

"github.com/krakendio/binder"
)

type Decorator func(*binder.Binder)

var (
ErrNeedsArguments = errors.New("need arguments")
ErrResponseExpected = errors.New("response expected")
)
22 changes: 11 additions & 11 deletions proxy/http.go → decorator/http.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package proxy
package decorator

import (
"bytes"
Expand All @@ -9,12 +9,12 @@ import (
"sync"

"github.com/krakendio/binder"
lua "github.com/yuin/gopher-lua"
lua "github.com/krakendio/krakend-lua/v2"

"github.com/luraproject/lura/v2/transport/http/server"
)

func registerHTTPRequest(ctx context.Context, b *binder.Binder) {
func RegisterHTTPRequest(ctx context.Context, b *binder.Binder) {
t := b.Table("http_response")

t.Static("new", newHttpResponse(ctx))
Expand Down Expand Up @@ -50,10 +50,10 @@ func newHttpResponse(ctx context.Context) func(*binder.Context) error {
}

if c.Top() == 4 {
headers, ok := c.Arg(4).Any().(*lua.LTable)
headers, ok := c.Arg(4).Any().(*lua.NativeTable)

if ok {
headers.ForEach(func(key, value lua.LValue) {
headers.ForEach(func(key, value lua.NativeValue) {
req.Header.Add(key.String(), value.String())
})
}
Expand All @@ -65,7 +65,7 @@ func newHttpResponse(ctx context.Context) func(*binder.Context) error {
return err
}
if resp == nil {
return errResponseExpected
return ErrResponseExpected
}
pushHTTPResponse(c, resp)
return nil
Expand Down Expand Up @@ -118,7 +118,7 @@ func pushHTTPResponse(c *binder.Context, r *http.Response) {
func httpStatus(c *binder.Context) error {
resp, ok := c.Arg(1).Data().(*httpResponse)
if !ok {
return errResponseExpected
return ErrResponseExpected
}
c.Push().Number(float64(resp.r.StatusCode))

Expand All @@ -128,10 +128,10 @@ func httpStatus(c *binder.Context) error {
func httpHeaders(c *binder.Context) error {
resp, ok := c.Arg(1).Data().(*httpResponse)
if !ok {
return errResponseExpected
return ErrResponseExpected
}
if c.Top() != 2 {
return errNeedsArguments
return ErrNeedsArguments
}
c.Push().String(resp.Header(c.Arg(2).String()))

Expand All @@ -141,7 +141,7 @@ func httpHeaders(c *binder.Context) error {
func httpBody(c *binder.Context) error {
resp, ok := c.Arg(1).Data().(*httpResponse)
if !ok {
return errResponseExpected
return ErrResponseExpected
}
c.Push().String(resp.Body())

Expand All @@ -151,7 +151,7 @@ func httpBody(c *binder.Context) error {
func httpClose(c *binder.Context) error {
resp, ok := c.Arg(1).Data().(*httpResponse)
if !ok {
return errResponseExpected
return ErrResponseExpected
}
if resp == nil {
return nil
Expand Down
11 changes: 5 additions & 6 deletions proxy/http_test.go → decorator/http_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package proxy
package decorator

import (
"context"
Expand All @@ -9,10 +9,9 @@ import (
"net/http/httptest"

"github.com/krakendio/binder"
lua "github.com/krakendio/krakend-lua/v2"
)

func Example_RegisterBackendModule() {
func ExampleRegisterHTTPRequest() {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
headers, _ := json.Marshal(r.Header)
fmt.Println(string(headers))
Expand All @@ -27,16 +26,16 @@ func Example_RegisterBackendModule() {
}))
defer ts.Close()

bindr := lua.NewBinderWrapper(binder.Options{
bindr := binder.New(binder.Options{
SkipOpenLibs: true,
IncludeGoStackTrace: true,
})

registerHTTPRequest(context.Background(), bindr.GetBinder())
RegisterHTTPRequest(context.Background(), bindr)

code := fmt.Sprintf("local url = '%s'\n%s", ts.URL, sampleLuaCode)

if err := bindr.WithCode("test-code", code); err != nil {
if err := bindr.DoString(code); err != nil {
fmt.Println(err.Error())
}

Expand Down
141 changes: 141 additions & 0 deletions decorator/lualist.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package decorator

import (
"encoding/json"

"github.com/krakendio/binder"
lua "github.com/krakendio/krakend-lua/v2"
)

func RegisterLuaList(b *binder.Binder) {
list := b.Table("luaList")
list.Static("new", func(c *binder.Context) error {
c.Push().Data(&lua.List{Data: []interface{}{}}, "luaList")
return nil
})
list.Dynamic("get", listGet)
list.Dynamic("set", listSet)
list.Dynamic("len", listLen)
list.Dynamic("del", listDel)
}

func listLen(c *binder.Context) error {
list, ok := c.Arg(1).Data().(*lua.List)
if !ok {
return ErrResponseExpected
}
c.Push().Number(float64(len(list.Data)))
return nil
}

func listGet(c *binder.Context) error {
if c.Top() != 2 {
return ErrNeedsArguments
}
tab, ok := c.Arg(1).Data().(*lua.List)
if !ok {
return ErrResponseExpected
}
index := int(c.Arg(2).Number())
if index < 0 || index >= len(tab.Data) {
return nil
}
if tab.Data[index] == nil {
c.Push().Data(nil, "luaNil")
return nil
}

switch t := tab.Data[index].(type) {
case string:
c.Push().String(t)
case json.Number:
n, _ := t.Float64()
c.Push().Number(n)
case int:
c.Push().Number(float64(t))
case float64:
c.Push().Number(t)
case bool:
c.Push().Bool(t)
case []interface{}:
c.Push().Data(&lua.List{Data: t}, "luaList")
case map[string]interface{}:
c.Push().Data(&lua.Table{Data: t}, "luaTable")
}

return nil
}

func listSet(c *binder.Context) error {
if c.Top() != 3 {
return ErrNeedsArguments
}
tab, ok := c.Arg(1).Data().(*lua.List)
if !ok {
return ErrResponseExpected
}
key := int(c.Arg(2).Number())
if key < 0 {
return nil
}
if key >= len(tab.Data) {
if cap(tab.Data) > key {
for i := len(tab.Data); i < key; i++ {
tab.Data = append(tab.Data, nil)
}
} else {
newData := make([]interface{}, key+1)
copy(newData, tab.Data)
tab.Data = newData
}
}
switch t := c.Arg(3).Any().(type) {
case lua.NativeString:
tab.Data[key] = c.Arg(3).String()
case lua.NativeNumber:
tab.Data[key] = c.Arg(3).Number()
case lua.NativeBool:
tab.Data[key] = c.Arg(3).Bool()
case *lua.NativeTable:
res := map[string]interface{}{}
t.ForEach(func(k, v lua.NativeValue) {
lua.ParseToTable(k, v, res)
})
tab.Data[key] = res
case *lua.NativeUserData:
if t.Value == nil {
tab.Data[key] = nil
} else {
switch v := t.Value.(type) {
case *lua.Table:
tab.Data[key] = v.Data
case *lua.List:
tab.Data[key] = v.Data
}
}
}

return nil
}

func listDel(c *binder.Context) error {
if c.Top() != 2 {
return ErrNeedsArguments
}
tab, ok := c.Arg(1).Data().(*lua.List)
if !ok {
return ErrResponseExpected
}
key := int(c.Arg(2).Number())
if key < 0 || key >= len(tab.Data) {
return nil
}

last := len(tab.Data) - 1
if key < last {
copy(tab.Data[key:], tab.Data[key+1:])
}
tab.Data[last] = nil
tab.Data = tab.Data[:last]
return nil
}
11 changes: 11 additions & 0 deletions decorator/luanil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package decorator

import "github.com/krakendio/binder"

func RegisterNil(b *binder.Binder) {
tab := b.Table("luaNil")
tab.Static("new", func(c *binder.Context) error {
c.Push().Data(nil, "luaNil")
return nil
})
}
Loading

0 comments on commit 42aa840

Please sign in to comment.