From: Gustavo Niemeyer Date: Wed, 16 Nov 2011 19:35:47 +0000 (-0200) Subject: net/http: fix EOF handling on response body X-Git-Tag: weekly.2011-11-18~34 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=c9355596cde33fe025e801066ee718a9941124c9;p=gostls13.git net/http: fix EOF handling on response body http.Response is currently returning 0, nil on EOF. R=golang-dev, bradfitz, bradfitz CC=golang-dev https://golang.org/cl/5394047 --- 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