I have four URLs: http://127.0.0.1/test?username=aaa http://127.0.0.1/test?Username=aaa http://127.0.0.1/test?UsernNme=aaa http://127.0.0.1/test?usernNme=aaa

Is there a way to get "username" from them in case-insensitive? c.Query("username") has any option about case-sensitive?

Comment From: thinkerou

using c.Params get all query string and loop all key/value like this: c.Query(strings.ToLower(key))

Comment From: skydroplet

According to help documentation c.Params is used to get the parameters in path, not querystring parameters, here is the test, the program only print [{userID 111}] when I send curl http://localhost:8080/test/111?userName=aaa, but I want get the "username", no matter the request is http://localhost:8080/test/111?UserName=aaa or http://localhost:8080/test/111?username=aaa

func main() {
    router := gin.Default()

    router.GET("/test/:userID", func(c *gin.Context) {
        userID := c.Param("userID")
        userName := c.Query("userName")

        fmt.Println(c.Params)

        c.String(http.StatusOK, "Hello %v:%v", userID, userName)
    })

    router.Run(":8080")
    return
}

Comment From: thinkerou

please read the answer: https://stackoverflow.com/questions/24699643/are-query-string-keys-case-sensitive

Comment From: dre2004

The stack overflow post didn't answer the actual question, it just describes what the RFC says what should be the case (query string parameters should be case insensitive). It's also stated at the end though it depends on the implementation.

In the case of Gin it appears that they are case sensitive and so if you're looking for a query string parameter the following two are not the same.

c.DefaultQuery("Username", "*")

c.DefaultQuery("username", "*")

I've tested it and if I send data with the querystring parameter as "..?Username=user1" it only works with the first example above. It will not work with the second one.

Comment From: rdmdb

You can loop over c.Request.URL.Query() as follows

func getQuery(c *gin.Context, key string) string {
  qparams := c.Request.URL.Query()
  for name, val := range qparams {
    if strings.EqualFold(key, name) {
      return val[0]
    }
  }
  return ""
}

Comment From: ryanlogsdon

You can loop over c.Request.URL.Query() as follows

func getQuery(c *gin.Context, key string) string { qparams := c.Request.URL.Query() for name, val := range qparams { if strings.EqualFold(key, name) { return val[0] } } return "" }

this code is very good, but there's still a problem: it may throw away data

it's valid to have a URL like this:

mysite.com/username=123&username=456

...in which case, Gin will build a list of values ["123", "456"] for the key username (note that I didn't change the case of the letters; the entire issue is when a key is reused in a URL)

but the Query() function returns a slice []string and the code above discards all but the first element, val[0].

By changing @rdmdb 's code to this, it'll work in all cases:

func getQuery(c *gin.Context, targetKey string) string {
    queryParams := c.Request.URL.Query()
    for key, values := range queryParams {
        if strings.EqualFold(targetKey, key) {
            return strings.Join(values, ",")  // if there are multiple values keyed to an input parameter, they'll be returned comma-separated
        }
    }
    return ""
}