Skip to content

Commit 55e6e82

Browse files
earthboundkidneild
authored andcommitted
net/http: add MaxBytesHandler
Fixes #39567 Change-Id: I226089b678a6a13d7ce69f360a23fc5bd297d550 GitHub-Last-Rev: 6435fd5 GitHub-Pull-Request: #48104 Reviewed-on: https://go-review.googlesource.com/c/go/+/346569 Trust: Damien Neil <dneil@google.com> Trust: Ian Lance Taylor <iant@golang.org> Run-TryBot: Damien Neil <dneil@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Damien Neil <dneil@google.com>
1 parent 36dbf7f commit 55e6e82

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

src/net/http/serve_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6682,3 +6682,63 @@ func testQuerySemicolon(t *testing.T, query string, wantX string, allowSemicolon
66826682
}
66836683
}
66846684
}
6685+
6686+
func TestMaxBytesHandler(t *testing.T) {
6687+
setParallel(t)
6688+
defer afterTest(t)
6689+
6690+
for _, maxSize := range []int64{100, 1_000, 1_000_000} {
6691+
for _, requestSize := range []int64{100, 1_000, 1_000_000} {
6692+
t.Run(fmt.Sprintf("max size %d request size %d", maxSize, requestSize),
6693+
func(t *testing.T) {
6694+
testMaxBytesHandler(t, maxSize, requestSize)
6695+
})
6696+
}
6697+
}
6698+
}
6699+
6700+
func testMaxBytesHandler(t *testing.T, maxSize, requestSize int64) {
6701+
var (
6702+
handlerN int64
6703+
handlerErr error
6704+
)
6705+
echo := HandlerFunc(func(w ResponseWriter, r *Request) {
6706+
var buf bytes.Buffer
6707+
handlerN, handlerErr = io.Copy(&buf, r.Body)
6708+
io.Copy(w, &buf)
6709+
})
6710+
6711+
ts := httptest.NewServer(MaxBytesHandler(echo, maxSize))
6712+
defer ts.Close()
6713+
6714+
c := ts.Client()
6715+
var buf strings.Builder
6716+
body := strings.NewReader(strings.Repeat("a", int(requestSize)))
6717+
res, err := c.Post(ts.URL, "text/plain", body)
6718+
if err != nil {
6719+
t.Errorf("unexpected connection error: %v", err)
6720+
} else {
6721+
_, err = io.Copy(&buf, res.Body)
6722+
res.Body.Close()
6723+
if err != nil {
6724+
t.Errorf("unexpected read error: %v", err)
6725+
}
6726+
}
6727+
if handlerN > maxSize {
6728+
t.Errorf("expected max request body %d; got %d", maxSize, handlerN)
6729+
}
6730+
if requestSize > maxSize && handlerErr == nil {
6731+
t.Error("expected error on handler side; got nil")
6732+
}
6733+
if requestSize <= maxSize {
6734+
if handlerErr != nil {
6735+
t.Errorf("%d expected nil error on handler side; got %v", requestSize, handlerErr)
6736+
}
6737+
if handlerN != requestSize {
6738+
t.Errorf("expected request of size %d; got %d", requestSize, handlerN)
6739+
}
6740+
}
6741+
if buf.Len() != int(handlerN) {
6742+
t.Errorf("expected echo of size %d; got %d", handlerN, buf.Len())
6743+
}
6744+
}

src/net/http/server.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3610,3 +3610,12 @@ func tlsRecordHeaderLooksLikeHTTP(hdr [5]byte) bool {
36103610
}
36113611
return false
36123612
}
3613+
3614+
// MaxBytesHandler returns a Handler that runs h with its ResponseWriter and Request.Body wrapped by a MaxBytesReader.
3615+
func MaxBytesHandler(h Handler, n int64) Handler {
3616+
return HandlerFunc(func(w ResponseWriter, r *Request) {
3617+
r2 := *r
3618+
r2.Body = MaxBytesReader(w, r.Body, n)
3619+
h.ServeHTTP(w, &r2)
3620+
})
3621+
}

0 commit comments

Comments
 (0)