aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/net/http/response_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/net/http/response_test.go')
-rw-r--r--libgo/go/net/http/response_test.go157
1 files changed, 151 insertions, 6 deletions
diff --git a/libgo/go/net/http/response_test.go b/libgo/go/net/http/response_test.go
index 421cf55f491..d8a53400cf2 100644
--- a/libgo/go/net/http/response_test.go
+++ b/libgo/go/net/http/response_test.go
@@ -456,8 +456,59 @@ some body`,
"",
},
+
+ // Issue 12785: HTTP/1.0 response with bogus (to be ignored) Transfer-Encoding.
+ // Without a Content-Length.
+ {
+ "HTTP/1.0 200 OK\r\n" +
+ "Transfer-Encoding: bogus\r\n" +
+ "\r\n" +
+ "Body here\n",
+
+ Response{
+ Status: "200 OK",
+ StatusCode: 200,
+ Proto: "HTTP/1.0",
+ ProtoMajor: 1,
+ ProtoMinor: 0,
+ Request: dummyReq("GET"),
+ Header: Header{},
+ Close: true,
+ ContentLength: -1,
+ },
+
+ "Body here\n",
+ },
+
+ // Issue 12785: HTTP/1.0 response with bogus (to be ignored) Transfer-Encoding.
+ // With a Content-Length.
+ {
+ "HTTP/1.0 200 OK\r\n" +
+ "Transfer-Encoding: bogus\r\n" +
+ "Content-Length: 10\r\n" +
+ "\r\n" +
+ "Body here\n",
+
+ Response{
+ Status: "200 OK",
+ StatusCode: 200,
+ Proto: "HTTP/1.0",
+ ProtoMajor: 1,
+ ProtoMinor: 0,
+ Request: dummyReq("GET"),
+ Header: Header{
+ "Content-Length": {"10"},
+ },
+ Close: true,
+ ContentLength: 10,
+ },
+
+ "Body here\n",
+ },
}
+// tests successful calls to ReadResponse, and inspects the returned Response.
+// For error cases, see TestReadResponseErrors below.
func TestReadResponse(t *testing.T) {
for i, tt := range respTests {
resp, err := ReadResponse(bufio.NewReader(strings.NewReader(tt.Raw)), tt.Resp.Request)
@@ -624,6 +675,7 @@ var responseLocationTests = []responseLocationTest{
{"/foo", "http://bar.com/baz", "http://bar.com/foo", nil},
{"http://foo.com/", "http://bar.com/baz", "http://foo.com/", nil},
{"", "http://bar.com/baz", "", ErrNoLocation},
+ {"/bar", "", "/bar", nil},
}
func TestLocationResponse(t *testing.T) {
@@ -702,13 +754,106 @@ func TestResponseContentLengthShortBody(t *testing.T) {
}
}
-func TestReadResponseUnexpectedEOF(t *testing.T) {
- br := bufio.NewReader(strings.NewReader("HTTP/1.1 301 Moved Permanently\r\n" +
- "Location: http://example.com"))
- _, err := ReadResponse(br, nil)
- if err != io.ErrUnexpectedEOF {
- t.Errorf("ReadResponse = %v; want io.ErrUnexpectedEOF", err)
+// Test various ReadResponse error cases. (also tests success cases, but mostly
+// it's about errors). This does not test anything involving the bodies. Only
+// the return value from ReadResponse itself.
+func TestReadResponseErrors(t *testing.T) {
+ type testCase struct {
+ name string // optional, defaults to in
+ in string
+ wantErr interface{} // nil, err value, or string substring
+ }
+
+ status := func(s string, wantErr interface{}) testCase {
+ if wantErr == true {
+ wantErr = "malformed HTTP status code"
+ }
+ return testCase{
+ name: fmt.Sprintf("status %q", s),
+ in: "HTTP/1.1 " + s + "\r\nFoo: bar\r\n\r\n",
+ wantErr: wantErr,
+ }
+ }
+
+ version := func(s string, wantErr interface{}) testCase {
+ if wantErr == true {
+ wantErr = "malformed HTTP version"
+ }
+ return testCase{
+ name: fmt.Sprintf("version %q", s),
+ in: s + " 200 OK\r\n\r\n",
+ wantErr: wantErr,
+ }
+ }
+
+ tests := []testCase{
+ {"", "", io.ErrUnexpectedEOF},
+ {"", "HTTP/1.1 301 Moved Permanently\r\nFoo: bar", io.ErrUnexpectedEOF},
+ {"", "HTTP/1.1", "malformed HTTP response"},
+ {"", "HTTP/2.0", "malformed HTTP response"},
+ status("20X Unknown", true),
+ status("abcd Unknown", true),
+ status("二百/两百 OK", true),
+ status(" Unknown", true),
+ status("c8 OK", true),
+ status("0x12d Moved Permanently", true),
+ status("200 OK", nil),
+ status("000 OK", nil),
+ status("001 OK", nil),
+ status("404 NOTFOUND", nil),
+ status("20 OK", true),
+ status("00 OK", true),
+ status("-10 OK", true),
+ status("1000 OK", true),
+ status("999 Done", nil),
+ status("-1 OK", true),
+ status("-200 OK", true),
+ version("HTTP/1.2", nil),
+ version("HTTP/2.0", nil),
+ version("HTTP/1.100000000002", true),
+ version("HTTP/1.-1", true),
+ version("HTTP/A.B", true),
+ version("HTTP/1", true),
+ version("http/1.1", true),
+ }
+ for i, tt := range tests {
+ br := bufio.NewReader(strings.NewReader(tt.in))
+ _, rerr := ReadResponse(br, nil)
+ if err := matchErr(rerr, tt.wantErr); err != nil {
+ name := tt.name
+ if name == "" {
+ name = fmt.Sprintf("%d. input %q", i, tt.in)
+ }
+ t.Errorf("%s: %v", name, err)
+ }
+ }
+}
+
+// wantErr can be nil, an error value to match exactly, or type string to
+// match a substring.
+func matchErr(err error, wantErr interface{}) error {
+ if err == nil {
+ if wantErr == nil {
+ return nil
+ }
+ if sub, ok := wantErr.(string); ok {
+ return fmt.Errorf("unexpected success; want error with substring %q", sub)
+ }
+ return fmt.Errorf("unexpected success; want error %v", wantErr)
+ }
+ if wantErr == nil {
+ return fmt.Errorf("%v; want success", err)
+ }
+ if sub, ok := wantErr.(string); ok {
+ if strings.Contains(err.Error(), sub) {
+ return nil
+ }
+ return fmt.Errorf("error = %v; want an error with substring %q", err, sub)
+ }
+ if err == wantErr {
+ return nil
}
+ return fmt.Errorf("%v; want %v", err, wantErr)
}
func TestNeedsSniff(t *testing.T) {