Skip to content

Commit

Permalink
the table getter supports client errors from lura
Browse files Browse the repository at this point in the history
  • Loading branch information
kpacha committed Sep 19, 2024
1 parent ee5978e commit 12a002a
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 16 deletions.
123 changes: 123 additions & 0 deletions proxy/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/luraproject/lura/v2/encoding"
"github.com/luraproject/lura/v2/logging"
"github.com/luraproject/lura/v2/proxy"
"github.com/luraproject/lura/v2/transport/http/client"
)

func TestProxyFactory_error(t *testing.T) {
Expand Down Expand Up @@ -713,3 +714,125 @@ responseData:set("grow_list", growingList)
return
}
}

func Test_tableGetSupportsClientErrors(t *testing.T) {
errA := client.HTTPResponseError{
Code: 418,
Msg: "I'm a teapot",
Enc: "text/plain",
}
errB := client.NamedHTTPResponseError{
HTTPResponseError: client.HTTPResponseError{
Code: 481,
Msg: "I'm not a teapot",
Enc: "text/plain",
},
}

dummyProxyFactory := proxy.FactoryFunc(func(_ *config.EndpointConfig) (proxy.Proxy, error) {
return func(ctx context.Context, req *proxy.Request) (*proxy.Response, error) {
return &proxy.Response{
Data: map[string]interface{}{
"error_backend_alias_a": errA,
"error_backend_alias_b": errB,
},
Metadata: proxy.Metadata{
Headers: map[string][]string{},
},
}, nil
}, nil
})

prxy, err := ProxyFactory(logging.NoOp, dummyProxyFactory).New(&config.EndpointConfig{
Endpoint: "/",
ExtraConfig: config.ExtraConfig{
ProxyNamespace: map[string]interface{}{
"post": `
local resp = response.load()
local responseData = resp:data()
local errorA = responseData:get('error_backend_alias_a')
responseData:set("code_a", errorA:get('http_status_code'))
responseData:set("body_a", errorA:get('http_body'))
responseData:set("encoding_a", errorA:get('http_body_encoding'))
local errorB = responseData:get('error_backend_alias_b')
responseData:set("code_b", errorB:get('http_status_code'))
responseData:set("body_b", errorB:get('http_body'))
responseData:set("encoding_b", errorB:get('http_body_encoding'))
responseData:set("name_b", errorB:get('name'))
`,
},
},
})

if err != nil {
t.Error(err)
}

URL, _ := url.Parse("https://some.host.tld/path/to/resource?and=querystring")

resp, err := prxy(context.Background(), &proxy.Request{
Method: "GET",
Path: "/some-path",
Params: map[string]string{"Id": "42"},
Headers: map[string][]string{},
URL: URL,
Body: io.NopCloser(strings.NewReader("initial req content")),
})
if err != nil {
t.Error(err)
}

bodyA, ok := resp.Data["body_a"].(string)
if !ok {
t.Errorf("cannot get 'body_a' %#v", resp.Data)
return
}
if bodyA != errA.Msg {
t.Errorf("unexpected body a. have %s, want %s", bodyA, errA.Msg)
}

bodyB, ok := resp.Data["body_b"].(string)
if !ok {
t.Errorf("cannot get 'body_b' %#v", resp.Data)
return
}
if bodyB != errB.Msg {
t.Errorf("unexpected body b. have %s, want %s", bodyB, errB.Msg)
}

codeA, ok := resp.Data["code_a"].(float64)
if !ok {
t.Errorf("cannot get 'code_a' %#v", resp.Data)
return
}
if int(codeA) != errA.Code {
t.Errorf("unexpected code a. have %d, want %d", int(codeA), errA.Code)
}

codeB, ok := resp.Data["code_b"].(float64)
if !ok {
t.Errorf("cannot get 'code_b' %#v", resp.Data)
return
}
if int(codeB) != errB.Code {
t.Errorf("unexpected code b. have %d, want %d", int(codeB), errB.Code)
}

encA, ok := resp.Data["encoding_a"].(string)
if !ok {
t.Errorf("cannot get 'encoding_a' %#v", resp.Data)
return
}
if encA != errA.Enc {
t.Errorf("unexpected encoding a. have %s, want %s", encA, errA.Enc)
}

encB, ok := resp.Data["encoding_b"].(string)
if !ok {
t.Errorf("cannot get 'encoding_b' %#v", resp.Data)
return
}
if encB != errB.Enc {
t.Errorf("unexpected encoding b. have %s, want %s", encB, errB.Enc)
}
}
31 changes: 15 additions & 16 deletions proxy/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/krakendio/binder"
"github.com/luraproject/lura/v2/proxy"
"github.com/luraproject/lura/v2/transport/http/client"
lua "github.com/yuin/gopher-lua"
)

Expand Down Expand Up @@ -215,6 +216,12 @@ func tableGet(c *binder.Context) error {
c.Push().Data(&luaList{data: t}, "luaList")
case map[string]interface{}:
c.Push().Data(&luaTable{data: t}, "luaTable")
case client.HTTPResponseError:
c.Push().Data(&luaTable{data: clientErrorToMap(t)}, "luaTable")
case client.NamedHTTPResponseError:
d := clientErrorToMap(t.HTTPResponseError)
d["name"] = t.Name()
c.Push().Data(&luaTable{data: d}, "luaTable")
default:
return fmt.Errorf("unknown type (%T) %v", t, t)
}
Expand Down Expand Up @@ -388,26 +395,10 @@ type luaTable struct {
data map[string]interface{}
}

func (l *luaTable) get(k string) interface{} {
return l.data[k]
}

func (l *luaTable) set(k string, v interface{}) {
l.data[k] = v
}

type luaList struct {
data []interface{}
}

func (l *luaList) get(k int) interface{} {
return l.data[k]
}

func (l *luaList) set(k int, v interface{}) {
l.data[k] = v
}

func parseToTable(k, v lua.LValue, acc map[string]interface{}) {

switch v.Type() {
Expand Down Expand Up @@ -442,3 +433,11 @@ func parseToTable(k, v lua.LValue, acc map[string]interface{}) {
acc[k.String()] = res
}
}

func clientErrorToMap(err client.HTTPResponseError) map[string]interface{} {
return map[string]interface{}{
"http_status_code": err.StatusCode(),
"http_body": err.Error(),
"http_body_encoding": err.Encoding(),
}
}

0 comments on commit 12a002a

Please sign in to comment.