From 1ab40cd213c3904e3f0e2e392aea9e1511f9f830 Mon Sep 17 00:00:00 2001 From: "hubert.siwik" Date: Tue, 9 Jul 2024 13:28:27 +0200 Subject: [PATCH] Header getter/setter should be case in-sensitive --- ftwhttp/header.go | 22 ++++++++++++++++------ ftwhttp/header_test.go | 12 ++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/ftwhttp/header.go b/ftwhttp/header.go index cb593321..59b03dd3 100644 --- a/ftwhttp/header.go +++ b/ftwhttp/header.go @@ -6,6 +6,7 @@ package ftwhttp import ( "bytes" "io" + "net/textproto" "sort" "github.com/rs/zerolog/log" @@ -34,7 +35,9 @@ func (w stringWriter) WriteString(s string) (n int, err error) { // Add adds the key, value pair to the header. // It appends to any existing values associated with key. +// The key is case in-sensitive func (h Header) Add(key, value string) { + key = canonicalHeaderKey(key) if h.Get(key) == "" { h.Set(key, value) } @@ -43,35 +46,37 @@ func (h Header) Add(key, value string) { // Set sets the header entries associated with key to // the single element value. It replaces any existing // values associated with key. +// The key is case in-sensitive func (h Header) Set(key, value string) { - h[key] = value + h[canonicalHeaderKey(key)] = value } // Get gets the first value associated with the given key. -// It is case insensitive; // If there are no values associated with the key, Get returns "". +// The key is case in-sensitive func (h Header) Get(key string) string { if h == nil { return "" } - v := h[key] + v := h[canonicalHeaderKey(key)] return v } // Value returns the value associated with the given key. -// It is case insensitive; +// The key is case in-sensitive func (h Header) Value(key string) string { if h == nil { return "" } - return h[key] + return h[canonicalHeaderKey(key)] } // Del deletes the value associated with key. +// The key is case in-sensitive func (h Header) Del(key string) { - delete(h, key) + delete(h, canonicalHeaderKey(key)) } // Write writes a header in wire format. @@ -138,3 +143,8 @@ func (h Header) getSortedHeadersByName() []string { return keys } + +// canonicalHeaderKey transform given to the canonical form +func canonicalHeaderKey(key string) string { + return textproto.CanonicalMIMEHeaderKey(key) +} diff --git a/ftwhttp/header_test.go b/ftwhttp/header_test.go index 780c1d4f..0c1b926f 100644 --- a/ftwhttp/header_test.go +++ b/ftwhttp/header_test.go @@ -111,6 +111,11 @@ func (s *headerTestSuite) TestHeaderSetGet() { h.Add("Other", "Value") value := h.Get("Other") s.Equalf("Value", value, "got: %s, want: %s\n", value, "Value") + + // Case in-sensitive + h.Add("camel-Header", "Value") + value = h.Get("Camel-header") + s.Equalf("Value", value, "got: %s, want: %s\n", value, "Value") } func (s *headerTestSuite) TestHeaderDel() { @@ -124,6 +129,13 @@ func (s *headerTestSuite) TestHeaderDel() { s.Equalf("", value, "#%d: got: %s, want: %s\n", i, value, "") } } + + // Case in-sensitive + h := Header{} + h.Add("content-Type", "Value") + h.Del("Content-type") + value := h.Get("Content-Type") + s.Equalf("", value, "#case: got: %s, want: %s\n", value, "") } func (s *headerTestSuite) TestHeaderClone() {