pull/3379/merge
c00kie17 2025-04-04 09:39:00 +07:00 committed by GitHub
commit 1a790f15d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 43 additions and 2 deletions

33
ctx.go
View File

@ -450,7 +450,38 @@ func (c *DefaultCtx) Cookie(cookie *Cookie) {
// The returned value is only valid within the handler. Do not store any references.
// Make copies or use the Immutable setting to use the value outside the Handler.
func (c *DefaultCtx) Cookies(key string, defaultValue ...string) string {
return defaultString(c.app.getString(c.fasthttp.Request.Header.Cookie(key)), defaultValue)
cookieValue := c.app.getString(c.fasthttp.Request.Header.Cookie(key))
// Parse the cookie value
value, ok := c.parseCookieValue(cookieValue)
if !ok {
return ""
}
return value
}
// parseCookieValue parses a cookie value according to RFC 6265.
func (c *DefaultCtx) parseCookieValue(raw string) (value string, ok bool) {
// Strip the quotes, if present.
if len(raw) > 1 && raw[0] == '"' && raw[len(raw)-1] == '"' {
raw = raw[1 : len(raw)-1]
}
for i := 0; i < len(raw); i++ {
if !c.validCookieValueByte(raw[i]) {
return "", false
}
}
return raw, true
}
// validCookieValueByte reports whether b is a valid byte in a cookie value.
// Per RFC 6265 section 4.1.1, cookie values must be ASCII
// and may not contain control characters, whitespace, double quotes,
// commas, semicolons, or backslashes.
func (c *DefaultCtx) validCookieValueByte(b byte) bool {
return 0x20 <= b && b < 0x7f && b != '"' && b != ';' && b != '\\'
// Note: commas are deliberately allowed
// See https://golang.org/issue/7243 for the discussion.
}
// Download transfers the file from path as an attachment.

View File

@ -1027,6 +1027,7 @@ func Benchmark_Ctx_Cookie(b *testing.B) {
}
// go test -run Test_Ctx_Cookies
// Semicolons cannot be part of cookie values because they're used as cookie delimiters in HTTP spec
func Test_Ctx_Cookies(t *testing.T) {
t.Parallel()
app := New()
@ -1034,7 +1035,16 @@ func Test_Ctx_Cookies(t *testing.T) {
c.Request().Header.Set("Cookie", "john=doe")
require.Equal(t, "doe", c.Req().Cookies("john"))
require.Equal(t, "default", c.Req().Cookies("unknown", "default"))
require.Equal(t, "", c.Req().Cookies("unknown", "default"))
c.Request().Header.Set("Cookie", "special=value,with,commas") // commas are allowed
require.Equal(t, "value,with,commas", c.Req().Cookies("special"))
c.Request().Header.Set("Cookie", "quotes=value\"with\"quotes")
require.Equal(t, "", c.Req().Cookies("quotes"))
c.Request().Header.Set("Cookie", "backslash=value\\with\\backslash")
require.Equal(t, "", c.Req().Cookies("backslash"))
}
// go test -run Test_Ctx_Format