Access Cookie members via accessors

This commit is contained in:
Aliaksandr Valialkin
2015-11-22 13:29:21 +02:00
parent 46ac549ae1
commit 9f7463cd28
4 changed files with 164 additions and 88 deletions
+121 -45
View File
@@ -7,71 +7,147 @@ import (
"time"
)
// CookieExpireDelete may be set on Cookie.Expire for expiring the given cookie.
var CookieExpireDelete = time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
var zeroTime time.Time
var (
// CookieExpireDelete may be set on Cookie.Expire for expiring the given cookie.
CookieExpireDelete = time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
// CookieExpireUnlimited indicates that the cookie doesn't expire.
CookieExpireUnlimited = zeroTime
)
// Cookie represents HTTP response cookie.
type Cookie struct {
// Key is cookie name.
Key []byte
// Value is cookie value.
Value []byte
// Expiration time for the cookie.
//
// Set expiration time to CookieExpireDelete for expiring (deleting)
// the cookie on the client.
//
// By default cookie lifetime is limited by browser session.
Expire time.Time
// Domain for the cookie.
//
// By default cookie is set to the current domain.
Domain []byte
// Path for the cookie.
//
// By default cookie is set to the current page only.
Path []byte
key []byte
value []byte
expire time.Time
domain []byte
path []byte
bufKV argsKV
buf []byte
}
var zeroTime time.Time
// Path returns cookie path.
func (c *Cookie) Path() []byte {
return c.path
}
// SetPath sets cookie path.
func (c *Cookie) SetPath(path string) {
c.buf = AppendBytesStr(c.buf[:0], path)
c.path = normalizePath(c.path, c.buf)
}
// SetPathBytes sets cookie path.
func (c *Cookie) SetPathBytes(path []byte) {
c.buf = append(c.buf[:0], path...)
c.path = normalizePath(c.path, c.buf)
}
// Domain returns cookie domain.
//
// The returned domain is valid until the next Cookie modification method call.
func (c *Cookie) Domain() []byte {
return c.domain
}
// SetDomain sets cookie domain.
func (c *Cookie) SetDomain(domain string) {
c.domain = AppendBytesStr(c.domain[:0], domain)
}
// SetDomain
func (c *Cookie) SetDomainBytes(domain []byte) {
c.domain = append(c.domain[:0], domain...)
}
// Expire returns cookie expiration time.
//
// CookieExpireUnlimited is returned if cookie doesn't expire
func (c *Cookie) Expire() time.Time {
expire := c.expire
if expire.IsZero() {
expire = CookieExpireUnlimited
}
return expire
}
// SetExpire sets cookie expiration time.
//
// Set expiration time to CookieExpireDelete for expiring (deleting)
// the cookie on the client.
//
// By default cookie lifetime is limited by browser session.
func (c *Cookie) SetExpire(expire time.Time) {
c.expire = expire
}
// Value returns cookie value.
//
// The returned value is valid until the next Cookie modification method call.
func (c *Cookie) Value() []byte {
return c.value
}
// SetValue sets cookie value.
func (c *Cookie) SetValue(value string) {
c.value = AppendBytesStr(c.value[:0], value)
}
// SetValueBytes sets cookie value.
func (c *Cookie) SetValueBytes(value []byte) {
c.value = append(c.value[:0], value...)
}
// Key returns cookie name.
//
// The returned value is valid until the next Cookie modification method call.
func (c *Cookie) Key() []byte {
return c.key
}
// SetKey sets cookie name.
func (c *Cookie) SetKey(key string) {
c.key = AppendBytesStr(c.key[:0], key)
}
// SetKeyBytes sets cookie name.
func (c *Cookie) SetKeyBytes(key []byte) {
c.key = append(c.key[:0], key...)
}
// Reset clears the cookie.
func (c *Cookie) Reset() {
c.Key = c.Key[:0]
c.Value = c.Value[:0]
c.Expire = zeroTime
c.Domain = c.Domain[:0]
c.Path = c.Path[:0]
c.key = c.key[:0]
c.value = c.value[:0]
c.expire = zeroTime
c.domain = c.domain[:0]
c.path = c.path[:0]
}
// AppendBytes appends cookie representation to dst and returns dst
// (maybe newly allocated).
func (c *Cookie) AppendBytes(dst []byte) []byte {
if len(c.Key) > 0 {
dst = appendQuotedArg(dst, c.Key)
if len(c.key) > 0 {
dst = appendQuotedArg(dst, c.key)
dst = append(dst, '=')
}
dst = appendQuotedArg(dst, c.Value)
dst = appendQuotedArg(dst, c.value)
if !c.Expire.IsZero() {
c.bufKV.value = AppendHTTPDate(c.bufKV.value[:0], c.Expire)
if !c.expire.IsZero() {
c.bufKV.value = AppendHTTPDate(c.bufKV.value[:0], c.expire)
dst = append(dst, ';', ' ')
dst = append(dst, strCookieExpires...)
dst = append(dst, '=')
dst = append(dst, c.bufKV.value...)
}
if len(c.Domain) > 0 {
dst = appendCookiePart(dst, strCookieDomain, c.Domain)
if len(c.domain) > 0 {
dst = appendCookiePart(dst, strCookieDomain, c.domain)
}
if len(c.Path) > 0 {
dst = appendCookiePart(dst, strCookiePath, c.Path)
if len(c.path) > 0 {
dst = appendCookiePart(dst, strCookiePath, c.path)
}
return dst
}
@@ -117,8 +193,8 @@ func (c *Cookie) ParseBytes(src []byte) error {
return errNoCookies
}
c.Key = append(c.Key[:0], kv.key...)
c.Value = append(c.Value[:0], kv.value...)
c.key = append(c.key[:0], kv.key...)
c.value = append(c.value[:0], kv.value...)
for s.next(kv, false) {
if len(kv.key) == 0 && len(kv.value) == 0 {
@@ -131,11 +207,11 @@ func (c *Cookie) ParseBytes(src []byte) error {
if err != nil {
return err
}
c.Expire = exptime
c.expire = exptime
case bytes.Equal(strCookieDomain, kv.key):
c.Domain = append(c.Domain[:0], kv.value...)
c.domain = append(c.domain[:0], kv.value...)
case bytes.Equal(strCookiePath, kv.key):
c.Path = append(c.Path[:0], kv.value...)
c.path = append(c.path[:0], kv.value...)
}
}
return nil
+5 -5
View File
@@ -32,19 +32,19 @@ func TestCookieAppendBytes(t *testing.T) {
testCookieAppendBytes(t, c, "foo", "", "foo=")
testCookieAppendBytes(t, c, "ффф", "12 лодлы", "%D1%84%D1%84%D1%84=12%20%D0%BB%D0%BE%D0%B4%D0%BB%D1%8B")
c.Domain = []byte("foobar.com")
c.SetDomain("foobar.com")
testCookieAppendBytes(t, c, "a", "b", "a=b; domain=foobar.com")
c.Path = []byte("/a/b")
c.SetPath("/a/b")
testCookieAppendBytes(t, c, "aa", "bb", "aa=bb; domain=foobar.com; path=/a/b")
c.Expire = CookieExpireDelete
c.SetExpire(CookieExpireDelete)
testCookieAppendBytes(t, c, "xxx", "yyy", "xxx=yyy; expires=Tue, 10 Nov 2009 23:00:00 GMT; domain=foobar.com; path=/a/b")
}
func testCookieAppendBytes(t *testing.T, c *Cookie, key, value, expectedS string) {
c.Key = []byte(key)
c.Value = []byte(value)
c.SetKey(key)
c.SetValue(value)
result := string(c.AppendBytes(nil))
if result != expectedS {
t.Fatalf("Unexpected cookie %q. Expected %q", result, expectedS)
+2 -2
View File
@@ -579,7 +579,7 @@ func (h *ResponseHeader) SetCanonical(key, value []byte) {
// SetCookie sets the given response cookie.
func (h *ResponseHeader) SetCookie(cookie *Cookie) {
h.cookies = setArg(h.cookies, cookie.Key, cookie.Cookie())
h.cookies = setArg(h.cookies, cookie.Key(), cookie.Cookie())
}
// SetCookie sets 'key: value' cookies.
@@ -754,7 +754,7 @@ func (h *RequestHeader) CookieBytes(key []byte) []byte {
//
// Returns false if cookie with the given cookie.Key is missing.
func (h *ResponseHeader) Cookie(cookie *Cookie) bool {
v := peekArgBytes(h.cookies, cookie.Key)
v := peekArgBytes(h.cookies, cookie.Key())
if v == nil {
return false
}
+36 -36
View File
@@ -282,26 +282,26 @@ func TestResponseHeaderSetCookie(t *testing.T) {
h.Set("Set-Cookie", "aaaaa=bxx")
var c Cookie
c.Key = []byte("foo")
c.SetKey("foo")
if !h.Cookie(&c) {
t.Fatalf("cannot obtain %q cookie", c.Key)
t.Fatalf("cannot obtain %q cookie", c.Key())
}
if string(c.Value) != "bar" {
t.Fatalf("unexpected cookie value %q. Expected %q", c.Value, "bar")
if string(c.Value()) != "bar" {
t.Fatalf("unexpected cookie value %q. Expected %q", c.Value(), "bar")
}
if string(c.Path) != "/aa/bb" {
t.Fatalf("unexpected cookie path %q. Expected %q", c.Path, "/aa/bb")
if string(c.Path()) != "/aa/bb" {
t.Fatalf("unexpected cookie path %q. Expected %q", c.Path(), "/aa/bb")
}
if string(c.Domain) != "aaa.com" {
t.Fatalf("unexpected cookie domain %q. Expected %q", c.Domain, "aaa.com")
if string(c.Domain()) != "aaa.com" {
t.Fatalf("unexpected cookie domain %q. Expected %q", c.Domain(), "aaa.com")
}
c.Key = []byte("aaaaa")
c.SetKey("aaaaa")
if !h.Cookie(&c) {
t.Fatalf("cannot obtain %q cookie", c.Key)
t.Fatalf("cannot obtain %q cookie", c.Key())
}
if string(c.Value) != "bxx" {
t.Fatalf("unexpected cookie value %q. Expecting %q", c.Value, "bxx")
if string(c.Value()) != "bxx" {
t.Fatalf("unexpected cookie value %q. Expecting %q", c.Value(), "bxx")
}
}
@@ -413,36 +413,36 @@ func TestResponseHeaderCookie(t *testing.T) {
var h ResponseHeader
var c Cookie
c.Key = []byte("foobar")
c.Value = []byte("aaa")
c.SetKey("foobar")
c.SetValue("aaa")
h.SetCookie(&c)
c.Key = []byte("йцук")
c.Domain = []byte("foobar.com")
c.SetKey("йцук")
c.SetDomain("foobar.com")
h.SetCookie(&c)
c.Reset()
c.Key = []byte("foobar")
c.SetKey("foobar")
if !h.Cookie(&c) {
t.Fatalf("Cannot find cookie %q", c.Key)
t.Fatalf("Cannot find cookie %q", c.Key())
}
var expectedC1 Cookie
expectedC1.Key = []byte("foobar")
expectedC1.Value = []byte("aaa")
expectedC1.SetKey("foobar")
expectedC1.SetValue("aaa")
if !equalCookie(&expectedC1, &c) {
t.Fatalf("unexpected cookie\n%#v\nExpected\n%#v\n", c, expectedC1)
}
c.Key = []byte("йцук")
c.SetKey("йцук")
if !h.Cookie(&c) {
t.Fatalf("cannot find cookie %q", c.Key)
t.Fatalf("cannot find cookie %q", c.Key())
}
var expectedC2 Cookie
expectedC2.Key = []byte("йцук")
expectedC2.Value = []byte("aaa")
expectedC2.Domain = []byte("foobar.com")
expectedC2.SetKey("йцук")
expectedC2.SetValue("aaa")
expectedC2.SetDomain("foobar.com")
if !equalCookie(&expectedC2, &c) {
t.Fatalf("unexpected cookie\n%v\nExpected\n%v\n", c, expectedC2)
}
@@ -450,8 +450,8 @@ func TestResponseHeaderCookie(t *testing.T) {
h.VisitAllCookie(func(key, value []byte) {
var cc Cookie
cc.ParseBytes(value)
if !bytes.Equal(key, cc.Key) {
t.Fatalf("Unexpected cookie key %q. Expected %q", key, cc.Key)
if !bytes.Equal(key, cc.Key()) {
t.Fatalf("Unexpected cookie key %q. Expected %q", key, cc.Key())
}
switch {
case bytes.Equal(key, []byte("foobar")):
@@ -482,17 +482,17 @@ func TestResponseHeaderCookie(t *testing.T) {
t.Fatalf("unexpected error: %s", err)
}
c.Key = []byte("foobar")
c.SetKey("foobar")
if !h1.Cookie(&c) {
t.Fatalf("Cannot find cookie %q", c.Key)
t.Fatalf("Cannot find cookie %q", c.Key())
}
if !equalCookie(&expectedC1, &c) {
t.Fatalf("unexpected cookie\n%v\nExpected\n%v\n", c, expectedC1)
}
c.Key = []byte("йцук")
c.SetKey("йцук")
if !h1.Cookie(&c) {
t.Fatalf("cannot find cookie %q", c.Key)
t.Fatalf("cannot find cookie %q", c.Key())
}
if !equalCookie(&expectedC2, &c) {
t.Fatalf("unexpected cookie\n%v\nExpected\n%v\n", c, expectedC2)
@@ -500,19 +500,19 @@ func TestResponseHeaderCookie(t *testing.T) {
}
func equalCookie(c1, c2 *Cookie) bool {
if !bytes.Equal(c1.Key, c2.Key) {
if !bytes.Equal(c1.Key(), c2.Key()) {
return false
}
if !bytes.Equal(c1.Value, c2.Value) {
if !bytes.Equal(c1.Value(), c2.Value()) {
return false
}
if !c1.Expire.Equal(c2.Expire) {
if !c1.Expire().Equal(c2.Expire()) {
return false
}
if !bytes.Equal(c1.Domain, c2.Domain) {
if !bytes.Equal(c1.Domain(), c2.Domain()) {
return false
}
if !bytes.Equal(c1.Path, c2.Path) {
if !bytes.Equal(c1.Path(), c2.Path()) {
return false
}
return true