GoLang HTTP Header Case Sensitivity Issues

Introduction

Today, while using the http package in GoLang, I found that the case of the headers I set did not match what I passed in.

Standards

The HTTP standard states that HTTP headers are case insensitive.

GoLang HTTP

GoLang normalizes headers when setting them, capitalizing the first letter and the first letter after a hyphen.

func (h Header) Add(key, value string) {
 textproto.MIMEHeader(h).Add(key, value)
}

func (h MIMEHeader) Add(key, value string) {
 key = CanonicalMIMEHeaderKey(key)
 h[key] = append(h[key], value)
}

// CanonicalMIMEHeaderKey returns the canonical format of the
// MIME header key s. The canonicalization converts the first
// letter and any letter following a hyphen to upper case;
// the rest are converted to lowercase. For example, the
// canonical key for "accept-encoding" is "Accept-Encoding".
// MIME header keys are assumed to be ASCII only.
// If s contains a space or invalid header field bytes, it is
// returned without modifications.
func CanonicalMIMEHeaderKey(s string) string {
// Quick check for canonical encoding.
 upper := true
for i := 0; i < len(s); i++ {
  c := s[i]
if !validHeaderFieldByte(c) {
   return s
  }
if upper && 'a' <= c && c <= 'z' {
   s, _ = canonicalMIMEHeaderKey([]byte(s))
   return s
  }
if !upper && 'A' <= c && c <= 'Z' {
   s, _ = canonicalMIMEHeaderKey([]byte(s))
   return s
  }
  upper = c == '-'
 }
return s
}

From the above source code, we can see that the <span>key</span> undergoes <span>canonicalMIMEHeaderKey</span> processing.

<span>Set</span> works the same way.

func (h Header) Set(key, value string) {
 textproto.MIMEHeader(h).Set(key, value)
}

func (h MIMEHeader) Set(key, value string) {
 h[CanonicalMIMEHeaderKey(key)] = []string{value}
}

No Case Conversion

If you do not want automatic case conversion, I asked <span>DeepSeek</span> and you can directly set the header.

req.Header["key"] = []string{"value"}

GoLang HTTP Header Case Sensitivity Issues

Previous Recommendations

Offline Experience with Xiaomi 15 Ultra

Step-by-step Guide: How to Quickly Review Others’ PRs Locally?

“Urgent Reminder! Your DeepSeek-R1 Model is Running ‘Naked’ – A Step-by-step Guide to Fixing the Ollama Security Vulnerability”

Leave a Comment