mirror of
https://github.com/soypat/lneto.git
synced 2026-08-20 14:39:02 +00:00
httpraw: fix overrwrite/empty val bugs in Header.Set/SetBytes (#159)
This commit is contained in:
@@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
"slices"
|
"slices"
|
||||||
"unsafe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
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.
|
// SetBytes is equivalent to [Header.Set] but with a []byte value. Does not keep reference to value slice.
|
||||||
// Calling SetBytes Mangles the buffer.
|
// Calling SetBytes Mangles the buffer.
|
||||||
func (h *Header) SetBytes(key string, value []byte) {
|
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.
|
// 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) {
|
func (h *Header) Set(key, value string) {
|
||||||
hb := &h.hbuf
|
hb := &h.hbuf
|
||||||
var useKv *argsKV
|
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.
|
// Search for key-value with largest buffer for value to store value reusing buffer.
|
||||||
gotkv := &hb.headers[i]
|
gotkv := &hb.headers[i]
|
||||||
if b2s(hb.musttoken(gotkv.key)) == key {
|
if gotkv.isValid() && b2s(hb.musttoken(gotkv.key)) == key {
|
||||||
if useKv == nil {
|
if useKv == nil {
|
||||||
useKv = gotkv
|
useKv = gotkv
|
||||||
} else if gotkv.value.len > useKv.value.len {
|
} else if gotkv.value.len > useKv.value.len {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user