From 657e0133d0e4edc0c7ac874651faffbcb716c20f Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Thu, 11 Jul 2019 16:33:20 +0300 Subject: [PATCH] add support for b.HandleMany(GET, /custom3/{ps:string}/{pssecond:string} /custom3/{ps:string}, CtrlMethodName) relative to: https://github.com/kataras/iris/issues/1292 Former-commit-id: de08c5eeab7a1c2729fbff7260de00cc2516f78c --- context/request_params.go | 40 +++++++++++++++++++++++++++++++++++ mvc/controller_handle_test.go | 26 +++++++++++++++++++++++ mvc/param.go | 1 + 3 files changed, 67 insertions(+) diff --git a/context/request_params.go b/context/request_params.go index 7757308b..740b2e8f 100644 --- a/context/request_params.go +++ b/context/request_params.go @@ -102,14 +102,24 @@ var ( // } // // Read https://github.com/kataras/iris/tree/master/_examples/routing/macros for more details. + // Checks for total available request parameters length + // and parameter index based on the hero/mvc function added + // in order to support the MVC.HandleMany("GET", "/path/{ps}/{pssecond} /path/{ps}") + // when on the second requested path, the 'pssecond' should be empty. ParamResolvers = map[reflect.Type]func(paramIndex int) interface{}{ reflect.TypeOf(""): func(paramIndex int) interface{} { return func(ctx Context) string { + if ctx.Params().Len() <= paramIndex { + return "" + } return ctx.Params().GetEntryAt(paramIndex).ValueRaw.(string) } }, reflect.TypeOf(int(1)): func(paramIndex int) interface{} { return func(ctx Context) int { + if ctx.Params().Len() <= paramIndex { + return 0 + } // v, _ := ctx.Params().GetEntryAt(paramIndex).IntDefault(0) // return v return ctx.Params().GetEntryAt(paramIndex).ValueRaw.(int) @@ -117,51 +127,81 @@ var ( }, reflect.TypeOf(int8(1)): func(paramIndex int) interface{} { return func(ctx Context) int8 { + if ctx.Params().Len() <= paramIndex { + return 0 + } return ctx.Params().GetEntryAt(paramIndex).ValueRaw.(int8) } }, reflect.TypeOf(int16(1)): func(paramIndex int) interface{} { return func(ctx Context) int16 { + if ctx.Params().Len() <= paramIndex { + return 0 + } return ctx.Params().GetEntryAt(paramIndex).ValueRaw.(int16) } }, reflect.TypeOf(int32(1)): func(paramIndex int) interface{} { return func(ctx Context) int32 { + if ctx.Params().Len() <= paramIndex { + return 0 + } return ctx.Params().GetEntryAt(paramIndex).ValueRaw.(int32) } }, reflect.TypeOf(int64(1)): func(paramIndex int) interface{} { return func(ctx Context) int64 { + if ctx.Params().Len() <= paramIndex { + return 0 + } return ctx.Params().GetEntryAt(paramIndex).ValueRaw.(int64) } }, reflect.TypeOf(uint(1)): func(paramIndex int) interface{} { return func(ctx Context) uint { + if ctx.Params().Len() <= paramIndex { + return 0 + } return ctx.Params().GetEntryAt(paramIndex).ValueRaw.(uint) } }, reflect.TypeOf(uint8(1)): func(paramIndex int) interface{} { return func(ctx Context) uint8 { + if ctx.Params().Len() <= paramIndex { + return 0 + } return ctx.Params().GetEntryAt(paramIndex).ValueRaw.(uint8) } }, reflect.TypeOf(uint16(1)): func(paramIndex int) interface{} { return func(ctx Context) uint16 { + if ctx.Params().Len() <= paramIndex { + return 0 + } return ctx.Params().GetEntryAt(paramIndex).ValueRaw.(uint16) } }, reflect.TypeOf(uint32(1)): func(paramIndex int) interface{} { return func(ctx Context) uint32 { + if ctx.Params().Len() <= paramIndex { + return 0 + } return ctx.Params().GetEntryAt(paramIndex).ValueRaw.(uint32) } }, reflect.TypeOf(uint64(1)): func(paramIndex int) interface{} { return func(ctx Context) uint64 { + if ctx.Params().Len() <= paramIndex { + return 0 + } return ctx.Params().GetEntryAt(paramIndex).ValueRaw.(uint64) } }, reflect.TypeOf(true): func(paramIndex int) interface{} { return func(ctx Context) bool { + if ctx.Params().Len() <= paramIndex { + return false + } return ctx.Params().GetEntryAt(paramIndex).ValueRaw.(bool) } }, diff --git a/mvc/controller_handle_test.go b/mvc/controller_handle_test.go index 0b1a3a6f..6634dedc 100644 --- a/mvc/controller_handle_test.go +++ b/mvc/controller_handle_test.go @@ -40,6 +40,13 @@ func (c *testControllerHandle) BeforeActivation(b BeforeActivation) { b.Handle("GET", "/hiservice/{ps:string}", "HiServiceBy") b.Handle("GET", "/hiparam/{ps:string}", "HiParamBy") b.Handle("GET", "/hiparamempyinput/{ps:string}", "HiParamEmptyInputBy") + b.HandleMany("GET", "/custom/{ps:string} /custom2/{ps:string}", "CustomWithParameter") + // if dynamic path exist + // then longest path should be registered first + // and the controller's method if wants to add path parameters + // dependency injection then they should accept the longest path parameters. + // See `testControllerHandle.CustomWithParameters`. + b.HandleMany("GET", "/custom3/{ps:string}/{pssecond:string} /custom3/{ps:string}", "CustomWithParameters") } // test `GetRoute` for custom routes. @@ -97,6 +104,16 @@ func (c *testControllerHandle) HiParamEmptyInputBy() string { return "empty in but served with ctx.Params.Get('ps')=" + c.Ctx.Params().Get("ps") } +func (c *testControllerHandle) CustomWithParameter(param1 string) string { + return param1 +} + +func (c *testControllerHandle) CustomWithParameters(param1, param2 string) string { + // it returns empty string for requested path: /custom3/value1, + // see BeforeActivation. + return param1 + param2 +} + type testSmallController struct{} // test ctx + id in the same time. @@ -137,6 +154,15 @@ func TestControllerHandle(t *testing.T) { Body().Equal("value") e.GET("/hiparamempyinput/value").Expect().Status(httptest.StatusOK). Body().Equal("empty in but served with ctx.Params.Get('ps')=value") + e.GET("/custom/value1").Expect().Status(httptest.StatusOK). + Body().Equal("value1") + e.GET("/custom2/value2").Expect().Status(httptest.StatusOK). + Body().Equal("value2") + e.GET("/custom3/value1/value2").Expect().Status(httptest.StatusOK). + Body().Equal("value1value2") + e.GET("/custom3/value1").Expect().Status(httptest.StatusOK). + Body().Equal("value1") + e.GET("/hi/param/empty/input/with/ctx/value").Expect().Status(httptest.StatusOK). Body().Equal("empty in but served with ctx.Params.Get('param2')= value == id == value") } diff --git a/mvc/param.go b/mvc/param.go index c7bdae57..180f30da 100644 --- a/mvc/param.go +++ b/mvc/param.go @@ -41,6 +41,7 @@ func getPathParamsForInput(params []macro.TemplateParam, funcIn ...reflect.Type) if _, ok := consumed[j]; ok { continue } + funcDep, ok := context.ParamResolverByTypeAndIndex(in, param.Index) if !ok { continue