From 9ba4cef1bac8ebc8fe71123bd20cfc681fdb78a8 Mon Sep 17 00:00:00 2001 From: Rem Date: Fri, 14 Jun 2019 16:07:33 +0200 Subject: [PATCH] Support SameSite value "None" cookie attribute (#581) * Support SameSite value "None" cookie attribute * Fix typo in CookieSameSiteNoneMode comment * fix comment for SameSite None --- cookie.go | 16 ++++++++++++++++ cookie_test.go | 23 +++++++++++++++++++++++ strings.go | 1 + 3 files changed, 40 insertions(+) diff --git a/cookie.go b/cookie.go index 8137643..fb6618a 100644 --- a/cookie.go +++ b/cookie.go @@ -31,6 +31,9 @@ const ( CookieSameSiteLaxMode // CookieSameSiteStrictMode sets the SameSite flag with the "Strict" parameter CookieSameSiteStrictMode + // CookieSameSiteNoneMode sets the SameSite flag with the "None" parameter + // see https://tools.ietf.org/html/draft-west-cookie-incrementalism-00 + CookieSameSiteNoneMode ) // AcquireCookie returns an empty Cookie object from the pool. @@ -119,8 +122,12 @@ func (c *Cookie) SameSite() CookieSameSite { } // SetSameSite sets the cookie's SameSite flag to the given value. +// set value CookieSameSiteNoneMode will set Secure to true also to avoid browser rejection func (c *Cookie) SetSameSite(mode CookieSameSite) { c.sameSite = mode + if mode == CookieSameSiteNoneMode { + c.SetSecure(true) + } } // Path returns cookie path. @@ -288,6 +295,11 @@ func (c *Cookie) AppendBytes(dst []byte) []byte { dst = append(dst, strCookieSameSite...) dst = append(dst, '=') dst = append(dst, strCookieSameSiteStrict...) + case CookieSameSiteNoneMode: + dst = append(dst, ';', ' ') + dst = append(dst, strCookieSameSite...) + dst = append(dst, '=') + dst = append(dst, strCookieSameSiteNone...) } return dst } @@ -386,6 +398,10 @@ func (c *Cookie) ParseBytes(src []byte) error { if caseInsensitiveCompare(strCookieSameSiteStrict, kv.value) { c.sameSite = CookieSameSiteStrictMode } + case 'n': // "none" + if caseInsensitiveCompare(strCookieSameSiteNone, kv.value) { + c.sameSite = CookieSameSiteNoneMode + } } } } diff --git a/cookie_test.go b/cookie_test.go index 50c2ad3..9add593 100644 --- a/cookie_test.go +++ b/cookie_test.go @@ -121,6 +121,29 @@ func TestCookieSameSite(t *testing.T) { t.Fatalf("missing SameSite flag in cookie %q", s) } + if err := c.Parse("foo=bar; samesite=none"); err != nil { + t.Fatalf("unexpected error: %s", err) + } + if c.SameSite() != CookieSameSiteNoneMode { + t.Fatalf("SameSite None Mode must be set") + } + s = c.String() + if !strings.Contains(s, "; SameSite=None") { + t.Fatalf("missing SameSite flag in cookie %q", s) + } + + if err := c.Parse("foo=bar"); err != nil { + t.Fatalf("unexpected error: %s", err) + } + c.SetSameSite(CookieSameSiteNoneMode) + s = c.String() + if !strings.Contains(s, "; SameSite=None") { + t.Fatalf("missing SameSite flag in cookie %q", s) + } + if !strings.Contains(s, "; secure") { + t.Fatalf("missing Secure flag in cookie %q", s) + } + if err := c.Parse("foo=bar"); err != nil { t.Fatalf("unexpected error: %s", err) } diff --git a/strings.go b/strings.go index 6fef4ea..f654f95 100644 --- a/strings.go +++ b/strings.go @@ -62,6 +62,7 @@ var ( strCookieSameSite = []byte("SameSite") strCookieSameSiteLax = []byte("Lax") strCookieSameSiteStrict = []byte("Strict") + strCookieSameSiteNone = []byte("None") strClose = []byte("close") strGzip = []byte("gzip")