From d802967d89e89c50077fb2d0d455163dcea0eb43 Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 18 Jul 2018 19:34:26 -0400 Subject: [PATCH] net/http/httptest: guarantee ResponseRecorder.Result returns a non-nil body The doc for ResponseRecorder.Result guarantees that the body of the returned http.Response will be non-nil, but this is only true if the caller's body is non-nil. With this change, if the caller's body is nil then the returned response's body will be an empty io.ReadCloser. --- src/net/http/httptest/recorder.go | 2 ++ src/net/http/httptest/recorder_test.go | 27 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/net/http/httptest/recorder.go b/src/net/http/httptest/recorder.go index 1d0310625b..67f90b8376 100644 --- a/src/net/http/httptest/recorder.go +++ b/src/net/http/httptest/recorder.go @@ -184,6 +184,8 @@ func (rw *ResponseRecorder) Result() *http.Response { res.Status = fmt.Sprintf("%03d %s", res.StatusCode, http.StatusText(res.StatusCode)) if rw.Body != nil { res.Body = ioutil.NopCloser(bytes.NewReader(rw.Body.Bytes())) + } else { + res.Body = http.NoBody } res.ContentLength = parseContentLength(res.Header.Get("Content-Length")) diff --git a/src/net/http/httptest/recorder_test.go b/src/net/http/httptest/recorder_test.go index b5f82d23e6..20172130ef 100644 --- a/src/net/http/httptest/recorder_test.go +++ b/src/net/http/httptest/recorder_test.go @@ -7,6 +7,7 @@ package httptest import ( "fmt" "io" + "io/ioutil" "net/http" "testing" ) @@ -39,6 +40,19 @@ func TestRecorder(t *testing.T) { return nil } } + hasResultContents := func(want string) checkFunc { + return func(rec *ResponseRecorder) error { + contentBytes, err := ioutil.ReadAll(rec.Result().Body) + if err != nil { + return err + } + contents := string(contentBytes) + if contents != want { + return fmt.Errorf("Result().Body = %s; want %s", contents, want) + } + return nil + } + } hasContents := func(want string) checkFunc { return func(rec *ResponseRecorder) error { if rec.Body.String() != want { @@ -286,4 +300,17 @@ func TestRecorder(t *testing.T) { } }) } + + // Test that even when a ResponseRecorder's body is nil, + // it will not return a response with nil body. + // Issue 26642 + t.Run("setting ResponseRecord.Body to nil", func(t *testing.T) { + rec := NewRecorder() + rec.Body = nil + check := hasResultContents("") + if err := check(rec); err != nil { + t.Error(err) + } + }) + }