diff --git a/http/httpraw/header.go b/http/httpraw/header.go index a7b8132..ada9046 100644 --- a/http/httpraw/header.go +++ b/http/httpraw/header.go @@ -4,7 +4,6 @@ import ( "bytes" "io" "slices" - "unsafe" ) const ( @@ -250,7 +249,7 @@ func (h *Header) Body() ([]byte, error) { // SetBytes is equivalent to [Header.Set] but with a []byte value. Does not keep reference to value slice. // Calling SetBytes Mangles the buffer. func (h *Header) SetBytes(key string, value []byte) { - h.Set(key, unsafe.String(&value[0], len(value))) + h.Set(key, b2s(value)) } // Set sets a key-value pair in the HTTP header. @@ -258,10 +257,10 @@ func (h *Header) SetBytes(key string, value []byte) { func (h *Header) Set(key, value string) { hb := &h.hbuf var useKv *argsKV - for i := len(hb.headers); len(hb.headers) > 0 && i <= 0; i++ { + for i := 0; i < len(hb.headers); i++ { // Search for key-value with largest buffer for value to store value reusing buffer. gotkv := &hb.headers[i] - if b2s(hb.musttoken(gotkv.key)) == key { + if gotkv.isValid() && b2s(hb.musttoken(gotkv.key)) == key { if useKv == nil { useKv = gotkv } else if gotkv.value.len > useKv.value.len { diff --git a/http/httpraw/header_test.go b/http/httpraw/header_test.go index a5c518c..4325d96 100644 --- a/http/httpraw/header_test.go +++ b/http/httpraw/header_test.go @@ -208,3 +208,35 @@ func TestCopyNormalizedHeaderValue(t *testing.T) { } } } + +func TestHeaderSetOverwrite(t *testing.T) { + var h Header + h.Reset(nil) + h.SetMethod("GET") + h.SetRequestURI("/") + h.SetProtocol("HTTP/1.1") + + h.Set("Host", "first.example.com") + h.Set("Host", "second.example.com") + + got := string(h.Get("Host")) + if got != "second.example.com" { + t.Errorf("want Host %q, got %q", "second.example.com", got) + } + req, err := h.AppendRequest(nil) + if err != nil { + t.Fatal(err) + } + if n := strings.Count(string(req), "Host:"); n != 1 { + t.Errorf("want 1 Host field in request, got %d:\n%s", n, req) + } +} + +func TestHeaderSetBytesEmptyValue(t *testing.T) { + var h Header + h.Reset(nil) + h.SetBytes("X-Empty", nil) + if got := h.Get("X-Empty"); len(got) != 0 { + t.Errorf("want empty value, got %q", got) + } +}