Fix PeekKeys()

RequestHeader.PeekKeys() and ResponseHeader.PeekKeys() were both
implemented wrong. The tests were also wrong causing this to never be
noticed. They both never actually returned all header keys, this has
been fixed now.

While this is a backwards incompatible change, I'm still going to
release it. Anyone using these functions would have noticed they
didn't work as documented and probably would not have continued using
them.

Fixes https://github.com/valyala/fasthttp/issues/2044
This commit is contained in:
Erik Dubbelboer
2025-08-09 13:50:07 +02:00
parent c20414a496
commit 81ebee8c79
3 changed files with 26 additions and 18 deletions
-8
View File
@@ -644,11 +644,3 @@ func peekAllArgBytesToDst(dst [][]byte, h []argsKV, k []byte) [][]byte {
}
return dst
}
func peekArgsKeys(dst [][]byte, h []argsKV) [][]byte {
for i, n := 0, len(h); i < n; i++ {
kv := &h[i]
dst = append(dst, kv.key)
}
return dst
}
+18 -2
View File
@@ -1992,9 +1992,25 @@ func (h *ResponseHeader) peekAll(key []byte) [][]byte {
// either though ReleaseRequest or your request handler returning.
// Any future calls to the Peek* will modify the returned value.
// Do not store references to returned value. Make copies instead.
func (h *header) PeekKeys() [][]byte {
func (h *RequestHeader) PeekKeys() [][]byte {
h.mulHeader = h.mulHeader[:0]
h.mulHeader = peekArgsKeys(h.mulHeader, h.h)
for key := range h.All() {
h.mulHeader = append(h.mulHeader, key)
}
return h.mulHeader
}
// PeekKeys return all header keys.
//
// The returned value is valid until the request is released,
// either though ReleaseRequest or your request handler returning.
// Any future calls to the Peek* will modify the returned value.
// Do not store references to returned value. Make copies instead.
func (h *ResponseHeader) PeekKeys() [][]byte {
h.mulHeader = h.mulHeader[:0]
for key := range h.All() {
h.mulHeader = append(h.mulHeader, key)
}
return h.mulHeader
}
+8 -8
View File
@@ -3426,13 +3426,13 @@ func TestRequestHeader_Keys(t *testing.T) {
t.Fatal(err)
}
actualKeys := h.PeekKeys()
expectedKeys := [][]byte{s2b("keep-alive"), s2b("aaa")}
if reflect.DeepEqual(actualKeys, expectedKeys) {
expectedKeys := [][]byte{[]byte("Content-Type"), []byte("Trailer"), []byte("Connection")}
if !reflect.DeepEqual(actualKeys, expectedKeys) {
t.Fatalf("Unexpected value %q. Expected %q", actualKeys, expectedKeys)
}
actualTrailerKeys := h.PeekTrailerKeys()
expectedTrailerKeys := [][]byte{s2b("aaa"), s2b("bbb"), s2b("ccc")}
if reflect.DeepEqual(actualTrailerKeys, expectedTrailerKeys) {
expectedTrailerKeys := [][]byte{s2b("Aaa"), s2b("Bbb"), s2b("Ccc")}
if !reflect.DeepEqual(actualTrailerKeys, expectedTrailerKeys) {
t.Fatalf("Unexpected value %q. Expected %q", actualTrailerKeys, expectedTrailerKeys)
}
}
@@ -3446,13 +3446,13 @@ func TestResponseHeader_Keys(t *testing.T) {
t.Fatal(err)
}
actualKeys := h.PeekKeys()
expectedKeys := [][]byte{s2b("keep-alive"), s2b("aaa")}
if reflect.DeepEqual(actualKeys, expectedKeys) {
expectedKeys := [][]byte{[]byte("Content-Type"), []byte("Trailer"), []byte("Connection")}
if !reflect.DeepEqual(actualKeys, expectedKeys) {
t.Fatalf("Unexpected value %q. Expected %q", actualKeys, expectedKeys)
}
actualTrailerKeys := h.PeekTrailerKeys()
expectedTrailerKeys := [][]byte{s2b("aaa"), s2b("bbb"), s2b("ccc")}
if reflect.DeepEqual(actualTrailerKeys, expectedTrailerKeys) {
expectedTrailerKeys := [][]byte{s2b("Aaa"), s2b("Bbb"), s2b("Ccc")}
if !reflect.DeepEqual(actualTrailerKeys, expectedTrailerKeys) {
t.Fatalf("Unexpected value %q. Expected %q", actualTrailerKeys, expectedTrailerKeys)
}
}