diff --git a/src/pkg/net/http/client_test.go b/src/pkg/net/http/client_test.go index d224380298..57a9dd9574 100644 --- a/src/pkg/net/http/client_test.go +++ b/src/pkg/net/http/client_test.go @@ -26,6 +26,31 @@ var robotsTxtHandler = HandlerFunc(func(w ResponseWriter, r *Request) { fmt.Fprintf(w, "User-agent: go\nDisallow: /something/") }) +// pedanticReadAll works like ioutil.ReadAll but additionally +// verifies that r obeys the documented io.Reader contract. +func pedanticReadAll(r io.Reader) (b []byte, err error) { + var bufa [64]byte + buf := bufa[:] + for { + n, err := r.Read(buf) + if n == 0 && err == nil { + return nil, fmt.Errorf("Read: n=0 with err=nil") + } + b = append(b, buf[:n]...) + if err == io.EOF { + n, err := r.Read(buf) + if n != 0 || err != io.EOF { + return nil, fmt.Errorf("Read: n=%d err=%#v after EOF", n, err) + } + return b, nil + } + if err != nil { + return b, err + } + } + panic("unreachable") +} + func TestClient(t *testing.T) { ts := httptest.NewServer(robotsTxtHandler) defer ts.Close() @@ -33,7 +58,7 @@ func TestClient(t *testing.T) { r, err := Get(ts.URL) var b []byte if err == nil { - b, err = ioutil.ReadAll(r.Body) + b, err = pedanticReadAll(r.Body) r.Body.Close() } if err != nil { diff --git a/src/pkg/net/http/transfer.go b/src/pkg/net/http/transfer.go index 2670d77ef0..d25c8fcde4 100644 --- a/src/pkg/net/http/transfer.go +++ b/src/pkg/net/http/transfer.go @@ -537,7 +537,9 @@ func (b *body) Read(p []byte) (n int, err error) { // Read the final trailer once we hit EOF. if err == io.EOF && b.hdr != nil { - err = b.readTrailer() + if e := b.readTrailer(); e != nil { + err = e + } b.hdr = nil } return n, err