mirror of
https://github.com/golang/go
synced 2024-11-11 21:20:21 -07:00
net/http: add Cookie.Valid method
The (*http.Cookie).String method used by SetCookie will silently discard or sanitize any fields it deems invalid, making it difficult to tell whether a cookie will be sent as expected. This change introduces a new (*http.Cookie).Valid method which may be used to check if any cookie fields will be discarded or sanitized prior to calling (*http.Cookie).String. Fixes #46370 Change-Id: I2db80078de190d267a9c675a9717c8be8acc8704 Reviewed-on: https://go-review.googlesource.com/c/go/+/338590 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Trust: Cherry Mui <cherryyz@google.com> Trust: Damien Neil <dneil@google.com> Reviewed-by: Damien Neil <dneil@google.com>
This commit is contained in:
parent
f375844342
commit
c8dd89ed3d
@ -142,3 +142,4 @@ pkg testing, type FuzzResult struct, T time.Duration
|
||||
pkg testing, type InternalFuzzTarget struct
|
||||
pkg testing, type InternalFuzzTarget struct, Fn func(*F)
|
||||
pkg testing, type InternalFuzzTarget struct, Name string
|
||||
pkg net/http, method (*Cookie) Valid() error
|
||||
|
@ -5,6 +5,8 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/http/internal/ascii"
|
||||
@ -236,6 +238,37 @@ func (c *Cookie) String() string {
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// Valid reports whether the cookie is valid.
|
||||
func (c *Cookie) Valid() error {
|
||||
if c == nil {
|
||||
return errors.New("http: nil Cookie")
|
||||
}
|
||||
if !isCookieNameValid(c.Name) {
|
||||
return errors.New("http: invalid Cookie.Name")
|
||||
}
|
||||
if !validCookieExpires(c.Expires) {
|
||||
return errors.New("http: invalid Cookie.Expires")
|
||||
}
|
||||
for i := 0; i < len(c.Value); i++ {
|
||||
if !validCookieValueByte(c.Value[i]) {
|
||||
return fmt.Errorf("http: invalid byte %q in Cookie.Value", c.Value[i])
|
||||
}
|
||||
}
|
||||
if len(c.Path) > 0 {
|
||||
for i := 0; i < len(c.Path); i++ {
|
||||
if !validCookiePathByte(c.Path[i]) {
|
||||
return fmt.Errorf("http: invalid byte %q in Cookie.Path", c.Path[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(c.Domain) > 0 {
|
||||
if !validCookieDomain(c.Domain) {
|
||||
return errors.New("http: invalid Cookie.Domain")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// readCookies parses all "Cookie" values from the header h and
|
||||
// returns the successfully parsed Cookies.
|
||||
//
|
||||
|
@ -529,6 +529,31 @@ func TestCookieSanitizePath(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCookieValid(t *testing.T) {
|
||||
tests := []struct {
|
||||
cookie *Cookie
|
||||
valid bool
|
||||
}{
|
||||
{nil, false},
|
||||
{&Cookie{Name: ""}, false},
|
||||
{&Cookie{Name: "invalid-expires"}, false},
|
||||
{&Cookie{Name: "invalid-value", Value: "foo\"bar"}, false},
|
||||
{&Cookie{Name: "invalid-path", Path: "/foo;bar/"}, false},
|
||||
{&Cookie{Name: "invalid-domain", Domain: "example.com:80"}, false},
|
||||
{&Cookie{Name: "valid", Value: "foo", Path: "/bar", Domain: "example.com", Expires: time.Unix(0, 0)}, true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
err := tt.cookie.Valid()
|
||||
if err != nil && tt.valid {
|
||||
t.Errorf("%#v.Valid() returned error %v; want nil", tt.cookie, err)
|
||||
}
|
||||
if err == nil && !tt.valid {
|
||||
t.Errorf("%#v.Valid() returned nil; want error", tt.cookie)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCookieString(b *testing.B) {
|
||||
const wantCookieString = `cookie-9=i3e01nf61b6t23bvfmplnanol3; Path=/restricted/; Domain=example.com; Expires=Tue, 10 Nov 2009 23:00:00 GMT; Max-Age=3600`
|
||||
c := &Cookie{
|
||||
|
Loading…
Reference in New Issue
Block a user