mirror of
https://github.com/golang/go.git
synced 2025-05-23 16:31:27 +00: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:
parent
fc3797a491
commit
31e94293fc
@ -454,10 +454,14 @@ func (r *Reader) ReadMIMEHeader() (MIMEHeader, error) {
|
|||||||
|
|
||||||
// Key ends at first colon; must not have spaces.
|
// Key ends at first colon; must not have spaces.
|
||||||
i := bytes.IndexByte(kv, ':')
|
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))
|
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.
|
// Skip initial spaces in value.
|
||||||
i++ // skip colon
|
i++ // skip colon
|
||||||
@ -503,6 +507,11 @@ MustRewrite:
|
|||||||
a := []byte(s)
|
a := []byte(s)
|
||||||
upper := true
|
upper := true
|
||||||
for i, v := range a {
|
for i, v := range a {
|
||||||
|
if v == ' ' {
|
||||||
|
a[i] = '-'
|
||||||
|
upper = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
if upper && 'a' <= v && v <= 'z' {
|
if upper && 'a' <= v && v <= 'z' {
|
||||||
a[i] = v + 'A' - 'a'
|
a[i] = v + 'A' - 'a'
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
type readResponseTest struct {
|
||||||
in string
|
in string
|
||||||
inCode int
|
inCode int
|
||||||
|
Loading…
x
Reference in New Issue
Block a user