前言
今天使用 GoLang 的 http 包发现设置的 Header 大小写与我传入的不一致。
标准
HTTP 的标准规定 HTTP 的 Header 是大小写不敏感的。
GoLang HTTP
GoLang 在设置 Header 时会进行标准化处理,首字母大写,并且 - 之后的第一个字母也是大写的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
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
}
|
从上面的源码中可以发现会对 key
进行 canonicalMIMEHeaderKey
处理。
Set
也是一样的
1
2
3
4
5
6
7
|
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}
}
|
不进行大小写转换
如果不想自动进行大小写转换,问了下 DeepSeek
可以直接设置 Header
1
|
req.Header["key"] = []string{"value"}
|