Skip to content

Commit 82674e6

Browse files
committed
don't enforce deadlines
1 parent 577f6cf commit 82674e6

File tree

3 files changed

+22
-103
lines changed

3 files changed

+22
-103
lines changed

src/net/http/httptest/example_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func ExampleResponseRecorder_requestController() {
4646
}
4747

4848
req := httptest.NewRequest("GET", "http://example.com/bar", strings.NewReader("bar"))
49-
w, req := httptest.NewRecorderWithDeadlineAwareRequest(req)
49+
w := httptest.NewRecorder()
5050
handler(w, req)
5151

5252
resp := w.Result()

src/net/http/httptest/recorder.go

Lines changed: 14 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@ package httptest
66

77
import (
88
"bytes"
9-
"errors"
109
"fmt"
1110
"io"
1211
"net/http"
1312
"net/textproto"
14-
"os"
1513
"strconv"
1614
"strings"
1715
"time"
@@ -45,18 +43,17 @@ type ResponseRecorder struct {
4543
// Flushed is whether the Handler called Flush.
4644
Flushed bool
4745

48-
// ReadDeadline is the read deadline that has been set using
46+
// ReadDeadline is the last read deadline that has been set using
4947
// "net/http".ResponseController
5048
ReadDeadline time.Time
5149

52-
// WriteDeadline is the write deadline that has been set using
50+
// WriteDeadline is the last write deadline that has been set using
5351
// "net/http".ResponseController
5452
WriteDeadline time.Time
5553

5654
result *http.Response // cache of Result's return value
5755
snapHeader http.Header // snapshot of HeaderMap at first Write
5856
wroteHeader bool
59-
requestBody *deadlineBodyReader
6057
}
6158

6259
// NewRecorder returns an initialized ResponseRecorder.
@@ -68,21 +65,6 @@ func NewRecorder() *ResponseRecorder {
6865
}
6966
}
7067

71-
// NewRecorderWithDeadlineAwareRequest returns an initialized ResponseRecorder
72-
// and wraps the body of the HTTP request passed as parameter in a special "io".ReadCloser
73-
// that supports read deadlines.
74-
// The request read deadline can be set using ResponseRecorder.SetReadDeadline
75-
// and "http".ResponseController.
76-
// The body of returned the HTTP request returns an error when the read deadline is reached.
77-
// The read deadline can be inspected by reading ResponseRecorder.ReadDeadline.
78-
func NewRecorderWithDeadlineAwareRequest(r *http.Request) (*ResponseRecorder, *http.Request) {
79-
rw := NewRecorder()
80-
rw.requestBody = &deadlineBodyReader{r.Body, time.Time{}}
81-
r.Body = rw.requestBody
82-
83-
return rw, r
84-
}
85-
8668
// DefaultRemoteAddr is the default remote address to return in RemoteAddr if
8769
// an explicit DefaultRemoteAddr isn't set on ResponseRecorder.
8870
const DefaultRemoteAddr = "1.2.3.4"
@@ -132,10 +114,6 @@ func (rw *ResponseRecorder) writeHeader(b []byte, str string) {
132114
// Write implements http.ResponseWriter. The data in buf is written to
133115
// rw.Body, if not nil.
134116
func (rw *ResponseRecorder) Write(buf []byte) (int, error) {
135-
if !rw.WriteDeadline.IsZero() && time.Now().After(rw.WriteDeadline) {
136-
return 0, os.ErrDeadlineExceeded
137-
}
138-
139117
rw.writeHeader(buf, "")
140118
if rw.Body != nil {
141119
rw.Body.Write(buf)
@@ -146,10 +124,6 @@ func (rw *ResponseRecorder) Write(buf []byte) (int, error) {
146124
// WriteString implements io.StringWriter. The data in str is written
147125
// to rw.Body, if not nil.
148126
func (rw *ResponseRecorder) WriteString(str string) (int, error) {
149-
if !rw.WriteDeadline.IsZero() && time.Now().After(rw.WriteDeadline) {
150-
return 0, os.ErrDeadlineExceeded
151-
}
152-
153127
rw.writeHeader(nil, str)
154128
if rw.Body != nil {
155129
rw.Body.WriteString(str)
@@ -193,10 +167,6 @@ func (rw *ResponseRecorder) WriteHeader(code int) {
193167
// with the recorder. To test whether Flush was
194168
// called, see rw.Flushed.
195169
func (rw *ResponseRecorder) FlushError() error {
196-
if !rw.WriteDeadline.IsZero() && time.Now().After(rw.WriteDeadline) {
197-
return os.ErrDeadlineExceeded
198-
}
199-
200170
if !rw.wroteHeader {
201171
rw.WriteHeader(200)
202172
}
@@ -213,28 +183,28 @@ func (rw *ResponseRecorder) Flush() {
213183

214184
// SetReadDeadline allows using "net/http".ResponseController.SetReadDeadline()
215185
// with the recorder.
186+
//
187+
// The deadline is recorded but is not enforced.
188+
// To prevent flaky tests reads made after the deadline will work
189+
// as if no deadline was set.
190+
//
216191
// To retrieve the deadline, use rw.ReadDeadline.
217-
// To use this method, be sure NewRecorderWithDeadlineAwareRequest
218192
func (rw *ResponseRecorder) SetReadDeadline(deadline time.Time) error {
219-
if rw.requestBody == nil {
220-
return errors.New("The request has not been created using NewRecorderWithDeadlineAwareRequest()")
221-
}
222-
223-
if deadline.After(rw.ReadDeadline) {
224-
rw.ReadDeadline = deadline
225-
rw.requestBody.deadline = deadline
226-
}
193+
rw.ReadDeadline = deadline
227194

228195
return nil
229196
}
230197

231198
// SetWriteDeadline allows using "net/http".ResponseController.SetWriteDeadline()
232199
// with the recorder.
200+
//
201+
// The deadline is recorded but is not enforced.
202+
// To prevent flaky tests writes made after the deadline will work
203+
// as if no deadline was set.
204+
//
233205
// To retrieve the deadline, use rw.WriteDeadline.
234206
func (rw *ResponseRecorder) SetWriteDeadline(deadline time.Time) error {
235-
if deadline.After(rw.WriteDeadline) {
236-
rw.WriteDeadline = deadline
237-
}
207+
rw.WriteDeadline = deadline
238208

239209
return nil
240210
}
@@ -329,16 +299,3 @@ func parseContentLength(cl string) int64 {
329299
}
330300
return int64(n)
331301
}
332-
333-
type deadlineBodyReader struct {
334-
io.ReadCloser
335-
deadline time.Time
336-
}
337-
338-
func (r *deadlineBodyReader) Read(p []byte) (n int, err error) {
339-
if time.Now().After(r.deadline) {
340-
return 0, os.ErrDeadlineExceeded
341-
}
342-
343-
return r.ReadCloser.Read(p)
344-
}

src/net/http/httptest/recorder_test.go

Lines changed: 7 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@
55
package httptest
66

77
import (
8-
"errors"
98
"fmt"
109
"io"
1110
"net/http"
12-
"os"
1311
"testing"
1412
"time"
1513
)
@@ -373,65 +371,29 @@ func TestRecorderPanicsOnNonXXXStatusCode(t *testing.T) {
373371
}
374372
}
375373

376-
type neverEnding byte
377-
378-
func (b neverEnding) Read(p []byte) (n int, err error) {
379-
for i := range p {
380-
p[i] = byte(b)
381-
}
382-
return len(p), nil
383-
}
384-
385-
func TestSetWriteDeadline(t *testing.T) {
374+
func TestRecorderSetWriteDeadline(t *testing.T) {
386375
rw := NewRecorder()
387376
rc := http.NewResponseController(rw)
388377

389-
expected := time.Now().Add(1 * time.Millisecond)
378+
expected := time.Now().Add(1 * time.Second)
390379
if err := rc.SetWriteDeadline(expected); err != nil {
391380
t.Errorf(`"ResponseController.WriteDeadline(): got unexpected error %q`, err)
392381
}
393382

394383
if rw.WriteDeadline != expected {
395384
t.Errorf(`"ResponseRecorder.WriteDeadline: got %q want %q`, rw.WriteDeadline, expected)
396385
}
397-
398-
if _, err := io.Copy(rw, neverEnding('a')); !errors.Is(err, os.ErrDeadlineExceeded) {
399-
t.Errorf(`"ResponseRecorder.Write(): got %q want %q`, err, os.ErrDeadlineExceeded)
400-
}
401-
402-
if _, err := rw.WriteString("a"); !errors.Is(err, os.ErrDeadlineExceeded) {
403-
t.Errorf(`"ResponseRecorder.WriteString(): got %q want %q`, err, os.ErrDeadlineExceeded)
404-
}
405-
406-
if err := rw.FlushError(); !errors.Is(err, os.ErrDeadlineExceeded) {
407-
t.Errorf(`"ResponseRecorder.FlushError(): got %q want %q`, err, os.ErrDeadlineExceeded)
408-
}
409-
410-
if b, _ := rw.Body.ReadByte(); b != 'a' {
411-
t.Errorf(`"ResponseRecorder.Body starts with %q ; want "a"`, b)
412-
}
413386
}
414387

415-
func TestSetReadDeadline(t *testing.T) {
416-
req, _ := http.NewRequest("GET", "https://example.com", neverEnding('a'))
417-
rw, req := NewRecorderWithDeadlineAwareRequest(req)
418-
rc := http.NewResponseController(rw)
388+
func TestRecorderSetReadDeadline(t *testing.T) {
389+
rw := NewRecorder()
419390

420-
expected := time.Now().Add(1 * time.Millisecond)
421-
if err := rc.SetReadDeadline(expected); err != nil {
422-
t.Errorf(`"ResponseController.SetReadDeadline(): got unexpected error %q`, err)
391+
expected := time.Now().Add(1 * time.Second)
392+
if err := rw.SetReadDeadline(expected); err != nil {
393+
t.Errorf(`"ResponseRecorder.SetReadDeadline(): got unexpected error %q`, err)
423394
}
424395

425396
if rw.ReadDeadline != expected {
426397
t.Errorf(`"ResponseRecorder.ReadDeadline: got %q want %q`, rw.ReadDeadline, expected)
427398
}
428-
429-
data, err := io.ReadAll(req.Body)
430-
if !errors.Is(err, os.ErrDeadlineExceeded) {
431-
t.Errorf(`"ResponseRecorder.GetDeadlineRequestBody(): got %q want %q`, err, os.ErrDeadlineExceeded)
432-
}
433-
434-
if b := data[0]; b != 'a' {
435-
t.Errorf(`Request Body starts with %q ; want "a"`, b)
436-
}
437399
}

0 commit comments

Comments
 (0)