Skip to content

Commit c29ced9

Browse files
Leo Diaz Sanchezncw
authored andcommitted
limit error in response body to 1024 bytes
1 parent efce653 commit c29ced9

File tree

2 files changed

+93
-11
lines changed

2 files changed

+93
-11
lines changed

swift.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@ import (
2525
)
2626

2727
const (
28-
DefaultUserAgent = "goswift/1.0" // Default user agent
29-
DefaultRetries = 3 // Default number of retries on token expiry
30-
TimeFormat = "2006-01-02T15:04:05" // Python date format for json replies parsed as UTC
31-
UploadTar = "tar" // Data format specifier for Connection.BulkUpload().
32-
UploadTarGzip = "tar.gz" // Data format specifier for Connection.BulkUpload().
33-
UploadTarBzip2 = "tar.bz2" // Data format specifier for Connection.BulkUpload().
34-
allContainersLimit = 10000 // Number of containers to fetch at once
35-
allObjectsChanLimit = 1000 // Number objects to fetch when fetching to a channel
28+
DefaultUserAgent = "goswift/1.0" // Default user agent
29+
DefaultRetries = 3 // Default number of retries on token expiry
30+
TimeFormat = "2006-01-02T15:04:05" // Python date format for json replies parsed as UTC
31+
UploadTar = "tar" // Data format specifier for Connection.BulkUpload().
32+
UploadTarGzip = "tar.gz" // Data format specifier for Connection.BulkUpload().
33+
UploadTarBzip2 = "tar.bz2" // Data format specifier for Connection.BulkUpload().
34+
allContainersLimit = 10000 // Number of containers to fetch at once
35+
allObjectsChanLimit = 1000 // Number objects to fetch when fetching to a channel
36+
respBodyErrSizeLimit = 1024 // Maximum size of response body to read when appending to error messages
3637
)
3738

3839
// ObjectType is the type of the swift object, regular, static large,
@@ -417,12 +418,14 @@ func appendResponseBodyToError(resp *http.Response, err error) error {
417418
return err
418419
}
419420

420-
body, readErr := io.ReadAll(resp.Body)
421-
if readErr != nil || len(body) == 0 {
421+
buf := make([]byte, respBodyErrSizeLimit)
422+
limitedReader := io.LimitReader(resp.Body, respBodyErrSizeLimit)
423+
n, readErr := limitedReader.Read(buf)
424+
if readErr != nil || n == 0 {
422425
return err
423426
}
424427

425-
trimmed := strings.TrimSpace(string(body))
428+
trimmed := strings.TrimSpace(string(buf[:n]))
426429
if trimmed == "" {
427430
return err
428431
}

swift_internal_test.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"net/http"
1515
"os"
1616
"reflect"
17+
"strings"
1718
"testing"
1819
"time"
1920
)
@@ -285,6 +286,84 @@ func TestInternalParseHeaders(t *testing.T) {
285286
}
286287
}
287288

289+
func TestInternalParseHeadersWithErrorMessageInBody(t *testing.T) {
290+
testCases := []struct {
291+
name string
292+
resp *http.Response
293+
errMap map[int]error
294+
expected string
295+
}{
296+
{
297+
name: "Container error with body",
298+
resp: &http.Response{
299+
StatusCode: 400,
300+
Header: http.Header{
301+
"Content-Type": []string{"text/plain"},
302+
},
303+
ContentLength: 15,
304+
Body: io.NopCloser(strings.NewReader("Body message")),
305+
Status: "Status message",
306+
},
307+
errMap: ContainerErrorMap,
308+
expected: "Bad Request: Body message",
309+
},
310+
{
311+
name: "Error with body",
312+
resp: &http.Response{
313+
StatusCode: 400,
314+
Header: http.Header{
315+
"Content-Type": []string{"text/plain"},
316+
},
317+
ContentLength: 15,
318+
Body: io.NopCloser(strings.NewReader("Body message")),
319+
Status: "Status message",
320+
},
321+
errMap: nil,
322+
expected: "HTTP Error: 400: Status message: Body message",
323+
},
324+
{
325+
name: "Object error with body",
326+
resp: &http.Response{
327+
StatusCode: 400,
328+
Header: http.Header{
329+
"Content-Type": []string{"text/plain"},
330+
},
331+
ContentLength: 15,
332+
Body: io.NopCloser(strings.NewReader("Body message")),
333+
Status: "Status message",
334+
},
335+
errMap: objectErrorMap,
336+
expected: "Bad Request: Body message",
337+
},
338+
{
339+
name: "Object error with body over 1024 bytes",
340+
resp: &http.Response{
341+
StatusCode: 400,
342+
Header: http.Header{
343+
"Content-Type": []string{"text/plain"},
344+
},
345+
ContentLength: 1025,
346+
Body: io.NopCloser(strings.NewReader(strings.Repeat("a", 1025))),
347+
Status: "Status message",
348+
},
349+
errMap: objectErrorMap,
350+
expected: fmt.Sprintf("%s: %s", "Bad Request", strings.Repeat("a", 1024)),
351+
},
352+
}
353+
354+
for _, tc := range testCases {
355+
t.Run(tc.name, func(t *testing.T) {
356+
err := c.parseHeaders(tc.resp, tc.errMap)
357+
if err == nil {
358+
t.Fatalf("Expected error, got nil")
359+
}
360+
if err.Error() != tc.expected {
361+
t.Errorf("Expected error %q, got %q", tc.expected, err.Error())
362+
}
363+
})
364+
}
365+
}
366+
288367
func TestInternalReadHeaders(t *testing.T) {
289368
resp := &http.Response{Header: http.Header{}}
290369
compareMaps(t, readHeaders(resp), Headers{})

0 commit comments

Comments
 (0)