🐛 bug: Case sensitivity for parameters in GetRouteURL (#2010)

* 🐛 bug: Case sensitivity for parameters in GetRouteURL

* ✏️ perf: error spell
pull/2042/head
Jinquan Wang 2022-08-24 15:16:19 +08:00 committed by GitHub
parent 8540d0afdc
commit 9c98a1fb37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 18 deletions

22
ctx.go
View File

@ -922,7 +922,7 @@ func (c *Ctx) Params(key string, defaultValue ...string) string {
if len(key) != len(c.route.Params[i]) {
continue
}
if c.route.Params[i] == key {
if c.route.Params[i] == key || (!c.app.config.CaseSensitive && utils.EqualFold(c.route.Params[i], key)) {
// in case values are not here
if len(c.values) <= i || len(c.values[i]) == 0 {
break
@ -1243,19 +1243,23 @@ func (c *Ctx) Bind(vars Map) error {
func (c *Ctx) getLocationFromRoute(route Route, params Map) (string, error) {
buf := bytebufferpool.Get()
for _, segment := range route.routeParser.segs {
for key, val := range params {
if segment.IsParam && (key == segment.ParamName || (segment.IsGreedy && len(key) == 1 && isInCharset(key[0], greedyParameters))) {
_, err := buf.WriteString(utils.ToString(val))
if err != nil {
return "", err
}
}
}
if !segment.IsParam {
_, err := buf.WriteString(segment.Const)
if err != nil {
return "", err
}
continue
}
for key, val := range params {
isSame := key == segment.ParamName || (!c.app.config.CaseSensitive && utils.EqualFold(key, segment.ParamName))
isGreedy := (segment.IsGreedy && len(key) == 1 && isInCharset(key[0], greedyParameters))
if isSame || isGreedy {
_, err := buf.WriteString(utils.ToString(val))
if err != nil {
return "", err
}
}
}
}
location := buf.String()

View File

@ -1587,6 +1587,11 @@ func Test_Ctx_Params(t *testing.T) {
utils.AssertEqual(t, "", c.Params("optional"))
return nil
})
app.Get("/test5/:id/:Id", func(c *Ctx) error {
utils.AssertEqual(t, "first", c.Params("id"))
utils.AssertEqual(t, "first", c.Params("Id"))
return nil
})
resp, err := app.Test(httptest.NewRequest(MethodGet, "/test/john", nil))
utils.AssertEqual(t, nil, err, "app.Test(req)")
utils.AssertEqual(t, StatusOK, resp.StatusCode, "Status code")
@ -1602,6 +1607,32 @@ func Test_Ctx_Params(t *testing.T) {
resp, err = app.Test(httptest.NewRequest(MethodGet, "/test4", nil))
utils.AssertEqual(t, nil, err, "app.Test(req)")
utils.AssertEqual(t, StatusOK, resp.StatusCode, "Status code")
resp, err = app.Test(httptest.NewRequest(MethodGet, "/test5/first/second", nil))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, StatusOK, resp.StatusCode, "Status code")
}
func Test_Ctx_Params_Case_Sensitive(t *testing.T) {
t.Parallel()
app := New(Config{CaseSensitive: true})
app.Get("/test/:User", func(c *Ctx) error {
utils.AssertEqual(t, "john", c.Params("User"))
utils.AssertEqual(t, "", c.Params("user"))
return nil
})
app.Get("/test2/:id/:Id", func(c *Ctx) error {
utils.AssertEqual(t, "first", c.Params("id"))
utils.AssertEqual(t, "second", c.Params("Id"))
return nil
})
resp, err := app.Test(httptest.NewRequest(MethodGet, "/test/john", nil))
utils.AssertEqual(t, nil, err, "app.Test(req)")
utils.AssertEqual(t, StatusOK, resp.StatusCode, "Status code")
resp, err = app.Test(httptest.NewRequest(MethodGet, "/test2/first/second", nil))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, StatusOK, resp.StatusCode, "Status code")
}
// go test -race -run Test_Ctx_AllParams
@ -3090,16 +3121,39 @@ func Benchmark_Ctx_Get_Location_From_Route(b *testing.B) {
// go test -run Test_Ctx_Get_Location_From_Route_name
func Test_Ctx_Get_Location_From_Route_name(t *testing.T) {
app := New()
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
app.Get("/user/:name", func(c *Ctx) error {
return c.SendString(c.Params("name"))
}).Name("User")
t.Run("case insensitive", func(t *testing.T) {
app := New()
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
app.Get("/user/:name", func(c *Ctx) error {
return c.SendString(c.Params("name"))
}).Name("User")
location, err := c.GetRouteURL("User", Map{"name": "fiber"})
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, "/user/fiber", location)
location, err := c.GetRouteURL("User", Map{"name": "fiber"})
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, "/user/fiber", location)
location, err = c.GetRouteURL("User", Map{"Name": "fiber"})
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, "/user/fiber", location)
})
t.Run("case sensitive",func(t *testing.T) {
app := New(Config{CaseSensitive: true})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
app.Get("/user/:name", func(c *Ctx) error {
return c.SendString(c.Params("name"))
}).Name("User")
location, err := c.GetRouteURL("User", Map{"name": "fiber"})
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, "/user/fiber", location)
location, err = c.GetRouteURL("User", Map{"Name": "fiber"})
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, "/user/", location)
})
}
// go test -run Test_Ctx_Get_Location_From_Route_name_Optional_greedy