Skip to content

Commit 318e68e

Browse files
authored
Reduce the size of the Cookie by 32 bytes. (#1866)
Replace the field `bufKV` with two `[]byte` fields and remove the filed `buf`. - Reduce Cookie from **224** to **192** bytes. - In the benchmark tests, although there is no significant performance improvement, it theoretically reduces memory usage by **14.3%**.
1 parent 0128871 commit 318e68e

File tree

1 file changed

+45
-46
lines changed

1 file changed

+45
-46
lines changed

cookie.go

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@ type Cookie struct {
7474
domain []byte
7575
path []byte
7676

77-
buf []byte
77+
bufK []byte
78+
bufV []byte
7879

79-
bufKV argsKV
8080
maxAge int
8181

8282
sameSite CookieSameSite
@@ -156,14 +156,14 @@ func (c *Cookie) Path() []byte {
156156

157157
// SetPath sets cookie path.
158158
func (c *Cookie) SetPath(path string) {
159-
c.buf = append(c.buf[:0], path...)
160-
c.path = normalizePath(c.path, c.buf)
159+
c.bufK = append(c.bufK[:0], path...)
160+
c.path = normalizePath(c.path, c.bufK)
161161
}
162162

163163
// SetPathBytes sets cookie path.
164164
func (c *Cookie) SetPathBytes(path []byte) {
165-
c.buf = append(c.buf[:0], path...)
166-
c.path = normalizePath(c.path, c.buf)
165+
c.bufK = append(c.bufK[:0], path...)
166+
c.path = normalizePath(c.path, c.bufK)
167167
}
168168

169169
// Domain returns cookie domain.
@@ -284,11 +284,11 @@ func (c *Cookie) AppendBytes(dst []byte) []byte {
284284
dst = append(dst, '=')
285285
dst = AppendUint(dst, c.maxAge)
286286
} else if !c.expire.IsZero() {
287-
c.bufKV.value = AppendHTTPDate(c.bufKV.value[:0], c.expire)
287+
c.bufV = AppendHTTPDate(c.bufV[:0], c.expire)
288288
dst = append(dst, ';', ' ')
289289
dst = append(dst, strCookieExpires...)
290290
dst = append(dst, '=')
291-
dst = append(dst, c.bufKV.value...)
291+
dst = append(dst, c.bufV...)
292292
}
293293
if len(c.domain) > 0 {
294294
dst = appendCookiePart(dst, strCookieDomain, c.domain)
@@ -336,8 +336,8 @@ func (c *Cookie) AppendBytes(dst []byte) []byte {
336336
// The returned value is valid until the Cookie reused or released (ReleaseCookie).
337337
// Do not store references to the returned value. Make copies instead.
338338
func (c *Cookie) Cookie() []byte {
339-
c.buf = c.AppendBytes(c.buf[:0])
340-
return c.buf
339+
c.bufK = c.AppendBytes(c.bufK[:0])
340+
return c.bufK
341341
}
342342

343343
// String returns cookie representation.
@@ -357,8 +357,8 @@ var errNoCookies = errors.New("no cookies found")
357357

358358
// Parse parses Set-Cookie header.
359359
func (c *Cookie) Parse(src string) error {
360-
c.buf = append(c.buf[:0], src...)
361-
return c.ParseBytes(c.buf)
360+
c.bufK = append(c.bufK[:0], src...)
361+
return c.ParseBytes(c.bufK)
362362
}
363363

364364
// ParseBytes parses Set-Cookie header.
@@ -368,30 +368,29 @@ func (c *Cookie) ParseBytes(src []byte) error {
368368
var s cookieScanner
369369
s.b = src
370370

371-
kv := &c.bufKV
372-
if !s.next(kv) {
371+
if !s.next(&c.bufK, &c.bufV) {
373372
return errNoCookies
374373
}
375374

376-
c.key = append(c.key, kv.key...)
377-
c.value = append(c.value, kv.value...)
375+
c.key = append(c.key, c.bufK...)
376+
c.value = append(c.value, c.bufV...)
378377

379-
for s.next(kv) {
380-
if len(kv.key) != 0 {
378+
for s.next(&c.bufK, &c.bufV) {
379+
if len(c.bufK) != 0 {
381380
// Case insensitive switch on first char
382-
switch kv.key[0] | 0x20 {
381+
switch c.bufK[0] | 0x20 {
383382
case 'm':
384-
if caseInsensitiveCompare(strCookieMaxAge, kv.key) {
385-
maxAge, err := ParseUint(kv.value)
383+
if caseInsensitiveCompare(strCookieMaxAge, c.bufK) {
384+
maxAge, err := ParseUint(c.bufV)
386385
if err != nil {
387386
return err
388387
}
389388
c.maxAge = maxAge
390389
}
391390

392391
case 'e': // "expires"
393-
if caseInsensitiveCompare(strCookieExpires, kv.key) {
394-
v := b2s(kv.value)
392+
if caseInsensitiveCompare(strCookieExpires, c.bufK) {
393+
v := b2s(c.bufV)
395394
// Try the same two formats as net/http
396395
// See: https://github.com/golang/go/blob/00379be17e63a5b75b3237819392d2dc3b313a27/src/net/http/cookie.go#L133-L135
397396
exptime, err := time.ParseInLocation(time.RFC1123, v, time.UTC)
@@ -405,52 +404,52 @@ func (c *Cookie) ParseBytes(src []byte) error {
405404
}
406405

407406
case 'd': // "domain"
408-
if caseInsensitiveCompare(strCookieDomain, kv.key) {
409-
c.domain = append(c.domain, kv.value...)
407+
if caseInsensitiveCompare(strCookieDomain, c.bufK) {
408+
c.domain = append(c.domain, c.bufV...)
410409
}
411410

412411
case 'p': // "path"
413-
if caseInsensitiveCompare(strCookiePath, kv.key) {
414-
c.path = append(c.path, kv.value...)
412+
if caseInsensitiveCompare(strCookiePath, c.bufK) {
413+
c.path = append(c.path, c.bufV...)
415414
}
416415

417416
case 's': // "samesite"
418-
if caseInsensitiveCompare(strCookieSameSite, kv.key) {
419-
if len(kv.value) > 0 {
417+
if caseInsensitiveCompare(strCookieSameSite, c.bufK) {
418+
if len(c.bufV) > 0 {
420419
// Case insensitive switch on first char
421-
switch kv.value[0] | 0x20 {
420+
switch c.bufV[0] | 0x20 {
422421
case 'l': // "lax"
423-
if caseInsensitiveCompare(strCookieSameSiteLax, kv.value) {
422+
if caseInsensitiveCompare(strCookieSameSiteLax, c.bufV) {
424423
c.sameSite = CookieSameSiteLaxMode
425424
}
426425
case 's': // "strict"
427-
if caseInsensitiveCompare(strCookieSameSiteStrict, kv.value) {
426+
if caseInsensitiveCompare(strCookieSameSiteStrict, c.bufV) {
428427
c.sameSite = CookieSameSiteStrictMode
429428
}
430429
case 'n': // "none"
431-
if caseInsensitiveCompare(strCookieSameSiteNone, kv.value) {
430+
if caseInsensitiveCompare(strCookieSameSiteNone, c.bufV) {
432431
c.sameSite = CookieSameSiteNoneMode
433432
}
434433
}
435434
}
436435
}
437436
}
438-
} else if len(kv.value) != 0 {
437+
} else if len(c.bufV) != 0 {
439438
// Case insensitive switch on first char
440-
switch kv.value[0] | 0x20 {
439+
switch c.bufV[0] | 0x20 {
441440
case 'h': // "httponly"
442-
if caseInsensitiveCompare(strCookieHTTPOnly, kv.value) {
441+
if caseInsensitiveCompare(strCookieHTTPOnly, c.bufV) {
443442
c.httpOnly = true
444443
}
445444

446445
case 's': // "secure"
447-
if caseInsensitiveCompare(strCookieSecure, kv.value) {
446+
if caseInsensitiveCompare(strCookieSecure, c.bufV) {
448447
c.secure = true
449-
} else if caseInsensitiveCompare(strCookieSameSite, kv.value) {
448+
} else if caseInsensitiveCompare(strCookieSameSite, c.bufV) {
450449
c.sameSite = CookieSameSiteDefaultMode
451450
}
452451
case 'p': // "partitioned"
453-
if caseInsensitiveCompare(strCookiePartitioned, kv.value) {
452+
if caseInsensitiveCompare(strCookiePartitioned, c.bufV) {
454453
c.partitioned = true
455454
}
456455
}
@@ -507,7 +506,7 @@ func parseRequestCookies(cookies []argsKV, src []byte) []argsKV {
507506
s.b = src
508507
var kv *argsKV
509508
cookies, kv = allocArg(cookies)
510-
for s.next(kv) {
509+
for s.next(&kv.key, &kv.value) {
511510
if len(kv.key) > 0 || len(kv.value) > 0 {
512511
cookies, kv = allocArg(cookies)
513512
}
@@ -519,7 +518,7 @@ type cookieScanner struct {
519518
b []byte
520519
}
521520

522-
func (s *cookieScanner) next(kv *argsKV) bool {
521+
func (s *cookieScanner) next(key, val *[]byte) bool {
523522
b := s.b
524523
if len(b) == 0 {
525524
return false
@@ -532,23 +531,23 @@ func (s *cookieScanner) next(kv *argsKV) bool {
532531
case '=':
533532
if isKey {
534533
isKey = false
535-
kv.key = decodeCookieArg(kv.key, b[:i], false)
534+
*key = decodeCookieArg(*key, b[:i], false)
536535
k = i + 1
537536
}
538537
case ';':
539538
if isKey {
540-
kv.key = kv.key[:0]
539+
*key = (*key)[:0]
541540
}
542-
kv.value = decodeCookieArg(kv.value, b[k:i], true)
541+
*val = decodeCookieArg(*val, b[k:i], true)
543542
s.b = b[i+1:]
544543
return true
545544
}
546545
}
547546

548547
if isKey {
549-
kv.key = kv.key[:0]
548+
*key = (*key)[:0]
550549
}
551-
kv.value = decodeCookieArg(kv.value, b[k:], true)
550+
*val = decodeCookieArg(*val, b[k:], true)
552551
s.b = b[len(b):]
553552
return true
554553
}

0 commit comments

Comments
 (0)