Skip to content

Commit ea143c2

Browse files
Thomasdezeeuwbradfitz
authored andcommitted
net/http/httptest: fill ContentLength in recorded Response
This change fills the ContentLength field in the http.Response returned by ResponseRecorder.Result. Fixes #16952. Change-Id: I9c49b1bf83e3719b5275b03a43aff5033156637d Reviewed-on: https://go-review.googlesource.com/28302 Reviewed-by: Brad Fitzpatrick <[email protected]> Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent e69d63e commit ea143c2

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

src/net/http/httptest/recorder.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"bytes"
99
"io/ioutil"
1010
"net/http"
11+
"strconv"
12+
"strings"
1113
)
1214

1315
// ResponseRecorder is an implementation of http.ResponseWriter that
@@ -162,6 +164,7 @@ func (rw *ResponseRecorder) Result() *http.Response {
162164
if rw.Body != nil {
163165
res.Body = ioutil.NopCloser(bytes.NewReader(rw.Body.Bytes()))
164166
}
167+
res.ContentLength = parseContentLength(res.Header.Get("Content-Length"))
165168

166169
if trailers, ok := rw.snapHeader["Trailer"]; ok {
167170
res.Trailer = make(http.Header, len(trailers))
@@ -186,3 +189,20 @@ func (rw *ResponseRecorder) Result() *http.Response {
186189
}
187190
return res
188191
}
192+
193+
// parseContentLength trims whitespace from s and returns -1 if no value
194+
// is set, or the value if it's >= 0.
195+
//
196+
// This a modified version of same function found in net/http/transfer.go. This
197+
// one just ignores an invalid header.
198+
func parseContentLength(cl string) int64 {
199+
cl = strings.TrimSpace(cl)
200+
if cl == "" {
201+
return -1
202+
}
203+
n, err := strconv.ParseInt(cl, 10, 64)
204+
if err != nil {
205+
return -1
206+
}
207+
return n
208+
}

src/net/http/httptest/recorder_test.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ func TestRecorder(t *testing.T) {
9494
return nil
9595
}
9696
}
97+
hasContentLength := func(length int64) checkFunc {
98+
return func(rec *ResponseRecorder) error {
99+
if got := rec.Result().ContentLength; got != length {
100+
return fmt.Errorf("ContentLength = %d; want %d", got, length)
101+
}
102+
return nil
103+
}
104+
}
97105

98106
tests := []struct {
99107
name string
@@ -141,7 +149,7 @@ func TestRecorder(t *testing.T) {
141149
w.(http.Flusher).Flush() // also sends a 200
142150
w.WriteHeader(201)
143151
},
144-
check(hasStatus(200), hasFlush(true)),
152+
check(hasStatus(200), hasFlush(true), hasContentLength(-1)),
145153
},
146154
{
147155
"Content-Type detection",
@@ -244,6 +252,16 @@ func TestRecorder(t *testing.T) {
244252
hasNotHeaders("X-Bar"),
245253
),
246254
},
255+
{
256+
"setting Content-Length header",
257+
func(w http.ResponseWriter, r *http.Request) {
258+
body := "Some body"
259+
contentLength := fmt.Sprintf("%d", len(body))
260+
w.Header().Set("Content-Length", contentLength)
261+
io.WriteString(w, body)
262+
},
263+
check(hasStatus(200), hasContents("Some body"), hasContentLength(9)),
264+
},
247265
}
248266
r, _ := http.NewRequest("GET", "http://foo.com/", nil)
249267
for _, tt := range tests {

0 commit comments

Comments
 (0)