]> Cypherpunks repositories - gostls13.git/commitdiff
net/http/httptest: guarantee ResponseRecorder.Result returns a non-nil body
authorJack <jackxbritton@gmail.com>
Thu, 19 Jul 2018 12:24:44 +0000 (12:24 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Fri, 20 Jul 2018 19:04:25 +0000 (19:04 +0000)
The doc for ResponseRecorder.Result guarantees that the body of the returned
http.Response will be non-nil, but this only holds 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.

Fixes #26442

Change-Id: I3b2fe4a2541caf9997dbb8978bbaf1f58cd1f471
GitHub-Last-Rev: d802967d89e89c50077fb2d0d455163dcea0eb43
GitHub-Pull-Request: golang/go#26453
Reviewed-on: https://go-review.googlesource.com/124875
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>

src/net/http/httptest/recorder.go
src/net/http/httptest/recorder_test.go

index 1d0310625b8bb0fec012e905d95e406d8f37fff7..67f90b837698a95e13d7b36cda71247b4abdd052 100644 (file)
@@ -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"))
 
index b5f82d23e6037793e958d40303e6a3c7e439ef72..0986554aa88e2e1eee685f3913a8f8bdef2b3f0e 100644 (file)
@@ -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 {
@@ -273,6 +287,15 @@ func TestRecorder(t *testing.T) {
                        },
                        check(hasStatus(200), hasContents("Some body"), hasContentLength(9)),
                },
+               {
+                       "nil ResponseRecorder.Body", // Issue 26642
+                       func(w http.ResponseWriter, r *http.Request) {
+                               w.(*ResponseRecorder).Body = nil
+                               io.WriteString(w, "hi")
+                       },
+                       check(hasResultContents("")), // check we don't crash reading the body
+
+               },
        } {
                t.Run(tt.name, func(t *testing.T) {
                        r, _ := http.NewRequest("GET", "http://foo.com/", nil)