diff --git a/api/next/61472.txt b/api/next/61472.txt new file mode 100644 index 0000000000..2e39c4b193 --- /dev/null +++ b/api/next/61472.txt @@ -0,0 +1 @@ +pkg net/http, method (*Request) CookiesNamed(string) []*Cookie #61472 diff --git a/src/net/http/request.go b/src/net/http/request.go index 99fdebcf9b..345ba3d4eb 100644 --- a/src/net/http/request.go +++ b/src/net/http/request.go @@ -431,6 +431,15 @@ func (r *Request) Cookies() []*Cookie { return readCookies(r.Header, "") } +// CookiesNamed parses and returns the named HTTP cookies sent with the request +// or an empty slice if none matched. +func (r *Request) CookiesNamed(name string) []*Cookie { + if name == "" { + return []*Cookie{} + } + return readCookies(r.Header, name) +} + // ErrNoCookie is returned by Request's Cookie method when a cookie is not found. var ErrNoCookie = errors.New("http: named cookie not present") diff --git a/src/net/http/request_test.go b/src/net/http/request_test.go index 6ce32332e7..8c8116123c 100644 --- a/src/net/http/request_test.go +++ b/src/net/http/request_test.go @@ -10,6 +10,7 @@ import ( "context" "crypto/rand" "encoding/base64" + "encoding/json" "errors" "fmt" "io" @@ -1256,6 +1257,76 @@ func TestRequestCookie(t *testing.T) { } } +func TestRequestCookiesByName(t *testing.T) { + tests := []struct { + in []*Cookie + filter string + want []*Cookie + }{ + { + in: []*Cookie{ + {Name: "foo", Value: "foo-1"}, + {Name: "bar", Value: "bar"}, + }, + filter: "foo", + want: []*Cookie{{Name: "foo", Value: "foo-1"}}, + }, + { + in: []*Cookie{ + {Name: "foo", Value: "foo-1"}, + {Name: "foo", Value: "foo-2"}, + {Name: "bar", Value: "bar"}, + }, + filter: "foo", + want: []*Cookie{ + {Name: "foo", Value: "foo-1"}, + {Name: "foo", Value: "foo-2"}, + }, + }, + { + in: []*Cookie{ + {Name: "bar", Value: "bar"}, + }, + filter: "foo", + want: []*Cookie{}, + }, + { + in: []*Cookie{ + {Name: "bar", Value: "bar"}, + }, + filter: "", + want: []*Cookie{}, + }, + { + in: []*Cookie{}, + filter: "foo", + want: []*Cookie{}, + }, + } + + for _, tt := range tests { + t.Run(tt.filter, func(t *testing.T) { + req, err := NewRequest("GET", "http://example.com/", nil) + if err != nil { + t.Fatal(err) + } + for _, c := range tt.in { + req.AddCookie(c) + } + + got := req.CookiesNamed(tt.filter) + + if !reflect.DeepEqual(got, tt.want) { + asStr := func(v any) string { + blob, _ := json.MarshalIndent(v, "", " ") + return string(blob) + } + t.Fatalf("Result mismatch\n\tGot: %s\n\tWant: %s", asStr(got), asStr(tt.want)) + } + }) + } +} + const ( fileaContents = "This is a test file." filebContents = "Another test file."