Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃 Case sensitivity for parameters in GetRouteURL #1907

Closed
martinwang2002 opened this issue May 12, 2022 · 7 comments 路 Fixed by #2010
Closed

馃 Case sensitivity for parameters in GetRouteURL #1907

martinwang2002 opened this issue May 12, 2022 · 7 comments 路 Fixed by #2010

Comments

@martinwang2002
Copy link

Question description

When using capitalized letters in fiber.Map{} with GetRouteURL, the case sensitivity of the keys is ignored.

Code snippet

package main

import "github.com/gofiber/fiber/v2"

func main() {
        app := fiber.New()

	// app := fiber.New(fiber.Config{
	// 	CaseSensitive: true,
	// })

	app.Get("/", func(c *fiber.Ctx) error {

		idUrl, err := c.GetRouteURL("id", fiber.Map{
			"testid": "ABC",
			"testId": "DEF",
		})

		if err != nil {
			panic(err)
		}

		return c.SendString(idUrl)
	})

	app.Get("/:testid/:testId/other_paths", func(c *fiber.Ctx) error {
		return c.SendString("Hello, World!\ntestid: " + c.Params("testid") + "\ntestId: " + c.Params("testId"))
	}).Name("id")

	app.Listen(":3001")
}

For example, GET /, you will receive /ABC/ABC/other_paths. The case sensitivity for GetRouteURL is ignored

On the other hand, c.Params can tell the difference between testid and testId.

I think that Params and GetRouteURL should behave the same behavior on case sensitivity.


Meanwhile, enabling CaseSensitive in the config will receive /ABC/DEF/other_paths

@welcome
Copy link

welcome bot commented May 12, 2022

Thanks for opening your first issue here! 馃帀 Be sure to follow the issue template! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

@ReneWerner87
Copy link
Member

code is developed by sujit-baniya -> #1831
@sujit-baniya can you check this

@sujit-baniya
Copy link
Contributor

@martinwang2002 Thank you for raising the issue. I checked with CaseSensitive enabled and disabled.

Case 1: CaseSensitive = false by default it's false
In this scenario the case is ignored. so testid and testId are same in this case

Case 2: CaseSensitive = true
In this scenario the case is checked. so testid and testId are different.

I was not able to replicate the issue as mentioned.

the fiber version used: 2.33.0

Here's the video of testing.
https://storyxpress.co/video/l332lwf6vd11rxxhl

Please let me know if I missed anything in the test

@martinwang2002
Copy link
Author

I agree with you.

Could you also please check this part?

app.Get("/:testid/:testId/other_paths", func(c *fiber.Ctx) error {
		return c.SendString("Hello, World!\ntestid: " + c.Params("testid") + "\ntestId: " + c.Params("testId"))
}).Name("id")

with url: http://127.0.0.1:3001/first/second/other_paths

In this part of code, you will find that testid and testId are different.


That's why I have this confustion. We can get parameters with case sensitivity, but we cannot set proper keys via GetRouteURL with CaseSensitive = false. Is this expected?

@sujit-baniya
Copy link
Contributor

@martinwang2002 I got it now. The issue seems to be coming from route parser.

@ReneWerner87 Can we do anything for it?

&{/ false   0 false false false false 1}
&{ true testid / 2 false false false false 0}
&{/ false   0 false false false false 1}
&{ true testid /other_paths 1 false false false false 0}
&{/other_paths false   0 false false true false 12}

@ReneWerner87
Copy link
Member

if CaseSensitive is set to false, the route is reduced to lower case and the parameters are also attached to the segments of the route in lowercase(in the registration process), since this does not matter according to the setting.

fiber/router.go

Lines 236 to 251 in aa22928

if !app.config.CaseSensitive {
pathPretty = utils.ToLower(pathPretty)
}
// Strict routing, remove trailing slashes
if !app.config.StrictRouting && len(pathPretty) > 1 {
pathPretty = utils.TrimRight(pathPretty, '/')
}
// Is layer a middleware?
isUse := method == methodUse
// Is path a direct wildcard?
isStar := pathPretty == "/*"
// Is path a root slash?
isRoot := pathPretty == "/"
// Parse path parameters
parsedRaw := parseRoute(pathRaw)
parsedPretty := parseRoute(pathPretty)

fiber/router.go

Lines 178 to 188 in aa22928

if !app.config.CaseSensitive {
prettyPath = utils.ToLower(prettyPath)
}
// Strict routing, remove trailing slashes
if !app.config.StrictRouting && len(prettyPath) > 1 {
prettyPath = utils.TrimRight(prettyPath, '/')
}
route.Path = prefixedPath
route.path = RemoveEscapeChar(prettyPath)
route.routeParser = parseRoute(prettyPath)

the request url is also reduced to lowercase for recognition when the setting is enabled

fiber/ctx.go

Lines 1548 to 1555 in aa22928

if !c.app.config.CaseSensitive {
c.detectionPathBuffer = utils.ToLowerBytes(c.detectionPathBuffer)
}
// If StrictRouting is disabled, we strip all trailing slashes
if !c.app.config.StrictRouting && len(c.detectionPathBuffer) > 1 && c.detectionPathBuffer[len(c.detectionPathBuffer)-1] == '/' {
c.detectionPathBuffer = utils.TrimRightBytes(c.detectionPathBuffer, '/')
}
c.detectionPath = c.app.getString(c.detectionPathBuffer)

possible solution:
is in the case that caseSensitive is set to false(default) we should everywhere where access to the key is tried to get the value, compare it additionally with the lower case variant, so that the upper and lower case really doesn't matter
util:

func ToLower(b string) string {

places:

fiber/ctx.go

Line 835 in aa22928

if c.route.Params[i] == key {

fiber/ctx.go

Line 1149 in aa22928

if key == segment.ParamName || segment.IsGreedy {

@ReneWerner87
Copy link
Member

But please still take a look at the performance after these changes

i expect only a slight increase if the value could not be found by the first check

func EqualFold(b, s string) bool {

or maybe a check with equalFolds, as this is even faster than converting to lowercase

ToLower -> 50ns
EqualFold -> 32ns

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants