textproto.CanonicalMIMEHeaderKey ignores keys with _ in. If an htttp server returns one of these, then it isn't possible to use http.Header.Get to fetch it as it doesn't get canonicalized.
For example, Backblaze use keys with _ in to store metadata - see the X-Bz-Info-src_last_modified_millis in the upload docs.
The Backblaze server returns this header all in lower case. Because it doesn't get canonicalised by textproto.CanonicalMIMEHeaderKey it remains in lower case and consequently `resp.Header.Get("X-Bz-Info-src_last_modified_millis") doesn't find it.
This is easy enough to work around, but caused me a bit of suprise and debugging!
The comment on textproto/reader.go on validHeaderFieldByte explains the problem nicely!
// validHeaderFieldByte reports whether b is a valid byte in a header
// field key. This is actually stricter than RFC 7230, which says:
// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
// "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
// token = 1*tchar
// TODO: revisit in Go 1.6+ and possibly expand this. But note that many
// servers have historically dropped '_' to prevent ambiguities when mapping
// to CGI environment variables.
func validHeaderFieldByte(b byte) bool {
return ('A' <= b && b <= 'Z') ||
('a' <= b && b <= 'z') ||
('0' <= b && b <= '9') ||
b == '-'
}
This could cause problems with S3 also which uses a similar scheme for returning user defined metadata too.
textproto.CanonicalMIMEHeaderKey ignores keys with
_in. If an htttp server returns one of these, then it isn't possible to usehttp.Header.Getto fetch it as it doesn't get canonicalized.For example, Backblaze use keys with
_in to store metadata - see the X-Bz-Info-src_last_modified_millis in the upload docs.The Backblaze server returns this header all in lower case. Because it doesn't get canonicalised by
textproto.CanonicalMIMEHeaderKeyit remains in lower case and consequently `resp.Header.Get("X-Bz-Info-src_last_modified_millis") doesn't find it.This is easy enough to work around, but caused me a bit of suprise and debugging!
The comment on textproto/reader.go on validHeaderFieldByte explains the problem nicely!
This could cause problems with S3 also which uses a similar scheme for returning user defined metadata too.