2

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"

Alan Millirud
  • 1,049
  • 7
  • 14

1 Answers1

1

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.

PRATHEESH PC
  • 1,461
  • 1
  • 3
  • 15
  • Good job! But please know that if `"` is removed, the content is not a valid json any more. Maybe a feasible solution is to encode the json content (`[]byte`) as a base64 string. Can you update your answer to mention that? – Zeke Lu May 19 '23 at 09:19