From 07f56fbc0b7b30ac27c0625ab425fcaf210f03a8 Mon Sep 17 00:00:00 2001 From: ismail simsek Date: Fri, 6 Sep 2024 14:07:52 +0200 Subject: [PATCH 1/3] update max bytes reader middleware error message --- backend/httpclient/max_bytes_reader.go | 5 +++-- backend/httpclient/max_bytes_reader_test.go | 20 +++++++++---------- .../response_limit_middleware_test.go | 18 ++++++++--------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/backend/httpclient/max_bytes_reader.go b/backend/httpclient/max_bytes_reader.go index 9bbdce1e3..066b6288a 100644 --- a/backend/httpclient/max_bytes_reader.go +++ b/backend/httpclient/max_bytes_reader.go @@ -24,12 +24,13 @@ var ErrResponseBodyTooLarge = errors.New("http: response body too large") // MaxBytesReader prevents clients from accidentally or maliciously // sending a large request and wasting server resources. func MaxBytesReader(r io.ReadCloser, n int64) io.ReadCloser { - return &maxBytesReader{r: r, n: n} + return &maxBytesReader{r: r, n: n, a: n} } type maxBytesReader struct { r io.ReadCloser // underlying reader n int64 // max bytes remaining + a int64 // the actual limit err error // sticky error } @@ -57,7 +58,7 @@ func (l *maxBytesReader) Read(p []byte) (n int, err error) { n = int(l.n) l.n = 0 - l.err = fmt.Errorf("error: %w, response limit is set to: %d", ErrResponseBodyTooLarge, n) + l.err = fmt.Errorf("error: %w, response limit is set to: %d", ErrResponseBodyTooLarge, l.a) return n, l.err } diff --git a/backend/httpclient/max_bytes_reader_test.go b/backend/httpclient/max_bytes_reader_test.go index 1f48be0bb..9ee01bc0d 100644 --- a/backend/httpclient/max_bytes_reader_test.go +++ b/backend/httpclient/max_bytes_reader_test.go @@ -12,14 +12,14 @@ import ( func TestMaxBytesReader(t *testing.T) { tcs := []struct { - limit int64 - bodyLength int - body string - err error + limit int64 + expectedBodyLength int + expectedBody string + err error }{ - {limit: 1, bodyLength: 1, body: "d", err: errors.New("error: http: response body too large, response limit is set to: 1")}, - {limit: 1000000, bodyLength: 5, body: "dummy", err: nil}, - {limit: 0, bodyLength: 0, body: "", err: errors.New("error: http: response body too large, response limit is set to: 0")}, + {limit: 1, expectedBodyLength: 1, expectedBody: "d", err: errors.New("error: http: response body too large, response limit is set to: 1")}, + {limit: 1000000, expectedBodyLength: 5, expectedBody: "dummy", err: nil}, + {limit: 0, expectedBodyLength: 0, expectedBody: "", err: errors.New("error: http: response body too large, response limit is set to: 0")}, } for _, tc := range tcs { t.Run(fmt.Sprintf("Test MaxBytesReader with limit: %d", tc.limit), func(t *testing.T) { @@ -28,13 +28,13 @@ func TestMaxBytesReader(t *testing.T) { bodyBytes, err := io.ReadAll(readCloser) if err != nil { - require.EqualError(t, tc.err, err.Error()) + require.EqualError(t, err, tc.err.Error()) } else { require.NoError(t, tc.err) } - require.Len(t, bodyBytes, tc.bodyLength) - require.Equal(t, string(bodyBytes), tc.body) + require.Len(t, bodyBytes, tc.expectedBodyLength) + require.Equal(t, tc.expectedBody, string(bodyBytes)) }) } } diff --git a/backend/httpclient/response_limit_middleware_test.go b/backend/httpclient/response_limit_middleware_test.go index 7948fb3ab..ec5b3b810 100644 --- a/backend/httpclient/response_limit_middleware_test.go +++ b/backend/httpclient/response_limit_middleware_test.go @@ -14,14 +14,14 @@ import ( func TestResponseLimitMiddleware(t *testing.T) { tcs := []struct { - limit int64 - bodyLength int - body string - err error + limit int64 + expectedBodyLength int + expectedBody string + err error }{ - {limit: 1, bodyLength: 1, body: "d", err: errors.New("error: http: response body too large, response limit is set to: 1")}, - {limit: 1000000, bodyLength: 5, body: "dummy", err: nil}, - {limit: 0, bodyLength: 5, body: "dummy", err: nil}, + {limit: 1, expectedBodyLength: 1, expectedBody: "d", err: errors.New("error: http: response body too large, response limit is set to: 1")}, + {limit: 1000000, expectedBodyLength: 5, expectedBody: "dummy", err: nil}, + {limit: 0, expectedBodyLength: 5, expectedBody: "dummy", err: nil}, } for _, tc := range tcs { t.Run(fmt.Sprintf("Test ResponseLimitMiddleware with limit: %d", tc.limit), func(t *testing.T) { @@ -51,8 +51,8 @@ func TestResponseLimitMiddleware(t *testing.T) { } require.NoError(t, res.Body.Close()) - require.Len(t, bodyBytes, tc.bodyLength) - require.Equal(t, string(bodyBytes), tc.body) + require.Len(t, bodyBytes, tc.expectedBodyLength) + require.Equal(t, string(bodyBytes), tc.expectedBody) }) } } From 6441e0b45c3abd52b40dd6793eb078107bf62713 Mon Sep 17 00:00:00 2001 From: ismail simsek Date: Fri, 6 Sep 2024 15:10:37 +0200 Subject: [PATCH 2/3] attempt to improve the naming --- backend/httpclient/max_bytes_reader.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/backend/httpclient/max_bytes_reader.go b/backend/httpclient/max_bytes_reader.go index 066b6288a..7a7fd3a4f 100644 --- a/backend/httpclient/max_bytes_reader.go +++ b/backend/httpclient/max_bytes_reader.go @@ -24,14 +24,14 @@ var ErrResponseBodyTooLarge = errors.New("http: response body too large") // MaxBytesReader prevents clients from accidentally or maliciously // sending a large request and wasting server resources. func MaxBytesReader(r io.ReadCloser, n int64) io.ReadCloser { - return &maxBytesReader{r: r, n: n, a: n} + return &maxBytesReader{r: r, remainingBytes: n, actualLimit: n} } type maxBytesReader struct { - r io.ReadCloser // underlying reader - n int64 // max bytes remaining - a int64 // the actual limit - err error // sticky error + r io.ReadCloser // underlying reader + remainingBytes int64 // max bytes remaining + actualLimit int64 // the actual limit + err error // sticky error } func (l *maxBytesReader) Read(p []byte) (n int, err error) { @@ -44,21 +44,21 @@ func (l *maxBytesReader) Read(p []byte) (n int, err error) { // If they asked for a 32KB byte read but only 5 bytes are // remaining, no need to read 32KB. 6 bytes will answer the // question of the whether we hit the limit or go past it. - if int64(len(p)) > l.n+1 { - p = p[:l.n+1] + if int64(len(p)) > l.remainingBytes+1 { + p = p[:l.remainingBytes+1] } n, err = l.r.Read(p) - if int64(n) <= l.n { - l.n -= int64(n) + if int64(n) <= l.remainingBytes { + l.remainingBytes -= int64(n) l.err = err return n, err } - n = int(l.n) - l.n = 0 + n = int(l.remainingBytes) + l.remainingBytes = 0 - l.err = fmt.Errorf("error: %w, response limit is set to: %d", ErrResponseBodyTooLarge, l.a) + l.err = fmt.Errorf("error: %w, response limit is set to: %d", ErrResponseBodyTooLarge, l.actualLimit) return n, l.err } From 63f106f337441474ceeb2be1c2e75606bc4a3675 Mon Sep 17 00:00:00 2001 From: ismail simsek Date: Fri, 6 Sep 2024 15:27:32 +0200 Subject: [PATCH 3/3] rename --- backend/httpclient/max_bytes_reader.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/httpclient/max_bytes_reader.go b/backend/httpclient/max_bytes_reader.go index 7a7fd3a4f..4a9d1cea0 100644 --- a/backend/httpclient/max_bytes_reader.go +++ b/backend/httpclient/max_bytes_reader.go @@ -24,13 +24,13 @@ var ErrResponseBodyTooLarge = errors.New("http: response body too large") // MaxBytesReader prevents clients from accidentally or maliciously // sending a large request and wasting server resources. func MaxBytesReader(r io.ReadCloser, n int64) io.ReadCloser { - return &maxBytesReader{r: r, remainingBytes: n, actualLimit: n} + return &maxBytesReader{r: r, remainingBytes: n, limit: n} } type maxBytesReader struct { r io.ReadCloser // underlying reader remainingBytes int64 // max bytes remaining - actualLimit int64 // the actual limit + limit int64 // the actual limit err error // sticky error } @@ -58,7 +58,7 @@ func (l *maxBytesReader) Read(p []byte) (n int, err error) { n = int(l.remainingBytes) l.remainingBytes = 0 - l.err = fmt.Errorf("error: %w, response limit is set to: %d", ErrResponseBodyTooLarge, l.actualLimit) + l.err = fmt.Errorf("error: %w, response limit is set to: %d", ErrResponseBodyTooLarge, l.limit) return n, l.err }