1
0
mirror of https://github.com/golang/go synced 2024-11-12 04:40:22 -07:00

net/textproto: accept bad MIME headers as browsers do

Accept certain non-compliant response headers
(in particular, when spaces preceed the colon).
All major browser and curl seem to support this,
and at least one webserver seems to send these.

*shrug*

R=golang-dev, gri
CC=golang-dev
https://golang.org/cl/5690059
This commit is contained in:
Brad Fitzpatrick 2012-02-22 11:13:59 +11:00
parent fc3797a491
commit 31e94293fc
2 changed files with 34 additions and 2 deletions

View File

@ -454,10 +454,14 @@ func (r *Reader) ReadMIMEHeader() (MIMEHeader, error) {
// Key ends at first colon; must not have spaces.
i := bytes.IndexByte(kv, ':')
if i < 0 || bytes.IndexByte(kv[0:i], ' ') >= 0 {
if i < 0 {
return m, ProtocolError("malformed MIME header line: " + string(kv))
}
key := CanonicalMIMEHeaderKey(string(kv[0:i]))
key := string(kv[0:i])
if strings.Index(key, " ") >= 0 {
key = strings.TrimRight(key, " ")
}
key = CanonicalMIMEHeaderKey(key)
// Skip initial spaces in value.
i++ // skip colon
@ -503,6 +507,11 @@ MustRewrite:
a := []byte(s)
upper := true
for i, v := range a {
if v == ' ' {
a[i] = '-'
upper = true
continue
}
if upper && 'a' <= v && v <= 'z' {
a[i] = v + 'A' - 'a'
}

View File

@ -164,6 +164,29 @@ func TestLargeReadMIMEHeader(t *testing.T) {
}
}
// Test that we read slightly-bogus MIME headers seen in the wild,
// with spaces before colons, and spaces in keys.
func TestReadMIMEHeaderNonCompliant(t *testing.T) {
// Invalid HTTP response header as sent by an Axis security
// camera: (this is handled by IE, Firefox, Chrome, curl, etc.)
r := reader("Foo: bar\r\n" +
"Content-Language: en\r\n" +
"SID : 0\r\n" +
"Audio Mode : None\r\n" +
"Privilege : 127\r\n\r\n")
m, err := r.ReadMIMEHeader()
want := MIMEHeader{
"Foo": {"bar"},
"Content-Language": {"en"},
"Sid": {"0"},
"Audio-Mode": {"None"},
"Privilege": {"127"},
}
if !reflect.DeepEqual(m, want) || err != nil {
t.Fatalf("ReadMIMEHeader =\n%v, %v; want:\n%v", m, err, want)
}
}
type readResponseTest struct {
in string
inCode int