aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2012-02-22 11:13:59 +1100
committerBrad Fitzpatrick <bradfitz@golang.org>2012-02-22 11:13:59 +1100
commit31e94293fc3f57f58bd0dae0698f0914b3e9a9e7 (patch)
treea6f46e035dfac8cb9fc52cc5d7da81b1d0c8ee72
parentfc3797a491ef01a61e8b3e9144ef28622a9efe06 (diff)
downloadgo-31e94293fc3f57f58bd0dae0698f0914b3e9a9e7.tar.gz
go-31e94293fc3f57f58bd0dae0698f0914b3e9a9e7.zip
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
-rw-r--r--src/pkg/net/textproto/reader.go13
-rw-r--r--src/pkg/net/textproto/reader_test.go23
2 files changed, 34 insertions, 2 deletions
diff --git a/src/pkg/net/textproto/reader.go b/src/pkg/net/textproto/reader.go
index 862cd536c4..125feb3e88 100644
--- a/src/pkg/net/textproto/reader.go
+++ b/src/pkg/net/textproto/reader.go
@@ -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'
}
diff --git a/src/pkg/net/textproto/reader_test.go b/src/pkg/net/textproto/reader_test.go
index 4d03691480..7c5d16227f 100644
--- a/src/pkg/net/textproto/reader_test.go
+++ b/src/pkg/net/textproto/reader_test.go
@@ -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