104 lines
4.1 KiB
Diff
104 lines
4.1 KiB
Diff
diff -up ./go/src/net/http/serve_test.go ./go/src/net/http/serve_test.go
|
|
--- ./go/src/net/http/serve_test.go 2019-08-13 18:50:13.000000000 +0200
|
|
+++ ./go/src/net/http/serve_test.go 2019-10-05 05:35:33.018025762 +0200
|
|
@@ -4725,6 +4725,10 @@ func TestServerValidatesHeaders(t *testi
|
|
{"foo\xffbar: foo\r\n", 400}, // binary in header
|
|
{"foo\x00bar: foo\r\n", 400}, // binary in header
|
|
{"Foo: " + strings.Repeat("x", 1<<21) + "\r\n", 431}, // header too large
|
|
+ // Spaces between the header key and colon are not allowed.
|
|
+ // See RFC 7230, Section 3.2.4.
|
|
+ {"Foo : bar\r\n", 400},
|
|
+ {"Foo\t: bar\r\n", 400},
|
|
|
|
{"foo: foo foo\r\n", 200}, // LWS space is okay
|
|
{"foo: foo\tfoo\r\n", 200}, // LWS tab is okay
|
|
diff -up ./go/src/net/http/transport_test.go ./go/src/net/http/transport_test.go
|
|
--- ./go/src/net/http/transport_test.go 2019-10-05 05:35:33.019025756 +0200
|
|
+++ ./go/src/net/http/transport_test.go 2019-10-05 05:39:12.037927288 +0200
|
|
@@ -4838,3 +4838,30 @@ func TestClientTimeoutKillsConn_AfterHea
|
|
t.Fatal("timeout")
|
|
}
|
|
}
|
|
+
|
|
+func TestInvalidHeaderResponse(t *testing.T) {
|
|
+ setParallel(t)
|
|
+ defer afterTest(t)
|
|
+ cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
|
|
+ conn, buf, _ := w.(Hijacker).Hijack()
|
|
+ buf.Write([]byte("HTTP/1.1 200 OK\r\n" +
|
|
+ "Date: Wed, 30 Aug 2017 19:09:27 GMT\r\n" +
|
|
+ "Content-Type: text/html; charset=utf-8\r\n" +
|
|
+ "Content-Length: 0\r\n" +
|
|
+ "Foo : bar\r\n\r\n"))
|
|
+ buf.Flush()
|
|
+ conn.Close()
|
|
+ }))
|
|
+ defer cst.close()
|
|
+ res, err := cst.c.Get(cst.ts.URL)
|
|
+ if err != nil {
|
|
+ t.Fatal(err)
|
|
+ }
|
|
+ defer res.Body.Close()
|
|
+ if v := res.Header.Get("Foo"); v != "" {
|
|
+ t.Errorf(`unexpected "Foo" header: %q`, v)
|
|
+ }
|
|
+ if v := res.Header.Get("Foo "); v != "bar" {
|
|
+ t.Errorf(`bad "Foo " header value: %q, want %q`, v, "bar")
|
|
+ }
|
|
+}
|
|
diff -up ./go/src/net/textproto/reader.go ./go/src/net/textproto/reader.go
|
|
--- ./go/src/net/textproto/reader.go 2019-08-13 18:50:13.000000000 +0200
|
|
+++ ./go/src/net/textproto/reader.go 2019-10-05 05:35:33.019025756 +0200
|
|
@@ -492,18 +492,12 @@ func (r *Reader) ReadMIMEHeader() (MIMEH
|
|
return m, err
|
|
}
|
|
|
|
- // Key ends at first colon; should not have trailing spaces
|
|
- // but they appear in the wild, violating specs, so we remove
|
|
- // them if present.
|
|
+ // Key ends at first colon.
|
|
i := bytes.IndexByte(kv, ':')
|
|
if i < 0 {
|
|
return m, ProtocolError("malformed MIME header line: " + string(kv))
|
|
}
|
|
- endKey := i
|
|
- for endKey > 0 && kv[endKey-1] == ' ' {
|
|
- endKey--
|
|
- }
|
|
- key := canonicalMIMEHeaderKey(kv[:endKey])
|
|
+ key := canonicalMIMEHeaderKey(kv[:i])
|
|
|
|
// As per RFC 7230 field-name is a token, tokens consist of one or more chars.
|
|
// We could return a ProtocolError here, but better to be liberal in what we
|
|
diff -up ./go/src/net/textproto/reader_test.go ./go/src/net/textproto/reader_test.go
|
|
--- ./go/src/net/textproto/reader_test.go 2019-08-13 18:50:13.000000000 +0200
|
|
+++ ./go/src/net/textproto/reader_test.go 2019-10-05 05:43:58.156469247 +0200
|
|
@@ -188,11 +188,10 @@ func TestLargeReadMIMEHeader(t *testing.
|
|
}
|
|
}
|
|
|
|
-// Test that we read slightly-bogus MIME headers seen in the wild,
|
|
-// with spaces before colons, and spaces in keys.
|
|
+// TestReadMIMEHeaderNonCompliant checks that we don't normalize headers
|
|
+// with spaces before colons, and accept 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.)
|
|
+ // These invalid headers will be rejected by net/http according to RFC 7230.
|
|
r := reader("Foo: bar\r\n" +
|
|
"Content-Language: en\r\n" +
|
|
"SID : 0\r\n" +
|
|
@@ -202,9 +201,9 @@ func TestReadMIMEHeaderNonCompliant(t *t
|
|
want := MIMEHeader{
|
|
"Foo": {"bar"},
|
|
"Content-Language": {"en"},
|
|
- "Sid": {"0"},
|
|
- "Audio Mode": {"None"},
|
|
- "Privilege": {"127"},
|
|
+ "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)
|