I use gin@v1.9.0
Trying to get cookie from request
Cookie example:
key={"ckey": "cvalue"}
code:
token, err := c.Request.Cookie("key")
Returns error
http: named cookie not present
But without curly braces, works fine
Cookie example:
key=cvalue
receive
token = "key=cvalue"
The issue is happening because of the cookie value format.
Let's look at these codes from net/http
// Strip the quotes, if present.
if allowDoubleQuote && len(raw) > 1 && raw[0] == '"' && raw[len(raw)-1] == '"' {
raw = raw[1 : len(raw)-1]
}
this statement is used to strip the "
from the beginning and the end of the string.
{"ckey": "cvalue"}
the quotes from this string cannot be removed.
And then it call another function which is a loop that iterates through each characters and checks the character is a valid byte.
for i := 0; i < len(raw); i++ {
if !validCookieValueByte(raw[i]) {
return "", false
}
}
validCookieValueByte implementation
func validCookieValueByte(b byte) bool {
return 0x20 <= b && b < 0x7f && b != '"' && b != ';' && b != '\\'
}
and the check is failing at here. Because we have a "
in {"ckey": "cvalue"}
Let's check with a sample code
func main() {
router := gin.Default()
router.GET("/get-cookie", func(c *gin.Context) {
cookie, err := c.Request.Cookie("key")
if err != nil {
c.String(http.StatusBadRequest, err.Error())
return
}
c.String(http.StatusOK, fmt.Sprintf("token = key=%v", cookie.Value))
})
router.Run(":8080")
}
This will fail
curl --request GET \
--url http://localhost:8080/get-cookie \
--cookie key='{"ckey": "cvalue"}'
but this will succeed
curl --request GET \
--url http://localhost:8080/get-cookie \
--cookie key='{ckey: cvalue}'
We can use http.Cookie to set the cookie as json
val := `{"ckey": "cvalue"}`
cookie := &http.Cookie{
Name: "key",
Value: val,
}
http.SetCookie(c.Writer, cookie)
SetCookie will remove the "
before saving the value.